From a536b94850323f1d670a20fef0e421490b25ac8a Mon Sep 17 00:00:00 2001 From: Eric Fontaine Date: Fri, 24 Sep 2021 09:36:40 -0400 Subject: [PATCH 1/6] updateConfig when move sliders too (#145) onchange only would trigger updateConfig when user releases the mouse from sliders. Adding oninput also allows updateConfig when dragging the sliders, which provides immediate feedback of the changes for the user. --- index_other.h | 5 +++++ index_ov2640.h | 5 +++++ index_ov3660.h | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/index_other.h b/index_other.h index 71b6971..a5a6231 100644 --- a/index_other.h +++ b/index_other.h @@ -258,6 +258,11 @@ const uint8_t index_simple_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Detection and framesize diff --git a/index_ov2640.h b/index_ov2640.h index 00724cf..f202ec7 100644 --- a/index_ov2640.h +++ b/index_ov2640.h @@ -498,6 +498,11 @@ const uint8_t index_ov2640_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Gain diff --git a/index_ov3660.h b/index_ov3660.h index ff4b88d..ca963c7 100644 --- a/index_ov3660.h +++ b/index_ov3660.h @@ -510,6 +510,11 @@ const uint8_t index_ov3660_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Gain From 60056e4064a36a8ee65ef4ebb93e2b480a27b3b2 Mon Sep 17 00:00:00 2001 From: Owen Date: Sat, 25 Sep 2021 15:13:29 +0200 Subject: [PATCH 2/6] Increase default WiFi Connect --- esp32-cam-webserver.ino | 2 +- myconfig.sample.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/esp32-cam-webserver.ino b/esp32-cam-webserver.ino index 44155aa..7e52667 100644 --- a/esp32-cam-webserver.ino +++ b/esp32-cam-webserver.ino @@ -95,7 +95,7 @@ extern void serialDump(); #endif #if !defined(WIFI_WATCHDOG) - #define WIFI_WATCHDOG 5000 + #define WIFI_WATCHDOG 8000 #endif // Number of known networks in stationList[] diff --git a/myconfig.sample.h b/myconfig.sample.h index 2b909eb..e0d79be 100644 --- a/myconfig.sample.h +++ b/myconfig.sample.h @@ -59,7 +59,7 @@ struct station stationList[] = {{"ssid1", "pass1", true}, // #define ST_IP 192,168,0,123 // #define ST_GATEWAY 192,168,0,2 // #define ST_NETMASK 255,255,255,0 -// One or two optional DNS servers can be supplied, but the current firmware never uses them ;-) +// One or two DNS servers can be supplied, only the NTP code currently uses them // #define ST_DNS1 192,168,0,2 // #define ST_DNS2 8,8,8,8 @@ -101,7 +101,7 @@ struct station stationList[] = {{"ssid1", "pass1", true}, * and how often we check to see if we are still connected, milliseconds * You may wish to increase this if your WiFi is slow at conencting, */ -// #define WIFI_WATCHDOG 5000 +// #define WIFI_WATCHDOG 8000 /* * Over The Air firmware updates can be disabled by uncommenting the folowing line From d3e09b0887664ac63c58d26e9911cc1e7b9e1c40 Mon Sep 17 00:00:00 2001 From: Eric Fontaine Date: Fri, 24 Sep 2021 09:36:40 -0400 Subject: [PATCH 3/6] updateConfig when move sliders too (#145) onchange only would trigger updateConfig when user releases the mouse from sliders. Adding oninput also allows updateConfig when dragging the sliders, which provides immediate feedback of the changes for the user. --- index_other.h | 5 +++++ index_ov2640.h | 5 +++++ index_ov3660.h | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/index_other.h b/index_other.h index 71b6971..a5a6231 100644 --- a/index_other.h +++ b/index_other.h @@ -258,6 +258,11 @@ const uint8_t index_simple_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Detection and framesize diff --git a/index_ov2640.h b/index_ov2640.h index 00724cf..f202ec7 100644 --- a/index_ov2640.h +++ b/index_ov2640.h @@ -498,6 +498,11 @@ const uint8_t index_ov2640_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Gain diff --git a/index_ov3660.h b/index_ov3660.h index ff4b88d..ca963c7 100644 --- a/index_ov3660.h +++ b/index_ov3660.h @@ -510,6 +510,11 @@ const uint8_t index_ov3660_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + document + .querySelectorAll('input[type="range"]') + .forEach(el => { + el.oninput = () => updateConfig(el) + }) // Custom actions // Gain From 8f5c53d82a82933e9a66562a25699e2d94dd5286 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 26 Sep 2021 00:59:38 +0200 Subject: [PATCH 4/6] discard out-of-sequence slider oninput updates --- app_httpd.cpp | 19 ++++++++++++++++++- index_other.h | 12 +++++++++--- index_ov2640.h | 12 +++++++++--- index_ov3660.h | 12 +++++++++--- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/app_httpd.cpp b/app_httpd.cpp index 54100ca..34cb47c 100644 --- a/app_httpd.cpp +++ b/app_httpd.cpp @@ -77,6 +77,8 @@ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: % httpd_handle_t stream_httpd = NULL; httpd_handle_t camera_httpd = NULL; +unsigned long long int cmdSerial = 0; + #ifdef __cplusplus extern "C" { #endif @@ -288,6 +290,8 @@ static esp_err_t cmd_handler(httpd_req_t *req){ size_t buf_len; char variable[32] = {0,}; char value[32] = {0,}; + unsigned long long int serial = 0; + flashLED(75); buf_len = httpd_req_get_url_query_len(req) + 1; @@ -300,6 +304,10 @@ static esp_err_t cmd_handler(httpd_req_t *req){ if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK && httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) { + char s[32] = {0,}; + if (httpd_query_key_value(buf, "ser", s, sizeof(s)) == ESP_OK) { + serial = atoi(s); + } } else { free(buf); httpd_resp_send_404(req); @@ -319,7 +327,16 @@ static esp_err_t cmd_handler(httpd_req_t *req){ int val = atoi(value); sensor_t * s = esp_camera_sensor_get(); int res = 0; - if(!strcmp(variable, "framesize")) { + if(serial > 0) { // If the command has a serialisation number + if(serial>cmdSerial) { // test if in sequence + cmdSerial = serial; + } else { + strcpy(variable, "skip"); // skip when out of sequence + } + } + + if(!strcmp(variable, "skip")) {} // do nothing, but return success + else if(!strcmp(variable, "framesize")) { if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val); } else if(!strcmp(variable, "quality")) res = s->set_quality(s, val); diff --git a/index_other.h b/index_other.h index a5a6231..2accb2a 100644 --- a/index_other.h +++ b/index_other.h @@ -139,7 +139,8 @@ const uint8_t index_simple_html[] = R"=====( } } - function updateConfig (el) { + var serialCounter = 0; + function updateConfig (el, serial=false) { let value switch (el.type) { case 'checkbox': @@ -157,7 +158,12 @@ const uint8_t index_simple_html[] = R"=====( return } - const query = `${baseHost}/control?var=${el.id}&val=${value}` + var query = '' + if (serial) { + query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` + } else { + query = `${baseHost}/control?var=${el.id}&val=${value}` + } fetch(query) .then(response => { @@ -261,7 +267,7 @@ const uint8_t index_simple_html[] = R"=====( document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el) + el.oninput = () => updateConfig(el, serial=true) }) // Custom actions diff --git a/index_ov2640.h b/index_ov2640.h index f202ec7..7b1f580 100644 --- a/index_ov2640.h +++ b/index_ov2640.h @@ -374,7 +374,8 @@ const uint8_t index_ov2640_html[] = R"=====( } } - function updateConfig (el) { + var serialCounter = 0; + function updateConfig (el, serial=false) { let value switch (el.type) { case 'checkbox': @@ -392,7 +393,12 @@ const uint8_t index_ov2640_html[] = R"=====( return } - const query = `${baseHost}/control?var=${el.id}&val=${value}` + var query = '' + if (serial) { + query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` + } else { + query = `${baseHost}/control?var=${el.id}&val=${value}` + } fetch(query) .then(response => { @@ -501,7 +507,7 @@ const uint8_t index_ov2640_html[] = R"=====( document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el) + el.oninput = () => updateConfig(el, serial=true) }) // Custom actions diff --git a/index_ov3660.h b/index_ov3660.h index ca963c7..4f508d6 100644 --- a/index_ov3660.h +++ b/index_ov3660.h @@ -386,7 +386,8 @@ const uint8_t index_ov3660_html[] = R"=====( } } - function updateConfig (el) { + var serialCounter = 0; + function updateConfig (el, serial=false) { let value switch (el.type) { case 'checkbox': @@ -404,7 +405,12 @@ const uint8_t index_ov3660_html[] = R"=====( return } - const query = `${baseHost}/control?var=${el.id}&val=${value}` + var query = '' + if (serial) { + query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` + } else { + query = `${baseHost}/control?var=${el.id}&val=${value}` + } fetch(query) .then(response => { @@ -513,7 +519,7 @@ const uint8_t index_ov3660_html[] = R"=====( document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el) + el.oninput = () => updateConfig(el, serial=true) }) // Custom actions From f895a65207969e66f9d18065a3dff8981d583e30 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 26 Sep 2021 02:06:55 +0200 Subject: [PATCH 5/6] Rate limit sending slider updates --- index_other.h | 21 +++++++++++++++++++-- index_ov2640.h | 19 ++++++++++++++++++- index_ov3660.h | 19 ++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/index_other.h b/index_other.h index 2accb2a..677f0f8 100644 --- a/index_other.h +++ b/index_other.h @@ -139,7 +139,22 @@ const uint8_t index_simple_html[] = R"=====( } } - var serialCounter = 0; + var rangeUpdateScheduled = false + var latestRangeConfig + + function updateRangeConfig (el) { + latestRangeConfig = el + if (!rangeUpdateScheduled) { + rangeUpdateScheduled = true; + setTimeout(function(){ + rangeUpdateScheduled = false + updateConfig(latestRangeConfig, serial=true) + }, 100); + } + } + + var serialCounter = 0 + function updateConfig (el, serial=false) { let value switch (el.type) { @@ -264,10 +279,12 @@ const uint8_t index_simple_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + + // Update range sliders as they are being moved document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el, serial=true) + el.oninput = () => updateRangeConfig(el) }) // Custom actions diff --git a/index_ov2640.h b/index_ov2640.h index 7b1f580..180a363 100644 --- a/index_ov2640.h +++ b/index_ov2640.h @@ -374,7 +374,22 @@ const uint8_t index_ov2640_html[] = R"=====( } } + var rangeUpdateScheduled = false + var latestRangeConfig + + function updateRangeConfig (el) { + latestRangeConfig = el + if (!rangeUpdateScheduled) { + rangeUpdateScheduled = true; + setTimeout(function(){ + rangeUpdateScheduled = false + updateConfig(latestRangeConfig, serial=true) + }, 100); + } + } + var serialCounter = 0; + function updateConfig (el, serial=false) { let value switch (el.type) { @@ -504,10 +519,12 @@ const uint8_t index_ov2640_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + + // Update range sliders as they are being moved document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el, serial=true) + el.oninput = () => updateRangeConfig(el) }) // Custom actions diff --git a/index_ov3660.h b/index_ov3660.h index 4f508d6..8217f16 100644 --- a/index_ov3660.h +++ b/index_ov3660.h @@ -386,7 +386,22 @@ const uint8_t index_ov3660_html[] = R"=====( } } + var rangeUpdateScheduled = false + var latestRangeConfig + + function updateRangeConfig (el) { + latestRangeConfig = el + if (!rangeUpdateScheduled) { + rangeUpdateScheduled = true; + setTimeout(function(){ + rangeUpdateScheduled = false + updateConfig(latestRangeConfig, serial=true) + }, 100); + } + } + var serialCounter = 0; + function updateConfig (el, serial=false) { let value switch (el.type) { @@ -516,10 +531,12 @@ const uint8_t index_ov3660_html[] = R"=====( .forEach(el => { el.onchange = () => updateConfig(el) }) + + // Update range sliders as they are being moved document .querySelectorAll('input[type="range"]') .forEach(el => { - el.oninput = () => updateConfig(el, serial=true) + el.oninput = () => updateRangeConfig(el) }) // Custom actions From b6eb928f90582cf27481dd4a503d4b4e18497f6e Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 26 Sep 2021 02:53:06 +0200 Subject: [PATCH 6/6] Remove sequence stuff, it caused problems when pages refreshed and is not needed --- app_httpd.cpp | 18 +----------------- index_other.h | 15 ++++----------- index_ov2640.h | 15 ++++----------- index_ov3660.h | 15 ++++----------- 4 files changed, 13 insertions(+), 50 deletions(-) diff --git a/app_httpd.cpp b/app_httpd.cpp index 34cb47c..0bc24c8 100644 --- a/app_httpd.cpp +++ b/app_httpd.cpp @@ -77,8 +77,6 @@ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: % httpd_handle_t stream_httpd = NULL; httpd_handle_t camera_httpd = NULL; -unsigned long long int cmdSerial = 0; - #ifdef __cplusplus extern "C" { #endif @@ -290,7 +288,6 @@ static esp_err_t cmd_handler(httpd_req_t *req){ size_t buf_len; char variable[32] = {0,}; char value[32] = {0,}; - unsigned long long int serial = 0; flashLED(75); @@ -304,10 +301,6 @@ static esp_err_t cmd_handler(httpd_req_t *req){ if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK && httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) { - char s[32] = {0,}; - if (httpd_query_key_value(buf, "ser", s, sizeof(s)) == ESP_OK) { - serial = atoi(s); - } } else { free(buf); httpd_resp_send_404(req); @@ -327,16 +320,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){ int val = atoi(value); sensor_t * s = esp_camera_sensor_get(); int res = 0; - if(serial > 0) { // If the command has a serialisation number - if(serial>cmdSerial) { // test if in sequence - cmdSerial = serial; - } else { - strcpy(variable, "skip"); // skip when out of sequence - } - } - - if(!strcmp(variable, "skip")) {} // do nothing, but return success - else if(!strcmp(variable, "framesize")) { + if(!strcmp(variable, "framesize")) { if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val); } else if(!strcmp(variable, "quality")) res = s->set_quality(s, val); diff --git a/index_other.h b/index_other.h index 677f0f8..ba4a297 100644 --- a/index_other.h +++ b/index_other.h @@ -148,14 +148,12 @@ const uint8_t index_simple_html[] = R"=====( rangeUpdateScheduled = true; setTimeout(function(){ rangeUpdateScheduled = false - updateConfig(latestRangeConfig, serial=true) - }, 100); + updateConfig(latestRangeConfig) + }, 150); } } - var serialCounter = 0 - - function updateConfig (el, serial=false) { + function updateConfig (el) { let value switch (el.type) { case 'checkbox': @@ -173,12 +171,7 @@ const uint8_t index_simple_html[] = R"=====( return } - var query = '' - if (serial) { - query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` - } else { - query = `${baseHost}/control?var=${el.id}&val=${value}` - } + const query = `${baseHost}/control?var=${el.id}&val=${value}` fetch(query) .then(response => { diff --git a/index_ov2640.h b/index_ov2640.h index 180a363..f923a21 100644 --- a/index_ov2640.h +++ b/index_ov2640.h @@ -383,14 +383,12 @@ const uint8_t index_ov2640_html[] = R"=====( rangeUpdateScheduled = true; setTimeout(function(){ rangeUpdateScheduled = false - updateConfig(latestRangeConfig, serial=true) - }, 100); + updateConfig(latestRangeConfig) + }, 150); } } - var serialCounter = 0; - - function updateConfig (el, serial=false) { + function updateConfig (el) { let value switch (el.type) { case 'checkbox': @@ -408,12 +406,7 @@ const uint8_t index_ov2640_html[] = R"=====( return } - var query = '' - if (serial) { - query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` - } else { - query = `${baseHost}/control?var=${el.id}&val=${value}` - } + const query = `${baseHost}/control?var=${el.id}&val=${value}` fetch(query) .then(response => { diff --git a/index_ov3660.h b/index_ov3660.h index 8217f16..eb7ca74 100644 --- a/index_ov3660.h +++ b/index_ov3660.h @@ -395,14 +395,12 @@ const uint8_t index_ov3660_html[] = R"=====( rangeUpdateScheduled = true; setTimeout(function(){ rangeUpdateScheduled = false - updateConfig(latestRangeConfig, serial=true) - }, 100); + updateConfig(latestRangeConfig) + }, 150); } } - var serialCounter = 0; - - function updateConfig (el, serial=false) { + function updateConfig (el) { let value switch (el.type) { case 'checkbox': @@ -420,12 +418,7 @@ const uint8_t index_ov3660_html[] = R"=====( return } - var query = '' - if (serial) { - query = `${baseHost}/control?var=${el.id}&val=${value}&ser=${++serialCounter}` - } else { - query = `${baseHost}/control?var=${el.id}&val=${value}` - } + const query = `${baseHost}/control?var=${el.id}&val=${value}` fetch(query) .then(response => {