Bad Moteino? R5 seems to "blink out" over time...

Started by G550_Pilot, March 30, 2018, 01:12:47 PM

damonb

Have you looked at how much free RAM is available to your code? I had similar symptoms once that turned out to be insufficient stack + heap space. It only failed under a very rare combination of conditions... very unpredictable and difficult to replicate.

G550_Pilot

Damon -

Good idea but we are not even close to the memory limit, as in by a factor of 10 or 20!

Felix

The way they fail indicate it's probably something in code, or maybe maybe as others suggested some power line/transient/noise issue.
If all else fails, save some time by implementing the 328's watchdog to reset the MCU.

G550_Pilot

Really???  :)

I never knew the 328 had a watchdog timer, I would have tried that a LONG time ago...

Always learning something new here....thanks Felix...

TomWS

Quote from: G550_Pilot on October 02, 2018, 09:42:33 PM
RFM69 radio;
#define RF_freq RF12_433MHZ               // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
Is the RF12_433MHz code point the same as RF69_433MHZ code point?

What else is baggage from RF12?

G550_Pilot

#20
Not Sure Tom -

I'm using the RF69 libraries so I assume there is no RF12 code or libraries involved:

#define RF69_COMPAT 1                                                 // Set to 1 if using RFM69CW or 0 is using RFM12B
#include <RFM69.h>         //get it here: http://github.com/lowpowerlab/rfm69
RFM69 radio;
#define RF_freq RF12_433MHZ               // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
#define IS_HIGHPOWER   true               // True only for RFM69HW High Power RFM69


perky

#21
Quote from: Felix on October 03, 2018, 11:32:44 AM
If all else fails, save some time by implementing the 328's watchdog to reset the MCU.

Is this timer not already being used for sleeping? Are you suggesting using the reset instead of the interrupt?

@G550_Pilot: Could we see the code that puts it to sleep (before and after) and what conditions you are using to wake it up? BTW Tom's pointed out you use the #define RF12_433MHz, which means an RFM12B header file is included somewhere for it to compile. How much more code from that library has been used was his question.

Mark.

G550_Pilot

#22
Mark -

Here is the code:
https://create.arduino.cc/editor/MD500_Pilot/40aa90d7-a429-427e-9303-fb4f3ead4a18/preview

The only #include is for the RFM69.h library which I assume is referencing the RF12. There is no other header included:

//*********************************************************************************************
//***********  Include these libraries:
//*********************************************************************************************
#include <RFM69.h>         //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h>      //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <EEPROM.h>
#include <SPI.h>
#include <TimerOne.h>
#include <JeeLib.h>
#include <avr/power.h>
#include <avr/sleep.h>



I think there is some confusion. I NEVER put this mote to sleep as it is powered 24x7 via a wall wart. I have commented out all of the sleep stuff because it was suggested early on that it was something to do with putting it to sleep and it not waking up. So to eliminate that possibility, I never put it to sleep, ever.




perky

OK, you did mention it was like it had gone to sleep and not woken up again so I assumed you were sleeping it. Anyway, why have you got JeeLib.h in there? That includes RF12.h so that's in the code too. It looks like you have a mix of two libraries.

Mark.

G550_Pilot

Hi Mark -

Yes, you are correct. But since I decided to power this full time I removed all of the sleeping and power savings from the code. This eliminated the "going to sleep and not waking up" issue.

On the JeeLib.h I will have to check and see. All of the high power Motes that I am running using this same nomenclature for the radio, I think maybe it had something to do with the HighPower settings being needed and hence the JeeLib.h? Honestly, once I got the radios running under high power a couple of years ago I never messed with the radio part of it again.

G550_Pilot

Quote from: G550_Pilot on October 03, 2018, 01:05:24 PM
Really???  :)

I never knew the 328 had a watchdog timer, I would have tried that a LONG time ago...

Always learning something new here....thanks Felix...

So this was a fantastic idea Felix, right up until the time I realized that I had no idea how to implement it since I am not sleeping AND I am using an interrupt driven event as opposed to a loop.

As I understand the WDT, you set it for a timeout of some sort (say 8 seconds), then you do something in your code and you reset your timeout before the 8 seconds are up and this resets the WDT. But when you have NO loop and it could be a week or so before your interrupt driven event kicks off, how do you make this work?

My first thought would be to simply throw a delay(100) followed by WDT reset in my loop statement (which is currently empty) so that every 100ms (or whatever) the reset happens, but will this screw up my water meter readings when the water meter is running?







perky

Quote from: G550_Pilot on October 16, 2018, 04:11:04 PM
My first thought would be to simply throw a delay(100) followed by WDT reset in my loop statement (which is currently empty) so that every 100ms (or whatever) the reset happens, but will this screw up my water meter readings when the water meter is running?
This isn't really how interrupt driven code should work. There should be minimal processing in ISR, by setting flags or doing quick non-blocking code only, and the main loop should decide what to do based on the flags set.

The general principle for an ISR should be 'get in and get out as quickly as possible', and main loop code written, with state machines if needed, to execute the loop as quickly as possible. The main loop then resets the watchdog somewhere in the loop.

So I wouldn't transmit anything in the ISR personally, or do any sensor measurements. Of course these are general rules and simple systems might get away with it, but bear in mind global interrupts are disabled in ISRs, so things like timers freeze and the millisecond timer counter won't run, and the retry mechanism may depend on it.

Mark

G550_Pilot

Mark -

Not sure I understand what you are saying. I am using the sketch that Felix wrote for the WaterMote, and all of the sensor measurements are done via an ISR, the radio work is done via a timer. This all works fine on two of the three water motes I run, I just need to figure out where to put the watchdog stuff on the third one that keeps hanging on me. I do not have a main loop in this code, it is completely empty.

attachInterrupt(INTERRUPTPIN, pulseCounterInterrupt, RISING);
Timer1.initialize(XMITPERIOD * 1000L);
Timer1.attachInterrupt(XMIT);

Felix

Reset the WDT in your main loop somewhere, as long as you dont hit the 8second mark (or whatever expiration you set) it will be fine and your node won't reset.
You can reset the WDT timer as often as you want, just dont let it expire, that's the whole idea.

G550_Pilot

Felix -

There is no main loop in your WaterMote. It is completely empty. (unless I am misunderstanding something). The loop() is totally empty.