---
# System prepended metadata

title: TTGO-Camera Plus mqtt傳圖搭配Node-Red
tags: [MQTT]

---

---
disqus: ahb0222
GA : G-CQ4L16KHK4
---
# TTGO-Camera Plus mqtt傳圖搭配Node-Red
> [color=#40f1ef][name=LHB阿好伯, 2021/07/16][:earth_africa:](https://www.facebook.com/LHB0222/)
###### tags: `MQTT`

[TOC]



___

ESP32CAM預設是透過WIFI傳遞mjpeg影像
同網域監看視訊影像很簡單
但是如果跨網域就要利用NAT的IP轉送
設定有點麻煩。

其他的方式，例如將照片上傳到Google空間，或者把照片上傳到Line等。不過都較為複雜

這次則是使用現在最流行的MQTT轉送照片，並用手機觀看，設定VGA品質每5秒一張，測試幾個小時都很正常。



（不過要記得的是我這次用的MQTT沒有安全性，只要有人訂閱同一個Topic就可以觀看你的照片喔）

步驟：

一、材料準備  
1.手機，安裝好MQTT APP：MQTT Dash（https://play.google.com/store/apps/details?id=net.routix.mqttdash&hl=zh\_TW）

2.ESP32CAM

二、ESP32CAM燒錄以下程式  
要先安裝程式庫，請利用功能表/草稿碼/匯入程式庫/管理程式庫，輸入關鍵字：PubSubClient，作者為Nick O'Leary這個  
![image](https://pic.pimg.tw/youyouyou/1606028504-2755668809-g_n.png "image")

___

![](https://i.imgur.com/7Z4Gv1i.png)


```cpp=
#include <esp_camera.h>
#include <WiFi.h>
#include <PubSubClient.h>
// ------ 以下修改成你自己的WiFi帳號密碼 ------
const char* ssid = "32NN";
const char* password = "0938881201";
 
// ------ 以下修改成你MQTT設定 ------
const char* mqtt_server = "mqtt.eclipseprojects.io";//免註冊MQTT伺服器
const unsigned int mqtt_port = 1883;
#define MQTT_USER               "my_name"             //本案例未使用
#define MQTT_PASSWORD           "my_password"         //本案例未使用
#define MQTT_PUBLISH_Monitor    "AHB0222/Esp32Cam"  // 放置Binary JPG Image的Topoc，記得要改成自己的
#define clientId "ahb0222"
 
 
// ------ OV2640相機設定 ------------
//#define 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
 
// ------TTGO-Camera Plus OV2640相機設定 ------------
#define CAMERA_MODEL_AI_THINKER
#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       26
#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


//#define PWDN_GPIO_NUM -1
//#define RESET_GPIO_NUM -1
//#define XCLK_GPIO_NUM 32
//#define SIOD_GPIO_NUM 13
//#define SIOC_GPIO_NUM 12
//#define Y9_GPIO_NUM 39
//#define Y8_GPIO_NUM 36
//#define Y7_GPIO_NUM 23
//#define Y6_GPIO_NUM 18
//#define Y5_GPIO_NUM 15
//#define Y4_GPIO_NUM 4
//#define Y3_GPIO_NUM 14
//#define Y2_GPIO_NUM 5
//#define VSYNC_GPIO_NUM 27
//#define HREF_GPIO_NUM 25
//#define PCLK_GPIO_NUM 19
//char clientId[50];
void mqtt_callback(char* topic, byte* payload, unsigned int msgLength);
WiFiClient wifiClient;
PubSubClient mqttClient(mqtt_server, mqtt_port, mqtt_callback, wifiClient);
 
//啟動WIFI連線
void setup_wifi() {
  Serial.printf("\nConnecting to %s", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("\nWiFi Connected.  IP Address: ");
  Serial.println(WiFi.localIP());
}
 
 
 
//MQTT callback，本案例沒使用
void mqtt_callback(char* topic, byte* payload, unsigned int msgLength) {
 
}
 
//重新連線MQTT Server
boolean mqtt_nonblock_reconnect() {
  boolean doConn = false;
  if (! mqttClient.connected()) {
    boolean isConn = mqttClient.connect(clientId);
    //boolean isConn = mqttClient.connect(clientId, MQTT_USER, MQTT_PASSWORD);
    char logConnected[100];
    sprintf(logConnected, "MQTT Client [%s] Connect %s !", clientId, (isConn ? "Successful" : "Failed"));
    Serial.println(logConnected);
  }
  return doConn;
}
 
//MQTT傳遞照片
void MQTT_picture() {
  //camera_fb_t * fb;    // camera frame buffer.
  camera_fb_t * fb = NULL;
  fb = esp_camera_fb_get();
  if (!fb) {
    delay(100);
    Serial.println("Camera capture failed, Reset");
    ESP.restart();
  }
 
  char* logIsPublished;
 
  if (! mqttClient.connected()) {
    // client loses its connection
    Serial.printf("MQTT Client [%s] Connection LOST !\n", clientId);
    mqtt_nonblock_reconnect();
  }
 
  if (! mqttClient.connected())
    logIsPublished = "  No MQTT Connection, Photo NOT Published !";
  else {
    int imgSize = fb->len;
    int ps = MQTT_MAX_PACKET_SIZE;
    // start to publish the picture
    mqttClient.beginPublish(MQTT_PUBLISH_Monitor, imgSize, false);
    for (int i = 0; i < imgSize; i += ps) {
      int s = (imgSize - i < s) ? (imgSize - i) : ps;
      mqttClient.write((uint8_t *)(fb->buf) + i, s);
    }
 
 
 
    boolean isPublished = mqttClient.endPublish();
    if (isPublished)
      logIsPublished = "  Publishing Photo to MQTT Successfully !";
    else
      logIsPublished = "  Publishing Photo to MQTT Failed !";
  }
  Serial.println(logIsPublished);
 esp_camera_fb_return(fb);//清除緩衝區
}
 
 
void setup() {
  Serial.begin(115200);
  //相機設定
  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.jpeg_quality = 10;  //10-63 lower number means higher quality
  config.fb_count = 2;
  //設定照片品質
  config.frame_size = FRAMESIZE_VGA ;// FRAMESIZE_ + UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA
  config.jpeg_quality = 6;
  esp_err_t err = esp_camera_init(&config);
  delay(500);
  //啟動WIFI連線
  setup_wifi();
  //sprintf(clientId, "ESP32CAM", "ahb0222");  // Create a random client ID
  //啟動MQTT連線
  mqtt_nonblock_reconnect();  
}
 
 
 
 
void loop() {
  mqtt_nonblock_reconnect(); 
  MQTT_picture();//用MQTT傳照片
  delay(60000);
  }
```

___

燒錄完成後，如果設定沒問題，就可以從序列視窗看到傳遞成功的畫面

![image](https://pic.pimg.tw/youyouyou/1605715633-376513904-g_n.png "image")

接下來就是設定手機的MQTT接收端

三、手機MQTT設定

安裝好APP後，先設定MQTT伺服器

1.點選右上角的 (+) 符號  
![1](https://pic.pimg.tw/youyouyou/1614762211-3968311743-g_n.jpg "1")

2.輸入與ESP32CAM燒錄時相同的MQTT設定  
Name：隨便輸入，自己記得即可  
Address：輸入與ESP32CAM程式相同的伺服器，本例：mqtt.eclipseprojects.io  
Port：1883  
其餘保留預設，按右上角的存檔符號  
![2](https://pic.pimg.tw/youyouyou/1614762439-3336220779-g_n.jpg "2")

3.進入剛建立好的MQTT伺服器內（本例為Esp32cam）  
點選右上角的(+)服務，加入新的選項  
![3](https://pic.pimg.tw/youyouyou/1614762243-3063984711-g_n.jpg "3")

4.選擇類型為Image  
![4](https://pic.pimg.tw/youyouyou/1614762264-393626936-g_n.jpg "4")

5.進入選項設定  
先將選項改為第三個Image file data received as binary payload contents  
Name：ESP32CAM（自己取名即可）  
Topic：請輸入你自己的ESP32CAM程式內相同的Topic  
完成後點右上的存檔符號  
![5](https://pic.pimg.tw/youyouyou/1614762278-345056686-g.png "5")

6.回到Dashboard時，就可以看到照片不斷的傳入喔  
![6](https://pic.pimg.tw/youyouyou/1614762294-1863769067-g_n.jpg "6")

7.可以點入，看大圖  
![7](https://pic.pimg.tw/youyouyou/1614762325-242757484-g_n.jpg "7")

🌟全文可以至下方連結觀看或是補充


全文分享至

https://www.facebook.com/LHB0222/

https://www.instagram.com/ahb0222/

有疑問想討論的都歡迎於下方留言

喜歡的幫我分享給所有的朋友 \o/

有所錯誤歡迎指教

# [:page_with_curl: 全部文章列表](https://hackmd.io/@LHB-0222/AllWritings)



![](https://i.imgur.com/nHEcVmm.jpg)


