My sending Moteino stops sending after what appears to be exactly 4 hours. I have run it 3 times now and all three times my receiving Moteino stops getting a signal. I have isolated it to the sender, since once I reset it, I begin getting radio data again. This is bizarre to me, since I don't have a RTC connected to it or anything, and all it is doing is checking a few sensors then sending the data. I don't have references to time, so the only thing I can figure is that it has something to do with this part of the default sending program:
int currPeriod = millis()/TRANSMITPERIOD;
if (currPeriod != lastPeriod)
{
lastPeriod=currPeriod;
photoSensor = analogRead(A2);
delay(100);
Anyone else experience this oddity? I thought I wouuld post it here before I really dug into what 'TRANSMITPERIOD' is. Only thing I can think of is that this IF statement above is not being satisfied and it is not sending.
Thanks!
Could you try to use the Send sketch with that node and see if it stops sending after a while...
The Send sketch is set to 300ms intervals. Try something closer to what you need, and let it send for 4 hours and see what it does. Don't do anything else on it, we're just trying to identify if the radio is OK or not.
I can do that, but I do have to set one pin high so my lamp stays on in my well house (cold here). Other than that I will leave it alone and report.
Thanks Felix.
Ideally it would be isolated from anything. Maybe you could keep the light on without the Moteino?
Either way let us know what's the outcome... Thanks
millis() returns unsigned long (32 bits), and putting the result of the division into a 16-bit signed int leads to all kinds of funky stuff happening. I'd suggest declaring currPeriod as unsigned long, and additionally, instead of the quirky integer division check use it for storing the last transmit time and check if elapsed millis() has passed the last value + TRANSMITPERIOD.
I second what kobuki says, it's worth remembering that millis is not always incremented by 1 so checking for exact values is dangerous. Might be worth toggling the LED as part of your sketch so you can see if its still running after 3 hours or a more serious problem.
Two things.
Check that the current time is greater than the past time. That will let you know if it rolled over. If I remember correctly, that shouldn't happen for 47 days.
Look up wdt, the 'watch dog timer'. If something in your code hangs up, it will automatically reset the Moteino.
OK, a third thing, pay attention to when it happens. Is it always at night? After sunset? Does it start up again the next day if left alone? Is it close to your 'heater'?
I think it could be a frequency drift with a change in temperature.
Regards,
John
All great points guys, thanks for helping debug this. Any of the mentioned pointers are potential issues.
Wow, thanks guys.
I have also thought about time of day, temp, etc as well. The "heater" is a 125 watt heat lamp. It is about 3' away. However it has been on constantly. Last night I reset the sender because it stopped. After about 30 seconds it stopped again. This was at night, about 24 degrees F. I reset it again and it ran for about 3 hours and stopped. I reset it this morning at about 7:30am and it ran until 12:33pm. So what I thought originally was 4 hours, is not true, it is sporadic . Back on Saturday it ran from about 9:33am until about 8:15pm, almost 11 hours before stopping. During this time, nothing else was going on. The relay for the heater (lightbulb) has been on. The only thing that is happening constantly is a couple sensor reads and a couple simple calculations. No definite pattern that I can tell.
Before it quit this afternoon was the first time the heater shut off, which seemed to go fine as it did in my testing. As the temp rose above freezing and up to about 40 everything seems to go fine until it quit. So, I am thinking I am going to start by changing the code and see if that helps as recommended by kobuki and Tomme and go from there. I was going to change to this, I think this makes sense....?
BTW, I did have the LED blinking during sending and when i stop receiver both the sender and receiver stop blinking.
void setup() {
unsigned long lastPeriod = -1;
}
void loop(){
unsigned long currPeriod = millis();
if ((currPeriod + TRANSMITPERIOD) >= lastPeriod)
{
lastPeriod=currPeriod;
sprintf(buf,"%d,%d,%d,%d,%d :\n",pumpAlarm,lightAlarm,photoSensor,floatSwitch,tempSensor); //Build string
//radio.send(GATEWAYID, buf, sendSize);
radio.send(GATEWAYID, buf, 30);
Blink(LED,3);
Serial.print (buf);
}
If anyone noticed, I moved that sensor read out of the if statement. Not that it mattered, it just wasn't necessary to be in there.
One further question, why go through all the trouble of a calculation to see if x time has passed and not just put a manual delay in there? Say 500ms. It is not necessary for me to control it to a finite time for this project.
Like
delay(500);
sprintf(buf,"%d,%d,%d,%d,%d :\n",pumpAlarm,lightAlarm,photoSensor,floatSwitch,tempSensor); //Build string
radio.send(GATEWAYID, buf, 30);
Blink(LED,3);
Serial.print (buf);
}
I will test the first code tonight and report back. Thanks for all the help I really appreciate it.
So far so good. On the sender I made the unsigned long changes. Been running for about 4 hours so far. Keeping my fingers crossed. If you want to see the progress, you can see my data on my Exosite Dashboard.
https://portals.exosite.com/views/1557739845/3656177209 (https://portals.exosite.com/views/1557739845/3656177209)
You should be fine using delay(500). Looks like you've got it working.
As John said, millis() rollover (start counting from zero) after 49 days. To deal with rollover, subtract the more recent time from the older time. More info here (http://forum.arduino.cc/index.php?PHPSESSID=qcfrhcoqo241jhd5fich685570&topic=122413.msg925654#msg925654)
Another troubleshooting technique is to make a sketch of only the chunk of code you suspect, add print statements to tell you when the code entered sections of code and print values of key variables. Load this sketch to a Moteino connected to a an FTDI cable so you can see the print outs in the serial monitor.
Looking good!
Quote from: ShadowGrass on March 10, 2014, 10:04:56 PM
So far so good. On the sender I made the unsigned long changes. Been running for about 4 hours so far. Keeping my fingers crossed. If you want to see the progress, you can see my data on my Exosite Dashboard.
https://portals.exosite.com/views/1557739845/3656177209 (https://portals.exosite.com/views/1557739845/3656177209)
Good you resolved this. BTW, the fixed delay you mentioned is the simplest and useful when you can do every scheduled task in a single run when it times out. Obviously, you can't do anything else while you wait on a delay(), unless you use interrupts, for example.
It looks like I celebrated a bit too early. It ran from about 6pm last night until 10:20am this morning. The heat (light bulb) turned off about 20 minutes prior to it failing, so I don't think that is an issue. I am starting to think I may have a faulty radio. Why else would it run for 16 hours then just stop, or 4 hours, or 15 minutes, 1 minute, etc. On my receiver I have a test for signal, so if it does not get data for roughly 30 seconds it sounds a buzzer. If I leave it sit, it never resumes sending. The LED on the sender does not flash, so I know it is not even attempting to send. It's as if the radio shuts off completely, but at that point the code appears to stop as well, otherwise the LED would still blink. So, I am at a loss again. This is my entire code, be kind.
// Well Monitor V1.3
// Sender Unit
#include <RFM69.h>
#include <SPI.h>
#include <VirtualWire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define NODEID 2 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
#define GATEWAYID 1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
//#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 30 // max # of ms to wait for an ack
#define LED 9 // Moteinos have LEDs on D9
#define SERIAL_BAUD 115200
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int temp; // define variable for the temperature to be stored
int photoSensor; //define variable for photoresistor
int floatSwitch; //define variable for float switch
int tempSensor; //define variable for temp sensor
int pumpTimer; //define variable to monitor pump run time
int pumpAlarm;
int lightAlarm;
#define pumpRelay 3
#define lightRelay 5
unsigned long TRANSMITPERIOD = 1000; //transmit a packet to gateway so often (in ms)
char buf[30];
byte sendSize=0;
boolean requestACK = false;
RFM69 radio;
void setup() {
pinMode(A0,INPUT);
pinMode(A2,INPUT);
pinMode(4,INPUT);
pinMode(lightRelay,OUTPUT);
pinMode(pumpRelay,OUTPUT);
pumpTimer = 0;
pumpAlarm = 0;
lightAlarm = 0;
sensors.begin(); // Start up the library
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //uncomment only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
// char buff[50];
// sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
// Serial.println(buff);
}
void loop() {
//read sensors
floatSwitch = digitalRead(A0); // Read Float Switch pin A0
delay(100);
sensors.requestTemperatures(); // Get Temp pin 4
temp = (sensors.getTempCByIndex(0));
delay(100);
tempSensor = (temp * 9)/5.0 + 32.0; //convert to F
photoSensor = analogRead(A2); // Read light sensor
delay(100);
// check for standing water and turn on pump if req
if (floatSwitch==1) {
digitalWrite(pumpRelay,HIGH);
delay(100);
pumpTimer++;
//Check to see if pump has run too long, 600 cycles, approx 20 minutes
if (pumpTimer >= 600)
pumpAlarm = 1;
}
// Turn pump off and reset alarms
else {
pumpTimer = 0;
pumpAlarm = 0;
digitalWrite(pumpRelay,LOW);
delay(100);
}
// check to see if we need to turn on light/ heat
if (tempSensor <= 38 ) {
digitalWrite(lightRelay,HIGH);
delay(100);
}
else {
digitalWrite(lightRelay,LOW);
delay(100);
}
// check to make sure bulb is good
if (digitalRead(lightRelay) == HIGH) {
if (photoSensor < 400) {
lightAlarm = 1;
}
else {
lightAlarm = 0;
}
}
delay(500); // make sure I am not sending too fast
sprintf(buf,"%d,%d,%d,%d,%d :\n",pumpAlarm,lightAlarm,photoSensor,floatSwitch,tempSensor); //Build string
radio.send(GATEWAYID, buf, 30); // send it
Blink(LED,3);
Serial.print (buf);
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
I'm wondering about one thing. The Moteinos are clocked at 16 MHz, while powered with 3.3V, and thus out of Atmel's spec, overclocked a bit. Could it be the cause? OTOH, I had receptions problems powering my Moteino from USB, probably caused by noise picked up from the PC. This might be a problem with my setup, but it might worth a try to power yours from a battery and try again. I understand that you have transmit problems, but still worth a try, IMO.
If it hears signals from 'foreign' radios, it will not transmit.
As I mentioned before, use the WDT.
I have a Moteino 1200 ft behind my house in the field in a plastic bucket that has not had a hick up since being deployed in mid December.
I would read the signal strength, rssi, to make sure they can hear each other. I also posted the spectrum showing hundreds of signals from others radios in the 'ether'.
Felix's lib will keep a radio from transmitting if it hears other signals on the frequency. I disabled this in my code, because I use one Mote as a 'Master' and all others are 'slaves'. The 'Slaves' only transmit when replying to the 'Master', thus no collisions. My current project will be event driven by the nodes though.
If you have a lot of signal strength from the well shack, you can set the TX threshold higher to ignore the weaker ambient signals.
The other thing I try to do is have the remote node is dumb as possible and put as much decision/smart code in the radio that is in my house. It's a lot easier changing things inside and not having to travel back and forth.
If you only have two radios, can you swap the indoor and outdoor radios and see if the issue follows the radio.
Just a bunch of ideas.
john
QuoteFelix's lib will keep a radio from transmitting if it hears other signals on the frequency. I disabled this in my code, because I use one Mote as a 'Master' and all others are 'slaves'.
Interesting point, I didn't know this. How would I go about that? In my scenario, I don't think my slave should listen at all, only send. The master should be the only one listening.
I have an excellent signal from the well house, it's only about 100' away, going through 3 stick/drywall walls.
The WDT function is also interesting. I would like to try disabling the listening on the slave and possibly increasing my TX threshold (not sure where to do this either). If this doesn't resolve it I will go the next step and try the WDT route.
Much thanks on the help.
Hm, the fact that it randomly stops leads me to believe it's not the radio that's the issue. But not saying that's impossible. It's a bit hard though to pinpoint the issue because even looking at hardware there are other "unseen" factors like noise which John mentioned.
How do you power the Moteino?
As John suggested, would it be possible to swap the units or use another one on the outside to try and narrow down if the issue is hardware related?
This is what I have:
Power is a 5v 500mA wall wart to Vin and Gnd.
Two relays in typical resistor, transistor, diode configuration, output.
One controls 120v ac heat lamp.
One controls 12v bilge pump (not currently connected)
One DS18B20 using OneWire in non-parasitic.
One photocell with 10k pull down resistor, input, analogRead.
Float switch with 10k pulldown resistor, input, digitalRead.
I thought maybe the AC could be bothering it or the relays. But there is no switching when it fails, and I'm pretty sure that point would have been raised already. I mean, the lines aren't touching the antennae but it is within a couple inches.
I don't have another board to replace the one that is out there. I could switch the two, but that would be very involved. I will leave that as last resort.
Ok, one last thing, can you please try this RFM69 library variant that I posted in this message: http://lowpowerlab.com/forum/index.php/topic,380.msg2108.html#msg2108
I am suspecting some issues with some changes I made that makes the radios less stable. The user that raised that topic reported that this older version makes them loose far fewer packets.
There's still a potential for RAM issues, or other things. We could try another Moteino on there and that should yield some more clues. But please try the older version of the lib and see if that makes a difference. Thanks
The library change did not correct the problem. I guess I will try to figure out John's suggestion on increasing the TX and possibly implementing WDT. I feel this is more of a patch than a fix however. Regardless I need it to run, and run reliably, so at this point whatever it takes for that to happen. It ran about 2 hours after the library change.
Quote from: ShadowGrass on March 11, 2014, 03:04:23 PM
QuoteFelix's lib will keep a radio from transmitting if it hears other signals on the frequency. I disabled this in my code, because I use one Mote as a 'Master' and all others are 'slaves'.
I found another post where John provided code on how to do this. So I made the change to my library and loaded it. It has been running since about 8:40pm last night, so going on 13 hours. This is one of the longest runs so far, so hopefully it continues. Just to reiterate what happens, the radio on the sender in the well house goes off, as in no led showing that it is sending, as it could be in a sleep or shutdown state. If this doesn't work I'll get down there with my laptop this weekend and add some debugging lines to see what exactly is going on. I was not able to increase my TX as I do not know how, I looked through the library and it looks to me as if it already at the max. I didn't change any of that, so whatever the default in the library is is what I am running.
Thanks.
Now I'm in suspense.
Yeah, me too...you can watch it live, that is the only way I know it is working. If Exosite stops getting updates, then you'll know. I have it send me an e-mail so I may know a little before you.
https://portals.exosite.com/views/1557739845/3656177209
Still going.....18 hours and still tickin. The best showing yet.
Cool. I was just looking at it on Exosite.
I don't know if you have seen this http://lowpowerlab.com/forum/index.php/topic,255.msg1205/topicseen.html#msg1205 (http://lowpowerlab.com/forum/index.php/topic,255.msg1205/topicseen.html#msg1205) ,but I think it might be what is causing problems.
If you just let a Moteino print out RSSI values every time it goes above a threshold you can get an idea of how much activity is on that frequency.
Moteino's have a lot of neighbors sharing the spectrum.
Good luck!
john
It died at 5:16pm.
I have the 433MHz variant. I don't have really any knowledge of how radios work, frequency, antennas etc. Your solution was to move to 933.05, so are you suggesting I try 433.05? I don't know where to set that. I was going to see how to boost the power as well.
In my program I have:
#define FREQUENCY RF69_433MHZ
In RFM69.cpp I see this code, would I change something here?:
/* 0x07 */ { REG_FRFMSB, (freqBand==RF69_315MHZ ? RF_FRFMSB_315 : (freqBand==RF69_433MHZ ? RF_FRFMSB_433 : (freqBand==RF69_868MHZ ? RF_FRFMSB_868 : RF_FRFMSB_915))) },
In RFM69.h I see:
[code]#define RF69_433MHZ 43
/* 0x08 */ { REG_FRFMID, (freqBand==RF69_315MHZ ? RF_FRFMID_315 : (freqBand==RF69_433MHZ ? RF_FRFMID_433 : (freqBand==RF69_868MHZ ? RF_FRFMID_868 : RF_FRFMID_915))) },
/* 0x09 */ { REG_FRFLSB, (freqBand==RF69_315MHZ ? RF_FRFLSB_315 : (freqBand==RF69_433MHZ ? RF_FRFLSB_433 : (freqBand==RF69_868MHZ ? RF_FRFLSB_868 : RF_FRFLSB_915))) },
[/code]
I moved mine to 915.05.
Bummer.
One easy question. Do you have CRC check enabled?
Right, 915.05, mistyped. Should I move mine?
What appears to be an easy question for you is Greek to me. I have no idea, I don't have anything in my sketch that says CRC..
Well, to sum it up a bit. Your transmitter is still stopping after an indefinite amount of time. You have disabled the "band is jammed" check in the code so your code is transmitting unconditionally. Yet it still stops. I think that shifting the frequency would not help here since it's the transmitter that stops evey time. Resorting to the watchdog is not a solution, but a workaround, but you're already aware of that.
If you could swap the receiver/transmitter Moteinos, that would help in identifying a hardware problem. And I still think that the highest chance you're dealing with is a hardware problem. Either just a faulty/slightly out of spec RFM69XX module, the slightly overclocked Moteino, or the sum of both. Maybe a sudden, unfiltered spike from the mains supply. Do you have any powerful power consumer in the same socket as the TX Moteino, by any chance? Could you try powering the TX side from a battery?
Sorry that it's just a bunch of ideas, but the random nature of this error you described very much resembles a PC problem casused by faulty HW I have dealt with over the many years I was working with them. I can't help but draw the parallels.
When I got my first Moteino one of the commands, if I remember correctly, was to turn CRC on and off. CRC does a compares a number calculated in the transmitter base on the TX message with a number calculated in the receiver base on the RX message. If the two don't match the message is discarded.
I would say 14 hours is a great improvement over four. You are headed in the right direction.
If the problem is interference, removing the 'listen for signals' code allows the TX to go on in there presence.
There is also the possibility that the receiver hears the foreign transmissions and goes out to lunch trying to understand it. Turning on CRC in both the radios will reduce that possibility to near zero.
Looking at today's data says it is not temperature related.
Hold on, he has RFM69HWs so using the RFM69 lib (unmodified?) which means CRC is automatic. So no need to check that specifically.
A HW fault is possible, but many other things are possible.
No there is nothing large in the mains, plus I have ample protection in my circuit design to protect from spikes, at least best practice. I am going to try a new Mote in the sender, otherwise I am what I think is a dead end. I could attempt to disassemble the whole thing but if I do that I may as well replace it for the amount of work involved. I appreciate all the feedback and help, but I'm throwing my hands up on the sender until I can replace it to rule it out completely.
Alright, after a prompt swap from Felix (thank you), I replaced the sending unit in the well house. I am happy to say that it has been running about 22 hours so far without a hiccup. My heat is working and thankfully my pump is pumping just in time for the spring melt. I wanted to thank everyone very much for your insight and expertise. You're a great group and I really appreciate all the time and help.
So, hopefully we can finally put this one to bed...speaking of..
Allright, I would still keep a close eye on that one though. I hope there are no issues with the library.