Author Topic: Bad Moteino? R5 seems to "blink out" over time...  (Read 6436 times)

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #32 on: October 17, 2018, 12:46:20 PM »
Ok, that's an older one, up to you but the loop still runs, just does nothing when it's empty.
So you could add your WDT resetting code there.

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #33 on: October 17, 2018, 12:55:25 PM »
Felix -

Thank You. I realize that I can put something in the loop() since it is empty, but I guess I don't understand fully the process. If the water meter is running and it is an interrupt based measurement of the water meter, does loop still run or will it wait until the water meter quits flowing?

If I simply threw in a WDT_reset(); in the loop would that work or would that be resetting way to fast? If I threw in a delay (say of 5 seconds with the WDT set at 8 seconds) would that delay cause a problem while the water meter is flowing?

And lastly, should I convert to the PulseMeter as opposed to continuing to use the WaterMote?

Thanks

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #34 on: October 17, 2018, 01:29:09 PM »
The waterMote sketch was coded back when I used RFM12b, I since switched to RFM69/pulsemeter. If you have it adjusted and it works, I would not bother.
The loop is empty in watermote because it just sits idle when nothing happens. You can add code there without a problem.
Interrupts interrupt normal code flow, and resume normal code when they are done.
Your loop code will be halted when an interrupt occurs.

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #35 on: October 17, 2018, 01:33:40 PM »
Don't you use this sketch?
https://github.com/LowPowerLab/RFM69/blob/master/Examples/PulseMeter/PulseMeter.ino

It looks like you're transmitting in an ISR, which will be with interrupts disabled, and yet sendWithRetry() relies on millis() function which is interrupt driven and won't increment while in the ISR. Have I misunderstood?

Edit: I didn't spot the re-enabling interrupts in XMIT(), so looks OK.

Mark
« Last Edit: October 17, 2018, 09:20:45 PM by perky »

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #36 on: October 17, 2018, 01:42:31 PM »
Your loop code will be halted when an interrupt occurs.

OK so my question is when my water is running and the loop code is halted, won't that by default force the watchdog to reset and reboot the Mote since the loop() is where I will be timing and resetting the WDT??

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #37 on: October 17, 2018, 01:46:19 PM »
It looks like you're transmitting in an ISR, which will be with interrupts disabled, and yet sendWithRetry() relies on millis() function which is interrupt driven and won't increment while in the ISR. Have I misunderstood?

Mark

I am not using sendWithRetry():

