(Solved) Arduino code on ESP8266 keep crashing on submitting CPM to Radmon

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Moderator
  • Moderator
  • Nuts about radioactive everything!
More
2 years 3 months ago - 2 years 3 months ago #5934 by Simomax
Chaps and chapesses, I have an issue with some arduino code constantly crashing my ESP8266 after a random(ish?) length of time. I started this project some months ago, fell into this crash/reboot mess and have pretty much left it alone until yesterday where I'm picking it up to try and get it sorted. Details of the hardware/software and what I have done thus far:

The hardware is a GK Radmon unit (yellow board) with the supplied ESP8266 - https://sites.google.com/site/diygeigercounter/home/gk-radmon
I am running the OLED and an ebay BME280 (temp/humidity/pressure sensor). No changes to original hardware at all.
I am running my own code pretty much from scratch, with the exception of some original functions, such as the HV setup, BME280 init and reading and Radmon submission. I have since changed the Radmon submission code, but not much, and this had no effect.
Features/functions are as follows (with their current state)
Record pulses at interrupt
Calculating CPM - Enabled
Reading BME280 - Disabled
Displaying on OLED - On startup only, after 60 seconds is disabled (unless button is pressed)
Submitting to Blynk - Disabled
Submitting to Radmon - Enabled
Submitting to another webserver - Disabled
Sending CPM to serial (much like the NET-IO GC10) - Disabled
Wifi connection - Always enabled

With the code for Radmon submission disabled this unit ran for over 4 months submitting to my Blynk server without a single hiccup. As soon as the Radmon submission code is enabled it will run for so long (between 5000 and 6000 seconds) then throw an exception (29). I have an extensive debug log, but all it shows is it runs for so long, starts to fail on Radmon submission, then crash, then reboot (internal watchdog timer). Then lather, rinse, repeat, over and over.
I have cut right back on the features of this counter (listed above) so it does little more than just take counts, calculate CPM and then submit to Radmon. I initially thought it was something with the timers clashing, so disabled everything else and still the same. So, with all features 

In the debug log I have recorded overnight the crash intervals are as follows:
Uptime before crash (in seconds since reboot): 5615, 5888, 5409, 5349, 5710, 5709, 5411.
As you can see the crash interval is similar, but not exact and appears to always be between 5000 and 6000 seconds. It was only yesterday I put in the code to count uptime and this is my finding so far.
The original GK Radmon code for Radmon.org submission does exactly the same as the code I pulled from the 'software' page except I had to change the line client.print(int(f_value[CPM])); to client.print(int(CPM))); as it was submitting strange numbers!

So far I know that the unit runs for months with everything enabled except Radmon submission. As soon as Radmon submission is enabled it will crash after some time. With everything disabled and only Radmon submission enabled, it will crash. So this leads me to one of two theories; 1, it is something in the arduino code or library causing the crash. Or 2, it is something hanging up on the Radmon server or sending back something causing the crash. I suspect the former as opposed to the latter, unless mw0uzo can shed any light from logs etc? It is also important to realize that the code I am running differs massively in the way it works to the original code written for the GK Radmon. the original code was designed to make a sample, submit the sample and then go to sleep for a while, wake up and sample again. I think each time this happened it would disconnect from WiFi then reconnect for the next time it woke up. My code is running all the time, and connected to WiFi constantly as it would record results to Blynk every 10 seconds.

Things I have not tried yet:
Re-coding the entire HTTP Radmon.org submission from scratch. Done this. Massive improvement. No crashes so far. I'm running with this for a while.
There is a WiFiClient clientGet function that may work better - not tried as yet I'm talking bollocks. It is just some different code to that I have already. This is running, and well.
Writing a php page on my server to simulate that of Radmon's submission to see if it is some difference between web servers.
Throwing the thing in a drawer, forgetting about it and calling it a day.

Any help on this would be very much welcomed! In fact, help me fix this and I will give you a giant hug!

A portion of the debug log up until and when it crashes:
Uptime: 5349 Seconds
Connecting to radmon.org
Request: GET /radmon.php?function=submit&user=radspod_north&password=My_Submission_Password&value=31&unit=CPM
 HTTP/1.0
HOST: radmon.org

closing connection
Sent to Radmon: OK


Uptime: 5409 Seconds
Connecting to radmon.org
Request: GET /radmon.php?function=submit&user=radspod_north&password=My_Submission_Password&value=35&unit=CPM
 HTTP/1.0
HOST: radmon.org

closing connection
Sent to Radmon: OK


Uptime: 5469 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL


Uptime: 5529 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL


Uptime: 5592 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL


Uptime: 5649 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL


Uptime: 5709 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL

Exception (29):
epc1=0x40206fcf epc2=0x00000000 epc3=0x40100401 excvaddr=0x00000000 depc=0x00000000

ctx: cont 
sp: 3fff0c00 end: 3fff0e80 offset: 01a0

>>>stack>>>
3fff0da0:  ae342452 61646133 61373732 40206fcd  
3fff0db0:  ae342452 00000037 3ffefe60 3ffef9c4  
3fff0dc0:  00577a15 3ffefe58 4020bc08 3ffef9c4  
3fff0dd0:  00577a15 00001f90 3ffef9d8 40206b7c  
3fff0de0:  401071a8 ae342452 401071a8 ae342452  
3fff0df0:  3ffe8a90 00000000 3ffef9a0 4020bf4c  
3fff0e00:  3ffe84e4 00000000 3ffef9a0 40203b6a  
3fff0e10:  00000000 00000000 3ffef55c 40207784  
3fff0e20:  402353c2 3ffefe50 00000000 00000001  
3fff0e30:  40236583 00000002 00000000 40106952  
3fff0e40:  3fff147c 402068fc 3ffefe50 3ffefe58  
3fff0e50:  3ffefa84 3ffef8f0 3ffefe50 402051b2  
3fff0e60:  3fffdad0 00000000 3ffefe50 4020bc54  
3fff0e70:  feefeffe feefeffe 3ffefe60 40100710  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v614f7c32
~ld
Starting Radspod V2......


This is the arduino code function for submitting to Radmon.org. Most is original GK Radmon code, with the exception of where I client.print the URL that I have changed for original code from the Radmon software page (below the commended out section):
void updateRadmon() {
  seconds = millis() / 1000;
  if (config.debugRadmon) { Serial.println("\r\n\r\nUptime: " + String(seconds) + " Seconds"); }
  
  sBuff = "Sent to Radmon: ";
  if (sendToRadmon())sBuff += "OK";        // call function that sends to Radmon.org
  else sBuff += "FAIL";
  if (config.debugRadmon) { Serial.println(sBuff);
  }
}

