arduino-sketches – Diff between revs 5 and 6
?pathlinks?
Rev 5 | Rev 6 | |||
---|---|---|---|---|
1 | /*************************************************************************/ |
1 | /*************************************************************************/ |
|
2 | /* Copyright (C) 2020 Wizardry and Steamworks - License: GNU GPLv3 */ |
2 | /* Copyright (C) 2020 Wizardry and Steamworks - License: GNU GPLv3 */ |
|
3 | /*************************************************************************/ |
3 | /*************************************************************************/ |
|
4 | |
4 | |
|
5 | // The AP to connect to via Wifi. |
5 | // The AP to connect to via Wifi. |
|
6 | #define STA_SSID "" |
6 | #define STA_SSID "" |
|
7 | // The AP Wifi password. |
7 | // The AP Wifi password. |
|
8 | #define STA_PSK "" |
8 | #define STA_PSK "" |
|
9 | // The MQTT broker to connect to. |
9 | // The MQTT broker to connect to. |
|
10 | #define MQTT_HOST "" |
10 | #define MQTT_HOST "" |
|
11 | // The MQTT broker username. |
11 | // The MQTT broker username. |
|
12 | #define MQTT_USERNAME "" |
12 | #define MQTT_USERNAME "" |
|
13 | // The MQTT broker password. |
13 | // The MQTT broker password. |
|
14 | #define MQTT_PASSWORD "" |
14 | #define MQTT_PASSWORD "" |
|
15 | // The MQTT broker port. |
15 | // The MQTT broker port. |
|
16 | #define MQTT_PORT 1883 |
16 | #define MQTT_PORT 1883 |
|
17 | // The default MQTT client ID is "esp-CHIPID" where CHIPID is the ESP8266 |
17 | // The default MQTT client ID is "esp-CHIPID" where CHIPID is the ESP8266 |
|
18 | // or ESP32 chip identifier. |
18 | // or ESP32 chip identifier. |
|
19 | #define MQTT_CLIENT_ID() String("esp-" + String(GET_CHIP_ID(), HEX)) |
19 | #define MQTT_CLIENT_ID() String("esp-" + String(GET_CHIP_ID(), HEX)) |
|
20 | // The authentication password to use for OTA updates. |
20 | // The authentication password to use for OTA updates. |
|
21 | #define OTA_PASSWORD "" |
21 | #define OTA_PASSWORD "" |
|
22 | // The OTA port on which updates take place. |
22 | // The OTA port on which updates take place. |
|
23 | #define OTA_PORT 8266 |
23 | #define OTA_PORT 8266 |
|
24 | // The default topic that the sketch subscribes to is "esp/CHIPID" where |
24 | // The default topic that the sketch subscribes to is "esp/CHIPID" where |
|
25 | // CHIPID is the ESP8266 or ESP32 chip identifier. |
25 | // CHIPID is the ESP8266 or ESP32 chip identifier. |
|
26 | #define MQTT_TOPIC() String("esp/" + String(GET_CHIP_ID(), HEX)) |
26 | #define MQTT_TOPIC() String("esp/" + String(GET_CHIP_ID(), HEX)) |
|
27 | |
27 | |
|
28 | // Platform specific defines. |
28 | // Platform specific defines. |
|
29 | #if defined(ARDUINO_ARCH_ESP8266) |
29 | #if defined(ARDUINO_ARCH_ESP8266) |
|
30 | #define GET_CHIP_ID() (ESP.getChipId()) |
30 | #define GET_CHIP_ID() (ESP.getChipId()) |
|
31 | #elif defined(ARDUINO_ARCH_ESP32) |
31 | #elif defined(ARDUINO_ARCH_ESP32) |
|
32 | #define GET_CHIP_ID() ((uint16_t)(ESP.getEfuseMac()>>32)) |
32 | #define GET_CHIP_ID() ((uint16_t)(ESP.getEfuseMac()>>32)) |
|
33 | #endif |
33 | #endif |
|
34 | |
34 | |
|
35 | // Miscellaneous defines. |
35 | // Miscellaneous defines. |
|
36 | //#define CHIP_ID_HEX (String(GET_CHIP_ID()).c_str()) |
36 | //#define CHIP_ID_HEX (String(GET_CHIP_ID()).c_str()) |
|
37 | #define HOSTNAME() String("esp-" + String(GET_CHIP_ID(), HEX)) |
37 | #define HOSTNAME() String("esp-" + String(GET_CHIP_ID(), HEX)) |
|
38 | |
38 | |
|
39 | // Platform specific libraries. |
39 | // Platform specific libraries. |
|
40 | #if defined(ARDUINO_ARCH_ESP8266) |
40 | #if defined(ARDUINO_ARCH_ESP8266) |
|
41 | #include <ESP8266WiFi.h> |
41 | #include <ESP8266WiFi.h> |
|
42 | #include <ESP8266mDNS.h> |
42 | #include <ESP8266mDNS.h> |
|
43 | #elif defined(ARDUINO_ARCH_ESP32) |
43 | #elif defined(ARDUINO_ARCH_ESP32) |
|
44 | #include <WiFi.h> |
44 | #include <WiFi.h> |
|
45 | #include <ESPmDNS.h> |
45 | #include <ESPmDNS.h> |
|
46 | #endif |
46 | #endif |
|
47 | // General libraries. |
47 | // General libraries. |
|
48 | #include <WiFiUdp.h> |
48 | #include <WiFiUdp.h> |
|
49 | #include <ArduinoOTA.h> |
49 | #include <ArduinoOTA.h> |
|
50 | #include <PubSubClient.h> |
50 | #include <PubSubClient.h> |
|
51 | #include <ArduinoJson.h> |
51 | #include <ArduinoJson.h> |
|
52 | #if defined(ARDUINO_ARCH_ESP32) |
52 | #if defined(ARDUINO_ARCH_ESP32) |
|
53 | #include <FS.h> |
53 | #include <FS.h> |
|
54 | #include <SPIFFS.h> |
54 | #include <SPIFFS.h> |
|
55 | #endif |
55 | #endif |
|
56 | // DHT11 |
56 | // DHT11 |
|
57 | #include <Adafruit_Sensor.h> |
57 | #include <Adafruit_Sensor.h> |
|
58 | #include <DHT.h> |
58 | #include <DHT.h> |
|
59 | #include <DHT_U.h> |
59 | #include <DHT_U.h> |
|
60 | |
60 | |
|
61 | const char *sta_ssid = STA_SSID; |
61 | const char *sta_ssid = STA_SSID; |
|
62 | const char *sta_psk = STA_PSK; |
62 | const char *sta_psk = STA_PSK; |
|
63 | const char *mqtt_host = MQTT_HOST; |
63 | const char *mqtt_host = MQTT_HOST; |
|
64 | const char *mqtt_username = MQTT_USERNAME; |
64 | const char *mqtt_username = MQTT_USERNAME; |
|
65 | const char *mqtt_password = MQTT_PASSWORD; |
65 | const char *mqtt_password = MQTT_PASSWORD; |
|
66 | const int mqtt_port = MQTT_PORT; |
66 | const int mqtt_port = MQTT_PORT; |
|
67 | const char *ota_password = OTA_PASSWORD; |
67 | const char *ota_password = OTA_PASSWORD; |
|
68 | const int ota_port = OTA_PORT; |
68 | const int ota_port = OTA_PORT; |
|
69 | |
69 | |
|
70 | WiFiClient espClient; |
70 | WiFiClient espClient; |
|
71 | PubSubClient mqttClient(espClient); |
71 | PubSubClient mqttClient(espClient); |
|
72 | |
72 | |
|
73 | // Uncomment the type of sensor in use: |
73 | // Uncomment the type of sensor in use: |
|
74 | #define DHTTYPE DHT11 // DHT 11 |
74 | #define DHTTYPE DHT11 // DHT 11 |
|
75 | //#define DHTTYPE DHT22 // DHT 22 (AM2302) |
75 | //#define DHTTYPE DHT22 // DHT 22 (AM2302) |
|
76 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) |
76 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) |
|
77 | |
77 | |
|
78 | // Define GPIO pins for supported architectures. |
78 | // Define GPIO pins for supported architectures. |
|
79 | #if defined(ARDUINO_ARCH_ESP8266) |
79 | #if defined(ARDUINO_ARCH_ESP8266) |
|
80 | int PINS[] = { D0, D1, D2, D3, D4, D5, D6, D7, D8 }; |
80 | int PINS[] = { D0, D1, D2, D3, D4, D5, D6, D7, D8 }; |
|
81 | #elif defined(ARDUINO_ARCH_ESP32) |
81 | #elif defined(ARDUINO_ARCH_ESP32) |
|
82 | int PINS[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, |
82 | int PINS[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, |
|
83 | 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, |
83 | 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, |
|
84 | 23, 25, 26, 27, 32, 33, 34, 35, 36, 37, |
84 | 23, 25, 26, 27, 32, 33, 34, 35, 36, 37, |
|
85 | 38, 39 |
85 | 38, 39 |
|
86 | }; |
86 | }; |
|
87 | #endif |
87 | #endif |
|
88 | |
88 | |
|
89 | const char* mqttSerialize(StaticJsonDocument<256> msg) { |
89 | const char* mqttSerialize(StaticJsonDocument<256> msg) { |
|
90 | char message[256]; |
90 | char message[256]; |
|
91 | serializeJson(msg, message); |
91 | serializeJson(msg, message); |
|
92 | return (const char*) message; |
92 | return (const char*) message; |
|
93 | } |
93 | } |
|
94 | |
94 | |
|
95 | void mqttCallback(char *topic, byte *payload, unsigned int length) { |
95 | void mqttCallback(char *topic, byte *payload, unsigned int length) { |
|
96 | String msgTopic = String(topic); |
96 | String msgTopic = String(topic); |
|
97 | // payload is not null terminated and casting will not work |
97 | // payload is not null terminated and casting will not work |
|
98 | char msgPayload[length + 1]; |
98 | char msgPayload[length + 1]; |
|
99 | snprintf(msgPayload, length + 1, "%s", payload); |
99 | snprintf(msgPayload, length + 1, "%s", payload); |
|
100 | Serial.println("Message received on topic: " + String(topic) + " with payload: " + String(msgPayload)); |
100 | Serial.println("Message received on topic: " + String(topic) + " with payload: " + String(msgPayload)); |
|
101 | |
101 | |
|
102 | // Parse the payload sent to the MQTT topic as a JSON document. |
102 | // Parse the payload sent to the MQTT topic as a JSON document. |
|
103 | StaticJsonDocument<256> doc; |
103 | StaticJsonDocument<256> doc; |
|
104 | Serial.println("Deserializing message...."); |
104 | Serial.println("Deserializing message...."); |
|
105 | DeserializationError error = deserializeJson(doc, msgPayload); |
105 | DeserializationError error = deserializeJson(doc, msgPayload); |
|
106 | if (error) { |
106 | if (error) { |
|
107 | Serial.println("Failed to parse MQTT payload as JSON: " + String(error.c_str())); |
107 | Serial.println("Failed to parse MQTT payload as JSON: " + String(error.c_str())); |
|
108 | return; |
108 | return; |
|
109 | } |
109 | } |
|
110 | |
110 | |
|
111 | // Ignore message with no identifier in the payload. |
111 | // Ignore message with no identifier in the payload. |
|
112 | if (!doc.containsKey("id")) { |
112 | if (!doc.containsKey("id")) { |
|
113 | return; |
113 | return; |
|
114 | } |
114 | } |
|
115 | |
115 | |
|
116 | // Do not listen to self. |
116 | // Do not listen to self. |
|
117 | String id = (const char *)doc["id"]; |
117 | String id = (const char *)doc["id"]; |
|
118 | if (id == String(MQTT_CLIENT_ID().c_str())) { |
118 | if (id == String(MQTT_CLIENT_ID().c_str())) { |
|
119 | return; |
119 | return; |
|
120 | } |
120 | } |
|
121 | |
121 | |
|
122 | // Reject messages that do not provide a reading pin. |
122 | // Reject messages that do not provide a reading pin. |
|
123 | if (!doc.containsKey("pin")) { |
123 | if (!doc.containsKey("pin")) { |
|
124 | Serial.println("MQTT message received but no pin supplied..."); |
124 | Serial.println("MQTT message received but no pin supplied..."); |
|
125 | return; |
125 | return; |
|
126 | } |
126 | } |
|
127 | |
127 | |
|
128 | const int pin = (const int)doc["pin"]; |
128 | const int pin = (const int)doc["pin"]; |
|
129 | |
129 | |
|
130 | StaticJsonDocument<256> msg; |
130 | StaticJsonDocument<256> msg; |
|
131 | msg["id"] = MQTT_CLIENT_ID().c_str(); |
131 | msg["id"] = String(MQTT_CLIENT_ID().c_str()); |
|
132 | DHT_Unified dht(PINS[pin], DHTTYPE); |
132 | DHT_Unified dht(PINS[pin], DHTTYPE); |
|
133 | dht.begin(); |
133 | dht.begin(); |
|
134 | // Print temperature sensor details. |
134 | // Print temperature sensor details. |
|
135 | sensors_event_t event; |
135 | sensors_event_t event; |
|
136 | dht.temperature().getEvent(&event); |
136 | dht.temperature().getEvent(&event); |
|
137 | switch (!isnan(event.temperature)) { |
137 | switch (!isnan(event.temperature)) { |
|
138 | case true: |
138 | case true: |
|
139 | msg["temperature"] = event.temperature; |
139 | msg["temperature"] = event.temperature; |
|
140 | break; |
140 | break; |
|
141 | default: |
141 | default: |
|
142 | Serial.println("Error reading temperature..."); |
142 | Serial.println("Error reading temperature..."); |
|
143 | break; |
143 | break; |
|
144 | } |
144 | } |
|
145 | |
145 | |
|
146 | dht.humidity().getEvent(&event); |
146 | dht.humidity().getEvent(&event); |
|
147 | switch (!isnan(event.relative_humidity)) { |
147 | switch (!isnan(event.relative_humidity)) { |
|
148 | case true: |
148 | case true: |
|
149 | msg["humidity"] = event.relative_humidity; |
149 | msg["humidity"] = event.relative_humidity; |
|
150 | break; |
150 | break; |
|
151 | default: |
151 | default: |
|
152 | Serial.println("Error reading humidity..."); |
152 | Serial.println("Error reading humidity..."); |
|
153 | break; |
153 | break; |
|
154 | } |
154 | } |
|
155 | // Eeek? |
155 | // Eeek? |
|
156 | //dht.end(); |
156 | //dht.end(); |
|
157 | |
157 | |
|
158 | // Publish the sensor data. |
158 | // Publish the sensor data. |
|
159 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
159 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
|
160 | } |
160 | } |
|
161 | |
161 | |
|
162 | bool mqttConnect() { |
162 | bool mqttConnect() { |
|
163 | Serial.println("Attempting to connect to MQTT broker: " + String(mqtt_host)); |
163 | Serial.println("Attempting to connect to MQTT broker: " + String(mqtt_host)); |
|
164 | mqttClient.setServer(mqtt_host, mqtt_port); |
164 | mqttClient.setServer(mqtt_host, mqtt_port); |
|
165 | |
165 | |
|
166 | StaticJsonDocument<255> msg; |
166 | StaticJsonDocument<255> msg; |
|
167 | if (mqttClient.connect(MQTT_CLIENT_ID().c_str(), mqtt_username, mqtt_password)) { |
167 | if (mqttClient.connect(MQTT_CLIENT_ID().c_str(), mqtt_username, mqtt_password)) { |
|
168 | Serial.println("Established connection with MQTT broker using client ID: " + MQTT_CLIENT_ID()); |
168 | Serial.println("Established connection with MQTT broker using client ID: " + MQTT_CLIENT_ID()); |
|
169 | mqttClient.setCallback(mqttCallback); |
169 | mqttClient.setCallback(mqttCallback); |
|
170 | msg["action"] = "connected"; |
170 | msg["action"] = "connected"; |
|
171 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
171 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
|
172 | Serial.println("Attempting to subscribe to MQTT topic: " + MQTT_TOPIC()); |
172 | Serial.println("Attempting to subscribe to MQTT topic: " + MQTT_TOPIC()); |
|
173 | if (!mqttClient.subscribe(MQTT_TOPIC().c_str())) { |
173 | if (!mqttClient.subscribe(MQTT_TOPIC().c_str())) { |
|
174 | Serial.println("Failed to subscribe to MQTT topic: " + MQTT_TOPIC()); |
174 | Serial.println("Failed to subscribe to MQTT topic: " + MQTT_TOPIC()); |
|
175 | return false; |
175 | return false; |
|
176 | } |
176 | } |
|
177 | Serial.println("Subscribed to MQTT topic: " + MQTT_TOPIC()); |
177 | Serial.println("Subscribed to MQTT topic: " + MQTT_TOPIC()); |
|
178 | msg.clear(); |
178 | msg.clear(); |
|
179 | msg["action"] = "subscribed"; |
179 | msg["action"] = "subscribed"; |
|
180 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
180 | mqttClient.publish(MQTT_TOPIC().c_str(), mqttSerialize(msg)); |
|
181 | return true; |
181 | return true; |
|
182 | } |
182 | } |
|
183 | else { |
183 | else { |
|
184 | Serial.println("Connection to MQTT broker failed with MQTT client state: " + String(mqttClient.state())); |
184 | Serial.println("Connection to MQTT broker failed with MQTT client state: " + String(mqttClient.state())); |
|
185 | } |
185 | } |
|
186 | |
186 | |
|
187 | return false; |
187 | return false; |
|
188 | } |
188 | } |
|
189 | |
189 | |
|
190 | bool loopWifiConnected() { |
190 | bool loopWifiConnected() { |
|
191 | // Process OTA loop first since emergency OTA updates might be needed. |
191 | // Process OTA loop first since emergency OTA updates might be needed. |
|
192 | ArduinoOTA.handle(); |
192 | ArduinoOTA.handle(); |
|
193 | |
193 | |
|
194 | // Process MQTT client loop. |
194 | // Process MQTT client loop. |
|
195 | if (!mqttClient.connected()) { |
195 | if (!mqttClient.connected()) { |
|
196 | // If the connection to the MQTT broker has failed then sleep before carrying on. |
196 | // If the connection to the MQTT broker has failed then sleep before carrying on. |
|
197 | if (!mqttConnect()) { |
197 | if (!mqttConnect()) { |
|
198 | return false; |
198 | return false; |
|
199 | } |
199 | } |
|
200 | } |
200 | } |
|
201 | mqttClient.loop(); |
201 | mqttClient.loop(); |
|
202 | |
202 | |
|
203 | return true; |
203 | return true; |
|
204 | } |
204 | } |
|
205 | |
205 | |
|
206 | void setup() { |
206 | void setup() { |
|
207 | Serial.begin(115200); |
207 | Serial.begin(115200); |
|
208 | Serial.println("Booted, setting up Wifi in 10s..."); |
208 | Serial.println("Booted, setting up Wifi in 10s..."); |
|
209 | delay(10000); |
209 | delay(10000); |
|
210 | |
210 | |
|
211 | WiFi.mode(WIFI_STA); |
211 | WiFi.mode(WIFI_STA); |
|
212 | #if defined(ARDUINO_ARCH_ESP8266) |
212 | #if defined(ARDUINO_ARCH_ESP8266) |
|
213 | WiFi.hostname(HOSTNAME().c_str()); |
213 | WiFi.hostname(HOSTNAME().c_str()); |
|
214 | #elif defined(ARDUINO_ARCH_ESP32) |
214 | #elif defined(ARDUINO_ARCH_ESP32) |
|
215 | WiFi.setHostname(HOSTNAME().c_str()); |
215 | WiFi.setHostname(HOSTNAME().c_str()); |
|
216 | #endif |
216 | #endif |
|
217 | WiFi.begin(sta_ssid, sta_psk); |
217 | WiFi.begin(sta_ssid, sta_psk); |
|
218 | while (WiFi.waitForConnectResult() != WL_CONNECTED) { |
218 | while (WiFi.waitForConnectResult() != WL_CONNECTED) { |
|
219 | Serial.println("Failed to connect to Wifi, rebooting in 5s..."); |
219 | Serial.println("Failed to connect to Wifi, rebooting in 5s..."); |
|
220 | delay(5000); |
220 | delay(5000); |
|
221 | ESP.restart(); |
221 | ESP.restart(); |
|
222 | } |
222 | } |
|
223 | |
223 | |
|
224 | Serial.print("Connected to Wifi: "); |
224 | Serial.print("Connected to Wifi: "); |
|
225 | Serial.println(WiFi.localIP()); |
225 | Serial.println(WiFi.localIP()); |
|
226 | |
226 | |
|
227 | Serial.println("Setting up OTA in 10s..."); |
227 | Serial.println("Setting up OTA in 10s..."); |
|
228 | delay(10000); |
228 | delay(10000); |
|
229 | |
229 | |
|
230 | // Port defaults to 8266 |
230 | // Port defaults to 8266 |
|
231 | ArduinoOTA.setPort(ota_port); |
231 | ArduinoOTA.setPort(ota_port); |
|
232 | |
232 | |
|
233 | // Hostname defaults to esp-[ChipID] |
233 | // Hostname defaults to esp-[ChipID] |
|
234 | ArduinoOTA.setHostname(HOSTNAME().c_str()); |
234 | ArduinoOTA.setHostname(HOSTNAME().c_str()); |
|
235 | |
235 | |
|
236 | // Set the OTA password |
236 | // Set the OTA password |
|
237 | ArduinoOTA.setPassword(ota_password); |
237 | ArduinoOTA.setPassword(ota_password); |
|
238 | |
238 | |
|
239 | ArduinoOTA.onStart([]() { |
239 | ArduinoOTA.onStart([]() { |
|
240 | switch (ArduinoOTA.getCommand()) { |
240 | switch (ArduinoOTA.getCommand()) { |
|
241 | case U_FLASH: // Sketch |
241 | case U_FLASH: // Sketch |
|
242 | Serial.println("OTA start updating sketch."); |
242 | Serial.println("OTA start updating sketch."); |
|
243 | break; |
243 | break; |
|
244 | #if defined(ARDUINO_ARCH_ESP8266) |
244 | #if defined(ARDUINO_ARCH_ESP8266) |
|
245 | case U_FS: |
245 | case U_FS: |
|
246 | #elif defined(ARDUINO_ARCH_ESP32) |
246 | #elif defined(ARDUINO_ARCH_ESP32) |
|
247 | case U_SPIFFS: |
247 | case U_SPIFFS: |
|
248 | #endif |
248 | #endif |
|
249 | Serial.println("OTA start updating filesystem."); |
249 | Serial.println("OTA start updating filesystem."); |
|
250 | SPIFFS.end(); |
250 | SPIFFS.end(); |
|
251 | break; |
251 | break; |
|
252 | default: |
252 | default: |
|
253 | Serial.println("Unknown OTA update type."); |
253 | Serial.println("Unknown OTA update type."); |
|
254 | break; |
254 | break; |
|
255 | } |
255 | } |
|
256 | }); |
256 | }); |
|
257 | ArduinoOTA.onEnd([]() { |
257 | ArduinoOTA.onEnd([]() { |
|
258 | Serial.println("OTA update complete."); |
258 | Serial.println("OTA update complete."); |
|
259 | SPIFFS.begin(); |
259 | SPIFFS.begin(); |
|
260 | #if defined(ARDUINO_ARCH_ESP8266) |
260 | #if defined(ARDUINO_ARCH_ESP8266) |
|
261 | // For what it's worth, check the filesystem on ESP8266. |
261 | // For what it's worth, check the filesystem on ESP8266. |
|
262 | SPIFFS.check(); |
262 | SPIFFS.check(); |
|
263 | #endif |
263 | #endif |
|
264 | ESP.restart(); |
264 | ESP.restart(); |
|
265 | }); |
265 | }); |
|
266 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { |
266 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { |
|
267 | Serial.printf("OTA update progress: %u%%\r", (progress / (total / 100))); |
267 | Serial.printf("OTA update progress: %u%%\r", (progress / (total / 100))); |
|
268 | }); |
268 | }); |
|
269 | ArduinoOTA.onError([](ota_error_t error) { |
269 | ArduinoOTA.onError([](ota_error_t error) { |
|
270 | Serial.printf("OTA update error [%u]: ", error); |
270 | Serial.printf("OTA update error [%u]: ", error); |
|
271 | switch (error) { |
271 | switch (error) { |
|
272 | case OTA_AUTH_ERROR: |
272 | case OTA_AUTH_ERROR: |
|
273 | Serial.println("OTA authentication failed"); |
273 | Serial.println("OTA authentication failed"); |
|
274 | break; |
274 | break; |
|
275 | case OTA_BEGIN_ERROR: |
275 | case OTA_BEGIN_ERROR: |
|
276 | Serial.println("OTA begin failed"); |
276 | Serial.println("OTA begin failed"); |
|
277 | break; |
277 | break; |
|
278 | case OTA_CONNECT_ERROR: |
278 | case OTA_CONNECT_ERROR: |
|
279 | Serial.println("OTA connect failed"); |
279 | Serial.println("OTA connect failed"); |
|
280 | break; |
280 | break; |
|
281 | case OTA_RECEIVE_ERROR: |
281 | case OTA_RECEIVE_ERROR: |
|
282 | Serial.println("OTA receive failed"); |
282 | Serial.println("OTA receive failed"); |
|
283 | break; |
283 | break; |
|
284 | case OTA_END_ERROR: |
284 | case OTA_END_ERROR: |
|
285 | Serial.println("OTA end failed"); |
285 | Serial.println("OTA end failed"); |
|
286 | break; |
286 | break; |
|
287 | default: |
287 | default: |
|
288 | Serial.println("Unknown OTA failure"); |
288 | Serial.println("Unknown OTA failure"); |
|
289 | break; |
289 | break; |
|
290 | } |
290 | } |
|
291 | ESP.restart(); |
291 | ESP.restart(); |
|
292 | }); |
292 | }); |
|
293 | ArduinoOTA.begin(); |
293 | ArduinoOTA.begin(); |
|
294 | |
294 | |
|
295 | // Set up MQTT client. |
295 | // Set up MQTT client. |
|
296 | mqttClient.setServer(mqtt_host, mqtt_port); |
296 | mqttClient.setServer(mqtt_host, mqtt_port); |
|
297 | mqttClient.setCallback(mqttCallback); |
297 | mqttClient.setCallback(mqttCallback); |
|
298 | |
298 | |
|
299 | // Touchdown. |
299 | // Touchdown. |
|
300 | Serial.println("Setup complete."); |
300 | Serial.println("Setup complete."); |
|
301 | } |
301 | } |
|
302 | |
302 | |
|
303 | void loop() { |
303 | void loop() { |
|
304 | // Check the Wifi connection status. |
304 | // Check the Wifi connection status. |
|
305 | int wifiStatus = WiFi.status(); |
305 | int wifiStatus = WiFi.status(); |
|
306 | switch (wifiStatus) { |
306 | switch (wifiStatus) { |
|
307 | case WL_CONNECTED: |
307 | case WL_CONNECTED: |
|
308 | if (!loopWifiConnected()) { |
308 | if (!loopWifiConnected()) { |
|
309 | delay(1000); |
309 | delay(1000); |
|
310 | break; |
310 | break; |
|
311 | } |
311 | } |
|
312 | delay(1); |
312 | delay(1); |
|
313 | break; |
313 | break; |
|
314 | case WL_NO_SHIELD: |
314 | case WL_NO_SHIELD: |
|
315 | Serial.println("No Wifi shield present."); |
315 | Serial.println("No Wifi shield present."); |
|
316 | goto DEFAULT_CASE; |
316 | goto DEFAULT_CASE; |
|
317 | break; |
317 | break; |
|
318 | case WL_NO_SSID_AVAIL: |
318 | case WL_NO_SSID_AVAIL: |
|
319 | Serial.println("Configured SSID not found."); |
319 | Serial.println("Configured SSID not found."); |
|
320 | goto DEFAULT_CASE; |
320 | goto DEFAULT_CASE; |
|
321 | break; |
321 | break; |
|
322 | // Temporary statuses indicating transitional states. |
322 | // Temporary statuses indicating transitional states. |
|
323 | case WL_IDLE_STATUS: |
323 | case WL_IDLE_STATUS: |
|
324 | case WL_SCAN_COMPLETED: |
324 | case WL_SCAN_COMPLETED: |
|
325 | delay(1000); |
325 | delay(1000); |
|
326 | break; |
326 | break; |
|
327 | // Fatal Wifi statuses trigger a delayed ESP restart. |
327 | // Fatal Wifi statuses trigger a delayed ESP restart. |
|
328 | case WL_CONNECT_FAILED: |
328 | case WL_CONNECT_FAILED: |
|
329 | case WL_CONNECTION_LOST: |
329 | case WL_CONNECTION_LOST: |
|
330 | case WL_DISCONNECTED: |
330 | case WL_DISCONNECTED: |
|
331 | default: |
331 | default: |
|
332 | Serial.println("Wifi connection failed with status: " + String(wifiStatus)); |
332 | Serial.println("Wifi connection failed with status: " + String(wifiStatus)); |
|
333 | DEFAULT_CASE: |
333 | DEFAULT_CASE: |
|
334 | delay(10000); |
334 | delay(10000); |
|
335 | ESP.restart(); |
335 | ESP.restart(); |
|
336 | break; |
336 | break; |
|
337 | } |
337 | } |
|
338 | } |
338 | } |
|
339 | |
339 | |