Mysensor hang on gw.send.... (and possibly roasting radios)
-
Hi all,
Mylibrary version: 1.5
Arduino Pro Mini (power LED cut to save battery)
DHT11 temperature sensor
3.3V FTDI USB cableI'm trying to build a battery powered temperatures sensor for my wife's green house. I have the device wake up every 15 minutes (will eventually do longer sleep times).
However, I'm having trouble with the code 'locking up' (I'm assuming it's hitting one of the "while(1)" loops in the mysensor code). It seems to happen after somewhere between 12 and 14 hours of running fine. I've pasted the code below, as well as a debug trace. It seems to be locking up somewhere in the gw.send(tempF, 0) call, as it's sending the updated temperature. This has happened in the same place several times. Some of the transmits fail, but that may be due to the fact that my 'dev' laptop has been probably on the outer edge of the range for the radio. But the same behavior happens even well within range. It also doesn't matter if I have it battery powered (two AAs) or powered from my laptop and FTDI cable.
When it hangs, the onboard "pin 13" LED remains lit (so presumably the SCK connected to pin 13) is held high at that point).
What is the best method folks have for debugging/troubleshooting these hangs? Do you just go into the mysensor code and riddle it with Serial.prints? I can do that, just want to minimize the dev churn as it takes it between 12 and 24 hours to fail ). Any other tips for troubleshooting this?
it may be related, but maybe not. I also seem to have killed two radios while trying to figure this out. Some times, after a certain number of hitting the 'reset' button the mini, I start getting "radio init failed" messages. Swapping out for a new radio brings it back. This has happened twice. However, it does NOT correspond to the hang-ups (i.e. I can 'reset' after a hang up and have it work again fine for a while). So maybe related, maybe not. Everything is wired on a breadboard right now. I power the radio and DHT11 from the VCC pin of the Mini.
Also, for the loop in the code below -- to try to improve a little of the accuracy of the DHT11, I read 10 values and calculate the average before sending the temps (eventually I'll be replacing the DHT with something more accurate). Just testing at this point.
Anyway - the code
#include <MySensor.h> #include <SPI.h> #include "DHT.h" //#define DEBUG DHT dht; #define NUMSAMPLES 10 int fTotal = 0.0; int iCount = 0; float humidity = 0.0; float temperature = 0.0; float averageTemp = 0.0; int BATTERY_SENSE_PIN = A0; int oldBatteryPcnt = 0; // 15 minutes #define SLEEP_TIME 900000 // in milliseconds MySensor gw; // Initialize temperature message MyMessage msg(0,V_TEMP); void setup() { // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif gw.begin(); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("Temperature Sensor/DHT/Battery", "1.0"); gw.present(0, S_TEMP); // Serial.begin(9600); #ifdef DEBUG Serial.println(); Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)"); #endif dht.setup(2); // data pin 2 } void loop() { // put your main code here, to run repeatedly: // Process incoming messages (like config from server) gw.process(); bool isMetric = gw.getConfig().isMetric; // bool isMetric = false; #ifdef DEBUG Serial.println("ismetric = " + String(isMetric)); #endif for(iCount = 0; iCount < NUMSAMPLES; iCount++) { delay(dht.getMinimumSamplingPeriod()); humidity = dht.getHumidity(); temperature = dht.getTemperature(); #ifdef DEBUG Serial.print(dht.getStatusString()); Serial.print("\t"); Serial.print(humidity, 1); Serial.print("\t\t"); Serial.print(temperature, 1); Serial.print("\t\t"); Serial.println(dht.toFahrenheit(temperature), 1); #endif fTotal += temperature; } averageTemp = fTotal / (NUMSAMPLES * 1.0); #ifdef DEBUG Serial.print("average tempC: "); Serial.println(averageTemp); #endif fTotal = 0.0; if(isMetric) { #ifdef DEBUG Serial.println("Sending C data..." + String(averageTemp)); #endif gw.send(msg.set(averageTemp, 0)); } else { float tempF = (averageTemp * 1.8) + 32.0; #ifdef DEBUG Serial.println("Sending F data..." + String(tempF)); #endif gw.send(msg.set(tempF, 0)); } // get the battery Voltage int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG Serial.println(sensorValue); #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003363075; int batteryPcnt = sensorValue / 10; #ifdef DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { #ifdef DEBUG Serial.println("Sending updated battery level"); #endif gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } #ifdef DEBUG Serial.println("nighty night..."); #endif gw.sleep(SLEEP_TIME); #ifdef DEBUG Serial.println("Good morning!"); #endif }
and the debug lines...
send: 3-3-0-0 s=255,c=0,t=17,pt=0,l=3,sg=0,st=ok:1.5
send: 3-3-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
read: 0-0-3 s=255,c=3,t=6,pt=0,l=1,sg=0:I
sensor started, id=3, parent=0, distance=1
send: 3-3-0-0 s=255,c=3,t=11,pt=0,l=25,sg=0,st=ok:Temperature Sensor/DHT/Ba
send: 3-3-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.0
send: 3-3-0-0 s=0,c=0,t=6,pt=0,l=0,sg=0,st=ok:Status Humidity (%) Temperature (C) (F)
gw config= 0
OK 34.0 23.0 73.4
OK 33.0 23.0 73.4
OK 33.0 23.0 73.4
OK 33.0 23.0 73.4
OK 32.0 23.0 73.4
OK 33.0 23.0 73.4
OK 33.0 23.0 73.4
OK 33.0 23.0 73.4
OK 33.0 23.0 73.4
OK 32.0 23.0 73.4
average tempC: 23.00
Sending F data...73.40
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=fail:73
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
Sending updated battery level
send: 3-3-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:102
night night...
Good morning!
gw config= 0
OK 33.0 23.0 73.4
TIMEOUT nan nan nan
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 34.0 22.0 71.6
OK 34.0 22.0 71.6
OK 33.0 22.0 71.6
average tempC: 17.60
Sending F data...63.68
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:64
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 33.0 22.0 71.6
OK 32.0 21.0 69.8
OK 34.0 22.0 71.6
OK 32.0 22.0 71.6
OK 32.0 21.0 69.8
OK 31.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
OK 33.0 22.0 71.6
average tempC: 21.80
Sending F data...71.24
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:71
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 33.0 21.0 69.8
OK 34.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
OK 33.0 21.0 69.8
average tempC: 21.00
Sending F data...69.80
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:70
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 33.0 21.0 69.8
OK 29.0 17.0 62.6
OK 31.0 18.0 64.4
OK 31.0 17.0 62.6
OK 32.0 17.0 62.6
OK 30.0 17.0 62.6
OK 30.0 17.0 62.6
OK 32.0 17.0 62.6
OK 40.0 20.0 68.0
OK 31.0 17.0 62.6
average tempC: 17.80
Sending F data...64.04
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:64
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 30.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
OK 35.0 17.0 62.6
average tempC: 17.00
Sending F data...62.60
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:63
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...<< some of the rounds cut out for brevity.........>>
Good morning!
gw config= 0
OK 22.0 22.0 71.6
OK 23.0 22.0 71.6
OK 23.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
average tempC: 22.00
Sending F data...71.60
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:72
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 22.0 22.0 71.6
OK 23.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 25.0 21.0 69.8
OK 22.0 21.0 69.8
OK 25.0 21.0 69.8
average tempC: 21.10
Sending F data...69.98
send: 3-3-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=fail:70
1023
Battery Voltage: 3.44 V
Battery percent: 102 %
night night...
Good morning!
gw config= 0
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 21.0 69.8
OK 22.0 22.0 71.6
OK 22.0 22.0 71.6
average tempC: 21.20
Sending F data...70.16
you can see that it dies when trying to send the temperature data.
Any thoughts?
--Steve
-
@stevebus looking at your code i would move this line
bool isMetric = gw.getConfig().isMetric;
to the setup() part and make isMetric a global variable each getConfig call is message to the gateway
And secondly you could add a
gw.wait(500);
after sending the temperature message to the gateway followed by an extra
gw.proccess();
to process any acknowledges from the gw
-
This wouldn't solve the entire problem, but have you tried pulling the power instead of pressing the reset button? Your radio problem might be related to http://forum.mysensors.org/topic/2738/are-we-initializing-the-nrf24l01-correctly and switching the radios causes a "proper" re-initialization, thus making the radio work again. Maybe your old radios work just fine.
-
@BartE - thanks for the tips. are you suggesting these may fix my hanging issue? or just generally good mysensors coding practices and can't hurt?
@mfalkvidd - Certainly could be my problem. Pulling power doesn't reset the radio, but I've only tried that after the radio won't re-initialize with the reset. So maybe I should always restart by power cycling? Any way to 'recover' the bad radios, they don't work even after a power cycle. Has anyone added the code to properly re-initialize the radio yet?