I have for a long time struggled with keeping power consumption low enough for an IoT system, with a very low current source. The source transmit data by a a square pulse (MBUS), and the current source needs to be disabled when a new data frame is received.
Modem sleep works, and allow us to use gpios to enable/disable charging. However, in modemsleep the system uses some 23 mA average, which is borderline to the application.
One alternative is to use deepsleep. In deepsleep the power consumption would be less than 10 mA in average, and the system would be powered in abundance. I have deepsleep working by strapping D0 to RST via 150 ohm. However, during deepsleep I am not able to turn on charging with the gpios and then sleep, as the pin values change to default during sleep. I believe that I have succeeded in writing to the pin registers and setting the bit activating high pullup during sleep. But if so, this does not help, as their values change also to default during deepsleep. Hopefully this is possible to mend, but I have not been able to find how.
The third alternative is to use light sleep. This form of sleep would reduce power consumption sufficiently, and also allow us to use the gpios as intended. However, I am not able to get lightsleep to start.
Here is the relevant parts of my code (reading and setting gpio registers is not included):
void setup() {
lightSleep = true;
// setup gpios to control charging from low current source
// Serial setup
Serial.begin(74880);
Serial.setDebugOutput(true);
delay(10);
//WiFi setup
WiFi.mode(WIFI_STA);
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, password);
Serial.print("?");
}
WiFi.config(ip, gateway, subnet);
IPAddress myip = WiFi.localIP();
// Enable light sleep as alternative to modem sleep
if (lightSleep) {
wifi_set_sleep_type(LIGHT_SLEEP_T);
}
sprintf((char*)setupMessage, "Setup done, connected to %u.%u.%u.%u after %d ms.\r\n", myip[0], myip[1], myip[2], myip[3], millis());
Serial.println((char*)setupMessage);
}
void loop() {
// turn off charging from low current source
// receive data from same source, cant charge and receive simultanously
// use gpios to set charging if all is well
if (doCharge) { // If not, only timing will start
digitalWrite(impedancePin, HIGH); // Set input impedance low
delay(10); // a delay is used to suppress any transient behaviour
digitalWrite(converterPin, HIGH); // enable the DCDC converter with converterPin HIG
}
Serial.println("Charging has started. Good night...");
// Alternative 1 - use modem sleep or lightsleep if enabled.
// Light sleep current(avg)= (8,5 * 1,5 + 1,5 * 70)/10 = 11,775 mA - good enough!
if (lightSleep) {
delay(1);
delay (delayTime - 1);
} else {
// Modem sleep current(avg)=8,5 * 15 + 1,5 * 70)/10 = 15 * 15,5 = 23,25 mA - too much!
int delayCheck;
delayCheck = delayTime;
while (delayCheck > 0) { // a buffer is already taken into account
delay (delayInterval);
delayCheck = delayCheck - delayInterval;
}
}
/*
// Alternative 2 - use deep sleep.
ESP.deepSleep(delayTime * 1000); // GPIO4&5s registers loose values during deepsleep
*/
}
}
So my questions are:
1) Is there a way to keep gpio values during deepsleep?
2) How can I fix the code above in order to get ligthsleep activated?
Best regards
Per