//----------------------------------------------------------------------------------------------+
//                              RADMON.ORG send function:
// Radmon only accepts CPM value. It's generally slower to connect to and get a response from.
// Sometimes the response isn't captured in DEBUG but the request is usually accepted.
//----------------------------------------------------------------------------------------------+

boolean sendToRadmon() {

  if (config.debugRadmon) {
    Serial.print("Connecting to ");
    Serial.println(RadmonHost);
  }

  const int httpPort = 80;
  if (!client.connect(RadmonHost, httpPort)) {
    if (config.debugRadmon) Serial.println("connection failed");
    return false;                       // report that it didn't connect
  }

  /* Original GK Radmon code
  
  // We now create a URI for the request
  String url = "function=submit&user=";
  url += UserName;
  url += "&password=";
  url += PassWord;
  url += "&value=";
  url += int(CPM);
  url += "&unit=CPM";


  if (config.debugRadmon) {
    Serial.print("Request: ");
    Serial.println(url);
  }

  // This will send the request to the server
  client.print(String("GET /radmon.php?") + url + " HTTP/1.1\r\n" +
               "Host: " + RadmonHost + "\r\n" +
               "Connection: close\r\n\r\n");
               
  End of Original GK Radmon code */
  
  
        if (config.debugRadmon) { Serial.print("Request: GET /radmon.php?function=submit&user="); }
        client.print("GET /radmon.php?function=submit&user=");
        if (config.debugRadmon) { Serial.print(String(UserName) + "&password="); }
        client.print(UserName); client.print("&password=");
        if (config.debugRadmon) { Serial.print(String(PassWord) + "&value="); }
        client.print(PassWord); client.print("&value=");
        if (config.debugRadmon) { Serial.println(String(CPM) + "&unit=CPM"); }
        client.print(int(CPM));
        client.print("&unit=CPM");
        if (config.debugRadmon) { Serial.println(" HTTP/1.0"); }
        client.println(" HTTP/1.0");
        if (config.debugRadmon) { Serial.println("HOST: radmon.org"); }
        client.println("HOST: radmon.org");
        client.println();
  

  delay(100);                            // give some time after request (was 10, changed to 100 to see if that increases stability)

  if (config.debugRadmon) {  // Read all the lines of the reply from server and print them to Serial
    while (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
    Serial.println();
    Serial.println("closing connection");
  }
  client.flush();                       // need to flush or read buffer else it only sends once
  //delay(1000);                        // reported to improve reliability try - if needed
  //client.stop();
  return true;                          // report that it connected
}


This is the full code if anyone is interested with settings.h following:
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include "SSD1306.h"
#include "SSD1306MyFonts.h"
#include <Wire.h>   
#include "SparkFunBME280.h"

#include "settings.h"

BME280 bme280;                          // for Temp, Humidity & pressure
SSD1306 display(0x3c, SDA_PIN, SCL_PIN); // OLED address (0x3c), SDA (GPIO0), SCL(GPIO2)
WiFiClient client;                      // Use WiFiClient class to create TCP connections

IPAddress ip;

int timerTask1, // Calculate CPM
    timerTask2, // Update Radmon
    timerTask3, // Update Blynk
    timerTask4, // Update HTTP
    timerTask5, // Read BME280
    timerTask6, // Update display #1
    timerTask7, // Update display #2
    timerTask8, // Update display #3
    blynkConnected,
    buttonPressed,
    currentDisplay;

long CPM;

float uSvhr,
      humidity,
      temp,
      pressure;
float f_value[3];                       // floats for CPM, Dose, RSSI

String dBuff,
       sBuff;
unsigned int PWMval;                    // PWM setting for HV
unsigned int lastPotVal = 0;            // used for pot HYSTERESIS
volatile unsigned long totalCounts = 0; // Total counts
int cpsCount = 0; // Used for calculating CPM. This var counts the amount of detections in one second
int cpsDispCount; // Used for displaying CPS
int cpmArray[60]; // Array used for storing CPS over 60 seconds. Each index equals the CPS over a given second
int cpmArrayStep = 0; // Used for stepping the index of above array when calculating CPM
float conversionFactor = 0.0057; // Conversion factor for uSv/hr - 0.00833 for LND712 / 0.0057 for SBM-20 / 0.00812 for J305B
int screenMillis;
unsigned long seconds;

SimpleTimer timer;



int lastConnectionAttempt = millis();
int connectionDelay = 5000; // try to reconnect every 5 seconds



void setup() 
{
  Serial.begin(115200);
  delay(500);
  if (config.debugStartup) { Serial.println("Starting Radspod V2......\r\n\r\n"); }
  //Serial.println("Starting Radspod V2......\r\n\r\n"); //------------------------------------------------------------------------------------------------
  if (config.debugStartup) { Serial.println("Setting Pins."); }
  pinMode(LED_PIN, OUTPUT);             // setup LED pin
  pinMode(INT_PIN, INPUT_PULLUP);       //set pin 2 turn on the internal pullup

  if (config.debugStartup) { Serial.println("Setting SDA, SCL Pins."); }
  Wire.pins(SDA_PIN, SCL_PIN);          // define pins used for I2C
  
  if (config.debugStartup) { Serial.println("Starting Wire."); }
  Wire.begin();
  
  if (config.debugStartup) { Serial.println("Setting WiFi Mode."); }
  WiFi.mode(WIFI_STA);

  if (config.debugStartup) { Serial.println("Starting Blynk."); }
  //Serial.println("Starting Blynk."); //------------------------------------------------------------------------------------------------
#if defined(USE_LOCAL_SERVER)
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS, SERVER, PORT);
#else
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
#endif
  while (Blynk.connect() == false) {}
    
  if (config.debugStartup) { Serial.println("Starting OTA."); }
  //Serial.println("Starting OTA."); //------------------------------------------------------------------------------------------------
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();
  ip = WiFi.localIP();
  if (config.debugStartup) { Serial.println(ip); }
  //Serial.println(ip); //------------------------------------------------------------------------------------------------
  
  if (config.debugStartup) { Serial.println("Initializing Display."); }
  // initialize and setup dispaly . . .
  display.init();
  display.flipScreenVertically();       // display pins on top
  display.setContrast(255);
  display.clear();

  display.setFont(ArialMT_Plain_16);
  display.setTextAlignment(TEXT_ALIGN_CENTER);   // center the following (anchor at 64px)
  display.drawString(64, 0, "Radspod V2");      // version #
  display.display();                             // display what you got so far

  if (config.useBME280) {
    if (config.debugStartup) { Serial.println("Initializing BME280."); }
    initBME280();            // initialize BME280 sensor
  }

  if (config.debugStartup) { Serial.println("Attaching Interrupt."); }
  attachInterrupt(INT_PIN, GetEvent, FALLING);   // Geiger event on INT_PIN triggers interrupt
  
  if (config.debugStartup) { Serial.println("Checking HV Pot."); }
  checkHVpot();                         // check the HV pot and set the HV

  if (config.debugStartup) { Serial.println("Writing Display Buffer."); }
  dBuff = String(PWMtoVolts(PWMval));   // convert current PWM to volts and display
  dBuff += " VOLTS";
  
  if (config.debugStartup) { Serial.println("Displaying Buffer."); }
  display.setFont(ArialMT_Plain_24);
  display.drawString(64, 18, dBuff);
  display.setFont(ArialMT_Plain_10);
  display.drawString(64, 52, "Schmoozie version.");
  display.display();
  if (config.debugStartup) { Serial.print(PWMtoVolts(PWMval));
  Serial.println(" Volts"); } 
  if (config.debugStartup) { Serial.println("Setup complete."); }
  delay(2000);
  display.clear(); 
  

// --------------------- Timers --------------------- //
  if (config.debugStartup) { Serial.println("Defining timer tasks."); }
  timerTask1 = timer.setInterval(cpmInterval, calculateCPM);
  if (config.useRM) { timerTask2 = timer.setInterval(radmonInterval, updateRadmon);
    if (config.debugStartup) { Serial.print("Using Radmon. Timer set at "); 
      Serial.println(radmonInterval); 
    }
  }
  if (config.useBL) { timerTask3 = timer.setInterval(blynkInterval, updateBlynk);
    if (config.debugStartup) { Serial.print("Using Blynk. Timer set at "); 
      Serial.println(blynkInterval); 
    }
  }
  if (config.useHT) { timerTask4 = timer.setInterval(httpInterval, updateHTTP);
    if (config.debugStartup) { Serial.print("Using HTTP. Timer set at "); 
      Serial.println(httpInterval); 
    }
  }
  if (config.useBME280) { timerTask5 = timer.setInterval(bme280Interval, readBME280);
    if (config.debugStartup) { Serial.print("Reading BME280. Timer set at "); 
      Serial.println(bme280Interval); 
    }
  }
  
  timerTask6 = timer.setInterval(mainDisplayInterval, updateDisplay);
  timerTask7 = timer.setInterval(secondDisplayInterval, updateDisplay2); // we create then disable this timer to be enabled later
      timer.disable(timerTask7);
  timerTask8 = timer.setInterval(thirdDisplayInterval, updateDisplay3); // we create then disable this timer to be enabled later
      timer.disable(timerTask8);
// ------------------- End Timers ------------------- //


  currentDisplay = 1;
  screenMillis = millis();
  if (config.debugStartup) { Serial.println("Running!!!!"); }
  //Serial.println("Running!!!!\r\n"); // ------------------------------------------------------------------------------------------------
  if (config.debugStartup) { 
    seconds = millis() / 1000;
    Serial.println("\r\n\r\n\r\nUptime: " +  String(seconds) + " Seconds");
  }  
}

