Moirtz Wagner d11f49a43d Dynamically load screens to save RAM.
Todo: make debug screen show things again.
2025-11-09 19:22:40 +01:00

174 lines
5.3 KiB
C++

#include <Arduino_GFX_Library.h>
#include <TouchDrvCSTXXX.hpp>
#include "lv_conf.h"
#include <lvgl.h>
#include <BME280I2C.h>
#include <EnvironmentCalculations.h>
#include <Wire.h>
#include <ui/ui.h>
#include <ui/vars.h>
#include <ui/actions.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <WiFi.h>
#include <WiFiManager.h>
#include <Ticker.h>
#include <PubSubClient.h>
#include "MQTT.h"
#include <tahoma.h>
#include <esp_task_wdt.h>
#define MEASINT_S 5
#define SCREEN_UPDATE_S 30 //update screen every 30 secs
#define HISTINT_S (5*60) //make history point every 5 min.
#define WDT_TIMEOUT SCREEN_UPDATE_S*3 //set WDT timeout to 3 times the screen update time
// -- Initial password to connect to the Thing, when it creates an own Access Point.
MQTT mqtt;
Ticker measurementTick;
Tahoma tahoma("1215-2900-8489.local","67ebd23e3a61763386d9");
unsigned char ChipID = 0x00;
volatile bool TouchEventFlag = false;
float barometerAltitude = 730.0; // meters ... map readings + barometer position
//using namespace MDO;
/*定义ESP32的SPI使用的引脚*/
BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X4,
BME280::Mode_Normal,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x76
);
BME280I2C bme(settings);
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 2 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
bool newMeasurement=false,newHistory=false;
float temp(NAN), hum(NAN), pres(NAN),seaLevelPress(NAN);
bool presAlarm = false;
bool mutex_locked = false;
static RTC_NOINIT_ATTR float test;
void measure(void){ //update temp every 30secs
static uint8_t dropCNT=0;
static float old_pres=0;
static uint32_t hist_update_cnt;
static uint32_t screen_update_cnt;
//settings.mode = BME280::Mode_Forced;
//bme.setSettings(settings);
++hist_update_cnt;
++screen_update_cnt;
if(newMeasurement){ //if flag was not yet handled completely, skip measurement but increase time counter for history timing
return;
}
bme.read(pres, temp, hum, BME280::TempUnit_Celsius, BME280::PresUnit_hPa);
//settings.mode = BME280::Mode_Sleep;
//bme.setSettings(settings);
temp = temp - 1.0; //adjust temp to compensate head dissipation of ESP
seaLevelPress = EnvironmentCalculations::EquivalentSeaLevelPressure(barometerAltitude, temp, pres, EnvironmentCalculations::AltitudeUnit_Meters, EnvironmentCalculations::TempUnit_Celsius);
/*if(history_isInitialized() && old_pres - pres > 0.1){
if(++dropCNT > 1){ //pressure drop at leaast 2 secs
old_pres = pres;
presAlarm = true;
}
}else{
old_pres = pres;
dropCNT = 0;
presAlarm = false;
}*/
if(screen_update_cnt >= SCREEN_UPDATE_S/MEASINT_S || presAlarm){ //update every 30 secs
newMeasurement = true;
screen_update_cnt = 0;
}
if(hist_update_cnt >= HISTINT_S/MEASINT_S || history_isInitialized() == false){ //add a point to history every 5 mins or init the hist, if no point present yet
history_append(seaLevelPress,temp,hum);
hist_update_cnt = 0;
newHistory = true;
newMeasurement = true;
}
}
void setup(void)
{
DisplayInit();
Serial.begin(115200);
lv_init();
WiFi.setSleep(WIFI_PS_MIN_MODEM);
lv_log_register_print_cb(log_print);
TouchInit();
bme.begin();
lv_display_t * disp = lv_display_create(SCREEN_WIDTH, SCREEN_HEIGHT);
lv_display_set_buffers(disp,draw_buf, NULL, sizeof(draw_buf),LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_0);
lv_display_set_flush_cb(disp, my_flush_cb);
lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, my_touch_read);
ui_init();
ledcAttachPin(PIN_REL, PWM_REL);
ledcSetup(PWM_REL, 100000, 8);
ledcWrite(PWM_REL, 0);
setBacklight(BL_BRIGHTNESS,300);
measurementTick.attach(MEASINT_S,measure);
mqtt.begin();
getLocalTime(&glblData.bootTime);
//lv_label_set_text_fmt(objects.debugTxt, "IP:\n %s\n\nHostname:\n %s\n\nMqtt-Server:\n %s\n\nMqtt-Port:\n %d\n\nMqtt-Topic:\n %s\n\nHeatBuffer:\n %d",glblData.myIP,Settings::prefs.hostname,Settings::prefs.mqtt_server,Settings::prefs.mqtt_port, Settings::prefs.mqtt_topic,glblData.enBuff);
measure();
esp_reset_reason_t reason = esp_reset_reason();
if ((reason != ESP_RST_DEEPSLEEP) && (reason != ESP_RST_SW)) {
test = glblData.settemp;
}
glblData.settemp = test;
ui_settemp(glblData.settemp);
esp_task_wdt_deinit();
esp_task_wdt_init(WDT_TIMEOUT, true);
esp_task_wdt_add(NULL);
}
unsigned long lastms = millis();
unsigned long secondsTick = 0, minutesTick = 0;
uint8_t statusCnt=0;
void loop()
{
if(newMeasurement){
esp_task_wdt_reset();
update_sensorNstatus(temp, hum, seaLevelPress,presAlarm);
test = glblData.settemp;
newMeasurement = false;
mqtt.sendStatus();
}
if(newHistory){
newHistory=false;
chart_autoscale();
}
if(millis() - minutesTick > 60000){
minutesTick = millis();
if(mqtt.wifiConnected){
update_wifi_strength(glblData.wifiStrength,glblData.wifiMode);
}
}
if(millis() - secondsTick > 1000){
secondsTick = millis();
update_clockdots();
}
mqtt.loop();
ui_tick();
if(!ui_isSleeping()){
lv_task_handler(); // let the GUI do its work
lv_tick_inc(millis() - lastms); // tell LVGL how much time has passed
}
lastms = millis();
}