Skip to content

Commit

Permalink
CO2 Gadget Beta v0.12.051. Reworked Improv-WiFi strategy.
Browse files Browse the repository at this point in the history
Fixes Sometimes Improv-WiFi do not tiggers #151
  • Loading branch information
melkati committed Apr 28, 2024
1 parent 927ccb7 commit fe67e77
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 78 deletions.
24 changes: 16 additions & 8 deletions CO2_Gadget.ino
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ bool wifiChanged = false;

// MQTT options
bool activeMQTT = true;
bool troubledMQTT = false; // There are problems connecting to MQTT. Temporary suspend MQTT
uint64_t timeTroubledMQTT = 0; // Time since MQTT is troubled
uint64_t timeToRetryTroubledMQTT = 900; // Time in seconds to retry MQTT connection after it is troubled (no need to retry so often as it retries automatically everytime WiFi is connected)
bool troubledMQTT = false; // There are problems connecting to MQTT. Temporary suspend MQTT
uint64_t timeTroubledMQTT = 0; // Time since MQTT is troubled
uint64_t timeToRetryTroubledMQTT = 900; // Time in seconds to retry MQTT connection after it is troubled (no need to retry so often as it retries automatically everytime WiFi is connected)
bool mqttDiscoverySent = false;
uint16_t timeBetweenMQTTPublish = 60; // Time in seconds between MQTT transmissions
uint16_t timeToKeepAliveMQTT = 3600; // Maximum time in seconds between MQTT transmissions - Default: 1 Hour
uint64_t lastTimeMQTTPublished = 0; // Time of last MQTT transmission

// ESP-NOW options
bool activeESPNOW = false;
bool troubledESPNOW = false; // There are problems connecting to ESP-NOW. Temporary suspend ESP-NOW
bool troubledESPNOW = false; // There are problems connecting to ESP-NOW. Temporary suspend ESP-NOW
uint8_t channelESPNow = 1;
uint16_t boardIdESPNow = 0;
uint16_t timeBetweenESPNowPublish = 60; // Time in seconds between ESP-NOW transmissions
Expand All @@ -67,6 +67,8 @@ uint64_t lastTimeESPNowPublished = 0; // Time of last ESP-NOW transmission
bool activeOTA = false;

// Display and menu options
bool mustInitMenu = false;
bool menuInitialized = false;
uint16_t DisplayBrightness = 100;
bool displayReverse = false;
bool showFahrenheit = false;
Expand Down Expand Up @@ -112,7 +114,8 @@ uint16_t co2OrangeRange = 700;
uint16_t co2RedRange = 1000;

// Variables for Improv-Serial
uint16_t timeToWaitForImprov = 5; // Time in seconds to wait for improv serial
bool waitingForImprov = true;
uint16_t timeToWaitForImprov = 0; // Time in seconds to wait for improv serial

#ifdef BUILD_GIT
#undef BUILD_GIT
Expand Down Expand Up @@ -544,7 +547,6 @@ void setup() {

Serial.printf("-->[STUP] Starting up...\n\n");

initImprov();
initPreferences();
initBattery();
initGPIO();
Expand All @@ -565,15 +567,21 @@ void setup() {
#ifdef SUPPORT_MQTT
initMQTT();
#endif
menu_init();
initButtons();
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
printLargeASCII(WiFi.localIP().toString().c_str());
Serial.println("");
}
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, brown_reg_temp); // enable brownout detector
initImprov();
if (timeToWaitForImprov > 0) {
Serial.println("-->[STUP] Waiting for Improv Serial " + String(timeToWaitForImprov) + " seconds...");
} else {
Serial.println("-->[STUP] Improv Serial enabled");
}
Serial.println("-->[STUP] Ready.");
Serial.flush();
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, brown_reg_temp); // enable brownout detector
timeInitializationCompleted = millis();
}

Expand Down
18 changes: 12 additions & 6 deletions CO2_Gadget_Buttons.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,25 @@ Button2 btnUp(BTN_UP); // Initialize the up button
Button2 btnDwn(BTN_DWN); // Initialize the down button

