Skip to content

Commit 0f20b49

Browse files
Wifi persistance (#46)
* Making the WiFi reconnect more robust. (#44) * Configurable wifi watchdog * Fix logic, Better user feedback for connect/disconnect Co-authored-by: Athrogate <AthrogatePEQ@users.noreply.github.com>
1 parent bab559b commit 0f20b49

File tree

2 files changed

+175
-68
lines changed

2 files changed

+175
-68
lines changed

esp32-cam-webserver.ino

Lines changed: 170 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ void startCameraServer(int hPort, int sPort);
7070
int streamPort = 81;
7171
#endif
7272

73+
#if !defined(WIFI_WATCHDOG)
74+
#define WIFI_WATCHDOG 5000
75+
#endif
76+
7377
// The stream URL
7478
char streamURL[64] = {"Undefined"}; // Stream URL to pass to the app.
7579

@@ -109,6 +113,99 @@ const int pwmMax = pow(2,pwmresolution)-1;
109113
int8_t recognition_enabled = 0;
110114
#endif
111115

116+
// Notification LED
117+
void flashLED(int flashtime) {
118+
#ifdef LED_PIN // If we have it; flash it.
119+
digitalWrite(LED_PIN, LED_ON); // On at full power.
120+
delay(flashtime); // delay
121+
digitalWrite(LED_PIN, LED_OFF); // turn Off
122+
#else
123+
return; // No notifcation LED, do nothing, no delay
124+
#endif
125+
}
126+
127+
// Lamp Control
128+
void setLamp(int newVal) {
129+
if (newVal != -1) {
130+
// Apply a logarithmic function to the scale.
131+
int brightness = round((pow(2,(1+(newVal*0.02)))-2)/6*pwmMax);
132+
ledcWrite(lampChannel, brightness);
133+
Serial.print("Lamp: ");
134+
Serial.print(newVal);
135+
Serial.print("%, pwm = ");
136+
Serial.println(brightness);
137+
}
138+
}
139+
140+
void WifiSetup(){
141+
// Feedback that we are now attempting to connect
142+
flashLED(400);
143+
144+
#if defined(WIFI_AP_ENABLE)
145+
#if defined(AP_ADDRESS)
146+
// User has specified the AP details, pre-configure AP
147+
IPAddress local_IP(AP_ADDRESS);
148+
IPAddress gateway(AP_ADDRESS);
149+
IPAddress subnet(255,255,255,0);
150+
WiFi.softAPConfig(local_IP, gateway, subnet);
151+
#endif
152+
#if defined(AP_CHAN)
153+
WiFi.softAP(ssid, password, AP_CHAN);
154+
Serial.println("Setting up Fixed Channel AccessPoint");
155+
Serial.print("SSID : ");
156+
Serial.println(ssid);
157+
Serial.print("Password : ");
158+
Serial.println(password);
159+
Serial.print("Channel : ");
160+
Serial.println(AP_CHAN);
161+
# else
162+
WiFi.softAP(ssid, password);
163+
Serial.println("Setting up AccessPoint");
164+
Serial.print("SSID : ");
165+
Serial.println(ssid);
166+
Serial.print("Password : ");
167+
Serial.println(password);
168+
#endif
169+
#else
170+
Serial.printf("Connecting to Wifi Network: %s ", ssid);
171+
#if defined(ST_IP)
172+
#if !defined (ST_GATEWAY) || !defined (ST_NETMASK)
173+
#error "You must supply both Gateway and NetMask when specifying a static IP address"
174+
#endif
175+
IPAddress staticIP(ST_IP);
176+
IPAddress gateway(ST_GATEWAY);
177+
IPAddress subnet(ST_NETMASK);
178+
#if !defined(ST_DNS1)
179+
WiFi.config(staticIP, gateway, subnet);
180+
#else
181+
IPAddress dns1(ST_DNS1);
182+
#if !defined(ST_DNS2)
183+
WiFi.config(staticIP, gateway, subnet, dns1);
184+
#else
185+
IPAddress dns2(ST_DNS2);
186+
WiFi.config(staticIP, gateway, subnet, dns1, dns2);
187+
#endif
188+
#endif
189+
#endif
190+
191+
// Initiate network connection request
192+
WiFi.begin(ssid, password);
193+
194+
// Wait to connect, or timeout
195+
unsigned long start = millis();
196+
while ((millis() - start <= WIFI_WATCHDOG) && (WiFi.status() != WL_CONNECTED)) {
197+
delay(WIFI_WATCHDOG / 10);
198+
Serial.print('.');
199+
}
200+
201+
// If we have connected, show details
202+
if (WiFi.status() == WL_CONNECTED) {
203+
Serial.println(" Succeeded");
204+
} else {
205+
Serial.println(" Failed");
206+
}
207+
#endif
208+
}
112209

113210
void setup() {
114211
Serial.begin(115200);
@@ -227,87 +324,66 @@ void setup() {
227324
s->set_framesize(s, FRAMESIZE_SVGA);
228325
#endif
229326

230-
// Feedback that hardware init is complete and we are now attempting to connect
231-
Serial.println("Wifi Initialisation");
232-
flashLED(400);
233-
delay(100);
327+
/*
328+
* Add any other defaults you want to apply at startup here:
329+
* uncomment the line and set the value as desired (see the comments)
330+
*/
331+
//s->set_brightness(s, 0); // -2 to 2
332+
//s->set_contrast(s, 0); // -2 to 2
333+
//s->set_saturation(s, 0); // -2 to 2
334+
//s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
335+
//s->set_whitebal(s, 1); // 0 = disable , 1 = enable
336+
//s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
337+
//s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
338+
//s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
339+
//s->set_aec2(s, 0); // 0 = disable , 1 = enable
340+
//s->set_ae_level(s, 0); // -2 to 2
341+
//s->set_aec_value(s, 300); // 0 to 1200
342+
//s->set_gain_ctrl(s, 1); // 0 = disable , 1 = enable
343+
//s->set_agc_gain(s, 0); // 0 to 30
344+
//s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6
345+
//s->set_bpc(s, 0); // 0 = disable , 1 = enable
346+
//s->set_wpc(s, 1); // 0 = disable , 1 = enable
347+
//s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
348+
//s->set_lenc(s, 1); // 0 = disable , 1 = enable
349+
//s->set_hmirror(s, 0); // 0 = disable , 1 = enable
350+
//s->set_vflip(s, 0); // 0 = disable , 1 = enable
351+
//s->set_dcw(s, 1); // 0 = disable , 1 = enable
352+
//s->set_colorbar(s, 0); // 0 = disable , 1 = enable
353+
354+
// We now have our config defined; setup the hardware.
355+
356+
// Initialise and set the lamp
357+
if (lampVal != -1) {
358+
ledcSetup(lampChannel, pwmfreq, pwmresolution); // configure LED PWM channel
359+
setLamp(lampVal); // set default value
360+
ledcAttachPin(LAMP_PIN, lampChannel); // attach the GPIO pin to the channel
361+
} else {
362+
Serial.println("No lamp, or lamp disabled in config");
363+
}
364+
365+
// We need a working Wifi before we can start the http handlers
366+
Serial.println("Starting WiFi");
234367

235368
#if defined(WIFI_AP_ENABLE)
236-
#if defined(AP_ADDRESS)
237-
IPAddress local_IP(AP_ADDRESS);
238-
IPAddress gateway(AP_ADDRESS);
239-
IPAddress subnet(255,255,255,0);
240-
WiFi.softAPConfig(local_IP, gateway, subnet);
241-
#endif
242-
#if defined(AP_CHAN)
243-
WiFi.softAP(ssid, password, AP_CHAN);
244-
Serial.println("Setting up Fixed Channel AccessPoint");
245-
Serial.print("SSID : ");
246-
Serial.println(ssid);
247-
Serial.print("Password : ");
248-
Serial.println(password);
249-
Serial.print("Channel : ");
250-
Serial.println(AP_CHAN);
251-
# else
252-
WiFi.softAP(ssid, password);
253-
Serial.println("Setting up AccessPoint");
254-
Serial.print("SSID : ");
255-
Serial.println(ssid);
256-
Serial.print("Password : ");
257-
Serial.println(password);
258-
#endif
369+
WifiSetup();
259370
#else
260-
Serial.print("Connecting to Wifi Network: ");
261-
Serial.println(ssid);
262-
#if defined(ST_IP)
263-
#if !defined (ST_GATEWAY) || !defined (ST_NETMASK)
264-
#error "You must supply both Gateway and NetMask when specifying a static IP address"
265-
#endif
266-
IPAddress staticIP(ST_IP);
267-
IPAddress gateway(ST_GATEWAY);
268-
IPAddress subnet(ST_NETMASK);
269-
#if !defined(ST_DNS1)
270-
WiFi.config(staticIP, gateway, subnet);
271-
#else
272-
IPAddress dns1(ST_DNS1);
273-
#if !defined(ST_DNS2)
274-
WiFi.config(staticIP, gateway, subnet, dns1);
275-
#else
276-
IPAddress dns2(ST_DNS2);
277-
WiFi.config(staticIP, gateway, subnet, dns1, dns2);
278-
#endif
279-
#endif
280-
#endif
281-
282-
WiFi.begin(ssid, password);
283-
284371
while (WiFi.status() != WL_CONNECTED) {
285-
delay(250); // Wait for Wifi to connect. If this fails wifi the code basically hangs here.
286-
// - It would be good to do something else here as a future enhancement.
287-
// (eg: go to a captive AP config portal to configure the wifi)
372+
WifiSetup();
288373
}
289-
290-
// feedback that we are connected
291-
Serial.println("WiFi connected");
292-
flashLED(200);
293-
delay(100);
294-
flashLED(200);
295-
delay(100);
296-
flashLED(200);
297374
#endif
298375

299-
// Start the Stream server, and the handler processes for the Web UI.
376+
// Start the two http handlers for the HTTP UI and Stream.
300377
startCameraServer(httpPort, streamPort);
301378

379+
// find our IP address
302380
IPAddress ip;
303381
char httpURL[64] = {"Unknown"};
304-
305382
#if defined(WIFI_AP_ENABLE)
306383
ip = WiFi.softAPIP();
307384
#else
308385
ip = WiFi.localIP();
309386
#endif
310-
311387
// Construct the App URL
312388
if (httpPort != 80) {
313389
sprintf(httpURL, "http://%d.%d.%d.%d:%d/", ip[0], ip[1], ip[2], ip[3], httpPort);
@@ -317,7 +393,15 @@ void setup() {
317393
// Construct the Stream URL
318394
sprintf(streamURL, "http://%d.%d.%d.%d:%d/", ip[0], ip[1], ip[2], ip[3], streamPort);
319395

320-
Serial.printf("\nCamera Ready!\nUse '%s' to connect\n\n", httpURL);
396+
// Inform the user
397+
Serial.printf("\nCamera Ready!\nUse '%s' to connect\n", httpURL);
398+
Serial.printf("Raw stream URL is '%s'\n", streamURL);
399+
Serial.printf("Stream viewer available at '%sview'\n", streamURL);
400+
// Burst flash the LED to show we are connected
401+
for (int i = 0; i < 5; i++) {
402+
flashLED(80);
403+
delay(120);
404+
}
321405
}
322406

323407
// Notification LED
@@ -345,8 +429,26 @@ void setLamp(int newVal) {
345429
}
346430

347431
void loop() {
348-
// Just loop forever.
432+
// Just loop forever, reconnecting Wifi As necesscary.
349433
// The stream and URI handler processes initiated by the startCameraServer() call at the
350434
// end of setup() will handle the camera and UI processing from now on.
351-
delay(10000);
435+
#if defined(WIFI_AP_ENABLE)
436+
delay(WIFI_WATCHDOG);
437+
#else
438+
static bool warned = false;
439+
if (WiFi.status() == WL_CONNECTED) {
440+
// We are connected, wait a bit and re-check
441+
if (warned) {
442+
Serial.println("WiFi reconnected");
443+
warned = false;
444+
}
445+
delay(WIFI_WATCHDOG);
446+
} else {
447+
if (!warned) {
448+
Serial.println("WiFi disconnected, retrying");
449+
warned = true;
450+
}
451+
WifiSetup();
452+
}
453+
#endif
352454
}

myconfig.sample.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ const char* password = "my-password";
4040
// #define ST_DNS1 192,168,0,2
4141
// #define ST_DNS2 8,8,8,8
4242

43+
// Wifi Watchdog defines how long we spend waiting for a connection before retrying,
44+
// and how often we check to see if we are still connected, milliseconds
45+
// You may wish to increase this if your WiFi is slow at conencting,
46+
// #define WIFI_WATCHDOG = 5000
47+
4348

4449
/*
4550
* Port numbers for WebUI and Stream, defaults to 80 and 81.

0 commit comments

Comments
 (0)