Skip to content

Commit da7114c

Browse files
committed
add SPIFFS flashing over the air
1 parent 5e3fb60 commit da7114c

File tree

3 files changed

+417
-21
lines changed

3 files changed

+417
-21
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
/**
2+
* @file OTA-mDNS-SPIFFS.ino
3+
*
4+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
5+
* @data 2015-09-18
6+
*
7+
*/
8+
9+
10+
#include <ESP8266WiFi.h>
11+
#include <ESP8266mDNS.h>
12+
#include <WiFiUdp.h>
13+
#include <FS.h>
14+
15+
16+
/**
17+
* @brief mDNS and OTA Constants
18+
* @{
19+
*/
20+
#define HOSTNAME "ESP8266-ota" ///< Hostename
21+
#define APORT 8266 ///< Port for OTA update
22+
/// @}
23+
24+
/**
25+
* @brief Default WiFi connection information.
26+
* @{
27+
*/
28+
const char* ap_default_ssid = "esp8266"; ///< Default SSID.
29+
const char* ap_default_psk = "esp8266esp8266"; ///< Default PSK.
30+
/// @}
31+
32+
/// OTA Update UDP server handle.
33+
WiFiUDP OTA;
34+
35+
/// Global WiFi SSID.
36+
String g_ssid = "";
37+
38+
/// Global WiFi PSK.
39+
String g_pass = "";
40+
41+
42+
/**
43+
* @brief Read WiFi connection information from file system.
44+
* @param ssid String pointer for storing SSID.
45+
* @param pass String pointer for storing PSK.
46+
* @return True or False.
47+
*
48+
* The config file have to containt the WiFi SSID in the first line
49+
* and the WiFi PSK in the second line.
50+
* Line seperator have to be \r\n (CR LF).
51+
*/
52+
bool loadConfig(String *ssid, String *pass)
53+
{
54+
// open file for reading.
55+
File configFile = SPIFFS.open("/cl_conf.txt", "r");
56+
if (!configFile)
57+
{
58+
Serial.println("Failed to open cl_conf.txt.");
59+
60+
return false;
61+
}
62+
63+
// Read content from config file.
64+
String content = configFile.readString();
65+
configFile.close();
66+
67+
content.trim();
68+
69+
// Check if ther is a second line available.
70+
uint8_t pos = content.indexOf("\r\n");
71+
if (pos == 0)
72+
{
73+
Serial.println("Infvalid content.");
74+
Serial.println(content);
75+
76+
return false;
77+
}
78+
79+
// Store SSID and PSK into string vars.
80+
*ssid = content.substring(0, pos);
81+
*pass = content.substring(pos + 2);
82+
83+
// Print SSID.
84+
Serial.print("ssid: ");
85+
Serial.println(*ssid);
86+
87+
return true;
88+
} // loadConfig
89+
90+
91+
/**
92+
* @brief Save WiFi SSID and PSK to configuration file.
93+
* @param ssid SSID as string pointer.
94+
* @param pass PSK as string pointer,
95+
* @return True or False.
96+
*/
97+
bool saveConfig(String *ssid, String *pass)
98+
{
99+
// Open config file for writing.
100+
File configFile = SPIFFS.open("/cl_conf.txt", "w");
101+
if (!configFile)
102+
{
103+
Serial.println("Failed to open cl_conf.txt for writing");
104+
105+
return false;
106+
}
107+
108+
// Save SSID and PSK.
109+
configFile.println(*ssid);
110+
configFile.println(*pass);
111+
112+
configFile.close();
113+
114+
return true;
115+
} // saveConfig
116+
117+
118+
/**
119+
* @brief Handle OTA update stuff.
120+
*
121+
* This function comes from ESP8266 Arduino example:
122+
* https://github.com/esp8266/Arduino/blob/esp8266/hardware/esp8266com/esp8266/libraries/ESP8266mDNS/examples/DNS_SD_Arduino_OTA/DNS_SD_Arduino_OTA.ino
123+
*
124+
* Modification for uploading SPIFFS images from Pascal Gollor.
125+
*
126+
*/
127+
static inline void ota_handle(void)
128+
{
129+
bool spiffs = false;
130+
131+
if (! OTA.parsePacket())
132+
{
133+
return;
134+
}
135+
136+
// Get remote IP
137+
IPAddress remote = OTA.remoteIP();
138+
139+
// Get command
140+
int cmd = OTA.parseInt();
141+
Serial.print("command: ");
142+
Serial.println(cmd);
143+
if (cmd == U_SPIFFS)
144+
{
145+
spiffs = true;
146+
Serial.println("Get SPIFFS image.");
147+
}
148+
149+
// Get remote port
150+
int port = OTA.parseInt();
151+
152+
// Get sketch size.
153+
int sketch_size = OTA.parseInt();
154+
155+
// Output stuff
156+
Serial.print("Update Start: ip:");
157+
Serial.print(remote);
158+
Serial.printf(", port:%d, size:%d\r\n", port, sketch_size);
159+
160+
// Stop all UDP connections.
161+
WiFiUDP::stopAll();
162+
163+
// OTA start Time
164+
uint32_t startTime = millis();
165+
166+
// Start Updateing.
167+
if(!Update.begin(sketch_size, cmd))
168+
{
169+
Serial.println("Update Begin Error");
170+
return;
171+
}
172+
173+
WiFiClient client;
174+
if (client.connect(remote, port))
175+
{
176+
uint32_t written;
177+
while(!Update.isFinished())
178+
{
179+
written = Update.write(client);
180+
if(written > 0) client.print(written, DEC);
181+
}
182+
Serial.setDebugOutput(false);
183+
184+
if(Update.end())
185+
{
186+
client.println("OK");
187+
Serial.printf("Update Success: %u\nRebooting...\n", (unsigned int)(millis() - startTime));
188+
ESP.restart();
189+
}
190+
else
191+
{
192+
Update.printError(client);
193+
Update.printError(Serial);
194+
}
195+
}
196+
else
197+
{
198+
Serial.printf("Connect Failed: %u\n", (unsigned int)(millis() - startTime));
199+
}
200+
} // ota_handle
201+
202+
203+
/**
204+
* @brief Arduino setup function.
205+
*/
206+
void setup()
207+
{
208+
g_ssid = "";
209+
g_pass = "";
210+
211+
Serial.begin(115200);
212+
213+
delay(100);
214+
215+
Serial.println("\r\n");
216+
Serial.print("Chip ID: ");
217+
Serial.println(ESP.getChipId(), HEX);
218+
219+
// Initialize file system.
220+
if (!SPIFFS.begin())
221+
{
222+
Serial.println("Failed to mount file system");
223+
return;
224+
}
225+
226+
// Load wifi connection information.
227+
if (! loadConfig(&g_ssid, &g_pass))
228+
{
229+
g_ssid = "";
230+
g_pass = "";
231+
232+
Serial.println("No WiFi connection information available.");
233+
}
234+
235+
// Set Hostname.
236+
WiFi.hostname(HOSTNAME);
237+
238+
Serial.println("Wait for WiFi connection.");
239+
240+
// Try to connect to WiFi AP.
241+
WiFi.mode(WIFI_STA);
242+
delay(10);
243+
WiFi.begin(g_ssid.c_str(), g_pass.c_str());
244+
245+
// Give ESP 10 seconds to connect to ap.
246+
unsigned long startTime = millis();
247+
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000)
248+
{
249+
Serial.write('.');
250+
delay(500);
251+
}
252+
Serial.println();
253+
254+
// check connection
255+
if(WiFi.status() == WL_CONNECTED)
256+
{
257+
Serial.print("IP address: ");
258+
Serial.println(WiFi.localIP());
259+
}
260+
else
261+
{
262+
Serial.println("Can not connect. Go into AP mode.");
263+
264+
// Go into AP mode.
265+
WiFi.mode(WIFI_AP);
266+
267+
delay(10);
268+
269+
WiFi.softAP(ap_default_ssid, ap_default_psk);
270+
271+
Serial.print("IP address: ");
272+
Serial.println(WiFi.softAPIP());
273+
}
274+
275+
// Initialize mDNS service.
276+
MDNS.begin(HOSTNAME);
277+
278+
// ... Add OTA service.
279+
MDNS.addService("arduino", "tcp", APORT);
280+
281+
// Open OTA Server.
282+
OTA.begin(APORT);
283+
}
284+
285+
286+
/**
287+
* @brief Arduino loop function.
288+
*/
289+
void loop()
290+
{
291+
// Handle OTA update.
292+
ota_handle();
293+
}
294+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
YOUR_SSID
2+
YOUR_PSK

0 commit comments

Comments
 (0)