void changeDisplay()
{
  if (config.debugDisplay) { Serial.print("\r\nChanging display - current display: "); }
  screenMillis = millis();
  currentDisplay += 1;
  if (currentDisplay > 3) { currentDisplay = 1; }
  if (config.debugDisplay) { Serial.println(String(currentDisplay)); }
  if (currentDisplay == 1)
  {
    timer.disable(timerTask8);
    timer.enable(timerTask6);
    updateDisplay();
  }
  else if (currentDisplay == 2)
  {
    timer.disable(timerTask6);
    timer.enable(timerTask7);
    updateDisplay2();
  }
  else if (currentDisplay == 3)
  {
    timer.disable(timerTask7);
    timer.enable(timerTask8);
    updateDisplay3();    
  }
}

void displayOff()
{
  if (config.debugDisplay) { Serial.println("\r\nDisplay off - stopping display timers."); }
  timer.disable(timerTask6);
  timer.disable(timerTask7);
  timer.disable(timerTask8);
  currentDisplay = 0;
  display.clear();
  display.display();
}

void updateDisplay()
{
  f_value[LAST_RSSI] = WiFi.RSSI();     // RSSI is 0 to -100 - closer to 0 (lower -) the better
  if (config.debugDisplay) { 
    sBuff = "RSSI: ";
    sBuff += String(f_value[LAST_RSSI]);
    sBuff += "db";
    Serial.println(sBuff); 
  }
  display.clear();
  if (config.debugDisplay) { Serial.println("\r\nWriting Display Buffer."); }
  dBuff = "RSSI: ";
  dBuff += String(int(f_value[LAST_RSSI]));   // convert current PWM to volts and display
  dBuff += "db";
  if (config.debugDisplay) { Serial.println("Displaying Buffer."); }
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, dBuff);
  display.setTextAlignment(TEXT_ALIGN_RIGHT);
  display.setFont(ArialMT_Plain_10);
  if (blynkConnected)
  {
    display.drawString(128, 0, "Blynk OK");
  }
  else
  {
    display.drawString(128, 0, "Blynk NOK");
  }
  dBuff = String(CPM);
  dBuff += " CPM";
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_24);
  display.drawString(64, 40, dBuff);
  dBuff = String(uSvhr);
  dBuff += " uSvhr";
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 24, dBuff);
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_10);
  dBuff = String(temp, 1);
  if (config.useCelsius) dBuff += "°C  ";   // degree char is now displaying - was not working
  else dBuff += "°F  ";
  dBuff += String(int(humidity));
  dBuff += "%  ";
  if (config.useBAR) {
    dBuff += String(int(pressure));
    dBuff += "mb";
  }
  else {
    dBuff += String(pressure);
    dBuff += "in";
  }
  if (config.debugDisplay) { 
    Serial.println("Displaying BME280.");
    Serial.println(dBuff); 
  }
  display.drawString(64, 12, dBuff);
  display.display();
  if (screenTimeout > 0 ) {
    if (millis() > screenMillis + screenTimeout) {
      displayOff();
    }
  }
}

