Skip to content

Commit 79d0bd2

Browse files
RTC-and-DeepSleep-examples
1 parent 68ffb25 commit 79d0bd2

File tree

6 files changed

+657
-0
lines changed

6 files changed

+657
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
**************************************************
3+
*
4+
* @file Qwiic.ino
5+
* @brief Example demonstrating easyC (I2C) communication between Inkplate 6 and
6+
* a Soldered BME280 or BME680 environmental sensor, using the LVGL library
7+
* for display rendering.
8+
*
9+
* This example reads temperature, humidity, and pressure data from a
10+
* Soldered BME280 sensor connected via the easyC interface and displays
11+
* it on the Inkplate 6 e-paper screen using LVGL elements.
12+
*
13+
* Note: Both BME280 and BME680 sensors are supported by the same
14+
* Soldered BME280/BME680 library. In this example, the BME280 is used,
15+
* as defined in the code. The sensor communicates over easyC (I2C)
16+
* using the default 0x76 address.
17+
*
18+
* For setup instructions and more information about Inkplate 6, visit:
19+
* https://soldered.com/documentation/inkplate/6/overview/
20+
*
21+
* @hardware Inkplate 6COLOR (ESP32-based e-paper display)
22+
* @sensors Soldered BME280 (or BME680) via easyC connector
23+
* @library Soldered BME280/BME680 Gas Sensor Arduino Library
24+
* https://github.com/SolderedElectronics/Soldered-BME280-BME680-Gas-Sensor-Arduino-Library
25+
*
26+
* @authors Soldered
27+
* @date November 2025
28+
**************************************************
29+
*/
30+
31+
32+
#include <Inkplate-LVGL.h>
33+
#include <BME280-SOLDERED.h> // Soldered BME280/BME680 library (easyC/I2C)
34+
35+
// Inkplate in 1-bit mode (fast partial updates)
36+
Inkplate inkplate(INKPLATE_1BIT);
37+
BME680 bme680; // easyC/I2C (Soldered uses 0x76)
38+
39+
// Optional temperature calibration offset
40+
const float TEMPERATURE_OFFSET = 0.0f;
41+
42+
// UI elements
43+
static lv_obj_t *panel_data;
44+
static lv_obj_t *lbl_title;
45+
static lv_obj_t *lbl_temp;
46+
static lv_obj_t *lbl_hum;
47+
static lv_obj_t *lbl_press;
48+
static lv_obj_t *lbl_warn;
49+
50+
// Refresh policy (do a FULL every ~20 partials)
51+
static int partialCount = 0;
52+
static const int FULL_REFRESH_EVERY = 20;
53+
54+
// Helpers
55+
static inline int dispW() { auto *d = lv_display_get_default(); return lv_display_get_horizontal_resolution(d); }
56+
static inline int dispH() { auto *d = lv_display_get_default(); return lv_display_get_vertical_resolution(d); }
57+
58+
static void make_opaque(lv_obj_t *obj) {
59+
lv_obj_set_style_bg_color(obj, lv_color_hex(0xFFFFFF), 0);
60+
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0);
61+
lv_obj_set_style_border_width(obj, 0, 0);
62+
}
63+
64+
// Minimal LVGL UI (no GFX icons to keep it LVGL-only)
65+
static void ui_create() {
66+
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
67+
68+
lbl_title = lv_label_create(lv_screen_active());
69+
lv_label_set_text(lbl_title, "Qwiic • BME280");
70+
lv_obj_set_style_text_color(lbl_title, lv_color_hex(0x000000), 0);
71+
lv_obj_set_pos(lbl_title, 8, 8);
72+
make_opaque(lbl_title);
73+
74+
panel_data = lv_obj_create(lv_screen_active());
75+
make_opaque(panel_data);
76+
lv_obj_set_style_pad_all(panel_data, 0, 0);
77+
lv_obj_set_style_border_width(panel_data, 0, 0);
78+
lv_obj_set_pos(panel_data, 0, 40);
79+
lv_obj_set_size(panel_data, dispW(), dispH() - 80);
80+
81+
lbl_temp = lv_label_create(panel_data);
82+
lv_obj_set_style_text_color(lbl_temp, lv_color_hex(0x000000), 0);
83+
lv_obj_set_pos(lbl_temp, 24, 40);
84+
85+
lbl_hum = lv_label_create(panel_data);
86+
lv_obj_set_style_text_color(lbl_hum, lv_color_hex(0x000000), 0);
87+
lv_obj_set_pos(lbl_hum, 24, 140);
88+
89+
lbl_press = lv_label_create(panel_data);
90+
lv_obj_set_style_text_color(lbl_press, lv_color_hex(0x000000), 0);
91+
lv_obj_set_pos(lbl_press, 24, 240);
92+
93+
lbl_warn = lv_label_create(panel_data); // shown only if sensor looks unresponsive
94+
lv_obj_set_style_text_color(lbl_warn, lv_color_hex(0x000000), 0);
95+
lv_obj_set_pos(lbl_warn, 24, 320);
96+
lv_label_set_text(lbl_warn, "");
97+
}
98+
99+
static void update_readings() {
100+
// Read sensor
101+
float tC = bme280.readTemperature() + TEMPERATURE_OFFSET; // °C
102+
float hum = bme280.readHumidity() / 10.0f; // library returns x10
103+
float hPa = bme280.readPressure() * 10.0f; // hPa (original style)
104+
105+
// Basic sanity check (some libs return 0 or extreme values if not connected)
106+
bool looks_bad = (hPa <= 0.0f) || (hum < 0.0f || hum > 100.0f) || (tC < -40.0f || tC > 85.0f);
107+
108+
char bufT[32], bufH[32], bufP[32];
109+
snprintf(bufT, sizeof(bufT), "Temperature: %.1f *C", tC);
110+
snprintf(bufH, sizeof(bufH), "Humidity: %.0f %%", hum);
111+
snprintf(bufP, sizeof(bufP), "Pressure: %.0f hPa", hPa);
112+
113+
lv_label_set_text(lbl_temp, bufT);
114+
lv_label_set_text(lbl_hum, bufH);
115+
lv_label_set_text(lbl_press, bufP);
116+
117+
if (looks_bad) {
118+
lv_label_set_text(lbl_warn, "Warning: sensor readings look invalid.\nCheck Qwiic cable and sensor power.");
119+
} else {
120+
lv_label_set_text(lbl_warn, "");
121+
}
122+
}
123+
124+
void setup() {
125+
Serial.begin(115200);
126+
127+
// LVGL + Inkplate in PARTIAL mode
128+
inkplate.begin(LV_DISP_RENDER_MODE_PARTIAL);
129+
130+
// Init BME280 (void return in this library)
131+
bme280.begin();
132+
133+
ui_create();
134+
update_readings();
135+
136+
// Initial FULL refresh
137+
lv_tick_inc(20);
138+
lv_timer_handler();
139+
inkplate.display();
140+
}
141+
142+
void loop() {
143+
update_readings();
144+
145+
lv_tick_inc(10);
146+
lv_timer_handler();
147+
inkplate.display(); // FULL
148+
149+
150+
delay(60000); // ~60 s between readings
151+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
**************************************************
3+
*
4+
* @file SimpleDeepSleep.ino
5+
* @brief Example showing how to put the Inkplate device into deep sleep, wake it up every 30 seconds and
6+
* display the wakeup count onto the screen
7+
*
8+
* For info on how to quickly get started with Inkplate 6COLOR visit https://soldered.com/documentation/inkplate/6color/overview/
9+
*
10+
* @authors Soldered
11+
* @date November 2025
12+
***************************************************/
13+
14+
#include <Inkplate-LVGL.h>
15+
#include "driver/rtc_io.h"
16+
17+
#define uS_TO_S_FACTOR 1000000 // Conversion factor for microseconds to seconds
18+
#define TIME_TO_SLEEP 30 // Sleep duration in seconds
19+
20+
RTC_DATA_ATTR int wakeCount = 0; // Retained variable across deep sleep cycles
21+
22+
Inkplate inkplate(INKPLATE_1BIT); // Create Inkplate LVGL instance
23+
24+
void setup()
25+
{
26+
Serial.begin(115200);
27+
28+
// Initialize Inkplate in FULL render mode (needed for LVGL and color)
29+
inkplate.begin(LV_DISP_RENDER_MODE_FULL);
30+
31+
// Increment persistent counter
32+
wakeCount++;
33+
34+
// Clear screen background to white
35+
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
36+
37+
// Create label text buffer
38+
char labelText[64];
39+
snprintf(labelText, sizeof(labelText), "Wake count: %d", wakeCount);
40+
41+
// Create LVGL label and style it
42+
lv_obj_t *label = lv_label_create(lv_screen_active());
43+
lv_label_set_text(label, labelText);
44+
lv_obj_set_style_text_color(label, lv_color_hex(0x000000), LV_PART_MAIN);
45+
lv_obj_set_style_text_font(label, &lv_font_montserrat_48, 0);
46+
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
47+
48+
// Render label and update display
49+
lv_tick_inc(50);
50+
lv_timer_handler();
51+
inkplate.display();
52+
53+
Serial.printf("Device wake count: %d\n", wakeCount);
54+
55+
// Configure deep sleep wake-up timer
56+
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
57+
58+
// Go to deep sleep
59+
esp_deep_sleep_start();
60+
}
61+
62+
void loop()
63+
{
64+
// Never reached; all logic in setup()
65+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
**************************************************
3+
*
4+
* @file RTCAlarm.ino
5+
* @brief Example showing how to set the date and time of the RTC as well as the alarm.
6+
* When the alarm is triggered, it displays on the screen along with the timestamp
7+
*
8+
For info on how to quickly get started with Inkplate 10 visit https://soldered.com/documentation/inkplate/10/overview/
9+
*
10+
* @authors Soldered
11+
* @date November 2025
12+
***************************************************/
13+
#include <Inkplate-LVGL.h>
14+
15+
Inkplate inkplate(INKPLATE_1BIT); // Inkplate LVGL display instance
16+
17+
18+
// Refresh once per minute
19+
#define REFRESH_DELAY 60000
20+
unsigned long lastRefresh = 0;
21+
22+
// Forward declarations
23+
void updateTimeLabel(lv_obj_t *label, lv_obj_t *alarmLabel);
24+
25+
void setup()
26+
{
27+
// Initialize Inkplate and LVGL
28+
inkplate.begin(LV_DISP_RENDER_MODE_FULL);
29+
inkplate.rtc.reset();
30+
31+
// Set time/date and alarm
32+
// Set initial time and date
33+
// 14:30:00
34+
inkplate.rtc.setTime(14, 30, 0);
35+
// Wednesday, 12.11.2025.
36+
inkplate.rtc.setDate(3, 12, 11, 2025);
37+
38+
// Set the alarm 1 minute from now
39+
inkplate.rtc.setAlarm(0, 31, 14, 12, 3);
40+
41+
// Set white background
42+
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
43+
44+
// Create main time label
45+
lv_obj_t *timeLabel = lv_label_create(lv_screen_active());
46+
lv_obj_set_style_text_color(timeLabel, lv_color_hex(0x000000), LV_PART_MAIN);
47+
lv_obj_set_style_text_font(timeLabel, &lv_font_montserrat_26, 0);
48+
lv_obj_align(timeLabel, LV_ALIGN_CENTER, 0, -30);
49+
50+
// Create secondary "ALARM!" label (hidden by default)
51+
lv_obj_t *alarmLabel = lv_label_create(lv_screen_active());
52+
lv_label_set_text(alarmLabel, "");
53+
lv_obj_set_style_text_color(alarmLabel, lv_color_hex(0x00AA00), LV_PART_MAIN); // green
54+
lv_obj_set_style_text_font(alarmLabel, &lv_font_montserrat_48, 0);
55+
lv_obj_align(alarmLabel, LV_ALIGN_CENTER, 0, 60);
56+
57+
// Initial display
58+
updateTimeLabel(timeLabel, alarmLabel);
59+
lv_tick_inc(50);
60+
lv_timer_handler();
61+
inkplate.display();
62+
63+
lastRefresh = millis();
64+
}
65+
66+
void loop()
67+
{
68+
// Refresh screen once per minute
69+
if (millis() - lastRefresh > REFRESH_DELAY)
70+
{
71+
lv_obj_t *timeLabel = lv_obj_get_child(lv_screen_active(), 0);
72+
lv_obj_t *alarmLabel = lv_obj_get_child(lv_screen_active(), 1);
73+
updateTimeLabel(timeLabel, alarmLabel);
74+
75+
lv_tick_inc(50);
76+
lv_timer_handler();
77+
inkplate.display();
78+
79+
lastRefresh = millis();
80+
}
81+
}
82+
83+
84+
// Update the main time label and show alarm status
85+
void updateTimeLabel(lv_obj_t *label, lv_obj_t *alarmLabel)
86+
{
87+
inkplate.rtc.getRtcData();
88+
89+
uint8_t hour = inkplate.rtc.getHour();
90+
uint8_t minute = inkplate.rtc.getMinute();
91+
uint8_t second = inkplate.rtc.getSecond();
92+
uint8_t day = inkplate.rtc.getDay();
93+
uint8_t weekday = inkplate.rtc.getWeekday();
94+
uint8_t month = inkplate.rtc.getMonth();
95+
uint16_t year = inkplate.rtc.getYear();
96+
97+
const char *wdayNames[] = {
98+
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
99+
100+
char timeText[128];
101+
snprintf(timeText, sizeof(timeText),
102+
"%02d:%02d:%02d\n%s, %02d/%02d/%04d",
103+
hour, minute, second, wdayNames[weekday], day, month, year);
104+
105+
lv_label_set_text(label, timeText);
106+
lv_obj_align(label, LV_ALIGN_CENTER, 0, -30);
107+
108+
// Check and display alarm status
109+
if (inkplate.rtc.checkAlarmFlag())
110+
{
111+
inkplate.rtc.clearAlarmFlag();
112+
lv_label_set_text(alarmLabel, "ALARM!");
113+
}
114+
else
115+
{
116+
lv_label_set_text(alarmLabel, "");
117+
}
118+
119+
lv_obj_align(alarmLabel, LV_ALIGN_CENTER, 0, 60);
120+
}

0 commit comments

Comments
 (0)