Skip to content

Commit 2830551

Browse files
committed
Improved power efficiency
1 parent 22539e6 commit 2830551

File tree

1 file changed

+102
-69
lines changed

1 file changed

+102
-69
lines changed

epdWeatherClockV1.ino

Lines changed: 102 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// Weather icon credits: https://github.com/SeBassTian23/ESP32-WeatherDisplay/tree/master
1+
//=============== HEADER SECTION ===============
22

3-
// base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code
4-
// enable or disable GxEPD2_GFX base class
3+
// E-paper weather clock v1 - Main code
4+
// Uses GxEPD2 library for e-paper display control
5+
6+
//=============== CONFIGURATION ===============
7+
// Enable/disable GxEPD2_GFX base class - uses ~1.2k more code
58
#define ENABLE_GxEPD2_GFX 0
69

710
#include <GxEPD2_3C.h>
@@ -197,23 +200,29 @@ BH1750 lightMeter(0x23); // Initalize light sensor
197200
GxEPD2_3C<GxEPD2_420c_Z21, GxEPD2_420c_Z21::HEIGHT> display(GxEPD2_420c_Z21(/*CS=5*/ /* SS*/ D7, /*DC=*/D1, /*RST=*/D2, /*BUSY=*/D3)); // 400x300, UC8276
198201
U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;
199202

200-
// #define SEALEVELPRESSURE_HPA (1013.25)
201-
#define BATPIN A0 // battery voltage divider connection pin (1M Ohm with 104 Capacitor)
202-
#define DEBUG_PIN D6
203-
#define BATTERY_LEVEL_SAMPLING 4
204-
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
205-
int TIME_TO_SLEEP = 900;
206-
207-
// battery related settings
208-
#define battType 3.6 // for ICR 4.2, for LFR 3.6
209-
#define battChangeThreshold 0.15
210-
#define battUpperLim 3.3 // for ICR or LiPo battery 4.19
211-
#define battHigh 3.4 // for ICR or LiPo battery 4.2
212-
#define battLow 2.9
213-
214-
int nightFlag = 0; // preserves data in rtc memory from deep sleep loss
215-
float battLevel;
216-
bool DEBUG_MODE = false, BATTERY_CRITICAL = false;
203+
//=============== GLOBAL CONSTANTS ===============
204+
// Hardware pins
205+
#define BATPIN A0 // Battery voltage divider pin (1M Ohm with 104 Capacitor)
206+
#define DEBUG_PIN D6 // Debug mode toggle pin
207+
208+
// Battery monitoring settings
209+
#define BATTERY_LEVEL_SAMPLING 4 // Number of samples to average
210+
#define battType 3.6 // Battery type voltage (ICR: 4.2, LFR: 3.6)
211+
#define battChangeThreshold 0.15 // Threshold for battery level changes
212+
#define battUpperLim 3.3 // Upper voltage limit
213+
#define battHigh 3.4 // Ideal battery voltage threshold (ICR: 4.1, LFR: 3.4)
214+
#define battLow 2.9 // Low battery threshold
215+
216+
// Sleep settings
217+
#define uS_TO_S_FACTOR 1000000 // Micro seconds to seconds conversion
218+
int TIME_TO_SLEEP = 900; // Default sleep time in seconds (15 mins)
219+
220+
//=============== GLOBAL VARIABLES ===============
221+
// State variables
222+
int nightFlag = 0; // Night mode state preserved across sleep
223+
float battLevel; // Current battery level
224+
bool DEBUG_MODE = false; // Debug mode state
225+
bool BATTERY_CRITICAL = false; // Critical battery state
217226

218227
String jsonBuffer;
219228

@@ -225,7 +234,8 @@ char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
225234

226235
int httpResponseCode;
227236

228-
// takes samples based on BATTERY_LEVEL_SAMPLING, averages them and returns actual battery voltage
237+
//=============== HELPER FUNCTIONS ===============
238+
// Measures and returns the averaged battery voltage
229239
float batteryLevel()
230240
{
231241
uint32_t Vbatt = 0;
@@ -239,11 +249,23 @@ float batteryLevel()
239249
return (Vbattf);
240250
}
241251

252+
// Disables WiFi and reduces CPU frequency to save power
253+
void turnOffWifi()
254+
{
255+
WiFi.disconnect(true); // Disconnect from the network
256+
WiFi.mode(WIFI_OFF); // Switch WiFi off
257+
setCpuFrequencyMhz(40); // Set CPU to 40MHz
258+
delay(1);
259+
Serial.println("WIFI OFF");
260+
}
261+
242262
// forward declaration
243263
void tempPrint(byte offset = 0);
244264

265+
//=============== MAIN SETUP AND LOOP ===============
245266
void setup()
246267
{
268+
setCpuFrequencyMhz(80);
247269
Serial.begin(115200);
248270
Serial.println("Setup");
249271
pinMode(BATPIN, INPUT);
@@ -271,7 +293,28 @@ void setup()
271293
}
272294
nightFlag = pref.getBool("nightFlag", false);
273295