void IRAM_ATTR buttonUpISR() {
if (actualDisplayBrightness == 0) // Turn on the display only if it's OFF
{
if (actualDisplayBrightness == 0) { // Turn on the display only if it's OFF
shouldWakeUpDisplay = true;
lastTimeButtonPressed = millis();
}
if (!menuInitialized) { // If the menu is not initialized yet, initialize it now (disable Improv WiFi functionality)
mustInitMenu = true;
publishMQTTLogData("-->[BUTT] mustInitMenu: " + String(mustInitMenu));
}
}

void IRAM_ATTR buttonDownISR() {
if (actualDisplayBrightness == 0) // Turn on the display only if it's OFF
{
if (actualDisplayBrightness == 0) { // Turn on the display only if it's OFF
shouldWakeUpDisplay = true;
lastTimeButtonPressed = millis();
}
if (!menuInitialized) { // If the menu is not initialized yet, initialize it now (disable Improv WiFi functionality)
mustInitMenu = true;
publishMQTTLogData("-->[BUTT] mustInitMenu: " + String(mustInitMenu));
}
}

// void doubleClick(Button2& btn) {
Expand All @@ -29,9 +35,9 @@ void IRAM_ATTR buttonDownISR() {
// }

void initButtons() {
// Interrupt Service Routine to turn on the display on button UP press
// Set Interrupt Service Routine to turn on the display on button UP or DOWN press (nothing to do with the button functionality for the menu itself)
attachInterrupt(BTN_UP, buttonUpISR, RISING);
attachInterrupt(BTN_DWN, buttonUpISR, RISING);
// attachInterrupt(BTN_DWN, buttonUpISR, RISING); // Conflicts with Improv because of GPIO 0

btnUp.setLongClickTime(LONGCLICK_TIME_MS);
btnUp.setLongClickHandler([](Button2 &b) { nav.doNav(enterCmd); });
Expand Down
81 changes: 68 additions & 13 deletions CO2_Gadget_Improv.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ void onImprovWiFiErrorCb(ImprovTypes::Error err) {
}

void onImprovWiFiConnectedCb(const char *ssid, const char *password) {
#ifdef WIFI_PRIVACY
#ifdef WIFI_PRIVACY
Serial.println("-->[IMPR] Connected to: " + String(ssid));
#else
#else
Serial.println("-->[IMPR] Connected to: " + String(ssid) + " with password: " + String(password));
#endif
#endif
wifiChanged = true;
activeWIFI = true;
wifiSSID = ssid;
Expand All @@ -31,26 +31,81 @@ void onImprovWiFiConnectedCb(const char *ssid, const char *password) {
}

void initImprov() {
char version[120]; // Ajusta el tamaño según tus necesidades
char version[120]; // Adjust the size of the buffer to your needs
sprintf(version, "CO2 Gadget Version: %s%s Flavour: %s\n", CO2_GADGET_VERSION, CO2_GADGET_REV, FLAVOUR);
Serial.println("-->[IMPR] Init Improv");
#if defined(CONFIG_IDF_TARGET_ESP32)
improvSerial.setDeviceInfo(ImprovTypes::ChipFamily::CF_ESP32, "CO2-Gadget-Beta-Desarrollo", version, "CO2-Gadget", "http://{LOCAL_IPV4}/preferences.html");
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
improvSerial.setDeviceInfo(ImprovTypes::ChipFamily::CF_ESP32_S3, "CO2-Gadget-Beta-Desarrollo", version, "CO2-Gadget", "http://{LOCAL_IPV4}/preferences.html");
#endif
#if defined(CONFIG_IDF_TARGET_ESP32)
improvSerial.setDeviceInfo(ImprovTypes::ChipFamily::CF_ESP32, "CO2-Gadget-Beta-Desarrollo", version, "CO2-Gadget", "http://{LOCAL_IPV4}/");
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
improvSerial.setDeviceInfo(ImprovTypes::ChipFamily::CF_ESP32_S3, "CO2-Gadget-Beta-Desarrollo", version, "CO2-Gadget", "http://{LOCAL_IPV4}/");
#endif

improvSerial.onImprovError(onImprovWiFiErrorCb);
improvSerial.onImprovConnected(onImprovWiFiConnectedCb);
// improvSerial.setCustomConnectWiFi(initWifi); // Optional
// improvSerial.setCustomConnectWiFi(initWifi); // Optional
}

void improvLoop() {
if (!inMenu) {
if (Serial.available() && Serial.peek() != 0x2A) { // 0x2A = '*'
improvSerial.handleSerial();
if (inMenu) { // If in menu ignore Improv functionality
#ifdef DEBUG_IMPROV_WIFI
static unsigned long lastPrintTime = 0;
if (waitingForImprov && (millis() - lastPrintTime >= 1000)) {
Serial.println("-->[IMPR] In menu, Improv functionality disabled");
lastPrintTime = millis();
}
#endif
return;
}

// If not '*' = 0x2A or '/' = 0x2F
if (Serial.available() && (Serial.peek() != 0x2A) && (Serial.peek() != 0x2F)) {
improvSerial.handleSerial();
#ifdef DEBUG_IMPROV_WIFI
static unsigned long lastPrintTime = 0;
if (millis() - lastPrintTime >= 1000) {
Serial.println("-->[IMPR] Handling Improv serial");
lastPrintTime = millis();
}
#endif
}

if (timeToWaitForImprov == 0) { // If time to wait for Improv is 0, Improv functionality will be enabled forever
#ifdef DEBUG_IMPROV_WIFI
static unsigned long lastPrintTime = 0;
if ((waitingForImprov) && (millis() - lastPrintTime >= 1000)) {
Serial.println("-->[IMPR] Improv functionality enabled forever");
lastPrintTime = millis();
}
#endif
return;
}

// If time to wait for Improv is over, disable Improv functionality
if (waitingForImprov) {
waitingForImprov = (millis() < timeInitializationCompleted + timeToWaitForImprov * 1000) > 0;
if (!waitingForImprov) {
mustInitMenu = true;
publishMQTTLogData("-->[IMPR] mustInitMenu: " + String(mustInitMenu));
Serial.println("-->[IMPR] Improv functionality disabled");
}
#ifdef DEBUG_IMPROV_WIFI
static unsigned long lastPrintTime = 0;
if (millis() - lastPrintTime >= 1000) {
Serial.println("-->[IMPR] Waiting for Improv: " + String(waitingForImprov));
lastPrintTime = millis();
}
#endif
}

#ifdef DEBUG_IMPROV_WIFI
if (waitingForImprov) {
static unsigned long lastPrintTime = 0;
if (millis() - lastPrintTime >= 1000) {
Serial.println("-->[IMPR] Time left waiting for Improv: " + String((timeInitializationCompleted + timeToWaitForImprov * 1000 - millis()) / 1000) + "sec");
lastPrintTime = millis();
}
}
#endif
}

#endif // CO2_Gadget_Improv_h
143 changes: 93 additions & 50 deletions CO2_Gadget_Menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1069,12 +1069,6 @@ result idle(menuOut &o, idleEvent e) {

void menuLoopTFT() {
#ifdef SUPPORT_TFT
if (millis() < (timeInitializationCompleted + timeToWaitForImprov * 1000)) { // Wait before starting the menu to avoid issues with Improv-WiFi
displayShowValues(shouldRedrawDisplay);
shouldRedrawDisplay = false;
return;
}

if ((wifiChanged) && (!inMenu)) {
wifiChanged = false;
displayNotification("To clear display", notifyInfo);
Expand All @@ -1098,12 +1092,6 @@ void menuLoopTFT() {

void menuLoopOLED() {
#ifdef SUPPORT_OLED
if (millis() < (timeInitializationCompleted + timeToWaitForImprov * 1000)) { // Wait before starting the menu to avoid issues with Improv-WiFi
displayShowValues(shouldRedrawDisplay);
shouldRedrawDisplay = false;
return;
}

if (nav.sleepTask) {
displayShowValues(shouldRedrawDisplay);
shouldRedrawDisplay = false;
Expand All @@ -1119,11 +1107,6 @@ void menuLoopOLED() {

void menuLoopEINK() {
#ifdef SUPPORT_EINK
if (millis() < (timeInitializationCompleted + timeToWaitForImprov * 1000)) { // Wait before starting the menu to avoid issues with Improv-WiFi
displayShowValues(false);
return;
}

nav.doInput();
if (nav.sleepTask) {
displayShowValues(false);
Expand All @@ -1135,40 +1118,14 @@ void menuLoopEINK() {
#endif
}

void menuLoop() {
if (Serial.available() && Serial.peek() == 0x2A) { // If the first byte is '*', then it's a command from the serial menu
nav.doInput(); // Do input, even if no display, as serial menu needs this
}

// Workaround: Try to avoid Serial TX buffer full if it's not connected to a receiving device
if ((Serial.availableForWrite() < 100) || (!workingOnExternalPower)) {
Serial.end();
delay(10);
Serial.begin(115200);
}

if (activeWIFI) {
activeMQTTMenu[0].enable();
} else {
activeMQTTMenu[0].disable();
}

#if defined(SUPPORT_TFT)
menuLoopTFT();
#elif defined(SUPPORT_OLED)
menuLoopOLED();
#elif defined(SUPPORT_EINK)
menuLoopEINK();
#else // For serial only output with display connected
if (!nav.sleepTask) {
if (nav.changed(0)) {
nav.doOutput();
}
}
void initMenu() {
#ifdef DEBUG_ARDUINOMENU
Serial.println("-->[MENU] Initializing menu...");
#endif
}

void menu_init() {
menuInitialized = true;
mustInitMenu = false;
waitingForImprov = false;
publishMQTTLogData("-->[MENU] Initializing menu...");
#ifdef SUPPORT_TFT
tft.loadFont(SMALL_FONT);
#endif
Expand Down Expand Up @@ -1205,4 +1162,90 @@ void menu_init() {
Serial.println("");
}

bool menuEntryCharacterReceived() {
// If the first byte is '*', then it's a command from the serial menu
if (Serial.available() && Serial.peek() == 0x2A) {
#ifdef DEBUG_ARDUINOMENU
Serial.println("-->[MENU] Serial command detected.");
#endif
return true;
}
return false;
}

void menuLoop() {
if (mustInitMenu) {
initMenu();
#ifdef DEBUG_ARDUINOMENU
Serial.println("-->[MENU] Initializing menu by mustInitMenu = true...");
#endif
}

// While we are waiting for Improv-WiFi to start, check if user is trying to access the menu to disable Improv-WiFi
if ((waitingForImprov) && (menuEntryCharacterReceived())) {
waitingForImprov = false;
#ifdef DEBUG_ARDUINOMENU
Serial.println("-->[MENU] Serial command detected. Improv-WiFi disabled.");
publishMQTTLogData("-->[MENU] Serial command detected. Improv-WiFi disabled.");
#endif
if (!menuInitialized) initMenu();
}

if (!menuInitialized) {
displayShowValues(shouldRedrawDisplay);
shouldRedrawDisplay = false;
#ifdef DEBUG_ARDUINOMENU
static unsigned long lastPrintTime2 = 0;
if (millis() - lastPrintTime2 >= 1000) {
Serial.println("-->[MENU] Waiting for Improv-WiFi to start...");
lastPrintTime2 = millis();
}
#endif
return;
}

#ifdef DEBUG_ARDUINOMENU
if (Serial.available()) {
Serial.print("-->[MENU] Received unknow byte: ");
Serial.println(Serial.peek(), HEX);
}
#endif

#ifdef DEBUG_ARDUINOMENU
static unsigned long lastPrintTime = 0;
if (millis() - lastPrintTime >= 1000) {
Serial.println("-->[MENU] menuLoop");
lastPrintTime = millis();
}
#endif

// Workaround: Try to avoid Serial TX buffer full if it's not connected to a receiving device
if ((Serial.availableForWrite() < 100) || (!workingOnExternalPower)) {
Serial.println("[MENU] Serial TX buffer full or not connected to a receiving device. Restarting Serial...");
Serial.end();
delay(10);
Serial.begin(115200);
}

if (activeWIFI) {
activeMQTTMenu[0].enable();
} else {
activeMQTTMenu[0].disable();
}

#if defined(SUPPORT_TFT)
menuLoopTFT();
#elif defined(SUPPORT_OLED)
menuLoopOLED();
#elif defined(SUPPORT_EINK)
menuLoopEINK();
#else // For serial only output with display connected
if (!nav.sleepTask) {
if (nav.changed(0)) {
nav.doOutput();
}
}
#endif
}

#endif // CO2_Gadget_Menu_h
Loading

0 comments on commit fe67e77

Please sign in to comment.