void updateDisplay2()
{
  if (totalCounts > 999999999) { totalCounts = 0; }
  sBuff = "Total Counts: ";
  sBuff += String(totalCounts);
  if (config.debugDisplay) { Serial.println(sBuff); }
  f_value[LAST_RSSI] = WiFi.RSSI();     // RSSI is 0 to -100 - closer to 0 (lower -) the better
  display.clear();
  dBuff = "Total: ";
  dBuff += String(totalCounts);   // display total counts
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, dBuff);
  dBuff = " RSSI: ";
  dBuff += String(int(f_value[LAST_RSSI]));   // convert current PWM to volts and display
  dBuff += "db";
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 18, dBuff);
  display.setTextAlignment(TEXT_ALIGN_RIGHT);
  display.setFont(ArialMT_Plain_10);
  if (blynkConnected)
  {
    display.drawString(128, 18, "Blynk OK");
  }
  else
  {
    display.drawString(128, 18, "Blynk NOK");
  }
  checkHVpot();                         // check the HV pot and set the HV
  dBuff = String(PWMtoVolts(PWMval));   // convert current PWM to volts and display
  dBuff += " Volts";
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_24);
  display.drawString(64, 30, dBuff);
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_10);
  dBuff = String(temp, 1);
  if (config.useCelsius) dBuff += "°C  ";   // degree char is now displaying - was not working
  else dBuff += "°F  ";
  dBuff += String(int(humidity));
  dBuff += "%  ";
  if (config.useBAR) {
    dBuff += String(int(pressure));
    dBuff += "mb";
  }
  else {
    dBuff += String(pressure);
    dBuff += "in";
  }
  if (config.debugDisplay) { Serial.println("Displaying BME280.");
  Serial.println(dBuff); }
  display.drawString(64, 54, dBuff);
  display.display();
  if (screenTimeout > 0 ) {
    if (millis() > screenMillis + screenTimeout) {
      displayOff();
    }
  }
}

void updateDisplay3()
{
  if (totalCounts > 999999999) { totalCounts = 0; }
  sBuff = "Total Counts: ";
  sBuff += String(totalCounts);
  if (config.debugDisplay) { Serial.println(sBuff); }
  f_value[LAST_RSSI] = WiFi.RSSI();     // RSSI is 0 to -100 - closer to 0 (lower -) the better
  display.clear();
  dBuff = "Total: ";
  dBuff += String(totalCounts);   // display total counts
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, dBuff);
  dBuff = String(cpsDispCount);   // convert current PWM to volts and display
  dBuff += " CPS";
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_24);
  display.drawString(64, 18, dBuff);
  if (config.debugDisplay) { Serial.println(dBuff); }
  checkHVpot();                         // check the HV pot and set the HV
  dBuff = String(PWMtoVolts(PWMval));   // convert current PWM to volts and display
  dBuff += " Volts";
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 42, dBuff);
  dBuff = String(CPM);   // convert current PWM to volts and display
  dBuff += " CPM";
  display.setTextAlignment(TEXT_ALIGN_RIGHT);
  display.setFont(ArialMT_Plain_10);
  display.drawString(128, 42, dBuff);
  dBuff = " RSSI: ";
  dBuff += String(int(f_value[LAST_RSSI]));   // convert current PWM to volts and display
  dBuff += "db";
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 54, dBuff);
  display.setTextAlignment(TEXT_ALIGN_RIGHT);
  display.setFont(ArialMT_Plain_10);
  if (blynkConnected)
  {
    display.drawString(128, 54, "Blynk OK");
  }
  else
  {
    display.drawString(128, 54, "Blynk NOK");
  }
  display.display();
  if (screenTimeout > 0 ) {
    if (millis() > screenMillis + screenTimeout) {
      displayOff();
    }
  }
}

void updateRadmon() {
  seconds = millis() / 1000;
  if (config.debugRadmon) { Serial.println("\r\n\r\nUptime: " + String(seconds) + " Seconds"); }
  
  sBuff = "Sent to Radmon: ";
  if (sendToRadmon())sBuff += "OK";        // call function that sends to Radmon.org
  else sBuff += "FAIL";
  if (config.debugRadmon) { Serial.println(sBuff);
  }
}

//----------------------------------------------------------------------------------------------+
//                              RADMON.ORG send function:
// Radmon only accepts CPM value. It's generally slower to connect to and get a response from.
// Sometimes the response isn't captured in DEBUG but the request is usually accepted.
//----------------------------------------------------------------------------------------------+

