Author Topic: MoteinoMega - radio receive while MCU sleep/shutdown  (Read 9938 times)

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
MoteinoMega - radio receive while MCU sleep/shutdown
« on: September 03, 2020, 09:44:25 AM »
I'm working on a project where I would love to shutdown either/both the radio and the Mega (either FOREVER or 8s multiplied by a value to give me a certain time frame, i.e., 15 mins).  I don't have any issues doing this with a regular Moteino....just can't seem to get it to work on a Mega.

So, my (hopefully) very simple question is this....can you put the radio and Mega to sleep and have an incoming RF packet wakeup both the radio and the Mega?  Or, if I keep the radio awake and just sleep the Mega, is there a way for the incoming RF packet to wake the Mega if I'm sleeping FOREVER?

I've seen lots of posts around this issue but I can't find one with a definitive answer for the Mega specifically.  Any help would be appreciated.
« Last Edit: September 05, 2020, 11:23:54 AM by Felix »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Mega - sleep/shutdown basic question
« Reply #1 on: September 03, 2020, 01:11:04 PM »
For the radio to wake the MCU, it will have to be in RX mode.
Then the MCU can FOREVER sleep, and the library data-received interrupt will wake it.
So in FOREVER sleep, the MCU is awaken by some interrupt you setup. In the case of RFM69 the library has that interrupt setup internally.
In WDT sleep the MCU will wake from the WDT interrupt that expires at the 8s or whatever other smaller interval on the AVR.
There is now a lower power sleep mode that saves another 4uA on a Moteino/MEGA called listen mode sleep, example in the library.
There should be no difference in code as far as how you sleep a Moteino or MoteinoMEGA (unless of course there should be a bug in the LowPower or RFM69 library).

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #2 on: September 03, 2020, 01:26:18 PM »
Thanks for the reply Felix.

Here's what I tested.  I have a Mega with an HW radio.

1.  If I put the radio to sleep and the Mega in shutdown (FOREVER, ADC and BOD off), incoming packets do not wake up either radio or the Mega.
Here is the relevant code in loop():

Code: [Select]
if (radio.receiveDone())
{
    CheckForWirelessHEX(radio, flash, false);
    //  Other code processing incoming packet

    radio.sleep();
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}

As far as I know, this is all that should be required.  However, in my app, the code above never wakes up anything and all incoming RF packets are ignored.  Does the OTA check have any bearing on the question?  I have read about listen mode but haven't played with it yet.  AFAIK, I don't have to do any special interrupt handling code for the radio to wake up the 1284p chip automatically?


syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #3 on: September 03, 2020, 01:50:28 PM »
To provide more background, here is a list of h/w that I have connected to the Mega, with pin numbers:

//  BME280 Temp/Humidity/Pressure - I2C 0x76, 3.3v
//  BNO055 9DOF IMU - I2C 0x28, 3.3v
//  Adafruit Ultimate GPS (TX=10, RX=11, EN=12), Serial1, 5v
//  Adafruit GA1A12S202 Analog Light Sensor - A2, 3.3v
//  Adafruit SI1145 UV/IR/Visible Light sensor - I2C 0x60, 3.3v, 10K PU
//  MAX9814 Microphone - A7, 3.3v
//  SDCard Reader SPI - CS:3, Card detect - 18, 5v
//  Vibration Sensor - 19, 3.3v, SW-18010P sensor
//  Buzzer - 13
//  Tri-Color LED (common cathode), G:A3, B:A4, R:A5

The GPS is using Serial1.  I am using the EnableInterrupt library for the vibration sensor.  I also have this define before the include of the EnableInterrupt library:

Code: [Select]
#define EI_NOTEXTERNAL
This sets up the vibration sensor interrupt:

Code: [Select]
enableInterrupt(19, vibrationISR, RISING);


Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Mega - sleep/shutdown basic question
« Reply #4 on: September 03, 2020, 02:26:02 PM »
radio.sleep() will sleep the radio, so nothing will wake your MEGA, please see my first reply again.
You have to call radio.receiveDone() to put the radio in RX mode (~15mA) before you sleep the MCU.

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #5 on: September 04, 2020, 01:58:47 PM »
Code: [Select]
void setup(void)
{
  Serial.begin(115200);
  Serial2.begin(115200);                         // Nextion
}

