ESP8266 偵測 網路斷線 後重開設備 + Thingspeak狀態監視 及 紀錄
算是這一篇的軟體升級版本XD
** 紅色字體部分請依現場環境修改 **
/*
for arduinoIDE 1.6.12 支援 ADC_MODE(ADC_VCC 但檔案目錄不支援中文,否則會檢查編譯錯誤
2016-11-12 by yulie~
使用第2腳控制繼電器時,於上傳程式當下必須將第2腳斷開,否則無法上傳程式
2016-10-03 簡化程式碼,增加被測裝置數量
2016-09-27 功能測試完成
定義update區域欄位
1: 0=loss, 1=Device Active, 2= local boot
2: 0=loss, 1=Device Active, 2= local boot
3: 0=loss, 1=Device Active, 2= local boot
4: 0=loss, 1=Device Active, 2= local boot
6: reboot count
7: Wi-Fi Fail count
8: ESP8266 Core Volt
thingspeak Server 只傳單一區域值第一筆之後的資料沒辦法再進資料庫
reedited for ESP8266 2016-09-17 by yulie~
H/W ESP8266
Network service check ipaddress & port
2015-07-26 by yulie~
*/
word chkTime = 60; // Sec 檢測連狀態間隔時間
byte actTime = 60; // 次 檢測連狀態正常達該次數後發 Active 紀錄 dev0 or dev1
byte wait = 5; // 次 檢測連線狀態失敗達該次數後關電重啟 only dev0
word wifiFail = 300; // Sec Wi-Fi connect fail Reboot wait time
byte off_time = 8; // Sec 設備斷電秒數
byte Relay_1 = 14; // 使用第14腳控制繼電器
byte LED = 16; // 使用第16腳控LED
#include <ESP8266WiFi.h>
#define SSID "****" // 無線網路連線名稱
#define PASS "******" // 無線網路連線密碼
char ip_1[] = "www.google.com"; word port_1 = 80; // 被檢查ip位址 & port
char ip_2[] = "192.168.1.31"; word port_2 = 80; // 被檢查ip位址 & port
char ip_3[] = "192.168.1.32"; word port_3 = 80; // 被檢查ip位址 & port
char ip_4[] = "192.168.1.52"; word port_4 = 80; // 被檢查ip位址 & port
char serverIP[] = "api.thingspeak.com"; word serverPort = 80;
const String GET = "GET /update?key=******************"; //ID for 網路設備重開記錄
unsigned long t, u, v, w = 0;
byte actCoun, devFail, status_1, status_1a, status_2, status_2a, status_3, status_3a, status_4, status_4a;;
word WiFi_fail, reboot_count;
ADC_MODE(ADC_VCC); //for core voltage
void setup() {
t, u, v, w = millis();
Serial.begin(115200); Serial.print("Connect to Wi-Fi : ");
Serial.println("."); Serial.println("start setup ...");
pinMode(Relay_1, OUTPUT); pinMode(LED, OUTPUT);
for (byte i = 0; i < 6; i++) {
digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); delay(500);
}
WiFi.mode(WIFI_STA); // Connecting to a WiFi network
Serial.print("Connect to Wi-Fi : ");
Serial.println( SSID );
WiFi.begin( SSID, PASS ); //Connect to Wi-Fi
updata(2, 2, 2, 2, 2, 0, 0); //開機信息為 2,2,0,0
float voltaje = ESP.getVcc();
Serial.print(voltaje / 1024);
Serial.println(" V");
}
void loop() {
while ( WiFi.status() != WL_CONNECTED ) // 持續等待並連接到指定的 WiFi SSID
{ // 如果連線AP 失敗時執行這一段程式
Serial.print( "Wi-Fi failed count : " );
delay(1000);
WiFi_fail++;
WiFi_fail = constrain ( WiFi_fail, 0, 65534); // 限制該值在0~100 之間
Serial.println(WiFi_fail);
if (WiFi_fail >= wifiFail) { //connect Wifi fail over 3min Run
rebootPower_1();
WiFi_fail = 0;
}
}
t = millis(); if (t - u > (chkTime * 1000)) { //30000 mS on chk
u = millis();
actCoun++;
Serial.println(" ");
status_1 = chkdev(ip_1, port_1);
status_2 = chkdev(ip_2, port_2);
status_3 = chkdev(ip_3, port_3);
status_4 = chkdev(ip_4, port_4);
if (status_1 == 1)digitalWrite(LED, HIGH);
if (status_1 == 0)digitalWrite(LED, LOW);
//狀態改變時上傳
if (status_1 != status_1a
|| status_2 != status_2a
|| status_3 != status_3a
|| status_4 != status_4a) {
status_1a = status_1; //狀態更新,做為下一次狀態比較用
status_2a = status_2; //狀態更新,做為下一次狀態比較用
status_3a = status_3; //狀態更新,做為下一次狀態比較用
status_4a = status_4; //狀態更新,做為下一次狀態比較用
if ( status_1 == 1 )updata(status_1, status_2, status_3, status_4, 0, reboot_count, WiFi_fail);
}
if (status_1 == 1) devFail = 0; //斷線計數歸零
else {
devFail++; //裝置斷線計數,給重開設備判斷用
actCoun = 0;
}
// device 0 or device 1 每60次傳送一次存活信息
if (actCoun >= actTime )updata(status_1, status_2, status_3, status_4, 0, reboot_count, WiFi_fail);
//裝置矢聯達指定次數則啓動繼電器關機重開
if (devFail >= wait) {
rebootPower_1();
devFail = 0;
}
//showCount(); //for debug
//reboot_count != 0 or WiFi_fail != 0 and connect OK send infomation...
if ((reboot_count != 0 || WiFi_fail != 0) && status_1 == 1) updata(status_1, status_2, status_3, status_4, 0, reboot_count, WiFi_fail);
}
}
//-------------------------------------------------------------------------------void updata()
word updata(word field1, word field2, word field3, word field4, word field5, word field6, word field7) {
float voltaje = ESP.getVcc(); voltaje = voltaje / 1024;
WiFiClient client;
if (client.connect(serverIP, serverPort)) {
String getStr = GET +
"&field1=" + String((float)field1, 0) + // active 01
"&field2=" + String((float)field2, 0) + // active 02
"&field3=" + String((float)field3, 0) + // active 03
"&field4=" + String((float)field4, 0) + // active 04
"&field5=" + String((float)field5, 0) + // active 05
"&field6=" + String((float)field6, 0) + // reboot_count
"&field7=" + String((float)field7, 0) + // WiFi_X_count
"&field8=" + String((float)voltaje, 2) + // Chip Vcc
" HTTP/1.1\r\n";;
client.print( getStr );
client.print( "Host: api.thingspeak.com\n" );
client.print( "Connection: close\r\n\r\n" );
delay(10);
// 處理遠端伺服器回傳的訊息,程式碼可以寫在這裡!
Serial.println(getStr);
client.stop();
actCoun = 0; //如果狀態傳送就將先前的存活計數歸零
WiFi_fail = 0;
reboot_count = 0;
}
else { //連線失敗執行此段程式
Serial.print(ip_1); Serial.print(" : "); Serial.print(port_1); Serial.println(" ThingSpeak Server disconnection ---- X ");
}
client.stop();
}
//------------------------------------------------------------------------------- check device
byte chkdev(char* IP, word PORT) {
WiFiClient client;
if (client.connect(IP, PORT)) { //連線成功執行此段程式
Serial.print(IP); Serial.print(" : "); Serial.print(PORT); Serial.println(" check device connected ");
return 1;
}
else { //連線失敗執行此段程式
Serial.print(IP); Serial.print(" : "); Serial.print(PORT); Serial.println(" check device disconnection ---- X ");
return 0;
}
}
//-------------------------------------------------------------------------------status_1, status_2
void showCount() { //for debug
Serial.print("status_1 : "); Serial.println(status_1); Serial.print("status_2 : "); Serial.println(status_2);
Serial.print("WiFi_fail : "); Serial.println(WiFi_fail); Serial.print("reboot_count : "); Serial.println(reboot_count);
uint32_t getVcc = ESP.getVcc(); float voltaje = ESP.getVcc(); Serial.println("core Volt : "); Serial.print(voltaje / 1024);
Serial.println(" V");
}
//-------------------------------------------------------------------------------void rebootPower_1()
void rebootPower_1() {
digitalWrite(Relay_1, HIGH); // Relay N.C connect (device power down)
Serial.print("power down~ Wait "); Serial.print(off_time); Serial.println(" Sec ..");
delay(off_time * 1000); //device power down 5 sec
digitalWrite(Relay_1, LOW);
Serial.println("power up");
reboot_count++;
}