boolean sendToRadmon() {

  if (config.debugRadmon) {
    Serial.print("Connecting to ");
    Serial.println(RadmonHost);
  }

  const int httpPort = 80;
  if (!client.connect(RadmonHost, httpPort)) {
    if (config.debugRadmon) Serial.println("connection failed");
    return false;                       // report that it didn't connect
  }

  /* Original GK Radmon code
  
  // We now create a URI for the request
  String url = "function=submit&user=";
  url += UserName;
  url += "&password=";
  url += PassWord;
  url += "&value=";
  url += int(CPM);
  url += "&unit=CPM";


  if (config.debugRadmon) {
    Serial.print("Request: ");
    Serial.println(url);
  }

  // This will send the request to the server
  client.print(String("GET /radmon.php?") + url + " HTTP/1.1\r\n" +
               "Host: " + RadmonHost + "\r\n" +
               "Connection: close\r\n\r\n");
               
  End of Original GK Radmon code */
  
  
        if (config.debugRadmon) { Serial.print("Request: GET /radmon.php?function=submit&user="); }
        client.print("GET /radmon.php?function=submit&user=");
        if (config.debugRadmon) { Serial.print(String(UserName) + "&password="); }
        client.print(UserName); client.print("&password=");
        if (config.debugRadmon) { Serial.print(String(PassWord) + "&value="); }
        client.print(PassWord); client.print("&value=");
        if (config.debugRadmon) { Serial.println(String(CPM) + "&unit=CPM"); }
        client.print(int(CPM));
        client.print("&unit=CPM");
        if (config.debugRadmon) { Serial.println(" HTTP/1.0"); }
        client.println(" HTTP/1.0");
        if (config.debugRadmon) { Serial.println("HOST: radmon.org"); }
        client.println("HOST: radmon.org");
        client.println();
  

  delay(100);                            // give some time after request (was 10, changed to 100 to see if that increases stability)

  if (config.debugRadmon) {  // Read all the lines of the reply from server and print them to Serial
    while (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
    Serial.println();
    Serial.println("closing connection");
  }
  client.flush();                       // need to flush or read buffer else it only sends once
  //delay(1000);                        // reported to improve reliability try - if needed
  //client.stop();
  return true;                          // report that it connected
}

void updateBlynk() {
  if (config.useBL) {
    checkHVpot();                         // check the HV pot and set the HV
    dBuff = String(PWMtoVolts(PWMval));
    if (config.debugBlynk) { Serial.println("Updating Blynk."); }
    //Serial.print("."); //------------------------------------------------------------------------------------------------
    Blynk.virtualWrite(vPIN_CPM,            CPM);
    Blynk.virtualWrite(vPIN_TEMPERATURE,    String(temp));
    Blynk.virtualWrite(vPIN_HUMIDITY,       String(int(humidity)));
    Blynk.virtualWrite(vPIN_PRESSURE,       String(pressure));
    Blynk.virtualWrite(vPIN_DOSE,           String(uSvhr));
    Blynk.virtualWrite(vPIN_RSSI,           String(f_value[LAST_RSSI]));
    Blynk.virtualWrite(vPIN_VOLTAGE,        String(PWMtoVolts(PWMval)));
    Blynk.virtualWrite(vPIN_TOTALCOUNTS,    String(totalCounts));
    Blynk.virtualWrite(vPIN_DBGDISPLAY,     config.debugDisplay);
    Blynk.virtualWrite(vPIN_DBGRADMON,      config.debugRadmon);
    Blynk.virtualWrite(vPIN_DBGBLYNK,       config.debugBlynk);
    Blynk.virtualWrite(vPIN_DBGHTTP,        config.debugHTTP);
    Blynk.virtualWrite(vPIN_DBGBME280,      config.debugBME280);
    Blynk.virtualWrite(vPIN_DBGCPMCALC,     config.debugCPMcalc);
    Blynk.virtualWrite(vPIN_DBGBUTTONS,     config.debugButtons);
    
  }
}

void updateHTTP() {
  if (config.debugHTTP) { Serial.println("Doing the HTTP thang."); }
}

void readBME280() {
  if (config.debugBME280) { Serial.println("Reading BME280."); }
  float PaPress;

  if (config.useCelsius) temp = bme280.readTempC();   // Convert Celsius to Fahrenheit
  else temp = bme280.readTempF();
  humidity = bme280.readFloatHumidity();              // Read humidity (percent)

  /*----------------------------------------------------------------------------------------------+
     Read pressure and convert to SEA LEVEL PRESSURE . . .
     There are severial methods, the first 3 are here. Now that pow is supported method 4 is used

    Method 1: Simple way to convert to SLP - good for lower elevations - no pow func required
      from: http://www.sandhurstweather.org.uk/barometric.pdf
    //   PaPress = PaPress + (config.elevation / 9.2); // convert to SLP
    Method 2: - adapted from Hans Matlab function
    //   PaPress = 1013.25 * (pow(PaPress / 1013.25, 0.190263) + pow(0.0000225577 * config.elevation, 5.25588));
    Method 3: - adapted from - http://n5jlc.duckdns.org/
    //   PaPress = PaPress / (pow(1 - (config.elevation / 44330.0), 5.255));

    No conversion if elevation = 0.
    /-----------------------------------------------------------------------------------------------*/

  PaPress = bme280.readFloatPressure() / 100.0F; // read pressure convert to mb (100pa = 1hPa = 1mb)

  // Method 4: most accurate sea level conversion, with temp compensation
  // - from http://keisan.casio.com/exec/system/1224575267

  if (config.elevation != 0) {
    double temp1 = 1.0 - (( 0.0065 * config.elevation) / (bme280.readTempC() + (0.0065 * config.elevation ) + 273.15));
    PaPress = PaPress * pow(temp1, -5.257);
  }

  if (config.useBAR) pressure = PaPress; // leave it in millibar
  else pressure = PaPress / 33.8939F;   // convert to inches Hg

  if (config.debugBME280) {                 // print sensor data
    Serial.print("Temperature: ");
    Serial.print(temp, 2);
    Serial.println(" degrees C/F");

    Serial.print("Pressure: ");
    Serial.print(pressure, 2);
    Serial.print(" mb\t");
    Serial.print(PaPress / 33.8939F, 2);
    Serial.println(" Hg");

    Serial.print("Humidity: ");
    Serial.print(humidity, 2);
    Serial.println(" %");
  }
}

void calculateCPM() // Calculate the CPM
{
  if (config.debugCPMcalc) { Serial.print("Calculating CPM: "); }
  cpmArray[cpmArrayStep] = cpsCount; // Set the index in the CPM array to that of the current CPS. The index initially starts at 0 when powered on
  cpmArrayStep++; // The next index we want to record
  if (cpmArrayStep >= 60) // There are 60 indexes, one for every second in a minute. If the index goes out of the bounds of our 60 indexes then cycle back to index 0
  {
    cpmArrayStep = 0;
  }
  CPM = 0; // Var used to temporarily calculate CPM
  unsigned int i;
  for (i = 0; i < 60; i++) // Get the value at each index of the CPM array
  {
    CPM += cpmArray[i]; // Add each index together to give a total over 60 seconds
//    Serial.print(cpmArray[i]);
//    Serial.print(", ");    
  }
//    Serial.println("  ");    
  cpsDispCount = cpsCount; // set this for use on the display as the current cps resets
  cpsCount = 0; // Reset the CPS variable ready for sampling the next second
  if (config.cpmSerialOn) { Serial.println(CPM); } // Print the current CPM to serial every interval if enabled
  else if (config.debugCPMcalc) { Serial.println(CPM); }
  uSvhr = CPM * conversionFactor; // Calculate uSv/hr from CPM using the conversion factor. CPM * conversion Factor = uSv/hr
  if (config.debugCPMcalc) { Serial.print(uSvhr);
  Serial.println(" uSv/hr"); }
}

// This function is called whenever the assigned Widget changes state
BLYNK_WRITE(vPIN_DISPBUTTON) {  // vPin is the Virtual Pin assigned to a Button Widget
 if (param.asInt()) {  // Assumes if 1 then follow through..
  changeDisplay();
 }
}
BLYNK_WRITE(vPIN_DBGDISPLAY) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugDisplay = param.asInt();
}
BLYNK_WRITE(vPIN_DBGRADMON) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugRadmon = param.asInt();
}
BLYNK_WRITE(vPIN_DBGBLYNK) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugBlynk = param.asInt();
}
BLYNK_WRITE(vPIN_DBGHTTP) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugHTTP = param.asInt();
}
BLYNK_WRITE(vPIN_DBGBME280) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugBME280 = param.asInt();
}
BLYNK_WRITE(vPIN_DBGCPMCALC) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugCPMcalc = param.asInt();
}
BLYNK_WRITE(vPIN_DBGBUTTONS) {  // vPin is the Virtual Pin assigned to a Button Widget
  config.debugButtons = param.asInt();
}

