Looks like it’s beyond just losing connectivity – I added an LED flashing timer and that stops flashing when it goes offline. I added a soft WDT, so we’ll see if at least catches the event and restarts. My code is so basic that I doubt it’s anywhere in mine, so I’m suspecting a library.
The most suspect is executing ArduinoOTA.handle();
before Blynk.run();
. Any best practices on ordering between the two? I could have sworn that OTA doesn’t work in the opposite order.
#include <Arduino.h>
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266_SSL.h>
#include <ESP8266WiFi.h>
char auth[] = "foo"; // Entrance
const char *hostname = "esp-entrance";
#include "../../common/common.cpp"
#define BUZZER_PIN 4 // D2
#define REED_SWITCH_PIN 14 // D5
#define BUZZER_TIME 3000L
#define V_DOOR V1
#define V_BUTTON_BUZZER V3
void unlock_entrance() {
Serial.println("Unlocking entrance");
digitalWrite(BUZZER_PIN, HIGH);
}
void lock_entrance() {
Serial.println("Locking entrance");
digitalWrite(BUZZER_PIN, LOW);
}
void init_pins() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(BUZZER_PIN, OUTPUT);
lock_entrance(); // If stuck, this will turn off the entrance buzzer upon restart
pinMode(REED_SWITCH_PIN, INPUT_PULLUP);
}
void warn_door_open() {
int is_door_closed = digitalRead(REED_SWITCH_PIN);
if (!is_door_closed) {
Serial.println("THE ENTRANCE GATE HAS BEEN LEFT OPEN!");
Blynk.notify("⚠️ THE ENTRANCE GATE HAS BEEN LEFT OPEN!");
blynk_timer.setTimeout(60 * 60 * 1000, warn_door_open); // check again every hour until it's closed
}
}
void send_reed_switch_state() {
int is_door_closed = digitalRead(REED_SWITCH_PIN);
Serial.println("Is entrance closed: " + String(is_door_closed));
Blynk.virtualWrite(V_DOOR, is_door_closed);
if (!is_door_closed) {
blynk_timer.setTimeout(60 * 1000, warn_door_open); // check back in a minute
}
}
BLYNK_WRITE(V_BUTTON_BUZZER) {
int pushed = param.asInt();
if (pushed) {
Serial.println("Buzzer button pushed");
unlock_entrance();
blynk_timer.setTimeout(BUZZER_TIME, []() { // Lambda Reconnection Timer Function
lock_entrance();
});
}
}
BLYNK_APP_CONNECTED() {
Serial.println("Blynk App Connected.");
send_reed_switch_state(); // in case of a stuck state
}
BLYNK_CONNECTED() {
Serial.println("Connected to Blynk Server");
send_reed_switch_state(); // in case of a stuck state
}
BLYNK_DISCONNECTED() {
Serial.println("Disconnected from Blynk Server.");
}
void setup() {
init_pins();
init_common();
send_reed_switch_state();
attachInterrupt(digitalPinToInterrupt(REED_SWITCH_PIN), send_reed_switch_state, CHANGE);
init_ota();
Serial.println("Initialized");
}
void loop() {
ArduinoOTA.handle();
Blynk.run();
blynk_timer.run();
}
common.cpp:
#define V_RSSI V10
#define V_UPTIME V11
#define STATS_INTERVAL 1000L
#define WDT_INTERVAL 10000L
char ssid[] = "foo";
char pass[] = "bar";
BlynkTimer blynk_timer;
void init_ota() {
Serial.println("Initializing OTA...");
ArduinoOTA.setHostname(hostname);
ArduinoOTA.begin();
}
void send_stats() {
int rssi = WiFi.RSSI();
Serial.println("RSSI: " + String(rssi));
Blynk.virtualWrite(V_RSSI, rssi);
int uptime = millis() / 1000 / 60 / 60; // in hours
Blynk.virtualWrite(V_UPTIME, uptime);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // blink onboard LED
ESP.wdtFeed();
}
void init_common() {
Serial.println("Initializing network code...");
wdt_enable(WDTO_8S); // Restart ESP after going to the Bahamas for 8 seconds
Serial.begin(115200);
Serial.setDebugOutput(true);
WiFi.begin(ssid, pass);
Blynk.config(auth);
Blynk.connect();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
blynk_timer.setInterval(STATS_INTERVAL, send_stats);
}