sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.61k stars 620 forks source link

Low Power mode on MKR WAN 1310 #431

Closed amasidlover closed 3 years ago

amasidlover commented 3 years ago

I'm using an MKRWAN 1310 with jumper cut, with the following sketch:

#include "ArduinoLowPower.h"
#include <LoRa.h>
#include <MKRWAN.h>

LoRaModem modem;

void setup() {
  for (int i=0; i < 15; i++) {
    pinMode(i, INPUT_PULLUP);
  }
  pinMode(LED_BUILTIN, OUTPUT);

  digitalWrite(LED_BUILTIN, HIGH);
  delay(3000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

void loop() {
    USBDevice.detach();

  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);

    LowPower.deepSleep(8000);

  LoRa.begin(868E6);
  LoRa.beginPacket();
  LoRa.print("D:");
  LoRa.endPacket();
  LoRa.end();

  digitalWrite(LORA_IRQ_DUMB, LOW);
  digitalWrite(LORA_RESET, LOW);
  digitalWrite(LORA_BOOT0, LOW);
}

I get a sleep current of 16uA (!) on the first sleep, however, after the LoRa send has occurred the sleep current sticks at 300uA. I've tried a variety of things to get the LoRa modem / Murata unit to shut down ( modem.dumb(), modem.sleep() ) but nothing seems to cause it to come back to the state it was in when the board is first powered on.

I've tried various things including LoRa.sleep() instead of .end() but still end up with much higher sleep currents after the radio unit has been powered up. I've even tried adding externally circuitry to try and power cycle the whole board after a send - but haven't yet succeeded in getting that to work.

I've found plenty of issues and posts with a similar problem to mine where the authors post the full code of something that doesn't 'work' (go in to low power mode) and responses that strongly suggest its possible - even suggesting 1 or 2 line changes to make it work, but I still haven't found (or managed to create) a full working example of a send followed by deep sleep in the <100uA range.

IoTThinks commented 3 years ago

Set LoRa RESET and SS to INPUT. Should use LoRa.end() instead of LoRa.sleep()

amasidlover commented 3 years ago

Thank you! That's definite progress, my loop is now:

void loop() {
    USBDevice.detach();

  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);

    LowPower.deepSleep(8000);

  LoRa.begin(868E6);
  LoRa.beginPacket();
  LoRa.print("D:");
  LoRa.endPacket();
  LoRa.end();

  digitalWrite(LORA_RESET, LOW);
  digitalWrite(LORA_BOOT0, LOW);
  pinMode(LORA_RESET, INPUT);
  pinMode(SS, INPUT);
}

And gives ~80uA when sleeping which is much, much better - is it possible to get the modem back into the power on state where its clearly using next to nothing or is 80uA the best this will do (which to be honest is probably good enough for this project)?

IoTThinks commented 3 years ago

You can try to disable adc or set to INPUT for all unused GIPOs.

From my experience, to reach under 100uA, we need to use better LDO with low idle consumption.

I even turn off the power of LoRa for my customed board. I can reach 13-19uA during deepsleep with esp32.

amasidlover commented 3 years ago

Just coming back to this; after further scrutinising of the Lora.h, Lora.cpp and the MKR WAN 1310 schematics I ended up with the following: LoRa.end();

    digitalWrite(LORA_RESET, LOW); 

    digitalWrite(LORA_BOOT0, LOW); 

    pinMode(LORA_RESET, INPUT); 

    pinMode(LORA_DEFAULT_SS_PIN, INPUT); 

    pinMode(LORA_IRQ_DUMB, INPUT); 

(followed by LowPower.deepSleep)

Which then gives a sleep current (with some peripheral circuitry) of 35uA - which is now matching what the board sleeps at with no radio transmission.

Success! Thanks for the pointers.