Hello community,
I have Blynk running on my ESP32 with two I2C devices connected.
- DS3232
- OLED Display
I have made use of the RTClib.h and Adafruit libraries for communicating with the OLED display.
I am also making use of FreeRTOS to run tasks.
Everything works 100% until the wifi disconnects.
I have read on this post that there might be a timing issue with the Wire library for ESP32 and my OLED display then prints garbage.
I will make use of the suggested fix by stickbreaker on GitHub.
The other problem I am facing is that my ESP does not reconnect to the Blynk server after the wifi connection has been restored.
The issue with my OLED also does not resolve after the wifi connection has been restored.
extern "C"
{
void app_loop();
void eraseMcuConfig();
void restartMCU();
}
#include "Settings.h"
#include <BlynkSimpleEsp32_SSL.h>
#ifndef BLYNK_NEW_LIBRARY
#error "Old version of Blynk library is in use. Please replace it with the new one."
#endif
#if !defined(BLYNK_TEMPLATE_ID) || !defined(BLYNK_DEVICE_NAME)
#error "Please specify your BLYNK_TEMPLATE_ID and BLYNK_DEVICE_NAME"
#endif
#include "BlynkState.h"
#include "ConfigStore.h"
#include "ResetButton.h"
#include "ConfigMode.h"
#include "Indicator.h"
#include "OTA.h"
#include "FreeRTOSTasks.h"
void can_rx();
void manual_control();
//void ir_remote();
void startScheduler();
void relay1Task();
void relay2Task();
void relay3Task();
void relay4Task();
//void controlHumidity();
void timer1Task();
inline
void BlynkState::set(State m)
{
if (state != m && m < MODE_MAX_VALUE)
{
DEBUG_PRINT(String(StateStr[state]) + " => " + StateStr[m]);
state = m;
// You can put your state handling here,
// i.e. implement custom indication
}
}
void printDeviceBanner()
{
//Blynk.printBanner();
DEBUG_PRINT("--------------------------");
DEBUG_PRINT(String("Product: ") + BLYNK_DEVICE_NAME);
DEBUG_PRINT(String("Hardware: ") + BOARD_HARDWARE_VERSION);
DEBUG_PRINT(String("Firmware: ") + BLYNK_FIRMWARE_VERSION " (build " __DATE__ " " __TIME__ ")");
if (configStore.getFlag(CONFIG_FLAG_VALID))
{
DEBUG_PRINT(String("Token: ...") + (configStore.cloudToken+28));
}
DEBUG_PRINT(String("Device: ") + BLYNK_INFO_DEVICE + " @ " + ESP.getCpuFreqMHz() + "MHz");
DEBUG_PRINT(String("MAC: ") + WiFi.macAddress());
DEBUG_PRINT(String("Flash: ") + ESP.getFlashChipSize() / 1024 + "K");
DEBUG_PRINT(String("ESP sdk: ") + ESP.getSdkVersion());
DEBUG_PRINT(String("Chip rev: ") + ESP.getChipRevision());
DEBUG_PRINT(String("Free mem: ") + ESP.getFreeHeap());
DEBUG_PRINT("--------------------------");
}
void runBlynkWithChecks()
{
Blynk.run();
if (BlynkState::get() == MODE_RUNNING)
{
if (!Blynk.connected())
{
if (WiFi.status() == WL_CONNECTED)
{
BlynkState::set(MODE_CONNECTING_CLOUD);
} else
{
BlynkState::set(MODE_CONNECTING_NET);
}
}
}
}
class Edgent
{
public:
void begin()
{
indicator_init();
button_init();
config_init();
WiFi.persistent(false);
WiFi.enableSTA(true); // Needed to get MAC
printDeviceBanner();
if (configStore.getFlag(CONFIG_FLAG_VALID))
{
BlynkState::set(MODE_CONNECTING_NET);
} else if (config_load_blnkopt())
{
DEBUG_PRINT("Firmware is preprovisioned");
BlynkState::set(MODE_CONNECTING_NET);
} else
{
BlynkState::set(MODE_WAIT_CONFIG);
}
}
void run()
{
app_loop();
switch (BlynkState::get())
{
case MODE_WAIT_CONFIG:
case MODE_CONFIGURING: enterConfigMode(); break;
case MODE_CONNECTING_NET: enterConnectNet(); break;
case MODE_CONNECTING_CLOUD: enterConnectCloud(); break;
case MODE_RUNNING: runBlynkWithChecks(); break;
case MODE_OTA_UPGRADE: enterOTA(); break;
case MODE_SWITCH_TO_STA: enterSwitchToSTA(); break;
case MODE_RESET_CONFIG: enterResetConfig(); break;
default: enterError(); break;
}
}
};
Edgent BlynkEdgent;
BlynkTimer timer3;
void app_loop()
{
can_rx();
timer3.run();
relay1Task();
startScheduler();
}
void can_rx(void)
{
CAN_frame_t rx_frame;
if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE)
{
switch (rx_frame.MsgID)
{
case 0x001:
Serial.println("Message from Temp and Humidity Node");
for(int i = 0; i < 4; i++)
{
oledDisplay.humTemp.humidity.buf[i] = rx_frame.data.u8[i];
}
for(int i = 4; i < 8; i++)
{
oledDisplay.humTemp.temp.buf[(i-4)] = rx_frame.data.u8[i];
}
printf(" Data Frame from 0x%08x, Temp is: %.2f\r\n",rx_frame.MsgID, oledDisplay.humTemp.temp.floatVal);
printf(" Data Frame from 0x%08x, Humidity is: %.2f\r\n",rx_frame.MsgID, oledDisplay.humTemp.humidity.floatVal);
return;
}
if(rx_frame.FIR.B.FF==CAN_frame_std)
{
Serial.println("New Standard Frame.");
}
//if(rx_frame.FIR.B.RTR==CAN_RTR) /
//printf(" RTR from 0x%08x, DLC %d\r\n",rx_frame.MsgID, rx_frame.FIR.B.DLC);
/*else
{
printf(" from 0x%08x, DLC %d\n",rx_frame.MsgID, rx_frame.FIR.B.DLC);
// convert to upper case and respond to sender
for(int i = 0; i < 8; i++)
{
if(rx_frame.data.u8[i] >= 'a' && rx_frame.data.u8[i] <= 'z')
{
rx_frame.data.u8[i] = rx_frame.data.u8[i] - 32;
}
}
} */
//respond to sender
//ESP32Can.CANWriteFrame(&rx_frame);
}
}
void manual_control()
{
if((digitalRead(s1) == LOW) && (SwitchState_1 == LOW))
{
SwitchState_1 = HIGH;
s1Bool = 1;
Serial.print("s1Bool: ");
Serial.println(s1Bool);
Blynk.virtualWrite(VPIN_BUTTON_1, HIGH);
}
if((digitalRead(s1) == HIGH) && (SwitchState_1 == HIGH))
{
SwitchState_1 = LOW;
s1Bool = 0;
Serial.print("s1Bool: ");
Serial.println(s1Bool);
Blynk.virtualWrite(VPIN_BUTTON_1, LOW);
}
if (digitalRead(s2) == LOW)
{
//digitalWrite(r3, LOW);
Blynk.virtualWrite(VPIN_BUTTON_2, HIGH);
//relayState_2 = HIGH;
SwitchState_2 = HIGH;
//Serial.println("INLET ON");
}
if (digitalRead(s2) == HIGH)
{
//digitalWrite(r3, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_2, LOW);
//relayState_2 = LOW;
SwitchState_2 = LOW;
//Serial.println("INLET OFF");
}
if (digitalRead(s3) == LOW)
{
//digitalWrite(r4, LOW);
Blynk.virtualWrite(VPIN_BUTTON_3, HIGH);
//relayState_3 = HIGH;
SwitchState_3 = HIGH;
//Serial.println("OUTLET ON");
}
if (digitalRead(s3) == HIGH)
{
//digitalWrite(r4, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_3, LOW);
//relayState_3 = LOW;
SwitchState_3 = LOW;
//Serial.println("OUTLET OFF");
}
if (digitalRead(s4) == LOW)
{
//digitalWrite(r5, LOW);
Blynk.virtualWrite(VPIN_BUTTON_4, HIGH);
//relayState_4 = HIGH;
SwitchState_4 = HIGH;
//Serial.println("HUMIDIFIER ON");
}
if (digitalRead(s4) == HIGH)
{
//digitalWrite(r5, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_4, LOW);
//relayState_4 = LOW;
SwitchState_4 = LOW;
//Serial.println("HUMIDIFIER OFF");
}
if (digitalRead(s5) == LOW && SwitchState_5 == LOW)
{
//digitalWrite(RelayPin5, LOW);
Blynk.virtualWrite(VPIN_BUTTON_5, HIGH);
//toggleState_5 = HIGH;
//SwitchState_5 = HIGH;
Serial.println("Switch-5 on");
}
if (digitalRead(s5) == HIGH && SwitchState_5 == HIGH)
{
//digitalWrite(RelayPin5, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_5, LOW);
//toggleState_5 = LOW;
//SwitchState_5 = LOW;
Serial.println("Switch-5 off");
}
/*if (digitalRead(SwitchPin6) == LOW && SwitchState_6 == LOW) {
digitalWrite(RelayPin6, LOW);
Blynk.virtualWrite(VPIN_BUTTON_6, HIGH);
toggleState_6 = HIGH;
SwitchState_6 = HIGH;
Serial.println("Switch-6 on");
}
if (digitalRead(SwitchPin6) == HIGH && SwitchState_6 == HIGH) {
digitalWrite(RelayPin6, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_6, LOW);
toggleState_6 = LOW;
SwitchState_6 = LOW;
Serial.println("Switch-6 off");
}
if (digitalRead(SwitchPin7) == LOW && SwitchState_7 == LOW) {
digitalWrite(RelayPin7, LOW);
Blynk.virtualWrite(VPIN_BUTTON_7, HIGH);
toggleState_7 = HIGH;
SwitchState_7 = HIGH;
Serial.println("Switch-7 on");
}
if (digitalRead(SwitchPin7) == HIGH && SwitchState_7 == HIGH) {
digitalWrite(RelayPin7, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_7, LOW);
toggleState_7 = LOW;
SwitchState_7 = LOW;
Serial.println("Switch-7 off");
}
if (digitalRead(SwitchPin8) == LOW && SwitchState_8 == LOW) {
digitalWrite(RelayPin8, LOW);
Blynk.virtualWrite(VPIN_BUTTON_8, HIGH);
toggleState_8 = HIGH;
SwitchState_8 = HIGH;
Serial.println("Switch-8 on");
}
if (digitalRead(SwitchPin8) == HIGH && SwitchState_8 == HIGH) {
digitalWrite(RelayPin8, HIGH);
Blynk.virtualWrite(VPIN_BUTTON_8, LOW);
toggleState_8 = LOW;
SwitchState_8 = LOW;
Serial.println("Switch-8 off");
}*/
}
void startScheduler(void)
{
/*Serial.print("waitMin: ");
Serial.println(waitMin);
Serial.print("currenttMin: ");
Serial.println(currentMin);*/
// Serial.println("SCHEDULER");
if(waitMin == currentMin)
{
waitMin = (currentMin + 1);
if(waitMin > 59)
{
waitMin -=60;
}
// LIGHTS 1 :: 07:00 - 01:00
if(Scheduler[0][0].Hour == (uint8_t)currentHour)
{
//Serial.println("Scheduler Hour Activated.");
if(Scheduler[0][0].Minute == (uint8_t)currentMin)
{
//Serial.println("Scheduler Min Activated.");
r1Time = Scheduler[0][0].OnTime;
//Serial.print("r1Time now activated: ");
//Serial.println(r1Time);
//Serial.print("waitMin: ");
//Serial.println(waitMin);
//Serial.print("currenttMin: ");
//Serial.println(currentMin);
}
}
// LIGHTS 2 :: 07:00 - 01:00
if(Scheduler[1][0].Hour == currentHour)
{
if(Scheduler[1][0].Minute == currentMin)
{
r2Time = Scheduler[1][0].OnTime;
}
}
// INLET :: 07:00 - 01:00
if(Scheduler[2][0].Hour == currentHour)
{
if(Scheduler[2][0].Minute == currentMin)
{
r3Time = Scheduler[2][0].OnTime;
}
}
// INLET ::
if(Scheduler[2][1].Hour == currentHour)
{
if(Scheduler[2][1].Minute == currentMin)
{
r3Time = Scheduler[2][1].OnTime;
}
}
// INLET
if(Scheduler[2][2].Hour == currentHour)
{
if(Scheduler[2][2].Minute == currentMin)
{
r3Time = Scheduler[2][2].OnTime;
}
}
// INLET
if(Scheduler[2][3].Hour == currentHour)
{
if(Scheduler[2][3].Minute == currentMin)
{
r3Time = Scheduler[2][3].OnTime;
}
}
// INLET
if(Scheduler[2][4].Hour == currentHour)
{
if(Scheduler[2][4].Minute == currentMin)
{
r3Time = Scheduler[2][4].OnTime;
}
}
// INLET
if(Scheduler[2][5].Hour == currentHour)
{
if(Scheduler[2][5].Minute == currentMin)
{
r3Time = Scheduler[2][5].OnTime;
}
}
// INLET
/*if(Scheduler[0][0].Month == currentMonth | 0xFF)
{
if(Scheduler[0][0].Day == currentDay | 0xFF)
{
if(Scheduler[0][0].Hour == currenHour)
{
if(Scheduler[0][0].Minute == currentMin)
{
r2Time = Scheduler[2][6].OnTime;
}
}
}
}*/
// OUTLET
if(Scheduler[3][0].Hour == currentHour)
{
if(Scheduler[3][0].Minute == currentMin)
{
r4Time = Scheduler[3][0].OnTime;
}
}
// OUTLET
if(Scheduler[3][1].Hour == currentHour)
{
if(Scheduler[3][1].Minute == currentMin)
{
r4Time = Scheduler[3][1].OnTime;
}
}
// OUTLET
if(Scheduler[3][2].Hour == currentHour)
{
if(Scheduler[3][2].Minute == currentMin)
{
r4Time = Scheduler[3][2].OnTime;
}
}
// OUTLET
if(Scheduler[3][3].Hour == currentHour)
{
if(Scheduler[3][3].Minute == currentMin)
{
r4Time = Scheduler[3][3].OnTime;
}
}
// OUTLET
if(Scheduler[3][4].Hour == currentHour)
{
if(Scheduler[3][4].Minute == currentMin)
{
r4Time = Scheduler[3][4].OnTime;
}
}
// OUTLET
if(Scheduler[3][5].Hour == currentHour)
{
if(Scheduler[3][5].Minute == currentMin)
{
r4Time = Scheduler[3][5].OnTime;
}
}
timer1Task();
}
}
/* TIMER SCHEDULE TASKS */
void timer1Task(void)
{
if(r1Time) //r1Time should be incremented by +1 as time is deducted by 1 as soon as task starts.
{
r1Time--;
r1TimeBool = 1;
r1SwitchState = 1;
}
else
{
r1TimeBool = 0;
}
}
/* RELAY TASKS */
/* If override switch is off,
relay will remain off */
void relay1Task(void) // LIGHTS
{
if(s1Bool)
{
digitalWrite(r1, LOW);
if((r1TimeBool) && (r1SwitchState))
{
Serial.print("s1Bool in r1Task: ");
Serial.println(s1Bool);
r1SwitchState = 0;
digitalWrite(r1, LOW);
}
if((r1TimeBool == 0) && (!r1SwitchState))
{
digitalWrite(r1, HIGH);
}
}
else
{
digitalWrite(r1, HIGH);
r1SwitchState = 1;
}
}
void relay2Task(void) //LIGHTS
{
if ((r2Time) || (relayState_1 == HIGH))
{
digitalWrite(r2, LOW); // Switch on Relay
r2Time--;
Serial.print("r2Time: ");
Serial.println(r2Time);
Serial.print("r2 State: ");
Serial.println(digitalRead(r2));
}
else if ((r2Time == 0) || (relayState_1 == LOW))
{
digitalWrite(r2, HIGH); // Switch off Relay
}
}
void relay3Task(void) //INLET
{
if ((r3Time) && (relayState_2 == HIGH))
{
digitalWrite(r3, LOW); // Switch on Relay
r3Time--;
}
else if ((r3Time == 0) | (relayState_2 == LOW))
{
digitalWrite(r3, HIGH); // Switch off Relay
}
}
void relay4Task(void) //OUTLET
{
if ((r4Time) && (relayState_3 == HIGH))
{
digitalWrite(r4, LOW); // Switch on Relay
r4Time--;
}
else if ((r4Time == 0) || (relayState_3 == LOW))
{
digitalWrite(r4, HIGH); // Switch off Relay
}
}
/*void controlHumidity(void)
{
if((humidity <= 53) && (relayState_4 == HIGH))
{
digitalWrite(r5, LOW);
}
if((humidity >= 56) || (relayState_4 == LOW))
{
digitalWrite(r5, HIGH);
}
}*/
This is the sample code I have obtained with regards to Blynk v2.0
I am in the process of moving the other functions to their own respective classes.
Any help will be greatly appreciated.