Pārlūkot izejas kodu

完成文件上传(我自己的接口,后面会失效)

xuxinyi 8 mēneši atpakaļ
vecāks
revīzija
134db23958
2 mainītis faili ar 141 papildinājumiem un 173 dzēšanām
  1. 1 11
      main/app_main.c
  2. 140 162
      main/camera.c

+ 1 - 11
main/app_main.c

@@ -25,16 +25,6 @@ void app_main(void)
 
     // 等待Wi-Fi连接
     vTaskDelay(10000 / portTICK_PERIOD_MS);
+    xTaskCreate(take_photo, "take_photo", 1024 * 50, NULL, 20, NULL);
 
-    take_photo();
-    vTaskDelay(4*1000 / portTICK_PERIOD_MS);
-    ESP_LOGI(TAG, "测试");
-
-    while (true)
-    {
-        /* code */
-        // 执行HTTP GET请求
-        vTaskDelay(4*1000 / portTICK_PERIOD_MS);
-    }
-    
 }

+ 140 - 162
main/camera.c

@@ -1,142 +1,19 @@
-/**
- * This example takes a picture every 5s and print its size on serial monitor.
- */
-
-// =============================== SETUP ======================================
-
-// 1. Board setup (Uncomment):
-// #define BOARD_WROVER_KIT
-// #define BOARD_ESP32CAM_AITHINKER
-// #define BOARD_ESP32S3_WROOM
-
-/**
- * 2. Kconfig setup
- *
- * If you have a Kconfig file, copy the content from
- *  https://github.com/espressif/esp32-camera/blob/master/Kconfig into it.
- * In case you haven't, copy and paste this Kconfig file inside the src directory.
- * This Kconfig file has definitions that allows more control over the camera and
- * how it will be initialized.
- */
-
-/**
- * 3. Enable PSRAM on sdkconfig:
- *
- * CONFIG_ESP32_SPIRAM_SUPPORT=y
- *
- * More info on
- * https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support
- */
-
-// ================================ CODE ======================================
-
 #include <esp_log.h>
 #include <esp_system.h>
 #include <nvs_flash.h>
 #include <sys/param.h>
 #include <string.h>
-
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
-
-// support IDF 5.x
-#ifndef portTICK_RATE_MS
-#define portTICK_RATE_MS portTICK_PERIOD_MS
-#endif
-
+#include "esp_http_client.h"
 #include "esp_camera.h"
 
-#define ESP32_S3_HEZHOU 1 //ESP32-S3-KORVO-2_V3.0配套的自定义引脚
-
-// WROVER-KIT PIN Map
-#ifdef BOARD_WROVER_KIT
-
-#define CAM_PIN_PWDN -1  //power down is not used
-#define CAM_PIN_RESET -1 //software reset will be performed
-#define CAM_PIN_XCLK 21
-#define CAM_PIN_SIOD 26
-#define CAM_PIN_SIOC 27
-
-#define CAM_PIN_D7 35
-#define CAM_PIN_D6 34
-#define CAM_PIN_D5 39
-#define CAM_PIN_D4 36
-#define CAM_PIN_D3 19
-#define CAM_PIN_D2 18
-#define CAM_PIN_D1 5
-#define CAM_PIN_D0 4
-#define CAM_PIN_VSYNC 25
-#define CAM_PIN_HREF 23
-#define CAM_PIN_PCLK 22
-
-#endif
-
-// ESP32Cam (AiThinker) PIN Map
-#ifdef BOARD_ESP32CAM_AITHINKER
-
-#define CAM_PIN_PWDN 32
-#define CAM_PIN_RESET -1 //software reset will be performed
-#define CAM_PIN_XCLK 0
-#define CAM_PIN_SIOD 26
-#define CAM_PIN_SIOC 27
-
-#define CAM_PIN_D7 35
-#define CAM_PIN_D6 34
-#define CAM_PIN_D5 39
-#define CAM_PIN_D4 36
-#define CAM_PIN_D3 21
-#define CAM_PIN_D2 19
-#define CAM_PIN_D1 18
-#define CAM_PIN_D0 5
-#define CAM_PIN_VSYNC 25
-#define CAM_PIN_HREF 23
-#define CAM_PIN_PCLK 22
-
-#endif
-// ESP32S3 (WROOM) PIN Map
-#ifdef BOARD_ESP32S3_WROOM
-#define CAM_PIN_PWDN 38
-#define CAM_PIN_RESET -1   //software reset will be performed
-#define CAM_PIN_VSYNC 6
-#define CAM_PIN_HREF 7
-#define CAM_PIN_PCLK 13
-#define CAM_PIN_XCLK 15
-#define CAM_PIN_SIOD 4
-#define CAM_PIN_SIOC 5
-#define CAM_PIN_D0 11
-#define CAM_PIN_D1 9
-#define CAM_PIN_D2 8
-#define CAM_PIN_D3 10
-#define CAM_PIN_D4 12
-#define CAM_PIN_D5 18
-#define CAM_PIN_D6 17
-#define CAM_PIN_D7 16
-#endif
-
-// ESP32-S3-KORVO-2_V3.0 音频开发版
-#ifdef ESP32_S3_KORVO
-#define CAM_PIN_PWDN -1 //没用直接接高
-#define CAM_PIN_RESET -1   //software reset will be performed
-#define CAM_PIN_VSYNC 21
-#define CAM_PIN_HREF 38
-#define CAM_PIN_PCLK 11
-#define CAM_PIN_XCLK 40
-#define CAM_PIN_SIOD 17
-#define CAM_PIN_SIOC 18
-#define CAM_PIN_D0 13
-#define CAM_PIN_D1 47
-#define CAM_PIN_D2 14
-#define CAM_PIN_D3 3
-#define CAM_PIN_D4 12
-#define CAM_PIN_D5 42
-#define CAM_PIN_D6 41
-#define CAM_PIN_D7 39
-#endif
+#define ESP32_S3_HEZHOU 1  // ESP32-S3-KORVO-2_V3.0配套的自定义引脚
 
 // ESP32-S3-合宙的开发板
 #ifdef ESP32_S3_HEZHOU
