aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-01-07 18:42:09 -0600
committerToby Vincent <tobyv@tobyvin.dev>2024-01-07 18:42:23 -0600
commit68ca8e59cdce4d0d6d90ec40f48c69b5f0de6613 (patch)
tree67c6d15e9df0c3bed0926f03ee2f91fce4e9797b
parentd9d7b361c63233f2904a1e0bb1be2c36f2722243 (diff)
Enable OTA
-rw-r--r--esp32cam_partitions.csv6
-rw-r--r--platformio.ini4
-rw-r--r--src/main.cpp85
3 files changed, 79 insertions, 16 deletions
diff --git a/esp32cam_partitions.csv b/esp32cam_partitions.csv
new file mode 100644
index 0000000..a179a89
--- /dev/null
+++ b/esp32cam_partitions.csv
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x5000,
+otadata, data, ota, 0xe000, 0x2000,
+app0, app, ota_0, 0x10000, 0x180000,
+app1, app, ota_1, 0x190000,0x180000,
+spiffs, data, spiffs, 0x310000,0xF0000,
diff --git a/platformio.ini b/platformio.ini
index 23e577c..46a70cc 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -11,8 +11,10 @@
[env:esp32cam]
platform = espressif32
board = esp32cam
+board_build.partitions = esp32cam_partitions.csv
framework = arduino
extra_scripts = pre:extra_script.py
+upload_protocol = espota
+upload_port = 10.42.0.189
monitor_speed = 115200
-upload_speed = 921600
lib_deps = espressif/esp32-camera@^2.0.4
diff --git a/src/main.cpp b/src/main.cpp
index e15bffa..7555b1f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#define APP_CPU 1
#define PRO_CPU 0
+#include <ArduinoOTA.h>
#include <OV2640.h>
#include <WebServer.h>
#include <WiFi.h>
@@ -29,6 +30,8 @@
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
+#define LED_GPIO_NUM 4
+
OV2640 cam;
WebServer server(80);
@@ -39,6 +42,7 @@ TaskHandle_t tMjpeg; // handles client connections to the webserver
TaskHandle_t tCam; // handles getting picture frames from the camera and storing
// them locally
TaskHandle_t tStream; // actually streaming frames to all connected clients
+TaskHandle_t tOTA;
// frameSync semaphore is used to prevent streaming buffer as it is replaced
// with the next frame
@@ -113,7 +117,6 @@ void camCB(void *pvParameters) {
xLastWakeTime = xTaskGetTickCount();
for (;;) {
-
// Grab a frame from the camera and query its size
cam.run();
size_t s = cam.getSize();
@@ -222,6 +225,9 @@ void streamCB(void *pvParameters) {
// Only bother to send anything if there is someone watching
UBaseType_t activeClients = uxQueueMessagesWaiting(streamingClients);
if (activeClients) {
+ // Enable LED while client connected
+ digitalWrite(LED_GPIO_NUM, HIGH);
+
// Adjust the period to the number of connected clients
xFrequency /= activeClients;
@@ -244,7 +250,7 @@ void streamCB(void *pvParameters) {
xSemaphoreTake(frameSync, portMAX_DELAY);
client->write(CTNTTYPE, cntLen);
- sprintf(buf, "%d\r\n\r\n", camSize);
+ sprintf(buf, "%zu\r\n\r\n", camSize);
client->write(buf, strlen(buf));
client->write((char *)camBuf, (size_t)camSize);
client->write(BOUNDARY, bdrLen);
@@ -262,6 +268,7 @@ void streamCB(void *pvParameters) {
} else {
// Since there are no connected clients, there is no reason to waste
// battery running
+ digitalWrite(LED_GPIO_NUM, LOW);
vTaskSuspend(NULL);
}
// Let other tasks run after serving every client
@@ -281,9 +288,21 @@ void handleJPG(void) {
if (!client.connected())
return;
+
+ int prev_led_state = digitalRead(LED_GPIO_NUM);
+ if (prev_led_state == LOW) {
+ digitalWrite(LED_GPIO_NUM, HIGH);
+ // Delay capture to prevent partial illumination
+ delay(200);
+ }
+
cam.run();
client.write(JHEADER, jhdLen);
client.write((char *)cam.getfb(), cam.getSize());
+
+ if (prev_led_state == LOW) {
+ digitalWrite(LED_GPIO_NUM, LOW);
+ }
}
// ==== Handle invalid URL requests ============================================
@@ -347,6 +366,13 @@ void mjpegCB(void *pvParameters) {
}
}
+void ota_handle(void *optionalArgs) {
+ for (;;) {
+ ArduinoOTA.handle();
+ delay(3500);
+ }
+}
+
// ==== SETUP method
// ==================================================================
void setup() {
@@ -355,6 +381,8 @@ void setup() {
Serial.begin(115200);
delay(1000); // wait for a second to let Serial connect
+ pinMode(LED_GPIO_NUM, OUTPUT);
+
// Configure the camera
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
@@ -371,26 +399,16 @@ void setup() {
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
- config.pin_sscb_sda = SIOD_GPIO_NUM;
- config.pin_sscb_scl = SIOC_GPIO_NUM;
+ config.pin_sccb_sda = SIOD_GPIO_NUM;
+ config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
-
- // Frame parameters: pick one
- // config.frame_size = FRAMESIZE_UXGA;
- // config.frame_size = FRAMESIZE_SVGA;
- // config.frame_size = FRAMESIZE_QVGA;
- config.frame_size = FRAMESIZE_VGA;
+ config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 2;
-#if defined(CAMERA_MODEL_ESP_EYE)
- pinMode(13, INPUT_PULLUP);
- pinMode(14, INPUT_PULLUP);
-#endif
-
if (cam.init(config) != ESP_OK) {
Serial.println("Error initializing the camera");
delay(10000);
@@ -415,6 +433,43 @@ void setup() {
Serial.print(ip);
Serial.println("/mjpeg/1");
+ ArduinoOTA
+ .onStart([]() {
+ String type;
+ if (ArduinoOTA.getCommand() == U_FLASH)
+ type = "sketch";
+ else // U_SPIFFS
+ type = "filesystem";
+
+ // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS
+ // using SPIFFS.end()
+ Serial.println("Start updating " + type);
+ })
+ .onEnd([]() { Serial.println("\nEnd"); })
+ .onProgress([](unsigned int progress, unsigned int total) {
+ Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
+ })
+ .onError([](ota_error_t error) {
+ Serial.printf("Error[%u]: ", error);
+ if (error == OTA_AUTH_ERROR)
+ Serial.println("Auth Failed");
+ else if (error == OTA_BEGIN_ERROR)
+ Serial.println("Begin Failed");
+ else if (error == OTA_CONNECT_ERROR)
+ Serial.println("Connect Failed");
+ else if (error == OTA_RECEIVE_ERROR)
+ Serial.println("Receive Failed");
+ else if (error == OTA_END_ERROR)
+ Serial.println("End Failed");
+ });
+
+ ArduinoOTA.begin();
+
+ // Start Android OTA RTOS task
+ xTaskCreatePinnedToCore(ota_handle, "TaskAutoConnect", 10000, NULL, 1, &tOTA,
+ 0);
+ // xTaskCreate(ota_handle, "ota", 8 * 1024, NULL, 1, NULL);
+
// Start mainstreaming RTOS task
xTaskCreatePinnedToCore(mjpegCB, "mjpeg", 4 * 1024, NULL, 2, &tMjpeg,
APP_CPU);