void checkHVpot() {
  unsigned int potVal;
  potVal = analogRead(A0); // ADC Pin - 0-1V ONLY!!!
  // don't keep re-adjusting the HV due to normal fluctuations in reading
  if (potVal > lastPotVal + POT_HYSTERESIS || potVal < lastPotVal - POT_HYSTERESIS) {
    PWMval = lmap(potVal, 0, 1023, HV_MIN_PWM, HV_MAX_PWM);
    setHV (PWMval); // set HV
    lastPotVal = potVal;
  }
}

void setHV (int volts) {
  if (volts == 0) analogWrite(PWM_PIN, 0); //must turn off PWM before WiFi
  else {
    analogWriteFreq(2500);              // freq 2.5kHz best (must set first)
    analogWrite(PWM_PIN, volts);        // set the voltage
  }
}

unsigned long PWMtoVolts(unsigned int PWM) {
  //----------------------------------------------------------------------------------------------+
  // Volts against PWM was measured by reading through 1G ohm with manual range set.
  // The data was plotted in Excel and a scatter graph made. Then a linear trend-line was used
  // to derive the formula. A trend line with a max of 700V gave the best results.
  //----------------------------------------------------------------------------------------------+
  unsigned long fVolts;

  fVolts = (float(PWM) * 1.3429) + 130.35;   // v1.2 PCB with STX13005
                                             // conversion r2=0.9979 best for 300V - 700V
  return fVolts;                             // return calculated voltage
}

void initBME280() {
  int tempRtrn;
  bme280.settings.commInterface = I2C_MODE;
  if (config.adr77) bme280.settings.I2CAddress = 0x77; // Adafruit or Sparkfun BME280
  else bme280.settings.I2CAddress = 0x76;              // eBay BME280

  //Run Mode; 0 = Sleep, 1 or 2 = Forced, 3 = Normal
  bme280.settings.runMode = 3;          // = Forced mode - takes reading once, stores it and sleeps

  //Standby; 0-7 = .5ms-20ms (see doc)
  bme280.settings.tStandby = 0;         // = .5ms

  //Filter; bits 0-4 = off-*16 FIR coefficients (see doc)
  bme280.settings.filter = 0;           // = Filter off
  //Temp, Pressure, and humidity OverSample; bits 0-5 = skip-*16 (see doc)
  bme280.settings.tempOverSample = 1;   // = *1
  bme280.settings.pressOverSample = 1;  // = *1
  bme280.settings.humidOverSample = 1;  // = *1

  tempRtrn = bme280.begin(); // init BME280
  if (config.debugStartup) {    // print init results
    Serial.print("bme280.begin= ");
    Serial.print(tempRtrn, HEX);
    if (tempRtrn == 0x60) Serial.println("  Init OK");
    else Serial.println("  Init FAIL");
  }
  delay(10);                            //BME280 requires 2ms to start up.
}

byte readButton(int buttonPin) { // reads LOW ACTIVE push button and debounces
  if (digitalRead(buttonPin)) return HIGH;    // still high, nothing happened, get out
  else {                                      // it's LOW - switch pushed
    delay(DEBOUNCE_MS);                       // wait for debounce period
    if (digitalRead(buttonPin)) return HIGH;  // no longer pressed
    else return LOW;                          // 'twas pressed
  }
}

