最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)
Posted daodanjishui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)相关的知识,希望对你有一定的参考价值。
最简单DIY基于ESP32CAM的物联网相机系统系列文章目录
第一篇:最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)
文章目录
前言
daodanjishui物联网核心原创技术之最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)。
发布这篇博文的季节是我发布第一个ESP32教程的第一周年纪念时期,翻看我备份的第一个源码是2020.5.23,也说明了周年纪念日也是我接触和入门ESP32的周年纪念日。而ESP32CAM这个款单片机在国内确实用得不多,使用者和开发者也不多,所以说在网上学习的资源更是少之又少,甚至能搜到的教程还有我自己出品的,ESP32CAM是一个待开发的新大陆,在这里我要创立一个:最简单DIY基于ESP32CAM的物联网相机系统系列专栏记录下我原创开源的幸福瞬间。
因为这个ESP32,所以我才接触了Arduino这个调包调库的IDE。以前十年的嵌入式积累也比不上使用这个IDE能达到的高度,几天时间就可以编写出一个成型的电子设计。呵呵,但是也感谢我十年前没有接触这个Arduino集成开发环境,因为不断地“吃快餐”和“拿来主义”会让我提前“发育不良”。嵌入式开发的功力来源于时间积累而不是一个开发工具。当一个嵌入式开发人员“成年”之后,再吃“Arduino快餐”,你会发现节约时间和精力又不影响“发育”,确实是一件美差事,这时候要底层技术有底层技术,要调包调库也轻轻松松,到了这样的地步,其实感觉嵌入式开发也没有人们想象中那么痛苦吧。
现在很多学校直接教授高级语言:C++、Python、Java等等,甚至都越过底层的C语言,甚至很多同学觉得连最基本的C语言版本的socket套接字编程变得比登天还难。社会的需求也造就了“吃快餐”环境,嵌入式开发的岗位工资比前端开发的工资少了至少5K。在国内献身于嵌入式的人才不多,大多数到半途就转行了,太残酷了。市面上活跃的总是那些用java写的网络斗地主,安卓客户端运行的麻辣炸金花,普通上班族下班之后玩玩斗地主,看看网络主播小视频打赏下主播也成了平常事。
那么网上虚拟的东西那么多?哪些会用到嵌入式开发的知识呢?是不是嵌入式开发钱途渺茫呢?芯片又那么贵,硬件又那么烧钱,那么daodanjishui还要开个“最简单DIY基于ESP32CAM的物联网相机系统”CSDN专栏还有意义么?目前来说,物联网时代的来临,各种嵌入式实时操作系统能够在廉价的单片机上运行,还有鸿蒙系统的出炉,虽然很多友商不愿意基于鸿蒙开发产品,但是该系统给国内物联网技术注入新鲜的血液,有些人会说其实很少人用鸿蒙系统来开发嵌入式的吧,目前确实是这个情况。但是现在物联网技术的应用确实很广泛:平衡车、自动售卖机、共享电车、共享汽车、共享充电宝、共享按摩椅、智慧屏、广告屏、智能监控摄像头、智能手环、智能秤、机顶盒、智能路由器、智能家居和还有我正在推出的智能彩灯,闭着眼睛都能数出一大堆未来将要流行起来的高性价比的电子设备。随着“共享时代”和“物联网时代”的悄悄来临,国内以物联网形态下的嵌入式开发将会迎来新的发展时机。作为嵌入式技术的开发人员如果真的能坚持下来咬住青山不放松,我坚信属于他们的春天即将会到来的。
一、最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)是什么?
在我的一篇博文:高性价比WIFI图传方案快速入门教程因为我只用了170行代码实现了嵌入式服务器ESP32高速wifi图传,在CSDN很多博主还在采用以前那个硬件串口线传输STM32单片机驱动的OV7670摄像头模块采集的图片,价格昂贵带FIFO的OV7670单摄像头就50块,STM32单片机的价格我还没有计算呢!ST公司芯片涨价了,STM32价格贵到离谱,成本也高,OV7670的像素才30万,图像也不清晰,还有些博主用ESP8266来传输STM32驱动OV7670拍摄的图片,这样用了三片单片机才完成无线图传,太麻烦了。
而我这个ESP32CAM搭载的是OV 2640高清摄像头像素达到130万,ESP32+OV2640在某宝价格才24块,国产芯片不会受到芯片涨价潮流而涨价,并且我ESP32CAM的Arduino开发环境下的库自带摄像头SCCB控制总线的方案,把底层驱动剥离开来,要是用STM32来驱动摄像头,要在SCCB上下功夫了,而在ESP32CAM的摄像头二次开发上,开发者能在上层应用上开发自己喜欢的功能,非常潮流,只是国内用的人少,大部分国内开发者跑了老外对这个国产芯片写的摄像头测试程序,想起来都觉得尴尬,ESP32相比ESP8266的WIFI传输速度快了很多,处理速度也快了很多。在我这里,读者可以学到一个系列的中文版本的物联网ESP32CAM高清高速摄像头二次开发的原创开源核心技术,攻破上位机和下位机和服务器的开发。
回到正题,本文要用ESP32CAM和摄像头实现在嵌入式主页(网页)采集图片信息显示在网页上,提取网页的图像信息,解码显示出图片。
二、实现需求
1.搭建ESP32CAM开发环境
前面的博文写过详细的搭建步骤了:https://blog.csdn.net/niruxi0401/article/details/118500369
直接跳转
2.复制我写好原创开源源码
通过用Arduino新建工程粘贴我的源码即可
第一个文件
camera_pins.h
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#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 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_ESP_EYE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_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
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
#define PWDN_GPIO_NUM 0
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#else
#error "Camera model not selected"
#endif
第二个文件:CameraWebServer.ino
//国内ESP32CAM物联网相机开源项目
//作者:daodanjishui
//时间:2021.4.18
//QQ:
#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiClient.h>
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
#include "camera_pins.h"
IPAddress apIP(192, 168, 4, 1);//ESP32主页的IP地址,写死了地址
const int serverPort0 = 80;//ESP32主页的端口号
WebServer webServer(serverPort0);
String msg;//图片信息字符串
//网页函数,传入参数是服务器IP,返回的是网页字符串
//首页示例网址,http://192.168.4.1
//采集图像信息网址,http://192.168.4.1/HandleVal?ssid=snapshot&password=daodanjishui
String index_html(String WiFiAddr){
return String("")+"<html> <meta http-equiv=\\"Content-Type\\" content=\\"text/html; charset=utf-8\\" /"+
"<head><meta http-equiv=\\"Content-Type\\" content=\\"text/html; charset=UTF-8\\">"+
"</head>"+
"<body>"+
"<h1>daodanjishui 经典图传程序</h1>"+
"<p></p> <form action=\\"HandleVal\\" method=\\"\\" name=\\"\\" >第一个参数是snapshot,第二个参数是daodanjishui,点击send发送图片给ESP主页<br>"+
"<input type=\\"text\\" value=\\"snapshot\\" name=\\"ssid\\" id=\\"cmd\\" size=\\"10\\" maxlength=\\"20\\">"+
"<input type=\\"text\\" value=\\"daodanjishui\\" name=\\"password\\" id=\\"cmd1\\" size=\\"10\\" maxlength=\\"20\\">"+
"<input type=\\"submit\\" value=\\"send\\" ><br>"+
"<h2>daodanjishui 原创经典值得期待!</h2>"+
" </form>"+
"</body>"+
"</html>";
}
void camera_init();
void wifi_init();
void webServer_init();
void handleRoot();
String getsnapshotstring();//给客户端发送图片十六进制字符串数据,没有多余的字符串
String getsnapshotstring(){//这个函数的功能是在ESP32的主页输入serial返回图片纯净十六进制字符串
camera_fb_t *fb = esp_camera_fb_get();
if (fb){
//Serial.printf("width: %d, height: %d, buf: 0x%x, len: %d\\n", fb->width, fb->height, fb->buf, fb->len);
char data[10];
msg = "";
for (int i = 0; i < fb->len; i++)
{
sprintf(data, "%02X", *((fb->buf + i)));
msg += data;
}
if (msg.length()>0){
Serial.print(msg);//直接打印十六进制的字符串,客户端不能直接解码
}
esp_camera_fb_return(fb);
return msg;//这个图片信息字符串是给浏览器查看的
}
return "";
}
void camera_init(){
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 PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
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;
}
#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
sensor_t * s = esp_camera_sensor_get();
// initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_vflip(s, 1); // flip it back
s->set_brightness(s, 1); // up the brightness just a bit
s->set_saturation(s, -2); // lower the saturation
}
// drop down frame size for higher initial frame rate
s->set_framesize(s, FRAMESIZE_QVGA);
#if defined(CAMERA_MODEL_M5STACK_WIDE)
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
#endif
}
void wifi_init(){
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP("dandaojishui ESP32CAM");
WiFi.begin();
Serial.println("AP is ok");
}
void webServer_init(){
webServer.on("/", HTTP_GET,handleRoot);//显示主页
webServer.on("/HandleVal", HTTP_GET, HandleVal);//接收配网提交的参数
webServer.onNotFound([]() {
String message = "Hello daodanjishui!\\n\\n";
message += "URI: ";
message += webServer.uri();
webServer.send(200, "text/plain", message);
});
webServer.begin();
Serial.println("webServer is ok");
}
void handleRoot() {//对客户端请求返回值处理
webServer.send(200, "text/html", index_html("192.168.4.1")); //!!!注意返回网页需要用"text/html" !!!
Serial.println("用户访问了ESP32主页");
}
void HandleVal()//对客户端请求返回值处理
{
String wifis = webServer.arg("ssid"); //从javascript发送的数据中找ssid的值
String wifip = webServer.arg("password"); //从JavaScript发送的数据中找password的值
if(wifis.equals("snapshot")){
String mymsg=getsnapshotstring();//这个函数的功能是在ESP32的主页输入serial返回以上是关于最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传)的主要内容,如果未能解决你的问题,请参考以下文章
最简单DIY基于ESP32CAM的物联网相机系统⑥(用上位机VS2013 MFC实现WIFI图传)