-#define CAM_PIN_PWDN -1 //没用直接接高
-#define CAM_PIN_RESET -1   //software reset will be performed
+#define CAM_PIN_PWDN -1      // 没用直接接高
+#define CAM_PIN_RESET -1     // software reset will be performed
 #define CAM_PIN_VSYNC 42
 #define CAM_PIN_HREF 41
 #define CAM_PIN_PCLK 36
@@ -154,15 +31,14 @@
 #endif
 
 static const char *TAG = "example:take_picture";
+#define BOUNDARY "----ESP32Boundary"
 
-#if ESP_CAMERA_SUPPORTED
 static camera_config_t camera_config = {
     .pin_pwdn = CAM_PIN_PWDN,
     .pin_reset = CAM_PIN_RESET,
     .pin_xclk = CAM_PIN_XCLK,
     .pin_sccb_sda = CAM_PIN_SIOD,
     .pin_sccb_scl = CAM_PIN_SIOC,
-
     .pin_d7 = CAM_PIN_D7,
     .pin_d6 = CAM_PIN_D6,
     .pin_d5 = CAM_PIN_D5,
@@ -174,60 +50,162 @@ static camera_config_t camera_config = {
     .pin_vsync = CAM_PIN_VSYNC,
     .pin_href = CAM_PIN_HREF,
     .pin_pclk = CAM_PIN_PCLK,
-
     .xclk_freq_hz = 20000000,  // XCLK 设置为 20MHz
     .ledc_timer = LEDC_TIMER_0,
     .ledc_channel = LEDC_CHANNEL_0,
-
-    .pixel_format = PIXFORMAT_JPEG, // RGB565 格式
-    .frame_size = FRAMESIZE_QVGA,     // 使用 QVGA (320x240)
-
-    .jpeg_quality = 2,   // JPEG 质量 (0-63, 低值=高质量)
-    .fb_count = 1,        // 降低到 2,减少 DRAM 负载
-    .fb_location = CAMERA_FB_IN_DRAM,  // 使用 DRAM (无 PSRAM)
+    .pixel_format = PIXFORMAT_JPEG, // 使用 JPEG 格式
+    .frame_size = FRAMESIZE_QVGA,    // 使用 QVGA (320x240)
+    .jpeg_quality = 20,   // JPEG 质量 (0-63, 低值=高质量)
+    .fb_count = 1,       // 帧缓存数量
+    .fb_location = CAMERA_FB_IN_DRAM, // 使用 DRAM
     .grab_mode = CAMERA_GRAB_WHEN_EMPTY,
 };
 
 static esp_err_t init_camera(void)
 {
-    //initialize the camera
     esp_err_t err = esp_camera_init(&camera_config);
     if (err != ESP_OK)
     {
         ESP_LOGE(TAG, "Camera Init Failed");
         return err;
     }
-
     return ESP_OK;
 }
-#endif
 
-void take_photo(void)
+// 上传图片到服务器
+#define MULTIPART_BOUNDARY "----WebKitFormBoundary7MA4YWxkTrZu0gW"  // 多部分表单的边界
+
+esp_err_t upload_picture(camera_fb_t *pic, long image_size)
 {
-#if ESP_CAMERA_SUPPORTED
-    if(ESP_OK != init_camera()) {
+    esp_http_client_config_t config = {
+        .url = "http://60.204.139.57:7002/upload",  // 服务器地址
+        .timeout_ms = 5000,
+        .buffer_size = 1024 * 16,
+    };
+
+    // 初始化 HTTP 客户端
+    esp_http_client_handle_t client = esp_http_client_init(&config);
+    if (client == NULL) {
+        ESP_LOGE(TAG, "Failed to initialize HTTP client");
+        return ESP_FAIL;
+    }
+
+    esp_http_client_set_method(client, HTTP_METHOD_POST);
+    // 设置请求头(multipart/form-data)
+    esp_http_client_set_header(client, "Content-Type", "multipart/form-data; boundary=" MULTIPART_BOUNDARY);
+
+    // 请求头开始部分
+    char part1[256];
+    int part1_len = snprintf(part1, sizeof(part1),
+                             "--" MULTIPART_BOUNDARY "\r\n"
+                             "Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n"
+                             "Content-Type: image/jpeg\r\n\r\n");
+
+    // 构建多部分表单数据的结束部分
+    char part2[64];
+    int part2_len = snprintf(part2, sizeof(part2), "\r\n--" MULTIPART_BOUNDARY "--\r\n");
+
+    // 设置总的Content-Length
+    long content_length = part1_len + image_size + part2_len;
+    char content_length_str[32];
+    snprintf(content_length_str, sizeof(content_length_str), "%ld", content_length);
+    esp_http_client_set_header(client, "Content-Length", content_length_str);
+
+    // 开始发送请求
+    int err = esp_http_client_open(client, content_length);
+    if (err != ESP_OK)
+    {
+        ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
+        esp_http_client_cleanup(client); // 清理 HTTP 客户端
+        return ESP_FAIL;
+    }
+
+    // 发送多部分表单数据的开始部分
+    esp_http_client_write(client, part1, part1_len);
+
+    // 发送文件数据
+    char buffer[1024];
+    size_t bytes_sent = 0;
+    while (bytes_sent < pic->len)
+    {
+        size_t to_send = (pic->len - bytes_sent < sizeof(buffer)) ? (pic->len - bytes_sent) : sizeof(buffer);
+        esp_http_client_write(client, (const char *)(pic->buf + bytes_sent), to_send);
+        bytes_sent += to_send;
+    }
+
+    // 发送多部分表单数据的结束部分
+    esp_http_client_write(client, part2, part2_len);
+
+    int response_length = esp_http_client_fetch_headers(client);
+    if (response_length < 0)
+    {
+        ESP_LOGE(TAG, "HTTP client fetch headers failed");
+    }
+    else
+    {
+        ESP_LOGI(TAG, "HTTP client fetch headers succeeded, length=%d", response_length);
+    }
+
+    // 动态分配初始缓冲区
+    char *response_buffer = (char *)malloc(1024);
+    if (response_buffer == NULL)
+    {
+        ESP_LOGE(TAG, "Failed to allocate memory for response buffer");
+        esp_http_client_cleanup(client);
+        return ESP_FAIL;
+    }
+
+    // 读取响应内容
+    int read_len = esp_http_client_read(client, response_buffer, 1024 - 1);
+    if (read_len >= 0)
+    {
+        response_buffer[read_len] = '\0'; // 确保字符串以null字符结尾
+        ESP_LOGI(TAG, "HTTP Response: %s", response_buffer);
+    }
+    else
+    {
+        ESP_LOGE(TAG, "Failed to read response");
+    }
+
+    // 释放分配的内存
+    free(response_buffer);
+
+    // 清理
+    esp_http_client_close(client);
+    esp_http_client_cleanup(client);
+
+    return err;
+}
+
+
+
+// 拍照并上传
+void take_photo(void *param)
+{
+    if (ESP_OK != init_camera())
+    {
         return;
     }
 
-    while (1)
+    ESP_LOGI(TAG, "Taking picture...");
+    camera_fb_t *pic = esp_camera_fb_get();
+    if (pic == NULL)
     {
-        ESP_LOGI(TAG, "Taking picture...");
-        camera_fb_t *pic = esp_camera_fb_get();
-        if ( pic == NULL) 
-        {
-            /* code */
-            ESP_LOGE(TAG, "Camera capture failed");
-            return; 
-        }
-        
-        // use pic->buf to access the image
-        ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
-        esp_camera_fb_return(pic);
-
-        vTaskDelay(5000 / portTICK_RATE_MS);
+        ESP_LOGE(TAG, "Camera capture failed");
+        return;
     }
-#else
-    ESP_LOGE(TAG, "Camera support is not available for this chip");
-    return;
-#endif
+
+    ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
+
+    // 上传图片
+    esp_err_t err = upload_picture(pic,pic->len);
+    if (err != ESP_OK)
+    {
+        ESP_LOGE(TAG, "Failed to upload picture");
+    }
+
+    vTaskDelay(600*1000 / portTICK_PERIOD_MS);
+
+    vTaskDelete(NULL);
 }
+