编辑
2026-04-30
软件编程
0

目录

IDE下载及配置
选择开发板
代码
以下为文章正文

警告

部分功能需要使用STEAM++。

IDE下载及配置

https://www.arduino.cc/en/software/

image.png

存档一份

098_arduino-ide_2.3.8_Windows_64bit.exe

ardunio更换代码格式中大括号的换行方式,使大括号单独占一行

创建以下文件

C:\Users\<你的用户名>\.arduinoIDE\.clang-format

注意前面有个点,且没有 .txt 后缀

文件内容如下

BreakBeforeBraces: Allman IndentWidth: 4

注:如果你还想顺便把缩进改成习惯的 4 个空格,可以在下面再加一行 IndentWidth: 4

安装ESP32开发包,文件-> 首选项->附加开发板管理器 输入

https://dl.espressif.cn/dl/package_esp32_index.json

image.png

工具-> 开发板->开发板管理器,搜索ESP32下载

image.png

选择开发板

代码

警告

基本功能已实现,等后续优化。

#include "esp_camera.h" #include "esp_system.h" #include <WiFi.h> #include <WiFiUdp.h> // 1. 引入 UDP 通信库 // ================= 需要修改的配置 ================= const char *ssid = "kellermen"; const char *password = "kellermen"; const char *tcpServerIP = "62.234.17.134"; const int tcpServerPort = 2007; char customFileName[32]; // 长度可变的特定字符串 const char *udpServerIP = "62.234.17.134"; // 目标IP地址 const int udpServerPort = 2000; // 目标端口号 const uint8_t updata_maxtime = 10; const int max_wait_time = 5; const int ioPin = 13; // ================================================ WiFiUDP Udp; // 2. 创建 WiFiUDP 对象 // ================================================ // 摄像头引脚定义(AI-Thinker 模组) #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 WiFiClient client; void setup() { Serial.begin(115200); // 连接WiFi WiFi.begin(ssid, password); Serial.print("正在连接WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } uint32_t chipId = 123456; for (int i = 0; i < 17; i = i + 8) { chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } snprintf(customFileName, sizeof(customFileName), "CAM_%08lu", chipId); Serial.printf("生成的动态文件名为: %s\n", customFileName); Serial.println("\nWiFi连接成功!"); Serial.print("ESP32-CAM的IP地址: "); Serial.println(WiFi.localIP()); // 初始化摄像头 camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; 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_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_VGA; config.jpeg_quality = 30; config.fb_count = 1; esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("摄像头初始化失败: 0x%x", err); return; } sensor_t *s = esp_camera_sensor_get(); // 开启垂直翻转和水平镜像,两者叠加即可实现 180 度旋转 s->set_vflip(s, 1); // 1 表示开启垂直翻转,0 表示关闭 s->set_hmirror(s, 1); // 1 表示开启水平镜像,0 表示关闭 Serial.println("摄像头初始化成功!"); pinMode(ioPin, INPUT); } uint8_t cam_delay = 65500; uint8_t updata_cnt = 0; void loop() { if (cam_delay < 65535) { cam_delay++; } if (updata_cnt < updata_maxtime) { updata_cnt++; } else { updata_cnt = 0; char sendtemp[200]; snprintf(sendtemp, sizeof(sendtemp), "#baotou#driveupdata#%s#door#m#p#o#0#1#2#3#4#5#6#7#8#9#", customFileName); Udp.beginPacket(udpServerIP, udpServerPort); Udp.print(sendtemp); // 将 write 替换为 print Udp.endPacket(); Serial.println("已发送 UDP 消息"); } int state = digitalRead(ioPin); // 判断并打印结果 if (state == HIGH) { } else { Serial.println("低电平"); if (cam_delay > max_wait_time) { cam_delay = 0; } else { Serial.print(cam_delay); Serial.print("-"); Serial.print(max_wait_time); Serial.println("放弃..."); delay(1000); return; } // 拍照 Serial.println("正在拍摄照片..."); camera_fb_t *fb_old = esp_camera_fb_get(); if (fb_old) { esp_camera_fb_return(fb_old); // 获取后直接释放 delay(500); // 稍微给传感器一点缓冲时间 } camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("拍照失败!"); ESP.restart(); return; } Serial.print("正在连接TCP服务器..."); if (!client.connect(tcpServerIP, tcpServerPort)) { Serial.println("连接失败,5秒后重试..."); delay(5000); return; } Serial.println("连接成功!"); // 1. 获取字符串长度,并先发送 1 个字节的长度信息 uint8_t nameLen = strlen(customFileName); client.write(&nameLen, 1); Serial.printf("正在发送字符串长度: %d\n", nameLen); // 2. 发送特定字符串的内容 Serial.printf("正在发送特定字符串: %s\n", customFileName); client.print(customFileName); // 3. 延时 1 秒 (1000毫秒) delay(1000); // 4. 发送JPEG图片的原始二进制数据 size_t sentBytes = client.write(fb->buf, fb->len); Serial.printf("照片发送完成!实际发送图片数据: %d / %d bytes\n", sentBytes, fb->len); // 释放摄像头缓冲区 esp_camera_fb_return(fb); // 主动断开TCP连接 client.stop(); Serial.println("TCP连接已断开。\n"); char sendtemp[200]; snprintf(sendtemp, sizeof(sendtemp), "#baotou#control#wechat#%s#data0#data1#data2#data3#data4#" "data5#data6#data7#data8#data9#", customFileName); Udp.beginPacket(udpServerIP, udpServerPort); Udp.print(sendtemp); // 将 write 替换为 print Udp.endPacket(); Serial.println("已发送 UDP 消息"); } delay(1000); // 等待1秒 }

以上为文章正文

本文作者:Kellermen

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!