// rolling your own map function saves a lot of memory
unsigned long lmap(unsigned long x, unsigned long in_min, unsigned long in_max, unsigned long out_min, unsigned long out_max) {
  return x > in_max ? out_max : (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void GetEvent() {  // ISR triggered for each new event (count)
  totalCounts ++; // Increase total counts each time the interrupt is fired
  cpsCount ++; // Increase var each time the interrupt is fired
  digitalWrite(LED_PIN, HIGH);        // flash LED as quickly as possible.
  delayMicroseconds(50);
  digitalWrite(LED_PIN, LOW);
}

void loop() 
{
  // check WiFi connection:
  if (WiFi.status() != WL_CONNECTED)
  {
    // (optional) "offline" part of code
    Serial.println("Blynk - Disconnected!");
    blynkConnected = false;
    // check delay:
    if (millis() - lastConnectionAttempt >= connectionDelay)
    {
      lastConnectionAttempt = millis();  
      // attempt to connect to Wifi network:
      if (WIFI_PASS && strlen(WIFI_PASS))
      {
        WiFi.begin((char*)WIFI_SSID, (char*)WIFI_PASS);
      }
      else
      {
        WiFi.begin((char*)WIFI_SSID);
      }
    }
  }
  else
  {
    Blynk.run();
    ArduinoOTA.handle();
    blynkConnected = true;
  }


  timer.run();
  if (readButton(SET_BUTTON) == LOW)
  {
    buttonPressed = true;
    if (config.debugButtons) { Serial.println("Button Pressed"); }    
  }
  else
  {
    if (buttonPressed == true) {
      buttonPressed = false;
      if (config.debugButtons) { Serial.println("Button Released"); } 
      changeDisplay();
    }
  }
}[/i][/i]


settings.h
#define debug_Startup            true
#define debug_Display            false
#define debug_Radmon             true
#define debug_Blynk              false
#define debug_HTTP               false
#define debug_BME280             false
#define debug_CPMcalc            false
#define debug_Buttons            false


// DEFINE YOUR WIFI NETWORK ...
#define WIFI_SSID             "My_WiFi_SSID"
#define WIFI_PASS             "My_WiFi_Password"

// PICK THE SITES YOU WANT TO SEND TO ...
#define SEND_TO_RADMON      true        // CPM will be sent to Radmon.org
#define SEND_TO_BLYNK       false         // all fields will be sent to Blynk
#define SEND_TO_HTTP        false        // all fields will be sent to HTTP
#define PRINT_TO_SERIAL     false        // prints the current CPM every second to serial.

// For Radmon.org: set the next 3 lines to your Radmon.org UserName and Password . . .
const char* RadmonHost = "radmon.org"; // No need to change this
const char* UserName = "My_Radmon_Username"; //Your Radmon.org user name
const char* PassWord = "My_Submission_Password"; //Your Radmon.org submission password

// Blynk Auth Code
#define AUTH                            "MY_Blynk_Auth_Token"
// Blynk local server settings - comment out to use cloud server
#define USE_LOCAL_SERVER       
#define SERVER                          "myserver.co.uk"
#define PORT                            8080

// Web server and PHP page to post to...
const char* host = "myserver.co.uk";
const int httpPort = 80;
String url = "radspod/north/postdata.php";

// Over The Air Hostname  
#define OTA_HOSTNAME                    "Radspod V2"
// Blynk Virtual Pins - Base
#define vPIN_CPM                   V1
#define vPIN_TEMPERATURE           V2
#define vPIN_HUMIDITY              V3
#define vPIN_PRESSURE              V4
#define vPIN_DOSE                  V5
#define vPIN_RSSI                  V6
#define vPIN_VOLTAGE               V7
#define vPIN_TOTALCOUNTS           V8
#define vPIN_DISPBUTTON            V10
#define vPIN_DBGDISPLAY            V11
#define vPIN_DBGRADMON             V12
#define vPIN_DBGBLYNK              V13
#define vPIN_DBGHTTP               V14
#define vPIN_DBGBME280             V15
#define vPIN_DBGCPMCALC            V16
#define vPIN_DBGBUTTONS            V17

#define cpmInterval                1000     // (in ms) How often the cpm is calculated. Don't change this without changing the array size etc.
#define radmonInterval             60000    // (in ms) How often data is sent to Radmon. Minimum 60 seconds (60000).
#define blynkInterval              10000    // (in ms) How often data is sent to Blynk.
#define httpInterval               10000    // (in ms) How often data is posted to HTTP.
#define bme280Interval             5000     // (in ms) How often the BME280 is read.
#define mainDisplayInterval        2000     // (in ms) How often the main display is updated.
#define secondDisplayInterval      1000     // (in ms) How often the 2nd display is updated.
#define thirdDisplayInterval       1000     // (in ms) How often the 3rd display is updated.
#define screenTimeout              60000    // (in ms) Screen timeout. 0 to disable timeout. OLED will burn if left on permanently


#define USE_BME280       false          // true if BME280 is used
#define USE_ADR77        false          // true = Adafruit or Sparkfun BME-280, false = eBay
#define ELEVATION        0              // elevation in meters if BME280 used
#define USE_BAR          true           // true = millibars, false = inches Hg
#define CELSIUS          true           // true = Celsius, false = Fahrenheit


#define SDA_PIN        0                // I2C SDA pin (pulled up) + PGM button and LED
#define SET_BUTTON     0                // also used to set HV adj mode
// TX                  1                // wired to serial comm
#define SCL_PIN        2                // I2C SCL pin (pulled up)
// RX                  3                // wired to serial comm
#define DONE_PIN       4                // input from solar charger DONE pin
#define PWM_PIN        5                // PWM for HV generation
#define LED_PIN        12               // flashes with count
#define INT_PIN        13               // Geiger events on this pin cause interrupt

#define LAST_RSSI        2              // (can't use "RSSI")
#define POT_HYSTERESIS   1              // amount of change in pot value needed to trigger a recalculation of HV (keeps the value from bouncing around)
#define HV_MIN_PWM       14             // minimum PWM duty - 14/1023 = 1.3% (~100V)
#define HV_MAX_PWM       620            // maximum PWM duty - 620/1023 = 60% (~875V)
#define DEBOUNCE_MS      50             // button debounce period in mS (50 is good)


struct strConfig {
  boolean useRM = SEND_TO_RADMON;
  boolean useBL = SEND_TO_BLYNK;
  boolean useHT = SEND_TO_HTTP;
  boolean cpmSerialOn = PRINT_TO_SERIAL;
  boolean useBME280 = USE_BME280;
  boolean adr77 = USE_ADR77;
  boolean useBAR = USE_BAR;
  boolean useCelsius = CELSIUS;
  boolean debugStartup = debug_Startup;
  boolean debugDisplay = debug_Display;
  boolean debugRadmon = debug_Radmon;
  boolean debugBlynk = debug_Blynk;
  boolean debugHTTP = debug_HTTP;
  boolean debugBME280 = debug_BME280;
  boolean debugCPMcalc = debug_CPMcalc;
  boolean debugButtons = debug_Buttons;
  long elevation = ELEVATION;
  ;
}   config;
Last edit: 2 years 3 months ago by Simomax.

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Moderator
  • Moderator
  • Nuts about radioactive everything!
More
2 years 3 months ago #5935 by Simomax
I forgot to add a couple of things:

I'm using Arduino OTA. This seems to make no difference whether enabled or not. Sometimes the ESP8266 will not recover from a crash and won't reboot, as has just happened now, and requires the reset button pressed or power cycling the unit. Latest debug log where it did not recover from the crash:
Uptime: 5443 Seconds
Connecting to radmon.org
Request: GET /radmon.php?function=submit&user=radspod_north&password=My_Submission_Password&value=27&unit=CPM
 HTTP/1.0
HOST: radmon.org

closing connection
Sent to Radmon: OK


Uptime: 5503 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL


Uptime: 5565 Seconds
Connecting to radmon.org
connection failed
Sent to Radmon: FAIL

Exception (29):
epc1=0x40206fd3 epc2=0x00000000 epc3=0x4020180b excvaddr=0x00000000 depc=0x00000000

ctx: cont 
sp: 3fff0c00 end: 3fff0e80 offset: 01a0

>>>stack>>>
3fff0da0:  ae342452 61646133 61373732 40206fd1  
3fff0db0:  ae342452 00000037 3ffefe60 3ffef9c4  
3fff0dc0:  0055c33c 3ffefe58 4020bc0c 3ffef9c4  
3fff0dd0:  0055c33c 00001f90 3ffef9d8 40206b80  
3fff0de0:  401071a8 ae342452 401071a8 ae342452  
3fff0df0:  3ffe8a90 00000000 3ffef9a0 4020bf50  
3fff0e00:  3ffe84e4 00000000 3ffef9a0 40203b6a  
3fff0e10:  00000000 00000000 3ffef55c 40207788  
3fff0e20:  402353c6 3ffefe50 00000000 00000001  
3fff0e30:  40236587 00000002 3ffef55c 40106952  
3fff0e40:  3fff147c 40206900 3ffefe50 3ffefe58  
3fff0e50:  3ffefa84 3ffef8f0 3ffefe50 402051b2  
3fff0e60:  3fffdad0 00000000 3ffefe50 4020bc58  
3fff0e70:  feefeffe feefeffe 3ffefe60 40100710  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(1,6)


 ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset

After a little digging it appears the memory address responsible(?) for causing the crash is that of the ESP8266 SPI flash memory - Address 40200000h as noted on this page here: https://www.esp8266.com/wiki/doku.php?id=esp8266_memory_map

It is tempting to strip the whole code down to simply connecting to WiFi and submitting a random number (between 10 and 30) to Radmon.org and see what happens. I'm 99% sure this isn't a conflict with other code in the program but is born from the HTTP code itself. I have very similar code running on three other units sending data to my web server and Blynk, with varying hardware (sensors/displays) and those three all run flawlessly. On checking the code for them I notice that I 'POST' the data to my server, as opposed to 'GET' as is used in the radmon.org arduino code. I could do with a new wall for banging my head against.... 
 

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Moderator
  • Moderator
  • Nuts about radioactive everything!
More
2 years 3 months ago #5936 by Simomax
I'm testing different code. I have ditched the old submission function entirely and trying some different code. It is running and submitting fine so far. Will have to see what it is like at >5000 seconds runtime. So far so good.
Uptime: 339 Seconds

Updating Radmon...
>>> Connecting to host: radmon.org
Sending data....
GET /radmon.php?function=submit&user=radspod_north&password=My_Submission_Password&value=39&unit=CPM HTTP/1.1
Host: radmon.org
User-Agent: ESP8266/1.0
Connection: close


End of sending data....

Response:
HTTP/1.1 200 OK
>>> Closing host: radmon.org

Please Log in or Create an account to join the conversation.

More
2 years 3 months ago #5937 by mw0uzo
Got to be something pointery with the string constructor or the HTTP library. It will be interesting to see the new code that works better.

Failing fixing it, I would probably go back to the standard C way of constructing the HTTP request in a character array and use strncpy to place in the strings and a counter to track the write position.

The extra help making things easier with the String type should all be well tested though. I also wonder if the http client should be destroyed and unalloc'd after a request.

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Moderator
  • Moderator
  • Nuts about radioactive everything!
More
2 years 3 months ago - 2 years 3 months ago #5939 by Simomax
The new code has surpassed 9000 seconds uptime. It seems OK so far. Fingers crossed. I have a feeling I know why it was failing with the previous code, and yes, could be what you mention about destroying the http client afterwards. In the previous code (I think) the http client was using an existing instance of WiFiClient. This was being used over and over and whilst there is a flush function it was never stopped. This new code looks like it creates a new instance of WiFiClient each time and stops it after use. 
Uptime: 9039 Seconds

Updating Radmon...
>>> Connecting to host: radmon.org
Sending data....
GET /radmon.php?function=submit&user=radspod_north&password=My_Submission_Password&value=24&unit=CPM HTTP/1.1
Host: radmon.org
User-Agent: ESP8266/1.0
Connection: close


End of sending data....

Response:
HTTP/1.1 200 OK
>>> Closing host: radmon.org

It looks happy. This is the new code below:
void updateRadmon() {
  seconds = millis() / 1000;
  if (config.debugRadmon) {
    Serial.println("\r\nUptime: " + String(seconds) + " Seconds");
  }
  if (config.debugRadmon) {
    Serial.println("\r\nUpdating Radmon...");
  }

  WiFiClient clientGet;
  const int httpGetPort = 80;

  //the path and file to send the data to:
  String urlGet = "/radmon.php";
  urlGet += "?function=submit&user=";
  urlGet += UserName;
  urlGet += "&password=";
  urlGet += PassWord;
  urlGet += "&value=";
  urlGet += int(CPM);
  urlGet += "&unit=CPM";

  if (config.debugRadmon) {
    Serial.print(">>> Connecting to host: ");
    Serial.println(RadmonHost);
  }
  
  if (!clientGet.connect(RadmonHost, httpGetPort)) {
    if (config.debugRadmon) {
      Serial.print("Connection failed: ");
      Serial.println(RadmonHost);
    }
    
  } else {
    if (config.debugRadmon) {
      Serial.println("Sending data....");
    }
    clientGet.println("GET " + urlGet + " HTTP/1.1");
    if (config.debugRadmon) {
      Serial.println("GET " + urlGet + " HTTP/1.1");
    }
    clientGet.print("Host: ");
    clientGet.println(RadmonHost);
    if (config.debugRadmon) {
      Serial.println("Host: " + String(RadmonHost));
    }
    clientGet.println("User-Agent: ESP8266/1.0");
    if (config.debugRadmon) {
      Serial.println("User-Agent: ESP8266/1.0");
    }
    clientGet.println("Connection: close\r\n\r\n");
    if (config.debugRadmon) {
      Serial.println("Connection: close\r\n\r\n");
    }
    
    unsigned long timeoutP = millis();
    while (clientGet.available() == 0) {
      if (millis() - timeoutP > 10000) {
        if (config.debugRadmon) {
          Serial.print(">>> Client Timeout: ");
          Serial.println(RadmonHost);
        }
        clientGet.stop();
        return;
      }
    }
    
    if (config.debugRadmon) {
      Serial.println("End of sending data....\r\n\r\nResponse:");
    }
    
    //just checks the 1st line of the server response. Could be expanded if needed.
    while (clientGet.available()) {
      String retLine = clientGet.readStringUntil('\r');
      if (config.debugRadmon) {
        Serial.println(retLine);
      }
      break;
    }
  } //end client connection if else
  
  if (config.debugRadmon) {
    Serial.print(">>> Closing host: ");
    Serial.println(RadmonHost);
  }
  clientGet.stop();
}
Last edit: 2 years 3 months ago by Simomax.

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Moderator
  • Moderator
  • Nuts about radioactive everything!
More
2 years 3 months ago #5941 by Simomax
17000 seconds uptime! Might have  cracked it. 

Please Log in or Create an account to join the conversation.

Moderators: Gamma-Man
Time to create page: 0.284 seconds
Powered by Kunena Forum
Everything's free. Please support us by considering a donation. Log in first!
Solar powered Raspberry Pi 4 server stats: CPU 42% Memory 14% Swap 12% CPU temp=52.5'C Uptime 19 Days