From 532ed3e46f0fc665d8338cbc8ae92228a500939c Mon Sep 17 00:00:00 2001 From: Miroslav Pivovarsky Date: Thu, 16 May 2024 22:28:03 +0200 Subject: [PATCH] change sending data to connect --- .../ESP32_PrusaConnectCam.ino | 5 +- ESP32_PrusaConnectCam/camera.cpp | 105 +++++++++++------- ESP32_PrusaConnectCam/camera.h | 1 + ESP32_PrusaConnectCam/connect.cpp | 47 ++++---- ESP32_PrusaConnectCam/mcu_cfg.h | 4 +- ESP32_PrusaConnectCam/server.cpp | 3 +- ESP32_PrusaConnectCam/system.cpp | 2 + 7 files changed, 101 insertions(+), 66 deletions(-) diff --git a/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino b/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino index eb67852..7c75475 100644 --- a/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino +++ b/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino @@ -16,6 +16,8 @@ Board configuration in the arduino IDE 2.3.2 Tools -> Board -> ESP32 Arduino -> AI Thinker ESP32 + Tools -> CPU Frequency -> 240MHz (WiFi/BT) + Tools -> Core debug level -> None Tools -> Flash frequency -> 80MHz Tools -> Flash Mode -> DIO Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) @@ -103,6 +105,7 @@ void setup() { /* init camera interface */ SystemCamera.Init(); SystemCamera.CapturePhoto(); + SystemCamera.CaptureReturnFrameBuffer(); /* init WEB server */ Server_InitWebServer(); @@ -113,7 +116,7 @@ void setup() { /* init tasks */ SystemLog.AddEvent(LogLevel_Info, F("Start tasks")); xTaskCreatePinnedToCore(System_TaskMain, "SystemNtpOtaUpdate", 8000, NULL, 1, &Task_SystemMain, 0); /*function, description, stack size, parameters, priority, task handle, core*/ - xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 6000, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/ + xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 8000, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/ xTaskCreatePinnedToCore(System_TaskWifiManagement, "WiFiManagement", 3800, NULL, 3, &Task_WiFiManagement, 0); /*function, description, stack size, parameters, priority, task handle, core*/ xTaskCreatePinnedToCore(System_TaskSdCardCheck, "CheckMicroSdCard", 3300, NULL, 4, &Task_SdCardCheck, 0); /*function, description, stack size, parameters, priority, task handle, core*/ xTaskCreatePinnedToCore(System_TaskSerialCfg, "CheckSerialConfiguration", 3300, NULL, 5, &Task_SerialCfg, 0); /*function, description, stack size, parameters, priority, task handle, core*/ diff --git a/ESP32_PrusaConnectCam/camera.cpp b/ESP32_PrusaConnectCam/camera.cpp index 6ad1fe4..f8202a5 100644 --- a/ESP32_PrusaConnectCam/camera.cpp +++ b/ESP32_PrusaConnectCam/camera.cpp @@ -86,10 +86,10 @@ void Camera::InitCameraModule() { FRAMESIZE_UXGA (1600 x 1200) */ - CameraConfig.frame_size = TFrameSize; /* FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */ - CameraConfig.jpeg_quality = PhotoQuality; /* 10-63 lower number means higher quality */ - CameraConfig.fb_count = 1; /* picture frame buffer alocation */ - CameraConfig.grab_mode = CAMERA_GRAB_LATEST; /* CAMERA_GRAB_WHEN_EMPTY or CAMERA_GRAB_LATEST */ + CameraConfig.frame_size = TFrameSize; /* FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */ + CameraConfig.jpeg_quality = PhotoQuality; /* 10-63 lower number means higher quality */ + CameraConfig.fb_count = 1; /* picture frame buffer alocation */ + CameraConfig.grab_mode = CAMERA_GRAB_LATEST; /* CAMERA_GRAB_WHEN_EMPTY or CAMERA_GRAB_LATEST */ if (CameraConfig.fb_location == CAMERA_FB_IN_DRAM) { log->AddEvent(LogLevel_Verbose, F("Camera frame buffer location: DRAM")); @@ -173,7 +173,7 @@ framesize_t Camera::TransformFrameSizeDataType(uint8_t i_data) { ret = FRAMESIZE_QVGA; log->AddEvent(LogLevel_Warning, "Bad frame size. Set default value. " + String(i_data)); break; - } + } return ret; } @@ -272,12 +272,20 @@ void Camera::CapturePhoto() { delay(CameraFlashTime); } + /* Capturing a training photo. Without this sequence, the camera will not obtain the current photo but photo from the previous cycle. */ + FrameBuffer = esp_camera_fb_get(); + if (FrameBuffer) { + esp_camera_fb_return(FrameBuffer); + } else { + log->AddEvent(LogLevel_Error, F("Camera capture failed training photo")); + } + int attempts = 0; const int maxAttempts = 5; do { log->AddEvent(LogLevel_Info, F("Taking photo...")); - delay(5); // delay for camera stabilization. test it + delay(5); // delay for camera stabilization. test it FrameBuffer = esp_camera_fb_get(); if (!FrameBuffer) { log->AddEvent(LogLevel_Error, F("Camera capture failed! photo")); @@ -297,8 +305,6 @@ void Camera::CapturePhoto() { log->AddEvent(LogLevel_Info, "Photo OK! " + String(ControlFlag, HEX)); } - esp_camera_fb_return(FrameBuffer); - attempts++; if (attempts >= maxAttempts) { log->AddEvent(LogLevel_Error, F("Failed to capture a valid photo after max attempts")); @@ -464,11 +470,24 @@ void Camera::CopyPhoto(String* i_data) { * @param i_to - end index */ void Camera::CopyPhoto(String* i_data, int i_from, int i_to) { - Photo = ""; - for (size_t i = i_from; i < i_to; i++) { - Photo += (char)FrameBuffer->buf[i]; + *i_data = ""; + + for (int i = i_from; i < i_to; i++) { + *i_data += (char)FrameBuffer->buf[i]; } - *i_data = Photo; +} + +/** + * @brief Copy photo from frame buffer to char array with range + * + * @param i_data - pointer to char array + * @param i_from - start index + * @param i_to - end index + */ +void Camera::CopyPhoto(char* i_data, int i_from, int i_to) { + int length = i_to - i_from; + memcpy(i_data, FrameBuffer->buf + i_from, length); + i_data[length + 1] = '\0'; } /** @@ -478,7 +497,7 @@ void Camera::CopyPhoto(String* i_data, int i_from, int i_to) { */ int Camera::GetPhotoSize() { log->AddEvent(LogLevel_Verbose, "Photo size: " + String(FrameBuffer->len)); - return (int) FrameBuffer->len; + return (int)FrameBuffer->len; } /** @@ -754,35 +773,35 @@ uint8_t Camera::GetFrameSize() { * @return uint16_t */ uint16_t Camera::GetFrameSizeWidth() { - uint16_t ret = 0; - - switch (FrameSize) { - case 0: - ret = 320; - break; - case 1: - ret = 352; - break; - case 2: - ret = 640; - break; - case 3: - ret = 800; - break; - case 4: - ret = 1024; - break; - case 5: - ret = 1280; - break; - case 6: - ret = 1600; - break; - default: - ret = 320; - break; + uint16_t ret = 0; + + switch (FrameSize) { + case 0: + ret = 320; + break; + case 1: + ret = 352; + break; + case 2: + ret = 640; + break; + case 3: + ret = 800; + break; + case 4: + ret = 1024; + break; + case 5: + ret = 1280; + break; + case 6: + ret = 1600; + break; + default: + ret = 320; + break; } - + return ret; } @@ -820,7 +839,7 @@ uint16_t Camera::GetFrameSizeHeight() { case 5: ret = 1024; break; - case 6: + case 6: ret = 1200; break; default: @@ -1011,4 +1030,4 @@ uint16_t Camera::GetCameraFlashTime() { return CameraFlashTime; } -/* EOF */ +/* EOF */ \ No newline at end of file diff --git a/ESP32_PrusaConnectCam/camera.h b/ESP32_PrusaConnectCam/camera.h index 938ee25..ec33ffd 100644 --- a/ESP32_PrusaConnectCam/camera.h +++ b/ESP32_PrusaConnectCam/camera.h @@ -88,6 +88,7 @@ public: void CopyPhoto(camera_fb_t *); void CopyPhoto(String*); void CopyPhoto(String*, int, int); + void CopyPhoto(char*, int, int); int GetPhotoSize(); String GetPhoto(); camera_fb_t *GetPhotoFb(); diff --git a/ESP32_PrusaConnectCam/connect.cpp b/ESP32_PrusaConnectCam/connect.cpp index 2eb98bf..bd7c35c 100644 --- a/ESP32_PrusaConnectCam/connect.cpp +++ b/ESP32_PrusaConnectCam/connect.cpp @@ -36,7 +36,8 @@ PrusaConnect::PrusaConnect(Configuration *i_conf, Logs *i_log, Camera *i_camera) */ void PrusaConnect::Init() { log->AddEvent(LogLevel_Info, F("Init PrusaConnect lib")); - TakePicture(); + //camera->CapturePhoto(); + //camera->CaptureReturnFrameBuffer(); } /** @@ -83,7 +84,10 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i /* check fingerprint and token length */ if ((Fingerprint.length() > 0) && (Token.length() > 0)) { client.setCACert(root_CAs); + //client.setInsecure(); client.setTimeout(1000); + client.setNoDelay(true); + log->AddEvent(LogLevel_Verbose, F("Connecting to server...")); /* connecting to server */ @@ -102,7 +106,7 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i } else { /* send data to server */ log->AddEvent(LogLevel_Verbose, F("Connected to server!")); - client.println("PUT https://" + PrusaConnectHostname + i_url_path + " HTTP/1.0"); + client.println("PUT https://" + PrusaConnectHostname + i_url_path + " HTTP/1.1"); client.println("Host: " + PrusaConnectHostname); client.println("User-Agent: ESP32-CAM"); client.println("Connection: close"); @@ -114,32 +118,36 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i client.println(); esp_task_wdt_reset(); + size_t sendet_data = 0; /* sending photo */ if (SendPhoto == i_data_type) { log->AddEvent(LogLevel_Verbose, F("Send data photo")); - int index = 0; - /* send data in fragments */ - for (index = 0; index < i_data_length; index += PHOTO_FRAGMENT_SIZE) { - camera->CopyPhoto(i_data, index, index + PHOTO_FRAGMENT_SIZE); - client.print(*i_data); - log->AddEvent(LogLevel_Verbose, String(i_data_length) + "/" + String(index)); + + /* sending photo */ + uint8_t *fbBuf = camera->GetPhotoFb()->buf; + size_t fbLen = camera->GetPhotoFb()->len; + for (size_t i=0; i < fbLen; i += PHOTO_FRAGMENT_SIZE) { + if ((i + PHOTO_FRAGMENT_SIZE) < fbLen) { + sendet_data += client.write(fbBuf, PHOTO_FRAGMENT_SIZE); + fbBuf += PHOTO_FRAGMENT_SIZE; + + } else if ((fbLen % PHOTO_FRAGMENT_SIZE) > 0) { + size_t remainder = fbLen % PHOTO_FRAGMENT_SIZE; + sendet_data += client.write(fbBuf, remainder); + } } - /* send rest of data */ - index -= PHOTO_FRAGMENT_SIZE; - if ((i_data_length > index) && ((i_data_length - index) > 0)) { - camera->CopyPhoto(i_data, index, i_data_length); - client.print(*i_data); - log->AddEvent(LogLevel_Verbose, String(i_data_length) + "/" + String(i_data_length)); - } + client.println("\r\n"); + client.flush(); + log->AddEvent(LogLevel_Verbose, String(i_data_length) + "/" + String(sendet_data)); /* sending device information */ } else if (SendInfo == i_data_type) { log->AddEvent(LogLevel_Verbose, F("Send data info")); - client.print(*i_data); + sendet_data = client.print(*i_data); } - log->AddEvent(LogLevel_Info, "Send done: " + String(i_data_length) + " bytes"); + log->AddEvent(LogLevel_Info, "Send done: " + String(sendet_data) + " bytes"); esp_task_wdt_reset(); /* read response from server */ @@ -194,7 +202,7 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i void PrusaConnect::SendPhotoToBackend() { log->AddEvent(LogLevel_Info, F("Start sending photo to prusaconnect")); String Photo = ""; - SendDataToBackend(&Photo, camera->GetPhotoSize(), "image/jpg", "Photo", HOST_URL_CAM_PATH, SendPhoto); + SendDataToBackend(&Photo, camera->GetPhotoFb()->len, "image/jpg", "Photo", HOST_URL_CAM_PATH, SendPhoto); SystemLog.AddEvent(LogLevel_Info, "Free RAM: " + String(ESP.getFreeHeap()) + " bytes"); } @@ -241,8 +249,9 @@ void PrusaConnect::SendInfoToBackend() { * @return none */ void PrusaConnect::TakePictureAndSendToBackend() { - TakePicture(); + camera->CapturePhoto(); SendPhotoToBackend(); + camera->CaptureReturnFrameBuffer(); } /** diff --git a/ESP32_PrusaConnectCam/mcu_cfg.h b/ESP32_PrusaConnectCam/mcu_cfg.h index 3d8ca2c..d3ce39f 100644 --- a/ESP32_PrusaConnectCam/mcu_cfg.h +++ b/ESP32_PrusaConnectCam/mcu_cfg.h @@ -14,7 +14,7 @@ #define _MCU_CFG_H_ /* ---------------- BASIC MCU CFG --------------*/ -#define SW_VERSION "1.0.2-rc1" ///< SW version +#define SW_VERSION "1.0.2-rc2" ///< SW version #define SW_BUILD __DATE__ " " __TIME__ ///< build number #define CONSOLE_VERBOSE_DEBUG false ///< enable/disable verbose debug log level for console #define DEVICE_HOSTNAME "Prusa-ESP32cam" ///< device hostname @@ -55,7 +55,7 @@ #define WEB_SERVER_PORT 80 ///< WEB server port #define SERIAL_PORT_SPEED 115200 ///< baud rate #define WDG_TIMEOUT 40 ///< wdg timeout [second] -#define PHOTO_FRAGMENT_SIZE 5000 ///< photo fragmentation size [bytes] +#define PHOTO_FRAGMENT_SIZE 1024 ///< photo fragmentation size [bytes] #define LOOP_DELAY 100 ///< loop delay [ms] #define WIFI_CLIENT_WAIT_CON false ///< wait for connecting to WiFi network #define DYNMIC_JSON_SIZE 1024 ///< maximum size for dynamic json [bytes] diff --git a/ESP32_PrusaConnectCam/server.cpp b/ESP32_PrusaConnectCam/server.cpp index 2ca20e4..bdae811 100644 --- a/ESP32_PrusaConnectCam/server.cpp +++ b/ESP32_PrusaConnectCam/server.cpp @@ -40,6 +40,7 @@ void Server_InitWebServer() { if (Server_CheckBasicAuth(request) == false) return; + SystemLog.AddEvent(LogLevel_Verbose, "Photo size: " + String(SystemCamera.GetPhotoFb()->len) + " bytes"); request->send_P(200, "image/jpg", SystemCamera.GetPhotoFb()->buf, SystemCamera.GetPhotoFb()->len); }); @@ -667,7 +668,7 @@ void Server_InitWebServer_Sets() { } }); - /* route for set prusa connect hostname */ + /* route for set prusa connect hostname /set_hostname?hostname=*/ server.on("/set_hostname", HTTP_GET, [](AsyncWebServerRequest* request) { SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /set_hostname")); if (Server_CheckBasicAuth(request) == false) diff --git a/ESP32_PrusaConnectCam/system.cpp b/ESP32_PrusaConnectCam/system.cpp index 6f4ea29..bfd3fea 100644 --- a/ESP32_PrusaConnectCam/system.cpp +++ b/ESP32_PrusaConnectCam/system.cpp @@ -500,12 +500,14 @@ void System_TaskCaptureAndSendPhoto(void *pvParameters) { Connect.SetSendingIntervalCounter(0); /* send network information to backend */ if ((WL_CONNECTED == WiFi.status()) && (false == FirmwareUpdate.Processing)) { + SystemLog.AddEvent(LogLevel_Verbose, F("Task photo processing. Start sending info")); esp_task_wdt_reset(); Connect.SendInfoToBackend(); } /* send photo to backend*/ if ((WL_CONNECTED == WiFi.status()) && (false == FirmwareUpdate.Processing)) { + SystemLog.AddEvent(LogLevel_Verbose, F("Task photo processing. Start sending photo")); esp_task_wdt_reset(); Connect.TakePictureAndSendToBackend(); }