8000 Add minimal example for ESP OTA · smartcoder00/arduinoWebSockets@28ed615 · GitHub
[go: up one dir, main page]

Skip to content

Commit 28ed615

Browse files
Tony763Links2004
authored andcommitted
Add minimal example for ESP OTA
1 parent 108090e commit 28ed615

File tree

4 files changed

+527
-0
lines changed

4 files changed

+527
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## Minimal example of WebsocketClientOTA and Python server
2+
3+
Take this as small example, how achieve OTA update on ESP8266 and ESP32.
4+
5+
Python server was wrote from train so take it only as bare example.
6+
It's working, but it's not mean to run in production.
7+
8+
9+
### Usage:
10+
11+
Start server:
12+
```bash
13+
cd python_ota_server
14+
python3 -m venv .venv
15+
source .venv/bin/activate
16+
pip3 install -r requirements.txt
17+
python3 main.py
18+
```
19+
20+
Flash ESP with example sketch and start it.
21+
22+
Change version inside example sketch to higher and compile it and save it to bin file.
23+
24+
Rename it to `mydevice-1.0.1-esp8266.bin` and place it inside new folder firmware (server create it).
25+
26+
When the ESP connect to server, it check if version flashed is equal to fw in firmware folder. If higher FW version is present,
27+
start the flash process.
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
* WebSocketClientOTA.ino
3+
*
4+
* Created on: 25.10.2021
5+
*
6+
*/
7+
8+
#include <Arduino.h>
9+
#include <ArduinoJson.h>
10+
11+
#ifdef ESP8266
12+
#include <ESP8266WiFi.h>
13+
#include <ESP8266mDNS.h>
14+
#include <Updater.h>
15+
#endif
16+
#ifdef ESP32
17+
#include "WiFi.h"
18+
#include "ESPmDNS.h"
19+
#include <Update.h>
20+
#endif
21+
22+
#include <WiFiUdp.h>
23+
#include <ESP8266WiFiMulti.h>
24+
25+
#include <WebSocketsClient.h>
26+
27+
#include <Hash.h>
28+
29+
ESP8266WiFiMulti WiFiMulti;
30+
WebSocketsClient webSocket;
31+
32+
#define USE_SERIAL Serial
33+
34+
// Variables:
35+
// Settable:
36+
const char *version = "1.0.0";
37+
const char *name = "mydevice";
38+
39+
// Others:
40+
#ifdef ESP8266
41+
const char *chip = "esp8266";
42+
#endif
43+
#ifdef ESP32
44+
const char *chip = "esp32";
45+
#endif
46+
47+
uint32_t maxSketchSpace = 0;
48+
int SketchSize = 0;
49+
bool ws_conn = false;
50+
51+
String IpAddress2String(const IPAddress& ipAddress)
52+
{
53+
return String(ipAddress[0]) + String(".") +
54+
String(ipAddress[1]) + String(".") +
55+
String(ipAddress[2]) + String(".") +
56+
String(ipAddress[3]);
57+
}
58+
59+
void greetings_(){
60+
StaticJsonDocument<200> doc;
61+
doc["type"] = "greetings";
62+
doc["mac"] = WiFi.macAddress();
63+
doc["ip"] = IpAddress2String(WiFi.localIP());
64+
doc["version"] = version;
65+
doc["name"] = name;
66+
doc["chip"] = chip;
67+
68+
char data[200];
69+
serializeJson(doc, data);
70+
webSocket.sendTXT(data);
71+
}
72+
73+
void register_(){
74+
StaticJsonDocument<200> doc;
75+
doc["type"] = "register";
76+
doc["mac"] = WiFi.macAddress();
77+
78+
char data[200];
79+
serializeJson(doc, data);
80+
webSocket.sendTXT(data);
81+
ws_conn = true;
82+
}
83+
84+
typedef void (*CALLBACK_FUNCTION)(JsonDocument &msg);
85+
86+
typedef struct {
87+
char type[50];
88+
CALLBACK_FUNCTION func;
89+
} RESPONSES_STRUCT;
90+
91+
void OTA(JsonDocument &msg){
92+
USE_SERIAL.print(F("[WSc] OTA mode: "));
93+
const char* go = "go";
94+
const char* ok = "ok";
95+
if(strncmp( msg["value"], go, strlen(go)) == 0 ) {
96+
USE_SERIAL.print(F("go\n"));
97+
SketchSize = int(msg["size"]);
98+
maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
99+
USE_SERIAL.printf("[WSc] Max sketch size: %u\n", maxSketchSpace);
100+
USE_SERIAL.printf("[WSc] Sketch size: %d\n", SketchSize);
101+
USE_SERIAL.setDebugOutput(true);
102+
if (!Update.begin(maxSketchSpace)) { //start with max available size
103+
Update.printError(Serial);
104+
ESP.restart();
105+
}
106+
} else if (strncmp( msg["value"], ok, strlen(ok)) == 0) {
107+
USE_SERIAL.print(F("OK\n"));
108+
register_();
109+
} else {
110+
USE_SERIAL.print(F("unknown value : "));
111+
USE_SERIAL.print(msg["value"].as<char>());
112+
USE_SERIAL.print(F("\n"));
113+
}
114+
}
115+
116+
void STATE(JsonDocument &msg){
117+
// Do something with message
118+
}
119+
120+
RESPONSES_STRUCT responses[] = {
121+
{"ota", OTA},
122+
{"state", STATE},
123+
};
124+
125+
void text(uint8_t * payload, size_t length){
126+
// Convert mesage to something usable
127+
char msgch[length];
128+
for (unsigned int i = 0; i < length; i++)
129+
{
130+
USE_SERIAL.print((char)payload[i]);
131+
msgch[i] = ((char)payload[i]);
132+
}
133+
msgch[length] = '\0';
134+
135+
// Parse Json
136+
StaticJsonDocument<200> doc_in;
137+
DeserializationError error = deserializeJson(doc_in, msgch);
138+
139+
if (error) {
140+
USE_SERIAL.print(F("deserializeJson() failed: "));
141+
USE_SERIAL.println(error.c_str());
142+
return;
143+
}
144+
145+
// Handle each TYPE of message
146+
int b = 0;
147+
148+
for( b=0 ; strlen(responses[b].type) ; b++ )
149+
{
150+
if( strncmp(doc_in["type"], responses[b].type, strlen(responses[b].type)) == 0 ) {
151+
responses[b].func(doc_in);
152+
}
153+
}
154+
}
155+
156+
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
157+
158+
switch(type) {
159+
case WStype_DISCONNECTED:
160+
USE_SERIAL.printf("[WSc] Disconnected!\n");
161+
break;
162+
case WStype_CONNECTED: {
163+
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
164+
165+
// send message to server when Connected
166+
// webSocket.sendTXT("Connected");
167+
greetings_();
168+
}
169+
break;
170+
case WStype_TEXT:
171+
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
172+
173+
// send message to server
174+
// webSocket.sendTXT("message here");
175+
text(payload, length);
176+
break;
177+
case WStype_BIN:
178+
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
179+
// hexdump(payload, length);
180+
if (Update.write(payload, length) != length) {
181+
Update.printError(Serial);
182+
ESP.restart();
183+
}
184+
yield();
185+
SketchSize -= length;
186+
USE_SERIAL.printf("[WSc] Sketch size left: %u\n", SketchSize);
187+
if (SketchSize < 1){
188+
if (Update.end(true)) { //true to set the size to the current progress
189+
USE_SERIAL.printf("Update Success: \nRebooting...\n");
190+
delay(5);
191+
yield();
192+
ESP.restart();
193+
} else {
194+
Update.printError(USE_SERIAL);
195+
ESP.restart();
196+
}
197+
USE_SERIAL.setDebugOutput(false);
198+
}
199+
200+
// send data to server
201+
// webSocket.sendBIN(payload, length);
202+
break;
203+
case WStype_PING:
204+
// pong will be send automatically
205+
USE_SERIAL.printf("[WSc] get ping\n");
206+
break;
207+
case WStype_PONG:
208+
// answer to a ping we send
209+
USE_SERIAL.printf("[WSc] get pong\n");
210+
break;
211+
}
212+
213+
}
214+
215+
void setup() {
216+
// USE_SERIAL.begin(921600);
217+
USE_SERIAL.begin(115200);
218+
219+
//Serial.setDebugOutput(true);
220+
USE_SERIAL.setDebugOutput(true);
221+
222+
USE_SERIAL.print(F("\nMAC: "));
223+
USE_SERIAL.println(WiFi.macAddress());
224+
USE_SERIAL.print(F("\nDevice: "));
225+
USE_SERIAL.println(name);
226+
USE_SERIAL.printf("\nVersion: %s\n", version);
227+
228+
for(uint8_t t = 4; t > 0; t--) {
229+
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
230+
USE_SERIAL.flush();
231+
delay(1000);
232+
}
233+
234+
WiFiMulti.addAP("SSID", "PASS");
235+
236+
//WiFi.disconnect();
237+
while(WiFiMulti.run() != WL_CONNECTED) {
238+
delay(100);
239+
}
240+
241+
// server address, port and URL
242+
webSocket.begin("10.0.1.5", 8081, "/");
243+
244+
// event handler
245+
webSocket.onEvent(webSocketEvent);
246+
247+
// use HTTP Basic Authorization this is optional remove if not needed
248+
// webSocket.setAuthorization("USER", "PASS");
249+
250+
// try ever 5000 again if connection has failed
251+
webSocket.setReconnectInterval(5000);
252+
253+
// start heartbeat (optional)
254+
// ping server every 15000 ms
255+
// expect pong from server within 3000 ms
256+
// consider connection disconnected if pong is not received 2 times
257+
webSocket.enableHeartbeat(15000, 3000, 2);
258+
259+
}
260+
261+
void loop() {
262+
webSocket.loop();
263+
}

0 commit comments

Comments
 (0)
0