|
|
@@ -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);
|
|
|
}
|
|
|
+
|