Hello, I've been working with the MKRWAN1300 and evaluating the sleep performance. I believe I have successfully achieved sleep. However the sleep current is 1.16mA. Is it possible to achieve a sleep current with the MKRWAN1300 of less than 1.16mA?
I have found community reports for other SAMD21 products that achieve a lower sleep current. However, I have not found a report that confirms a sleep current less than 1.16mA for the MKRWAN1300 is achievable.
My hardware configuration is 3.3V power is applied to the Vbatt input. USB is disconnected. A0 (DAC output) is connected to A1 (ADC input).
At the moment I suspect a bug in the MKRWAN firmware preventing the Murata device from sleeping properly but I haven't found anything yet.
Wiring.c in the Arduino library was updated to remove initialization of the IO as floating inputs. I have attached my sketch below for reference.
#include <Arduino.h>
#include <ArduinoLog.h>
#include <ArduinoLowPower.h>
#include <MKRWAN.h>
#include <ZeroRegs.h>
#include <RTCZero.h>
#include "arduino_secrets.h"
#define SLEEP_PERIOD ( (uint32_t) 5000 )
// ADC configuration
#define extSensorPin PIN_A1
#define extSensorEnablePin 1
LoRaModem modem;
static uint32_t msgCount = 0;
bool regsShown = false;
// RTCZero rtc;
// Uncomment if using the Murata chip as a module
// LoRaModem modem(Serial1);
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
String appEui = SECRET_APP_EUI;
String appKey = SECRET_APP_KEY;
void blink( int numBlink = 1, unsigned int speed = 200 ) {
int i;
while ( numBlink-- ) {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(speed); // wait
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(speed); // wait
}
}
void printTimeStamp(Print* _logOutput) {
char c[12];
int m = sprintf(c, "%10lu ", millis());
_logOutput->print(c);
}
void printNewline(Print* _logOutput) {
_logOutput->print('\n');
}
void reboot() {
NVIC_SystemReset();
while(1) ;
}
void pinStr( uint32_t ulPin, unsigned strength) // works like pinMode(), but to set drive strength
{
// Handle the case the pin isn't usable as PIO
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
{
return ;
}
if(strength) strength = 1; // set drive strength to either 0 or 1 copied
PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].bit.DRVSTR = strength ;
}
void InitIO() {
// Note: wiring.c initializes all GPIO as inputs with no pull ups ... it has been modified to eliminate this
// Configure digital pins used by the application
pinMode(LED_BUILTIN, OUTPUT);
pinMode(extSensorPin, OUTPUT);
pinStr(extSensorPin, 1);
digitalWrite(extSensorEnablePin, LOW);
// Configure the ADC
analogReadResolution(12);
analogWriteResolution(12);
analogReference(AR_INTERNAL1V65);
}
void alarmEvent() {
// RTC alarm wake interrupt callback
// do nothing
}
void setup() {
Log.begin(LOG_LEVEL_VERBOSE, &Serial, true);
InitIO();
Serial.begin(115200);
int waitForSerial = 5;
while (!Serial && !Serial.available() && waitForSerial ) {
delay(2000);
blink(2);
waitForSerial--;
}
Log.notice(F("Start" CR));
// initialize the RTC - need to do this or the sleep function is unreliable after reset
// rtc.begin(false);
LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, alarmEvent, CHANGE);
// Log.notice(F("Reset modem ..." CR));
// modem.restart(); // This does not work for some reason
Log.notice(F("Initialize modem ..." CR));
if (!modem.begin(US915_HYBRID)) {
Log.error(F("Failed to start module, rebooting MKRWAN in 1 seconds ..." CR));
delay(1000);
reboot();
};
Log.notice(F("Your module version is: %s" CR), modem.version().c_str());
Log.notice(F("Your device EUI is: %s" CR), modem.deviceEUI().c_str());
int connected = modem.connected();
if ( !connected ) {
int joinFailed = 0;
while ( !connected && joinFailed < 10 ) {
connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Log.notice(F("LoRaWAN network not joined, retry join in 60 seconds ..." CR));
blink(1);
delay(60000);
joinFailed++;
}
}
}
if ( connected ) {
Log.notice(F("LoRaWAN network joined" CR));
modem.setPort(10);
modem.dataRate(3);
modem.setADR(true);
blink(3);
}
}
void loop() {
blink(3);
Log.notice(F("Wake" CR));
// Dump SAMD21 registers
if ( Serial ) {
if (! regsShown ) {
ZeroRegOptions opts = { Serial, false };
printZeroRegs(opts);
regsShown = true;
}
} else {
regsShown = false;
}
digitalWrite(extSensorEnablePin, HIGH);
analogWrite(PIN_A0, 1024); // apply voltage to DAC to test analog input
delay(10);
int extSensor = analogRead(extSensorPin);
digitalWrite(extSensorEnablePin, LOW);
int err;
String msg = "Sleep Test:" + String(msgCount) + ":" + String(extSensor);
modem.beginPacket();
modem.print(msg);
err = modem.endPacket(true);
if (err > 0) {
Log.notice(F("LoRa message sent: %l, vwc = 0x%x" CR), msgCount, extSensor);
msgCount++;
blink(2);
} else {
Log.notice(F("LoRa error sending message: %l, vwc = 0x%x" CR), msgCount, extSensor);
blink(1);
}
delay(1000);
blink(3);
LowPower.deepSleep(SLEEP_PERIOD);
}