Hi LowPowerLab folks!
I cannot find any simple guides for doing low power applications with Moteino.
If they exist pls. kindly point them to me.
If the don't, then I'd like to contribute to creating and maintaining that and even some more sample codes for the RFM69_LowPowerLab library.
I have gotten basic sleep/wake to work based on the DeepSleep and DeepSleep_usingLowPowerLibrary available on version 1.4.0 getting about 1.27V drop in 7 hours which is about 180mV drop per hour, hooked up to the 7F supercap that I purchased along with my Moteinos[1].
But there was no clear instruction on how to prepare and recover from sleep. For example I noticed I needed to flush and end the serial port and on wake I needed to re-initialize the serial port and the radio.
Also, the current DeepSleep examples seem a bit cryptic for first time users. For example, I did not understand nor use this part of the example code:
for (uint8_t i=0; i<=A5; i++)
{
#ifdef WITH_RFM69
if (i == RF69_SPI_CS) continue;
#endif
#ifdef WITH_SPIFLASH
if (i == FLASH_SS) continue;
#endif
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
What does this do? Why is the loop specifically to A5 ?? Using this actually breaks the implementation!
Anyway, I have seen there is a lot of expertise on the subject in this forum, but no simple how-to's nor practical examples.
With your help I can dedicate some time to create some basic guides and code examples for others like me who are just starting get their feet wet with Moteino and low power applications.
My particular application and use case:
Equipment:
Moteino (trace antenna) R6 with 4MBit Flash, powered by the Supercapacitor - 7.5F 5.4V
The charging is done by 2 solar panels 2.5W 5V/500mAh 130x150mm
The two panels are in parallel and charge the cap through a 11DQ05 Schottky diode.
Application:
Plant grow system.
The Moteino must wake up on "sunrise" (when lights are turned on) and the sleep when lights off. On sleep, it may be required to send some readings over the 12h sleep period.
The code structure that is working for us.
The code is simplified for clarity. Three dots ... indicates irrelevant code snipped for this discussion.
I believe a similar code structure could be generalized and used as a practical and concrete example on how to do basic sleep / wake with Moteino.
Ideas and any comments welcome...
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
#include <LowPower.h>
RFM69 radio;
SPIFlash flash(FLASH_SS, 0xEF30)
boolean powerOn = false;
boolean lightsOn = false;
boolean valveInitialized = false;
boolean radioInitialized = false;
boolean setupDone = false;
boolean recover = true;
boolean lowPowerMode = false;
void setup() {
Serial.begin(9600);
/*
...
Init IO here
The power() function activates a relay that powers a servo and the sensor circuitry.
when power(OFF) these circuits are completely isolated from power source
*/
powerOn = power(OFF);
}
void loop() {
int ourVoltage = analogRead(MOT_VIN);
int photoCell = analogRead(PCL_VOUT);
if(photoCell < LIGHTS_OFF){
if(lowPowerMode){
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// Logic here keeps counters and decides to Tx some sensor values if required
return;
}
Serial.println("LOW POWER MODE");
Serial.flush();
Serial.end();
delay(1000);
recover = false;
lowPowerMode = true;
powerOn = power(OFF);
doSleepRadio();
radioInitialized=false;
return;
}
else{
if(lowPowerMode){
lowPowerMode=false;
Serial.begin(9600);
Serial.println("NORMAL POWER");
}
}
// valve brownout
if(ourVoltage < VALVE_CUTOFF){
recover = true;
powerOn = power(OFF);
doSleepRadio();
}
if(recover){
if(ourVoltage >= VALVE_CONTINUE){
recover = false;
}
else{
Blink(LED, 100, 10);
Serial.print("VLOW_OUR:");
Serial.println(ourVoltage);
Serial.print("VLOW_PCL:");
Serial.println(photoCell);
return;
}
}
if(!radioInitialized){
doInitRadio();
radioInitialized=true;
}
if(!valveInitialized){
doInitValve();
valveInitialized=true;
}
if (radio.receiveDone()) {
/*
...
ack, dispatch message to other logic, response, etc.
*/
}
delay(10);
}
void doInitRadio(){
flash.initialize();
radio.initialize(FREQUENCY, deviceSetup.deviceId, deviceSetup.networkId);
radio.setHighPower();
/*
...
*/
}
void doSleepRadio(){
radio.sleep();
flash.sleep();
}
void doInitValve(){
/*
...
*/
}
Notes and additional questions:
[1] Given the [experimentally measured] discharge rate per hour, is there any way to calculate the current consumption ?
[2] What is the canonical way you guys are measuring current consumption with an oscilloscope ? I want to be able to capture some graphs but I don't have a current probe, so wondering if any of you had been using some simple/cheap method like a 1ohm resistor or similar...