ESP32CAM 使用 MQTT 傳拍照圖到 FastWeb 平臺
ESP32是樂鑫在ESP8266後推出的一款集成WiFi功能的微控制器,相較於ESP8266,ESP32擁有更強大的性能,可用于複雜應用的開發。
ESP32CAM在ESP32的基礎上擴展了攝像頭模組,體積極小,可廣泛應用於各種物聯網場合,適用于家庭智慧設備、工業無線控制、無線監控、QR無線識別,無線定位系統信號以及其它物聯網應用,是物聯網應用的理想解決方案。
MQTT是一種基於發佈/訂閱模式的羽量級通訊協定,它的特點是可使用極少的代碼與有限的頻寬為遠端連接的設備提供即時可靠的消息訂閱服務,被廣泛應用於物聯網運用。MQTT單條報文允許的最大體積為 256 M,ESP32CAM拍攝的圖片的體積大小遠小於這個數值,可以考慮使用MQTT協定來傳輸圖片。
那麼,要如何將ESP32CAM獲取的圖片通過MQTT進行傳輸呢?可參考以下資訊進行設置。
使用Arduino IDE 編譯並上傳以下Arduino程式。該程式使用的是esp32開發板,需要在Arduino IDE中添加安裝該開發板環境,並在編譯時選擇開發板環境為ESP32系列開發板。在Arduino IDE中添加ESP32開發板環境。注意燒錄時ESP32CAM的開發板中IO0針腳需要進行接地操作,否則會導致刷寫失敗。
#include "WiFi.h" #include "esp_camera.h" #include "esp_timer.h" #include "img_converters.h" #include "Arduino.h" #include "soc/soc.h" // Disable brownour problems #include "soc/rtc_cntl_reg.h" // Disable brownour problems #include "driver/rtc_io.h" //#include "StringArray.h" #include <PubSubClient.h> #include <base64.h> #include <libb64/cencode.h> //esp32-cam針腳定義 拍照相關 constexpr int kCameraPin_PWDN = 32; constexpr int kCameraPin_RESET = -1; // NC constexpr int kCameraPin_XCLK = 0; constexpr int kCameraPin_SIOD = 26; constexpr int kCameraPin_SIOC = 27; constexpr int kCameraPin_Y9 = 35; constexpr int kCameraPin_Y8 = 34; constexpr int kCameraPin_Y7 = 39; constexpr int kCameraPin_Y6 = 36; constexpr int kCameraPin_Y5 = 21; constexpr int kCameraPin_Y4 = 19; constexpr int kCameraPin_Y3 = 18; constexpr int kCameraPin_Y2 = 5; constexpr int kCameraPin_VSYNC = 25; constexpr int kCameraPin_HREF = 23; constexpr int kCameraPin_PCLK = 22; // 此處需替換連接的無線網路為自己使用的無線網路 const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; // 此處需替換MQTT服務端為自己使用的服務端 const char* mqtt_server = "YOUR_MQTT_BROKER_HOSTNAME"; const int mqtt_port = 1883; const char* mqtt_user = "YOUR_MQTT_BROKER_USERNAME"; const char* mqtt_password = "YOUR_MQTT_BROKER_PASSWORD"; //設置主題 const char* mqtt_TopicName = "/devices/esp32/data"; //設置相機幀的解析度大小 framesize_t resolution_ = FRAMESIZE_QVGA; //定義延時時間1000=1s #define SLEEP_DELAY 60000 //延遲60s #define FILE_PHOTO "/photo.jpg" // OV2640 相機模組的針腳定義 #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 // 選擇相機型號 #define CAMERA_MODEL_WROVER_KIT //#define CAMERA_MODEL_ESP_EYE //#define CAMERA_MODEL_M5STACK_PSRAM //#define CAMERA_MODEL_M5STACK_WIDE //#define CAMERA_MODEL_AI_THINKER //#define ESP32_CLIENT_ID = WiFi.macAddress() //const char* esp_client_id = WiFi.macAddress() WiFiClient mqttClient; PubSubClient client(mqttClient); const int LED_BUILTIN = 4; void setup_camera() { // OV2640 camera module camera_config_t config; config.pin_pwdn = kCameraPin_PWDN; config.pin_reset = kCameraPin_RESET; config.pin_xclk = kCameraPin_XCLK; config.pin_sscb_sda = kCameraPin_SIOD; config.pin_sscb_scl = kCameraPin_SIOC; config.pin_d7 = kCameraPin_Y9; config.pin_d6 = kCameraPin_Y8; config.pin_d5 = kCameraPin_Y7; config.pin_d4 = kCameraPin_Y6; config.pin_d3 = kCameraPin_Y5; config.pin_d2 = kCameraPin_Y4; config.pin_d1 = kCameraPin_Y3; config.pin_d0 = kCameraPin_Y2; config.pin_vsync = kCameraPin_VSYNC; config.pin_href = kCameraPin_HREF; config.pin_pclk = kCameraPin_PCLK; config.xclk_freq_hz = 20000000; config.ledc_timer = LEDC_TIMER_0; config.ledc_channel = LEDC_CHANNEL_0; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 10; config.fb_count = 1; esp_err_t err = esp_camera_init(&config); Serial.printf("esp_camera_init: 0x%x\n", err); // sensor_t *s = esp_camera_sensor_get(); // s->set_framesize(s, FRAMESIZE_QVGA); } String msg; int timeCount = 0; void getimg(){//拍照分段發送到mqtt 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[4104]; //client.publish(mqtt_TopicName, "0"); for (int i = 0; i < fb->len; i++){ sprintf(data, "%02X", *((fb->buf + i))); msg += data; // if (msg.length() == 4096){ // timeCount += 1; // client.beginPublish(mqtt_TopicName, msg.length(), 0); // client.print(msg); // client.endPublish(); // msg = ""; // } } if (msg.length() > 0){ client.beginPublish(mqtt_TopicName, msg.length(), 0); client.print(msg); client.endPublish(); msg = ""; } //client.publish(mqtt_TopicName, "1"); timeCount = 0; esp_camera_fb_return(fb); } } void setup_wifi() { delay(10); // 連接WIFI Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.print("IP address : "); Serial.println(WiFi.localIP()); } //MQTT重連 void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); setup_camera(); //設置相機 setup_wifi(); //連接WIFI client.setServer(mqtt_server, mqtt_port); //連接MQTT Broker if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("mqtt connected"); } } void loop() { getimg(); if (!client.connected()) { reconnect(); } delay(10000); }
使用FastWeb網頁開發平臺的示例來接收,可查看ESP32CAM傳輸的介面。ESP32CAM的畫面使用十六進位文本進行傳輸,MQTT接收到傳輸的資訊後,使用專用的解析函數可將十六進位的內容重新轉換成圖片。以上的示例使用的介面可自行搭建,只要幾分鐘就可以搭建完成。
UGCM.HexToJPG(apayload,"profile-image.jpg");
UgImage01.Picture.LoadFromFile("profile-image.jpg");
如果您需要瞭解更多當前展示範例的詳細資訊,可點擊以下連結查看。
產品簡介:https://isoface.net/isoface/production/software/fastweb/web
運行範例:https://web.diylogi.com/...
視頻說明:https://isoface.net/.../video-tutorial/fastweb/w-eq-dem-2009
範例手冊:https://isoface.net/isoface/doc/fastweb/demo/mqtt-esp32-cam/