最簡單DIY基于ESP32CAM的物聯網相機系統系列文章目錄
第一篇:最簡單DIY基于ESP32CAM的物聯網相機系統①(用網頁實作拍照圖傳)
文章目錄
- 最簡單DIY基于ESP32CAM的物聯網相機系統系列文章目錄
- 前言
- 一、最簡單DIY基于ESP32CAM的物聯網相機系統①(用網頁實作拍照圖傳)是什么?
- 二、實作需求
- 1.搭建ESP32CAM開發環境
- 2.復制我寫好原創開源原始碼
- 三、運行與除錯
- 總結
前言
????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回傳圖片純凈十六進制內容,沒有其他東西多余的
webServer.send(200, "text/plain",mymsg);//在這里回傳圖片檔案給服務器,這個可以發送給C#的客戶端,也可以發給相機服務器接收
return;
}else{
String mymsg="error cmd!";
webServer.send(200, "text/plain",mymsg);//在這里回傳圖片檔案給服務器,這個可以發送給C#的客戶端,也可以發給相機服務器接收
}
String cmd="ssid="+wifis+" password="+wifip+" is OK";
webServer.send(200, "text/plain", cmd);//在這里回傳資料給客戶端
}
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
camera_init();
wifi_init();
webServer_init();
Serial.print("ESP32 index.html Ready! Use http://");
Serial.print(WiFi.softAPIP());
Serial.print(":");
Serial.print(String(serverPort0));
Serial.println(" to connect");
}
void loop() {
webServer.handleClient();
}
三、運行與除錯
(1)燒錄代碼開機

(2)開機就會在Arduino專屬串口監視器列印開機資訊如下:

(3)截圖顯示的代碼都是我寫的詳細中文注釋,只有兩個檔案,沒有額外的庫,不用擔心看不懂了,主要的功能是ESP32CAM開機會創建一個熱點,熱點的IP地址是:192.168.4.1,熱點的名稱是:daodanjishuiESP32CAM,沒有密碼,這是一個嵌入式服務器主頁地址,當你用手機連上這個高速WIFI熱點的時候,輸入網址:192.168.4.1就可以在手機的瀏覽器打開我寫的相機主頁如下圖:

(4)點擊send按鈕之后,就會發現構成jpg圖片的十六進制字串全部一股腦瞬間傳輸到瀏覽器上了,圖片資料以FFD8開頭,以FFD9結束,這是jpg壓縮格式的要求,實作了高速wifi控制和傳輸的遠程CAM相機拍照,速度幾乎是瞬間完成,因為攝像頭采集的資料不需要經過串口發送出去,直接在將ESP32記憶體的資料通過高速wifi發送到手機上瀏覽器上或者是電腦瀏覽器上,這跟串口圖傳有本質性的區別,如下圖所示:

(5)用電腦瀏覽器打開試試,再將圖片資料復制到一個圖片查看器軟體就可以看到原圖了(圖片查看器可以到最后鏈接下載):



除錯到此結束,根據結果可以滿足博文提出的要求,
總結
總結:物聯網相機網頁遠程控制拍照+高速WIFI無線圖傳的簡易方案就完成了,有很多讀者疑問為什么不直接在瀏覽器中顯示圖片出來呢?那么這就涉及到很高深的技術問題,更多需求和更多的功能請關注我下期相關系列的開源專案,絕對不會讓你們失望的,精彩值得期待,
免費代碼下載鏈接:https://www.cirmall.com/circuit/23966/
點我直接跳轉
圖片查看器下載鏈接:
點我直接跳轉
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295018.html
標籤:其他
上一篇:音箱語音互動技術,樂鑫ESP32-H2芯片應用,無線WiFi芯片模組
下一篇:充電樁物聯網卡具有什么樣的優勢?
