Hi Community,
I hope you can help me with my problem. I have created a project and actually all the functions work as I expect. However, I have a problem every morning. Always at about 7am (+/- 30 min) I have a Heartbeat timeout (see DEBUG log). After that I try to restart via WDT but then Blynk can’t sync anything anymore … in this case only a hard-reset helps to bring it back to work.
Since everything runs stable during the day I assume that I have a bug in my code that triggers the timeout. Does anyone have a tip what I should change or where i do the error?
My timer input is set to 10.00- 13.30 on all days in the correct timezone.
Thank you in advance for your help.
My Hardware Setup:
Arduino Mega + ESP8266 (NodeMUC 1.3 (AT Firmeware))
Blynk Local Server 0.41.14 (Java 8 on Raspi) // before i used the could with same result
Blynk Libary: v0.6.1
iOS App: 2.26.5
NodeMCU:
AT version:1.3.0.0(Jul 14 2016 18:54:01)
SDK version:2.0.0(656edbf)
#define BLYNK_DEBUG
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Blynk.h>
#include <DHT.h>
#include <Wire.h>
#include "cactus_io_BME280_I2C.h"
#include <Adafruit_CCS811.h>
#include <WidgetRTC.h>
#include <TimeLib.h>
#include <avr/wdt.h>
Adafruit_CCS811 ccs;
BME280_I2C bme; // I2C using address 0x76
BlynkTimer timer;
WidgetRTC rtc;
WidgetTerminal terminal(V1);
char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
WidgetLED ledLicht(V46);
WidgetLED ledVentilator(V47);
WidgetLED ledLuefter(V48);
WidgetLED ledTest(V2);
bool ledStatus = false;
#define BLYNK_GREEN "#23C48E"
#define BLYNK_BLUE "#04C0F8"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_RED "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define EspSerial Serial3
#define led 32
#define onboardLed 13
#define ventilator 35
#define luefterLow 33
#define luefterHigh 34
#define DHTPIN A11
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define ESP8266_BAUD 9600
ESP8266 wifi(&EspSerial);
char Date[16];
char Time[16];
int t;
int h;
int t_a;
int h_a;
int t_i;
int h_i;
int maxTemp = 30;
int maxH = 65;
char currentTime[9];
bool clockSync = false;
bool notifiedT = false;
bool notifiedH = false;
int alldays ;
int manual = 0;
long startsecondswd; // weekday start time in seconds
long stopsecondswd; // weekday stop time in seconds
long nowseconds; // time now in seconds
bool isFirstConnect = true;
// Calibration for Soil Sensors
const int AirValue1 = 595;
const int WaterValue1 = 300;
const int AirValue2 = 580;
const int WaterValue2 = 293;
const int AirValue3 = 586;
const int WaterValue3 = 290;
const int AirValue4 = 590;
const int WaterValue4 = 290;
int soil_sensor1 = A1;
int output_value1 ;
int moisturelevel1;
int soil_sensor2 = A2;
int output_value2 ;
int moisturelevel2 ;
int soil_sensor3 = A3;
int output_value3 ;
int moisturelevel3 ;
int soil_sensor4 = A7;
int output_value4 ;
int moisturelevel4 ;
int co2_ppm ;
int TVOC;
int ledPin = 32;
int ventilatorPin = 35;
int luefterLowPin = 33;
int luefterHighPin = 34;
void setup()
{
dht.begin();
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
pinMode(onboardLed, OUTPUT);
digitalWrite(onboardLed, LOW);
pinMode(ventilatorPin, OUTPUT);
digitalWrite(ventilatorPin, HIGH);
pinMode(luefterLowPin, OUTPUT);
digitalWrite(luefterLowPin, HIGH);
pinMode(luefterHighPin, OUTPUT);
digitalWrite(luefterHigh, HIGH);
Serial.begin(9600);
EspSerial.begin(ESP8266_BAUD);
Blynk.begin(auth, wifi, ssid, pass, "x.x.x.x", 8080);
setSyncInterval(10 * 60); // RTC Sync interval in seconds (10 minutes)
// Clear the terminal content
terminal.clear();
Blynk.virtualWrite(V1,"Blynk v ", BLYNK_VERSION, ": Sync gestartet\n");
Blynk.virtualWrite(V1,"-------------\n");
Blynk.syncVirtual(V33, V35, V36);
delay(20);
Blynk.syncVirtual(V15, V16);
terminal.flush();
if (!ccs.begin()) {
Serial.println("Start des co2-Sensors fehlgeschlagen! Bitte ueberpruefen Sie Ihre Verdrahtung.");
terminal.println("Start des co2-Sensors fehlgeschlagen! Bitte ueberpruefen Sie Ihre Verdrahtung.");
terminal.flush();
}
if (!bme.begin()) {
Serial.println("Es konnte kein BME280 Sensor gefunden werden!");
Serial.println("Bitte überprüfen Sie die Verkabelung!");
// while (1);
}
bme.setTempCal(-1);
// Setup a function to be called every second
timer.setInterval(100000L, checkBlynk);
timer.setInterval(14000L, clockDisplay);
timer.setInterval(31000L, sendSensor);
timer.setInterval(60000L, activetoday);
// timer.setInterval(3000L, lcd_data);
ledLicht.on();
ledLicht.setColor(BLYNK_RED);
ledVentilator.on();
ledVentilator.setColor(BLYNK_RED);
ledLuefter.on();
ledLuefter.setColor(BLYNK_RED);
ledTest.on();
ledTest.setColor(BLYNK_RED);
}
void resetNotifiedT()
{
notifiedT = 0;
}
void resetNotifiedH()
{
notifiedH = 0;
}
void checkBlynk() {
if (!Blynk.connected()) {
Serial.println();
Serial.println("*********** Verbindungs Fehler ************");
Serial.println("Nicht mit dem Blynk-Server verbunden");
Serial.println("*********** Automatischer Neustart ************");
Serial.println();
wdt_enable(WDTO_1S);
}
}
BLYNK_CONNECTED() {
rtc.begin();
}
void activetoday() {
if (alldays == 1) {
Blynk.syncVirtual(V34);
}
}
void clockDisplay() { // only needs to be done once after time sync
if ((year() != 1970) && (clockSync == false)) {
sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
Serial.println(currentTime);
// terminal.println(currentTime);
clockSync = true;
}
int gmthour = hour();
if (gmthour == 24) {
gmthour = 0;
}
String displayhour = String(gmthour, DEC);
int hourdigits = displayhour.length();
if (hourdigits == 1) {
displayhour = "0" + displayhour;
}
String displayminute = String(minute(), DEC);
int minutedigits = displayminute.length();
if (minutedigits == 1) {
displayminute = "0" + displayminute;
}
}
BLYNK_WRITE(V15)
{
maxTemp = param.asInt();
}
BLYNK_WRITE(V16)
{
maxH = param.asInt();
}
BLYNK_WRITE(V33) {
switch (param.asInt())
{
case 1: // Item 1
alldays = 1;
terminal.println("Automatik Beleuchtung: Auto");
break;
case 2: // Item 2
alldays = 0;
digitalWrite(ledPin, HIGH);
ledLicht.setColor(BLYNK_RED);
terminal.println("Automatik Beleuchtung: Manuell Aus");
break;
case 3:
alldays = 0;
digitalWrite(ledPin, LOW); // set LED OFF
ledLicht.setColor(BLYNK_GREEN);
terminal.println("Automatik Beleuchtung: Manuell An");
break;
default:
terminal.println("Automatik Beleuchtung: Auto");
alldays = 1;
}
// Serial.println("DEBUG: V33 OK");
terminal.flush();
}
BLYNK_WRITE(V34)//All days
{
if (alldays == 1) {
sprintf(Date, "%02d/%02d/%04d", day(), month(), year());
sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
TimeInputParam t(param);
terminal.print("Check Automatik Beleuchtung gestartet: ");
terminal.println(Time);
terminal.flush();
int dayadjustment = -1;
if (weekday() == 1) {
dayadjustment = 6; // needed for Sunday, Time library is day 1 and Blynk is day 7
}
if (t.isWeekdaySelected(weekday() + dayadjustment)) { //Time library starts week on Sunday, Blynk on Monday
terminal.println("Automatik aktiv heute");
terminal.flush();
if (t.hasStartTime()) // Process start time
{
terminal.println(String("Starte Nachtphase: ") + t.getStartHour() + ":" + t.getStartMinute());
terminal.flush();
}
if (t.hasStopTime()) // Process stop time
{
terminal.println(String("Stop Nachtphase : ") + t.getStopHour() + ":" + t.getStopMinute());
terminal.flush();
}
// Display timezone details, for information purposes only
terminal.println(String("Zeitzone: ") + t.getTZ()); // Timezone is already added to start/stop time
// terminal.println(String("Time zone offset: ") + t.getTZ_Offset()); // Get timezone offset (in seconds)
terminal.flush();
for (int i = 1; i <= 7; i++) { // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
if (t.isWeekdaySelected(i)) {
// terminal.println(String("Tag ") + i + " ist ausgewaehlt");
// terminal.flush();
}
}
nowseconds = ((hour() * 3600L) + (minute() * 60L) + second());
// terminal.println(String("hour : ") + (hour() * 3600L) );
// terminal.println(String("minute : ") + (minute() * 60L));
// terminal.println(String("second : ") + second());
// terminal.println((hour() * 3600L) + (minute() * 60) + second());
startsecondswd = (t.getStartHour() * 3600L) + (t.getStartMinute() * 60L);
// terminal.println(String("DEBUG : nowseconds : ") + nowseconds);
// terminal.println(String("DEBUG : Startpsecondswd : ") + startsecondswd); // used for debugging
terminal.flush();
if (nowseconds >= startsecondswd) {
terminal.print("LED aus ab");
terminal.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
terminal.flush();
if (nowseconds <= startsecondswd + 90) { // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(ledPin, HIGH);
ledLicht.setColor(BLYNK_RED);
terminal.print("LED Bechleuchtung ist ausgeschalten. Es ist Nacht !");
// set LED ON
// Blynk.virtualWrite(V2, 1);
// code here to switch the relay ON
}
}
else {
digitalWrite(ledPin, LOW); // set LED OFF
ledLicht.setColor(BLYNK_GREEN);
terminal.println("LED Bechleutung eingeschalten. Es ist Tag.");
terminal.flush();
}
stopsecondswd = (t.getStopHour() * 3600L) + (t.getStopMinute() * 60L);
// terminal.println(String("DEBUG : nowseconds : ") + nowseconds);
// terminal.println(String("DEBUG : Stopsecondswd : ") + stopsecondswd); // used for debugging
// terminal.flush();
if (nowseconds >= stopsecondswd) {
digitalWrite(ledPin, LOW); // set LED OFF
ledLicht.setColor(BLYNK_GREEN);
terminal.print("LED an ab");
terminal.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
terminal.println("LED Bechleutung eingeschalten. Es ist Tag.");
terminal.flush();
if (nowseconds <= stopsecondswd + 90) { // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(ledPin, LOW); // set LED OFF
ledLicht.setColor(BLYNK_GREEN);
terminal.println("LED Bechleutung eingeschalten. Es ist Tag.");
// code here to switch the relay OFF
}
}
else {
if (nowseconds >= startsecondswd) {
digitalWrite(ledPin, HIGH);
ledLicht.setColor(BLYNK_RED);
terminal.print("LED Bechleuchtung ist ausgeschaltet. Es ist Nacht !");
terminal.flush();
}
}
}
else {
terminal.println("Automatik heute nicht aktiv.");
terminal.flush();
}
terminal.println();
}
}
BLYNK_WRITE(V35) {
switch (param.asInt())
{
case 1:
terminal.println("Umluftventilator Aus");
digitalWrite(ventilatorPin, HIGH);
ledVentilator.setColor(BLYNK_RED);
break;
case 2:
terminal.println("Umluftventilator An");
digitalWrite(ventilatorPin, LOW);
ledVentilator.setColor(BLYNK_GREEN);
break;
default:
digitalWrite(ventilatorPin, HIGH);
ledVentilator.setColor(BLYNK_RED);
}
terminal.flush();
}
BLYNK_WRITE(V36) {
switch (param.asInt())
{
case 1:
terminal.println("Abluftventilator Aus");
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_RED);
break;
case 2:
terminal.println("Abluftventilator 100%");
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, LOW);
ledLuefter.setColor(BLYNK_BLUE);
break;
case 3:
terminal.println("Abluftventilator 80%");
digitalWrite(luefterHighPin, LOW);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_DARK_BLUE);
break;
default:
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_RED);
}
terminal.flush();
}
BLYNK_WRITE(V1)
{
if (String("Marco") == param.asStr()) {
terminal.println("You said: 'Marco'") ;
terminal.println("I said: 'Polo'") ;
} else {
// Send it back
terminal.print("You said:");
terminal.write(param.getBuffer(), param.getLength());
terminal.println();
}
terminal.flush();
}
void sendSensor()
{
String notifyStringT;
String notifyStringH;
bme.readSensor();
h_a = dht.readHumidity();
t_a = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
h_i = bme.getHumidity();
t_i = bme.getTemperature_C(); // or dht.readTemperature(true) for Fahrenheit
output_value1 = analogRead(soil_sensor1);
moisturelevel1 = constrain ( map(output_value1, AirValue1, WaterValue1, 0, 100), 0, 100);
output_value2 = analogRead(soil_sensor2);
moisturelevel2 = constrain ( map(output_value2, AirValue2, WaterValue2, 0, 100), 0, 100);
output_value3 = analogRead(soil_sensor3);
moisturelevel3 = constrain ( map(output_value3, AirValue3, WaterValue3, 0, 100), 0, 100);
output_value4 = analogRead(soil_sensor4);
moisturelevel4 = constrain (map(output_value4, AirValue4, WaterValue4, 0, 100), 0, 100);
if (ccs.available()) {
if (!ccs.readData()) {
ccs.setDriveMode(4);
ccs.readData();
co2_ppm = (ccs.geteCO2());
TVOC = (ccs.getTVOC());
}
else {
terminal.println("CO2-Sensor - FEHLER!");
ccs.readData();
}
}
if (t_i >= maxTemp && !notifiedT)
{
notifiedT = true;
notifyStringT = "Alarm - Temperatur IST:" + String(t_i) + " SOLL MAX:" + String(maxTemp);
Serial.println(notifyStringT);
terminal.println(notifyStringT);
Blynk.notify(notifyStringT);
timer.setTimeout(600000L, resetNotifiedT);
}
if (h_i >= maxH && !notifiedH)
{
notifiedH = true;
notifyStringH = "Alarm - Luftfeuchtigkeit IST:" + String(h_i) + " SOLL MAX:" + String(maxH);
Serial.println(notifyStringH);
terminal.println(notifyStringH);
Blynk.notify(notifyStringH);
timer.setTimeout(600000L, resetNotifiedH);
}
Blynk.virtualWrite(V5, h_i);
Blynk.virtualWrite(V6, t_i);
Blynk.virtualWrite(V13, h_a);
Blynk.virtualWrite(V14, t_a);
Blynk.virtualWrite(V7, moisturelevel1 );
Blynk.virtualWrite(V8, moisturelevel2 );
Blynk.virtualWrite(V9, moisturelevel3 );
Blynk.virtualWrite(V10, moisturelevel4 );
Blynk.virtualWrite(V21, output_value1 );
Blynk.virtualWrite(V22, output_value2 );
Blynk.virtualWrite(V23, output_value3 );
Blynk.virtualWrite(V24, output_value4 );
// 400ppm - 8192ppm
Blynk.virtualWrite(V11, co2_ppm);
// 0ppb- 1187ppb
Blynk.virtualWrite(V12, TVOC);
terminal.flush();
}
void loop()
{
Blynk.run();
timer.run(); // Initiates BlynkTimer
}
Debug Log:
07:25:21.929 -> [144256271] <[14].[EE|00|09]vw[00]11[00]417
07:25:21.929 -> [144256434] <[14].[EF|00|07]vw[00]12[00]2
07:25:21.929 -> [144256685] <[06].[F0|00|00]
07:25:21.929 -> [144256791] >[00].[F0|00|C8]
07:25:41.960 -> [144266770] <[06].[F1|00|00]
07:25:41.960 -> [144266878] >[00].[F1|00|C8]
07:25:41.960 -> [144276856] <[06].[F2|00|00]
07:25:41.960 -> [144276963] >[00].[F2|00|C8]
07:27:11.957 -> [144363900] Heartbeat timeout: 144363900, 144276963, 144276856
07:27:11.957 -> [144368911] <[14].[F3|00|07]vw[00]5[00]44
07:27:11.957 -> [144373922] Cmd error
07:27:40.176 -> [144384021] <[1D|00|01|00] xxxxxxxxx AUTH CODE xxxxxxxxx
07:27:40.176 ->
07:27:40.176 -> *********** Verbindungs Fehler ************
07:27:40.176 -> Nicht mit dem Blynk-Server verbunden
07:27:40.176 -> *********** Automatischer Neustart ************
07:27:40.176 ->
07:27:40.176 -> [0]
FREEEEEEZZZZZZZ -> no more reaction until hard-reset