epaper29.tc¶
EPaper 2.9" Display Controller & Data Logger
// EPaper 2.9" Display Controller & Data Logger
// Sensors + EPaper display + 24h logging + WebChart + UDP globals
// 24h data logging arrays (96 x 15-min intervals)
// Index 0 = ring buffer position pointer, 1-96 = data
persist float aco2[97];
persist float atvc[97];
persist float tmpa[97];
persist float axhum[97];
// Sensor readings — shared via UDP (auto-send on assignment)
global float wtemp = 0.0;
global float whumi = 0.0;
global float wtvoc = 0.0;
global float wco2 = 0.0;
// Local sensor readings (not shared)
float eco2 = 0;
float ahum = 0.0;
// Received via UDP from other devices
global float bpress = 0.0;
global float sedc = 0.0;
global float wrga = 0.0;
global float wrgh = 0.0;
global float wrgg = 0.0;
global float atmp = 0.0;
global float pwl = 0.0;
// Averaging accumulators
float tmps = 0.0;
float hums = 0.0;
float tvcs = 0.0;
float co2s = 0.0;
int mcnt = 0;
// State
int last_m15 = -1;
int cnt = 0;
char dt[128];
char lbl[32];
void read_sensors() {
wtemp = sensorGet("BME280#Temperature");
whumi = sensorGet("BME280#Humidity");
bpress = sensorGet("BME280#Pressure");
wtvoc = sensorGet("SGP30#TVOC");
eco2 = sensorGet("SGP30#eCO2");
ahum = sensorGet("BME280#AbsHumidity");
wco2 = sensorGet("SCD30#CarbonDioxide");
}
void update_display() {
// Row 1: Temperature, Humidity, Pressure, Time
sprintf(dt, "[f1p7x0y5]%.1f C", wtemp);
dspText(dt);
sprintf(dt, "[p7x70y5]%.1f %% [x250y5t] ", whumi);
dspText(dt);
//dspText("[x250y5t]");
sprintf(dt, "[p11x140y5]%.1f hPa", bpress);
dspText(dt);
// Row 2: TVOC, eCO2, Abs Humidity
sprintf(dt, "[p18x30y25]TVOC: %.1f ppb", wtvoc);
dspText(dt);
sprintf(dt, "[p18x160y25]eCO2: %.1f ppm", eco2);
dspText(dt);
sprintf(dt, "[p18c26l5]ahum: %.1f g^m3", ahum);
dspText(dt);
// solar inverters
sprintf(dt, "[p25c1l5]WR 1 (Dach) : %.1f W", sedc);
dspText(dt);
sprintf(dt, "[p25c1l6]WR 2 (Garage): %.1f W", -wrga);
dspText(dt);
sprintf(dt, "[p25c1l7]WR 3 (G-Haus): %.1f W", -wrgh);
dspText(dt);
sprintf(dt, "[p25c1l8]WR 4 (Garten): %.1f W", -wrgg);
dspText(dt);
// CO2
sprintf(dt, "[p25c1l10]CO2 : %.0f ppm", wco2);
dspText(dt);
sprintf(dt, "[x170y95r120:30f2p6x185y100] %.0f %", pwl);
dspText(dt);
sprintf(dt, "[f0s2p10x210y70] %.0f C", atmp);
dspText(dt);
// Flush to EPaper
dspText("[d]");
}
void EverySecond() {
read_sensors();
cnt = cnt + 1;
// Accumulate for averaging
tmps = tmps + wtemp;
hums = hums + whumi;
tvcs = tvcs + wtvoc;
co2s = co2s + wco2;
mcnt = mcnt + 1;
// 15-minute data logging
int m15 = (tasm_hour * 60 + tasm_minute) / 15 + 1;
if (m15 != last_m15 && last_m15 > 0) {
if (mcnt > 0) {
aco2[last_m15] = co2s / (float)mcnt;
atvc[last_m15] = tvcs / (float)mcnt;
tmpa[last_m15] = tmps / (float)mcnt;
axhum[last_m15] = hums / (float)mcnt;
saveVars();
}
mcnt = 0;
co2s = 0.0;
tvcs = 0.0;
tmps = 0.0;
hums = 0.0;
}
last_m15 = m15;
// Sync graph position with time
int pos = m15;
if (pos >= 96) {
pos = 0;
}
// Update display every 10 seconds
int ups = tasm_uptime;
if (ups % 10 == 0) {
update_display();
}
// EPaper refresh every 5 min (prevent ghosting)
if (ups % 300 == 0) {
dspText("[Id]");
dspText("[id]");
}
// Sensor readings auto-send via UDP on assignment (global float)
}
void web_label(int idx) {
LGetString(idx, lbl);
dt = "{s}";
dt += lbl;
dt += "{m}";
webSend(dt);
}
void WebCall() {
web_label(0);
sprintf(dt, "%.1f C{e}", wtemp);
webSend(dt);
web_label(1);
sprintf(dt, "%.1f %{e}", whumi);
webSend(dt);
web_label(20);
sprintf(dt, "%.1f g/m3{e}", ahum);
webSend(dt);
web_label(4);
sprintf(dt, "%.0f ppm{e}", wco2);
webSend(dt);
web_label(2);
sprintf(dt, "%.1f hPa{e}", bpress);
webSend(dt);
sprintf(dt, "{s}Heap{m}%d kb{e}", tasm_heap/1024);
webSend(dt);
}
void WebPage() {
WebChartSize(640, 200);
// Dual Y-axis: TVOC (left 0-3000 ppb) + CO2 (right 0-2000 ppm)
WebChart(0, "Air Quality", "TVOC|ppb", 0xFF0000, atvc[0], 96, atvc, 0, 15, 0.0, 3000.0);
WebChart(0, "", "CO2|ppm", 0x0000FF, aco2[0], 96, aco2, 0, 15, 0.0, 2000.0);
// Dual Y-axis: Humidity (left 0-100 %) + Temperature (right 0-40 C)
WebChart(0, "Climate", "Humidity|%", 0xFF0000, axhum[0], 96, axhum, 1, 15, 0.0, 100.0);
WebChart(0, "", "Temperature|C", 0x0000FF, tmpa[0], 96, tmpa, 1, 15, 0.0, 40.0);
}
int main() {
// Initial display setup: clear, draw separator lines
dspText("[zD0]");
dspText("[x0y20h296x0y40h296]");
dspText("[d]");
// Set initial time slot
last_m15 = (tasm_hour * 60 + tasm_minute) / 15 + 1;
print("EPaper display started\n");
return 0;
}