void loop(void)
{
  if (radio.receiveDone())
  {
    xData = * (WData *) radio.DATA;
    // process command
  }
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Mega - sleep/shutdown basic question
« Reply #6 on: September 04, 2020, 02:59:56 PM »
You're saying this works on a Moteino but not MoteinoMEGA?

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #7 on: September 04, 2020, 03:33:47 PM »
To give you a factual answer, I went back and looked at all of my Moteino projects.  Here are the facts as I know them:

1.  I have several Moteino projects that are sleeping FOREVER both the radio and the MCU.  An external interrupt (ie, reed switch, water leak making contact), wakes up the MCU which in turn wakes up the radio (at least I think it's in that order).
2.  We also have Moteino projects that sleep for 8S and sleeping both the radio and the MCU.  The WDT (I assume) wakes up the MCU which wakes up the radio.

So, technically, I don't have a Moteino project where the radio is awake, the MCU is asleep, and an incoming RF packet wakes up the MCU.  But if I remember correctly there has been a lot of posts where folks claim to do this with a Moteino.  That's why I assumed I could do it with a Mega.  If I'm wrong please correct me and I'll stop beating my head against the wall.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Mega - sleep/shutdown basic question
« Reply #8 on: September 04, 2020, 03:58:43 PM »
The radio should be able to wake the MCU (either 328p or 1284p) if the radio is left in RX mode and a packet is received.
The interrupt is active HIGH, and is setup as such to trigger ISR0 in the library, which calls interruptHandler which reads the packet payload from the radio and then continues after your .sleep(FOREVER) call.
I don't recall when I last tried this but it did work and should work. I guess I don't have a use case where the radio should be left ON but the MCU slept. You're saving some mAs of course but the radio RX will eat around 15mA so not a great sleep mode.

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #9 on: September 05, 2020, 01:13:37 AM »
I guess the bottom line is that I'm saying, with my code and h/w setup, leaving the radio in RX mode (via receivedone), and sleeping just the MCU, an incoming RF packet does not wake up the MCU.  If anyone has successfully done this with a Mega and RFM69 I would love to know how it's done.

The use case is simple, but not something you see every day.  In my case, the object containing the Mega is a remotely-controlled vehicle containing an array of various sensors.  Since the vehicle is battery operated, I'm trying to save as much battery as I can by sleeping anything possible.  Since I can't sleep the radio, I would like to at least sleep the MCU.  My plan was to send a packet to the vehicle for various telemetry and log info, and have the incoming RF packet wake up the MCU which would then process the request and go back to sleep.  This isn't a traditional "sleep" function where somebody pushes a button, or a WDT goes off, or even a switch or other actuator internally triggers to wake the MCU and/or radio.  This is a true "external" stimulus in the form of an incoming RF packet.  The vehicle is essentially all alone in the big world and needs to conserve all the battery that is possible.

If the Moteino family/RFM69 radio combination is the wrong platform for such a model, I'm more than happy to switch platforms.  I try not to get too attached to any one platform and to constantly look at new options.

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #10 on: September 05, 2020, 10:59:11 AM »
Well, I think the problem is solved.

What I found out is that in loop() I send out a packet, which I'm guessing takes the radio from RX to TX mode.

I just added a simple receivedone() before the powerDown() command and now the MCU sleeps until woken up by the radio.

Many thanks for Felix for his quick responses and great customer service.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Mega - sleep/shutdown basic question
« Reply #11 on: September 05, 2020, 11:01:47 AM »
Well you wrote that reply while I was writing and upl0oading the code :-)

I wrote an example for you, posted here: https://github.com/LowPowerLab/RFM69/blob/master/Examples/Gateway_sleepMCU/Gateway_sleepMCU.ino

Below is the excerpt from loop():

Code: [Select]
void loop() {
  //ensure radio in RX mode before sleeping
  radio.receiveDone(); //this checks if a packet is ready and processes it (saves it in lib buffer), or else puts radio in RX mode

  Serial.println("FOREVER SLEEP...");
  Serial.flush();

  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //sleep the MCU

  if (radio.receiveDone()) //WAKEUP by radio interrupt!
  {
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print("#[");
    Serial.print(++packetCount);
    Serial.print(']');
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");

    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);

    Serial.print("  [RSSI:");Serial.print(radio.RSSI);Serial.print("]");

    if (radio.ACKRequested()) radio.sendACK();

    Serial.println();
    digitalWrite(LED_BUILTIN, LOW);
  }
}

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Mega - sleep/shutdown basic question
« Reply #12 on: September 05, 2020, 11:17:11 AM »
Thanks again Felix.  Still love that Mega!

Just like a good woman, the more time you put into understanding her, the more good things come out of it.