274-
if (!BATTERY_CRITICAL)
296+
if (lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE))
297+
{
298+
Serial.println(F("BH1750 Advanced begin"));
299+
}
300+
else
301+
{
302+
Serial.println(F("Error initialising BH1750"));
303+
errMsg("Error BH1750");
304+
while (1)
305+
; // Runs forever
306+
}
307+
float lux = 0;
308+
while (!lightMeter.measurementReady(true))
309+
{
310+
yield();
311+
}
312+
lux = lightMeter.readLightLevel(); // Get Lux value
313+
Serial.print("Light: ");
314+
Serial.print(lux);
315+
Serial.println(" lx");
316+
317+
if (!BATTERY_CRITICAL && lux != 0)
275318
{
276319
bool wifiConfigExist = pref.isKey("ssid");
277320
if (!wifiConfigExist)
@@ -334,49 +377,31 @@ void setup()
334377
;
335378
}
336379
}
337-
if (lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE))
338-
{
339-
Serial.println(F("BH1750 Advanced begin"));
340-
}
341-
else
342-
{
343-
Serial.println(F("Error initialising BH1750"));
344-
errMsg("Error BH1750");
345-
while (1)
346-
; // Runs forever
347-
}
348-
float lux = 0;
349-
while (!lightMeter.measurementReady(true))
350-
{
351-
yield();
352-
}
353-
lux = lightMeter.readLightLevel();
354-
Serial.print("Light: ");
355-
Serial.print(lux);
356-
Serial.println(" lx");
357380

358-
if (!rtc.begin())
381+
float hTempHold, lTempHold, tempBattLevel;
382+
383+
if (lux != 0 || DEBUG_MODE == true)
359384
{
360-
Serial.println("Couldn't find RTC");
361-
errMsg("Error RTC");
362-
while (1)
363-
; // Runs forever
364-
}
365-
Serial.println("RTC Ready");
385+
if (!rtc.begin())
386+
{
387+
Serial.println("Couldn't find RTC");
388+
errMsg("Error RTC");
389+
while (1)
390+
; // Runs forever
391+
}
392+
Serial.println("RTC Ready");
366393

367-
DateTime now = rtc.now();
394+
DateTime now = rtc.now();
368395

369-
if ((now.hour() == 0) && (now.minute() >= 0 && now.minute() < 15))
370-
{ // reset high low at midnight
371-
pref.putFloat("hTemp", 0.0);
372-
pref.putFloat("lTemp", 60.0);
373-
}
396+
if ((now.hour() == 0) && (now.minute() >= 0 && now.minute() < 15))
397+
{ // reset high low at midnight
398+
pref.putFloat("hTemp", 0.0);
399+
pref.putFloat("lTemp", 60.0);
400+
}
374401

375-
if (lux != 0 || DEBUG_MODE == true)
376-
{
377402
if (sensor.begin() == true) // Function to check if the sensor will correctly self-identify with the proper Device ID/Address
378403
{
379-
Serial.println("Lux Begin");
404+
Serial.println("TMP117 Begin");
380405
}
381406
else
382407
{
@@ -429,12 +454,7 @@ void setup()
429454
customApiKey = pref.getString("apiCustom", "");
430455
}
431456
else
432-
{
433-
// wifioff cpu speed reduced
434-
WiFi.disconnect(true); // Disconnect from the network
435-
WiFi.mode(WIFI_OFF); // Switch WiFi off
436-
setCpuFrequencyMhz(40);
437-
}
457+
turnOffWifi(); // wifioff cpu speed reduced
438458

439459
hTemp = pref.getFloat("hTemp", -1.0);
440460
lTemp = pref.getFloat("lTemp", -1.0);
@@ -446,8 +466,9 @@ void setup()
446466
pref.putFloat("lTemp", 60.0);
447467
pref.putFloat("battLevel", battType);
448468
}
469+
470+
hTempHold = hTemp, lTempHold = lTemp, tempBattLevel = battLevel;
449471
}
450-
float hTempHold = hTemp, lTempHold = lTemp, tempBattLevel = battLevel;
451472
bool tempNightFlag = nightFlag;
452473

453474
Serial.println("Setup done");
@@ -494,7 +515,8 @@ void setup()
494515
}
495516
else
496517
{
497-
Serial.println("Time");
518+
turnOffWifi(); // turn off wifi if not connected
519+
Serial.println("Time Only");
498520
display.drawBitmap(270, 0, wifiOff, 12, 12, GxEPD_BLACK);
499521
tempPrint(40);
500522
Serial.println("Time Done");
@@ -522,19 +544,24 @@ void setup()
522544

523545
Serial.println("Data Write Done");
524546
pref.end();
525-
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
526547
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP / 60) + " Mins");
548+
549+
// Disable peripherals
550+
Wire.end();
551+
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
527552
// Go to sleep now
528553
Serial.println("Going to sleep now");
529554
Serial.flush();
530-
delay(100);
555+
delay(10);
556+
// Enter deep sleep
531557
esp_deep_sleep_start();
532558
}
533559
}
534560

535561
void loop() {}
536562

537-
// Handles the httpresponse and returns the data as json payload
563+
//=============== WEATHER AND DISPLAY FUNCTIONS ===============
564+
// Fetches weather data from API and returns JSON response
538565
String weatherDataAPI(const char *serverName)
539566
{
540567
WiFiClient client;
@@ -920,6 +947,9 @@ void weatherPrint()
920947
u8g2Fonts.print(s);
921948
}
922949
}
950+
951+
// Turn off WiFi as soon as possible after data fetch
952+
turnOffWifi();
923953
}
924954

925955
// UNCOMMENT BELOW FUNCTION IF YOU WISH TO USE ONLY oPENwEATHERmAP API
@@ -1104,8 +1134,11 @@ void weatherPrint()
11041134
u8g2Fonts.print(s);
11051135
}
11061136
}
1137+
// Turn off WiFi as soon as possible after data fetch
1138+
turnOffWifi();
11071139
}*/
11081140

1141+
//=============== UI HELPER FUNCTIONS ===============
11091142
// In case of api failure, it displays network info for debugging
11101143
void networkInfo()
11111144
{

0 commit comments

Comments
 (0)