Skip to content

Commit fc4e0f3

Browse files
committed
calling esp_camera_sensor_get() while streaming crashes module, dont do it, report errors more coherently
1 parent 740db4e commit fc4e0f3

File tree

2 files changed

+63
-43
lines changed

2 files changed

+63
-43
lines changed

app_httpd.cpp

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ extern String sketchMD5;
6565
extern bool otaEnabled;
6666
extern char otaPassword[];
6767
extern unsigned long xclk;
68+
extern int sensorPID;
6869

6970
typedef struct {
7071
httpd_req_t *req;
@@ -166,7 +167,8 @@ void serialDump() {
166167
Serial.println("Preferences file: ");
167168
dumpPrefs(SPIFFS);
168169
if (critERR.length() > 0) {
169-
Serial.printf("\r\n\r\nA critical error has occurred when initialising Camera Hardware, see startup megssages\r\n");
170+
Serial.printf("\r\n\r\nAn error or halt has occurred with Camera Hardware, see previous messages.\r\n");
171+
Serial.printf("A reboot is required to recover from this.\r\nError message: (html)\r\n %s\r\n\r\n", critERR.c_str());
170172
}
171173
Serial.println();
172174
return;
@@ -286,9 +288,15 @@ static esp_err_t stream_handler(httpd_req_t *req){
286288
free(_jpg_buf);
287289
_jpg_buf = NULL;
288290
}
289-
if((res != ESP_OK) || streamKill){
290-
// This is the only exit point from the stream loop.
291+
if(res != ESP_OK){
292+
// This is the error exit point from the stream loop.
291293
// We end the stream here only if a Hard failure has been encountered or the connection has been interrupted.
294+
Serial.printf("Stream failed, code = %i : %s\r\n", res, esp_err_to_name(res));
295+
break;
296+
}
297+
if((res != ESP_OK) || streamKill){
298+
// We end the stream here when a kill is signalled.
299+
Serial.printf("Stream killed\r\n");
292300
break;
293301
}
294302
int64_t frame_time = esp_timer_get_time() - last_frame;
@@ -346,6 +354,8 @@ static esp_err_t cmd_handler(httpd_req_t *req){
346354
return ESP_FAIL;
347355
}
348356

357+
if (critERR.length() > 0) return httpd_resp_send_500(req);
358+
349359
int val = atoi(value);
350360
sensor_t * s = esp_camera_sensor_get();
351361
int res = 0;
@@ -429,42 +439,45 @@ static esp_err_t cmd_handler(httpd_req_t *req){
429439

430440
static esp_err_t status_handler(httpd_req_t *req){
431441
static char json_response[1024];
432-
sensor_t * s = esp_camera_sensor_get();
433442
char * p = json_response;
434443
*p++ = '{';
435-
p+=sprintf(p, "\"lamp\":%d,", lampVal);
436-
p+=sprintf(p, "\"autolamp\":%d,", autoLamp);
437-
p+=sprintf(p, "\"min_frame_time\":%d,", minFrameTime);
438-
p+=sprintf(p, "\"framesize\":%u,", s->status.framesize);
439-
p+=sprintf(p, "\"quality\":%u,", s->status.quality);
440-
p+=sprintf(p, "\"xclk\":%u,", xclk);
441-
p+=sprintf(p, "\"brightness\":%d,", s->status.brightness);
442-
p+=sprintf(p, "\"contrast\":%d,", s->status.contrast);
443-
p+=sprintf(p, "\"saturation\":%d,", s->status.saturation);
444-
p+=sprintf(p, "\"sharpness\":%d,", s->status.sharpness);
445-
p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
446-
p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
447-
p+=sprintf(p, "\"awb\":%u,", s->status.awb);
448-
p+=sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain);
449-
p+=sprintf(p, "\"aec\":%u,", s->status.aec);
450-
p+=sprintf(p, "\"aec2\":%u,", s->status.aec2);
451-
p+=sprintf(p, "\"ae_level\":%d,", s->status.ae_level);
452-
p+=sprintf(p, "\"aec_value\":%u,", s->status.aec_value);
453-
p+=sprintf(p, "\"agc\":%u,", s->status.agc);
454-
p+=sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain);
455-
p+=sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling);
456-
p+=sprintf(p, "\"bpc\":%u,", s->status.bpc);
457-
p+=sprintf(p, "\"wpc\":%u,", s->status.wpc);
458-
p+=sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma);
459-
p+=sprintf(p, "\"lenc\":%u,", s->status.lenc);
460-
p+=sprintf(p, "\"vflip\":%u,", s->status.vflip);
461-
p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
462-
p+=sprintf(p, "\"dcw\":%u,", s->status.dcw);
463-
p+=sprintf(p, "\"colorbar\":%u,", s->status.colorbar);
464-
p+=sprintf(p, "\"cam_name\":\"%s\",", myName);
465-
p+=sprintf(p, "\"code_ver\":\"%s\",", myVer);
466-
p+=sprintf(p, "\"rotate\":\"%d\",", myRotation);
467-
p+=sprintf(p, "\"stream_url\":\"%s\"", streamURL);
444+
// Do not get attempt to get sensor when in error; causes a panic..
445+
if (critERR.length() == 0) {
446+
sensor_t * s = esp_camera_sensor_get();
447+
p+=sprintf(p, "\"lamp\":%d,", lampVal);
448+
p+=sprintf(p, "\"autolamp\":%d,", autoLamp);
449+
p+=sprintf(p, "\"min_frame_time\":%d,", minFrameTime);
450+
p+=sprintf(p, "\"framesize\":%u,", s->status.framesize);
451+
p+=sprintf(p, "\"quality\":%u,", s->status.quality);
452+
p+=sprintf(p, "\"xclk\":%u,", xclk);
453+
p+=sprintf(p, "\"brightness\":%d,", s->status.brightness);
454+
p+=sprintf(p, "\"contrast\":%d,", s->status.contrast);
455+
p+=sprintf(p, "\"saturation\":%d,", s->status.saturation);
456+
p+=sprintf(p, "\"sharpness\":%d,", s->status.sharpness);
457+
p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
458+
p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
459+
p+=sprintf(p, "\"awb\":%u,", s->status.awb);
460+
p+=sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain);
461+
p+=sprintf(p, "\"aec\":%u,", s->status.aec);
462+
p+=sprintf(p, "\"aec2\":%u,", s->status.aec2);
463+
p+=sprintf(p, "\"ae_level\":%d,", s->status.ae_level);
464+
p+=sprintf(p, "\"aec_value\":%u,", s->status.aec_value);
465+
p+=sprintf(p, "\"agc\":%u,", s->status.agc);
466+
p+=sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain);
467+
p+=sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling);
468+
p+=sprintf(p, "\"bpc\":%u,", s->status.bpc);
469+
p+=sprintf(p, "\"wpc\":%u,", s->status.wpc);
470+
p+=sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma);
471+
p+=sprintf(p, "\"lenc\":%u,", s->status.lenc);
472+
p+=sprintf(p, "\"vflip\":%u,", s->status.vflip);
473+
p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
474+
p+=sprintf(p, "\"dcw\":%u,", s->status.dcw);
475+
p+=sprintf(p, "\"colorbar\":%u,", s->status.colorbar);
476+
p+=sprintf(p, "\"cam_name\":\"%s\",", myName);
477+
p+=sprintf(p, "\"code_ver\":\"%s\",", myVer);
478+
p+=sprintf(p, "\"rotate\":\"%d\",", myRotation);
479+
p+=sprintf(p, "\"stream_url\":\"%s\"", streamURL);
480+
}
468481
*p++ = '}';
469482
*p++ = 0;
470483
httpd_resp_set_type(req, "application/json");
@@ -527,8 +540,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
527540
d+= sprintf(d,"<body>\n");
528541
d+= sprintf(d,"<img src=\"/logo.svg\" style=\"position: relative; float: right;\">\n");
529542
if (critERR.length() > 0) {
530-
d+= sprintf(d,"<span style=\"color:red;\">%s<hr></span>\n", critERR.c_str());
531-
d+= sprintf(d,"<h2 style=\"color:red;\">(the serial log may give more information)</h2><br>\n");
543+
d+= sprintf(d,"%s<hr>\n", critERR.c_str());
532544
}
533545
d+= sprintf(d,"<h1>ESP32 Cam Webserver</h1>\n");
534546
// Module
@@ -696,15 +708,16 @@ static esp_err_t index_handler(httpd_req_t *req){
696708

697709
if (strncmp(view,"simple", sizeof(view)) == 0) {
698710
Serial.println("Simple index page requested");
711+
if (critERR.length() > 0) return error_handler(req);
699712
httpd_resp_set_type(req, "text/html");
700713
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
701714
return httpd_resp_send(req, (const char *)index_simple_html, index_simple_html_len);
702715
} else if(strncmp(view,"full", sizeof(view)) == 0) {
703716
Serial.println("Full index page requested");
717+
if (critERR.length() > 0) return error_handler(req);
704718
httpd_resp_set_type(req, "text/html");
705719
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
706-
sensor_t * s = esp_camera_sensor_get();
707-
if (s->id.PID == OV3660_PID) {
720+
if (sensorPID == OV3660_PID) {
708721
return httpd_resp_send(req, (const char *)index_ov3660_html, index_ov3660_html_len);
709722
}
710723
return httpd_resp_send(req, (const char *)index_ov2640_html, index_ov2640_html_len);

esp32-cam-webserver.ino

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ unsigned long imagesServed = 0; // Total image requests
144144
// This will be displayed to identify the firmware
145145
char myVer[] PROGMEM = __DATE__ " @ " __TIME__;
146146

147+
// This will be set to the sensors PID (identifier) during initialisation
148+
//camera_pid_t sensorPID;
149+
int sensorPID;
150+
147151
// Camera module bus communications frequency.
148152
// Originally: config.xclk_freq_mhz = 20000000, but this lead to visual artifacts on many modules.
149153
// See https://github.com/espressif/esp32-camera/issues/150#issuecomment-726473652 et al.
@@ -373,7 +377,8 @@ void StartCamera() {
373377
sensor_t * s = esp_camera_sensor_get();
374378

375379
// Dump camera module, warn for unsupported modules.
376-
switch (s->id.PID) {
380+
sensorPID = s->id.PID;
381+
switch (sensorPID) {
377382
case OV9650_PID: Serial.println("WARNING: OV9650 camera module is not properly supported, will fallback to OV2640 operation"); break;
378383
case OV7725_PID: Serial.println("WARNING: OV7725 camera module is not properly supported, will fallback to OV2640 operation"); break;
379384
case OV2640_PID: Serial.println("OV2640 camera module detected"); break;
@@ -382,7 +387,7 @@ void StartCamera() {
382387
}
383388

384389
// OV3660 initial sensors are flipped vertically and colors are a bit saturated
385-
if (s->id.PID == OV3660_PID) {
390+
if (sensorPID == OV3660_PID) {
386391
s->set_vflip(s, 1); //flip it back
387392
s->set_brightness(s, 1); //up the blightness just a bit
388393
s->set_saturation(s, -2); //lower the saturation
@@ -720,6 +725,8 @@ void setup() {
720725
// the unit will need rebooting to restart it, either by OTA on success, or manually by the user
721726
Serial.println("Stopping Camera");
722727
esp_err_t err = esp_camera_deinit();
728+
critERR = "<h1>OTA Has been started</h1><hr><p>Camera has Halted!</p>";
729+
critERR += "<p>Wait for OTA to finish and reboot, or <a href=\"control?var=reboot&val=0\" title=\"Reboot Now (may interrupt OTA)\">reboot manually</a> to recover</p>";
723730
})
724731
.onEnd([]() {
725732
Serial.println("\r\nEnd");

0 commit comments

Comments
 (0)