Code: [Select]
//*********************************************************************************************
//*********** We only transmit if there are changes to send...helps to save power....
//*********************************************************************************************

  if (water.GPM!=GPMlast || water.GAL!=GALlast || water.GLM!=GLMlast)  //Check and see if we used any water.....
  {
    if (debug)
       {
       Serial.println("Time to transmit.......");
       }
   
    radio.send(0, &water, sizeof water);

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #38 on: October 17, 2018, 01:58:09 PM »
OK so my question is when my water is running and the loop code is halted, won't that by default force the watchdog to reset and reboot the Mote since the loop() is where I will be timing and resetting the WDT??
The idea is the watchdog timeout is much longer that the time spent in the ISR, so will be continually reset unless a lock-up has happened.

But I think the solution is not a watchdog reset, but to move the XMIT() function which is currently the ISR into the main loop. Use a volatile flag set in the ISR and use that to trigger the transmit routine, clearing the flag when it's done. If I'm right, the sendWithRetry() function might freeze because millis() is frozen in the ISR (assuming the millis() function here is the Arduino interrupt driven one).

Edit: I saw your reply, even the send() routine uses millis(). If the canSend() routine get's stuck (and this has happened before) then there's no timeout and it'll get stuck there. I would move all your transmit code to the main loop as above. I assume this routine is attached to the timer interrupt like Felix's code.

Mark.
« Last Edit: October 17, 2018, 02:19:07 PM by perky »

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #39 on: October 17, 2018, 02:53:24 PM »
Mark -

I think I am closer to understanding what you are saying.

I was assuming that since all of the code Felix wrote does, in fact, work the way it is written that having the XMIT function where it is currently located is was not actually a problem. Is that because of the interrupts() here in the XMIT function that re-enables the interrupts so it is not an issue with millis()?:

Code: [Select]
void XMIT()
{
  noInterrupts();                                   
  PulseCounter = PulseCounterVolatile;
  interrupts();                                            <--------------------
 
  if (millis() - TIMESTAMP_pulse_curr >= 5000)
  {
    ledState = !ledState;
    digitalWrite(LED, ledState);
  }

I appreciate the time you are investing in trying to help me understand. I am working on understanding how the interrupt/noInterrupts works in relation to attachInterrupt. From what I am gathering from you, the transmit function should not work at all if it is in an ISR or at least it's not a good idea to place it there, is that correct?

If that is correct, does the inclusion of the noInterrupts/interrupts functions in the XMIT function alleviate the issues caused by using it there?


On to your recommendation of using a volatile flag/variable. I assume that in my code where the actual transmit happens:

Code: [Select]
if (water.GPM!=GPMlast || water.GAL!=GALlast || water.GLM!=GLMlast)  //Check and see if we used any water.....
  {
    if (debug)
       {
       Serial.println("Time to transmit.......");
       }
   
    radio.send(0, &water, sizeof water);

I would instead set a variable there indicating that we should transmit and then create a function in my loop that looks at that variable and transmits the information if the variable has been set, then reset the variable (and the WDT). Is that correct?

I guess thanks to my ignorance, I was assuming that as long as my water was running and hence the interrupt driven part of the code was in control, everything stopped until the water stopped, it just stays right there and does not execute anything else (like the loop()) until it is done. Since I think that is not correct, how often (in general) does the loop() run while the water is flowing? Is it once per pulse of the water meter, once per ms or ???




ChemE

  • Sr. Member
  • ****
  • Posts: 419
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #40 on: October 17, 2018, 04:38:20 PM »
An empty loop is just...
Code: [Select]
while(1) {
}
...which takes 2 clock cycles to branch back to the top.  So your empty loop is executing 8,000,000 times per second.  Crazy waste of energy right?
« Last Edit: October 17, 2018, 04:40:31 PM by ChemE »

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #41 on: October 17, 2018, 05:20:08 PM »
An empty loop is just...
Code: [Select]
while(1) {
}
...which takes 2 clock cycles to branch back to the top.  So your empty loop is executing 8,000,000 times per second.  Crazy waste of energy right?

WOW....I did not realize how many fast it was actually running....

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #42 on: October 17, 2018, 09:11:08 PM »
@G550_Pilot

Ah, yes. I didn't spot that re-enabling of interrupts in the XMIT() ISR. That would appear to update millis().

As a general programming principle re-enabling interrupts within an ISR can be dangerous, it could be interrupted itself by another interrupt and in cases where there are multiple interrupts can cause stack overflow or retriggering of the same interrupt ISR with non re-entrant code. This could be problematical if the timeout of the send() function is greater than the frequency period of calling XMIT(), but it appears to be OK as XMIT() is called every 5 seconds and the tx timeout is only 1 second.

I don't personally like doing this though, I think it's better to have a static volatile flag that simply gets set by the 5 second timer interrupt instead of running XMIT(), and in the main loop look for the flag being set. When you see it, clear the flag and run XMIT() as a normal function. This minimises the time in the ISR where interrupts are disabled by hardware to just the flag setting part, and millis() will update as it should.

Mark
« Last Edit: October 18, 2018, 11:34:48 AM by perky »

ChemE

  • Sr. Member
  • ****
  • Posts: 419
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #43 on: October 18, 2018, 08:30:57 AM »
As Perky said, it is best practice to keep ISRs as short as humanly possibly.  I try to keep mine to fewer than 100 clock cycles just to stretch myself; most people probably aren't as crazy about efficiency as me.  Sending a packet even at 300kbps and using my uber fast radio code still takes 1ms which is 16,000 clock cycles.  I believe the RFM69 library needs more like 4+ ms.

G550_Pilot

  • Full Member
  • ***
  • Posts: 151
  • Country: us
Re: Bad Moteino? R5 seems to "blink out" over time...
« Reply #44 on: October 18, 2018, 11:25:13 AM »
As Perky said, it is best practice to keep ISRs as short as humanly possibly.  I try to keep mine to fewer than 100 clock cycles just to stretch myself; most people probably aren't as crazy about efficiency as me.  Sending a packet even at 300kbps and using my uber fast radio code still takes 1ms which is 16,000 clock cycles.  I believe the RFM69 library needs more like 4+ ms.

Are you using a different radio library to get those transmit times down?