ESP32 之 esp32-cam wifi拍照传图系统
1.效果演示
2.材料准备
- ESP32-cam
- USB转TTL
- 按钮x2 开关x2
3.原理图接线
GND - GND
TX - RX
RX - TX
VCC - 5V
GPIO_0 - GND 下载模式
GPIO_0 不接线 运行模式
4.下载代码
- 需要提前搭建Arduino环境,在这就不多说,在这里要注意安装好程序相关的库
代码下载,主函数代码如下
#include "camera_pins.h"
// 你的wifi账号密码
const char* ssid = "DY";
const char* password = "1403119048";
// 在端口80上创建AsyncWebServer对象
AsyncWebServer server(80);
boolean takeNewPhoto = false;
bool LED_flag = false;
void setup() {
Serial.begin(115200); //串口初始化
pinMode(LED_1, OUTPUT); //初始化 LED
pinMode(KEY_1, INPUT); //按键1初始化
pinMode(KEY_2, INPUT); //按键2初始化
WiFi.begin(ssid, password); //连接wifi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
if (!SPIFFS.begin(true)) { //初始化SPIFFS
Serial.println("An Error has occurred while mounting SPIFFS");
ESP.restart();}
else {
delay(500);
Serial.println("SPIFFS mounted successfully");
}
//Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// Camera initOV2640 camera module
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;
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
ESP.restart();
}
// 路由主页
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html);
});
//路由抓拍
server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
takeNewPhoto = true;
request->send_P(200, "text/plain", "Taking Photo");
});
//
server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
});
//路由控制LED开关
server.on("/LED", HTTP_GET, [](AsyncWebServerRequest * request) {
LED_flag =!LED_flag;
digitalWrite(LED_1, LED_flag);
});
// 启动服务器
server.begin();
Serial.print("IP Address: http://"); //打印IP地址用于服务器连接
Serial.println(WiFi.localIP());
}
void loop() {
//判断是否抓拍
if (takeNewPhoto) {
capturePhotoSaveSpiffs();
takeNewPhoto = false;
}
//串口接收指令
while(Serial.available()){
char c=Serial.read();
if(c=='1'){//开关LED
LED_flag =!LED_flag;
digitalWrite(LED_1, LED_flag);
Serial.write("1\n");//返回到调试程序上
}
else if(c=='2') {//拍照
takeNewPhoto = true;
Serial.write("2\n");//返回到调试程序上
}
}
//=====按键扫描=====
int key_val = KEY_Scan();
if(key_val == 1){ //按键1按下
digitalWrite(LED_1, HIGH);
takeNewPhoto = true;
delay(500);
digitalWrite(LED_1, LOW);
}
if(key_val == 2){ //按键2按下
LED_flag =!LED_flag;
digitalWrite(LED_1, LED_flag);
}
delay(1);
}
// 检查照片捕获是否成功
bool checkPhoto( fs::FS &fs ) {
File f_pic = fs.open( FILE_PHOTO );
unsigned int pic_sz = f_pic.size();
return ( pic_sz > 100 );
}
// 捕捉照片并保存到SPIFFS
void capturePhotoSaveSpiffs( void ) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // 布尔值指示图片是否被正确拍摄
do {
// 用照相机拍照
Serial.println("Taking a photo...");
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
//照片文件名称
Serial.printf("Picture file name: %s\n", FILE_PHOTO);
File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE);
// 插入照片文件中的数据
if (!file) {
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO);
Serial.print(" - Size: ");
Serial.print(file.size());
Serial.println(" bytes");
}
// 关闭文件
file.close();
esp_camera_fb_return(fb);
// 检查文件是否正确地保存在SPIFFS中
ok = checkPhoto(SPIFFS);
} while ( !ok );
//将文件保存到SD卡当中
}
//按键扫描
int KEY_Scan(void)
{
static int key_up = 1;//按键按松开标志
if(key_up && (digitalRead(KEY_1) == 0 || digitalRead(KEY_2) == 0 ))
{
delay(10);//去抖动
key_up=0;
if(digitalRead(KEY_1) == 0)return 1;
if(digitalRead(KEY_2) == 0)return 2;
}else if( digitalRead(KEY_1) == 1 || digitalRead(KEY_2) == 1)key_up=1;
return 0; // 无按键按下
}