| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #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"
- #include "esp_http_client.h"
- #include "esp_camera.h"
- #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_VSYNC 42
- #define CAM_PIN_HREF 41
- #define CAM_PIN_PCLK 36
- #define CAM_PIN_XCLK 39
- #define CAM_PIN_SIOD 21
- #define CAM_PIN_SIOC 46
- #define CAM_PIN_D0 34
- #define CAM_PIN_D1 47
- #define CAM_PIN_D2 48
- #define CAM_PIN_D3 33
- #define CAM_PIN_D4 35
- #define CAM_PIN_D5 37
- #define CAM_PIN_D6 38
- #define CAM_PIN_D7 40
- #endif
- static const char *TAG = "example:take_picture";
- #define BOUNDARY "----ESP32Boundary"
- 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,
- .pin_d4 = CAM_PIN_D4,
- .pin_d3 = CAM_PIN_D3,
- .pin_d2 = CAM_PIN_D2,
- .pin_d1 = CAM_PIN_D1,
- .pin_d0 = CAM_PIN_D0,
- .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, // 使用 JPEG 格式
- .frame_size = FRAMESIZE_SVGA, // 使用 QVGA (320x240)
- .jpeg_quality = 60, // 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)
- {
- esp_err_t err = esp_camera_init(&camera_config);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Camera Init Failed");
- return err;
- }
- return ESP_OK;
- }
- // 上传图片到服务器
- #define MULTIPART_BOUNDARY "----WebKitFormBoundary7MA4YWxkTrZu0gW" // 多部分表单的边界
- esp_err_t upload_picture(camera_fb_t *pic, long image_size)
- {
- 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;
- }
- ESP_LOGI(TAG, "Taking picture...");
- camera_fb_t *pic = esp_camera_fb_get();
- if (pic == NULL)
- {
- ESP_LOGE(TAG, "Camera capture failed");
- return;
- }
- 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);
- }
|