Page 1 of 1

ESP32 CAM post camera shot to Mosquitto MQTT broker not working...

Posted: Mon Sep 16, 2019 2:16 pm
by Pcborges
Hi, would like to include a picture to my Node-Red Dashboard that subscribes to Mosquitto MQTT topics that currently shows Temperature and Humidity of the room it is installed.

For that I addapted a script that can be found at: https://github.com/ldab/ESP32-CAM-MQTT to use Mosquitto instead of https://www.cloudmqtt.com/

There are instructions to increase buffer size at PubSubClient.h as below:
#define MQTT_MAX_PACKET_SIZE 1530
But it has no effect at all.

I have verified on the code below that it prints the image buffer (in Hex) successfully at the Serial monitor.
I have verified using WIRESHARK at the Mosquitto server that only the first 8 bytes "FFD8FFE0" of the image taken do arrive to Mosquitto.

Now I am trying to find out if the rest of the image is lost at the ESP32CAM side or just ignored by Mosquitto.

Printout from the sketch below:

Code: Select all

Taking picture now
Camera capture success: 3
buffer is 2318 bytes
FFD8FFE000104A46494600010101000000000000FFDB0043000A07080908060A0908090B0B0A0C0F19100F0E0E0F1F161712192420262624202322282D3A31282B362B2223324433363B3D4041402730474C463F4B3A3F403EFFDB0043010B0B0B0F0D0F1D10101D3E2923293E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3EFFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFC0001108007800A003012100021101031101FFDA000C03010002110311003F00CDBC6BA9756B886D27489220BC79287A8A848D554F26C5FF00E015A31F2A226B8D487FCB95937FBA3149F6BB95FBFA4AB1FF00658545D0FD9918D47AF9BA64C9FEEC79A0EA569B49FB395F69154555C394CCBBD5379C2AC6ABECB596F3EECF00D362B10990E699BAA2E31A4D2D224635368D004A4A0029B4C02814811E95073AC6A6E7800A01FAD457B7C12409110DC64D5396A5954DFAB263772684BA550AACDDBD6A4BD8A9A8DEED5DA9DEB0A6B8666EB54415CB134DA4489494C2C079EF49537105368B8C4A4A2F71094868012928407697F2BC7A9DC88CF0CE775560620583873BBEEBC6DCAD68CD3A915C08D1CED6DDDFE951E3239CD662B14EF6364C37506A9D04B128A2E0252F028B808690D02DC29314008453680128A004A38CF3401D4DF48ADA8DCFCEBFEB0E79E95007DB9CB36D6F7AD1DE2CD00AA9E8DFA528C63EF65AA2C20920F3E1DBB9467B29CE2B1B907914921498838A4E734C42514857128A7600A4E6905C439A677A601499A560139A2803D9E4154A4B1B4624B5A5BB13D7744A6B42CAD3E996120C359C23FDC5D9559B43D3B3C40C0FFD757A902BB681687A3CEBF46AC9D6B445B5B7FB45BB49205FF581BB7BD161339EA2A442519A00293BD001453011BA53E355C82FD33DA81049E5F3B071B8E07A0A6F92CDD14D2B1442DC1C536824F6C7154AEEEADEDBFD7CA1335A9450D63534D2D6369232FBC91C1E9599FF00094D87F14575FF0001553524DC3FE124D3F9E6551FED256B3E395600F620D055CE1B58D3CE9D7431CC2FCA1FE959D504B133CD19AA602668CD48077A4A0043E9571115C1EA3E95403FE48FEE2E2914F98D8CD2019730ABE08C2FD2B38F1C52067A8E83AFC37BA701793C50CF1FC8CD24806EF4343C767A86C592758E5392C91CEAC6B4B8CE6FC55791CA2D215F3018B7AFEF3193D2B9EA800EF8AD36D7752DC7175FF90D280D486E357BAB9B7315CEC914FAAF4AA3FC3DF34980CA28620A29820A6D2005FBD5A90425ADF7B36050034A46472F267F2A8F0B1FDC5DBF8D172AC31A4E6AACC327341258827F2777CA0E78AB4F318956482EFF00787B47B814A6EC1A95BED1707FE5B4A7EAE69BE7C9BB24E71CF22819641F346EFF0046527FD9C546203CE597F4A43E519F676EECBFA9AB3F6366842FCB9C673BC51717299CC0A9DADD6929DC41451701290D00397AD6B6EFF4651FECD2195FB534D00413F6351D30035228C8E290AC0CA476A45049E0503EA5909C629682C31C527F0D0320917D2A1A0C843494005250049D13EB57A139B7A63B8CCF3484D2191C9CA9AAF40899E27548D997E5906E5F7E71562DD50C89E636D53CE69C42E3AF7CA11623F5EF52EFB7ED9AD2D1BD85719B90FDC068ACD96B50A46A5619048700D4B0D979DA6C9700FCEAF8C7F7A824A1CE693341214E5193C5301F3FCBB56AC5AB7C98A0053F7A90D218C6AAB408EAFC536F159DE69D0A0C2C5A781F53E63F35D4DF951736D6F36244F31B72B8DC0808D5480E675C8AD45C80914437448D854C7F13D658863EEBFF008F1A4C68646A8523C8E48CF14E68C638A45085053768A07707B33245FBBC67DEADD9E068A83FBEF9FF00D08502B142EE1590B14182BFAD66B039C628B1018AB50A606EC7D29815E63994D4B6E70D48095BAD26686312AA3753401D5DD79FE21D543C08B1AA47B06FE06324D6BFD9351FB6471C92C4C6280FCC3FDA22ADD98FA905DE90F35F667B825BC84E76FF00B4F552E346F2609A4FB4E7646CFF00771D0668B0C649A5AC3751C7BDCFEEDCF1EC56AA3C6CA7F8B1EF49A0B90B213DE99E5B54887F98D1C7C8A580B0D3AD81EDBFF9D0B7195B277B7D69648965EA3A55125610007AD48FC027D29019E4F269F19F9A908B0D4943284AAEFF00EB0D023D5049616EDE5C7240BF422A412EFBC95F1F27951C61BA86C17357B0EC453ED66CF97B9BA74AA37F17FA0CC23B7DE5FE4E83F88EDA186A366887DE5832F83E95972D8DD16CB267F1152590980A9C1183EF4EF21BBA9A4C090C0367CFB36FD4553BBB78ECE0022624312DCD3893632E2E71536699230F4AAF70DFBBFAD2114E957AD202CF6A4CD001504BD6828EAE73FBF6E6911D91F28C55BDAB4B8729A96AF283FBC9E5E7FBD53F9F27FCF41FF7CD218D6964C7DE53FF0001A85E77E8761A4035AF590FF81A85AE949CB463340085D187FABFD2B2F569772855E0014C9919A3214735276A484318D55B96E40A1815E815204E869680B0545274A00EAE565F338563F5A9236B703E756CF738AD6C516D268FA0703F4A76FCFBFE352046F263DAAABDC1E69010E734E4FC698D13FB62B0EF1C492315E9DA813203D053B3489187AD5493E6763400CC53715221C38A7E68189BAA376E2803FFD9
MQTT Publish succesful
Taking picture now
Camera capture success: 3
buffer is 2303 bytes
FFD8FFE000104A46494600010101000000000000FFDB0043000A07080908060A0908090B0B0A0C0F19100F0E0E0F1F161712192420262624202322282D3A31282B362B2223324433363B3D4041402730474C463F4B3A3F403EFFDB0043010B0B0B0F0D0F1D10101D3E2923293E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3EFFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFC0001108007800A003012100021101031101FFDA000C03010002110311003F00CEBE6BB9758B882D6758A38C2FFCB243DAABEDD593ABD949FEF475A681CA8634FA9AF1F63B27FF00746290DDDDA8CBE928DF475A8BA1F291FF0069704CDA54CBFEEA669C750B5F2C9FB3C8A7D1E3514C7CA64DCEA464E111147B2D66B4A58F34EE2D08D8D32A442514D95718C3DA9869086525161052520128140CF498981D6B527246014EBF43505DEA29BF644738EF56C6576BE578F1BB04FA5225E2A85576038F5A9B58A2A6A17DB3E546158B2CC5CFCC79AA26E404D213484253690B601453042534D20233D292A80292A6C0251F4A00ECAFA564D5AEB19FBF55C3C20C819598B7DC647E56ACA44372238E43E5B6F07A1E94C00E3BD4DC0AB768C9B5BB30ED5573413D44A4FAD3B805252185252105250034D474C341292908334B40CEA6FE78DB54B91BC67CC23AD428E3EE976DBE80D54D3B9A6831829E734A36E30AD96CD4123A58525808DDCFFBD590460907B5526397713BD275A448520A486277A29D89128A2C035AA3A4C04E9C51400949401ED0FBB1D4D5292CED5FEFDAC0FF00EF460D68515A5D36C64CE6CE01FEEC616AA1D0F4DFF9F73FF7F5EA5A19049A0DAB3655E74F656AC9D6B4516907DA2D8CAE17EF86E7F1A4B703069286213E6CD276A0075277A04252D2019274A746A382DD28158749E592C53206E38FA537C963D14D005761B4E29B401ED6E2A8DDDDDBDAF33C9B47D335A9451D5F525D36347311937B6300E2B30789ECCFDF86E87D154D4318A3C456279FDEA2FF00B495AAFDD1867B114C1338AD66C3EC575F2AFEE5FEE9FE959D4B6130A6D2244E94B4804A09A77298D7EA2AD4680E73DA96E21FF2A7DD5C5229F324C7E74C436E610D8C7159CE3069033D3F41D7A1BBD3545ECF1457119D8C5DC0DDE8D44BF62D4555249A38E46EA91CEAC4D5DD0F5DCE77C4F7892ADA42BBFF0077B83799D7B0AE7F3EB4083DBF0AD27D775019C5CFFE435A06413EAD757303457056453EABD2A9F1E5F3F7A931223CD2D002502801699DA9808A7E6AD3B78898771F957D4D480D2222392E4FE54CF953EE2E28191BC9DAAB4C0352116EDEE3C86621410C36F353BCA5143C572BCF68F3F255FA8C87ED13E3FD63E0F5F9A99E61DD9FE7CD2B05CB59127CFF00E8E18F6D9518833C6E8F1F515362AC33ECE46371407F16A9BEC8CD1EDDA38E73B80A2E16B19EEA55B0C306818A648526681077A69A18C72D6AE7FD157FDDA405614868190CD515021C6A54E83A531DD08E38F4A173E946A227C60514B5340A38A057219173CF7A828B12069334C57133CD03AD0049FC157617CDBFD290C8FBD21348089FA1A86988B1242F1C70BB0E2604A7BE38A96155CAEF3B45315AC3EE845B3094EDD07BD6AF96E1A8CDE87A6696B37A6C5445A69E9CD4DCBB103FDD353C369F68D3649C1F9D24DBFEF74A64141861B9A69A7726C2548A295C07CBC10B53DAB7CA45000DF7A9290C61E6ABD311D6789EDE2B4BDD3E14E123B15FC4F98F5D1DC8506CED6641226E2194F2BC2350B443D0E7B5A86D84B858A35DC8AC022E38CBD6508A3F43F99A631A8A1950E3AF34AF12FE152026D02985681DC57B4F323F908CFBD59B41B74A031CBC99FE629858A5770A499D80061D7DEB358107691410380AB512E173EB4015E63994D49037CD48091BAD368284AAE7EF1A047557924FE21D511A048E211C5B177F1C649AD6FB25E8BB82269E2DD142DCAFB95AB021BDD21E6BC1E6DC7CC20439D9FED4954E7D1FCA82490DC642216C04F4A4D05C61D31609E288B3E4A337D31B6A93C6CAD8E7F1A4511B293D0D3363500C7F98D1274A7C2D8D3ADC6DFEF7F3A22053C92EFF005A7488253F376A6415C42037AD3DBA7D290CA04E4D3E334844ED4DA062542FF7A803D4C49636DF2472C207B3549E6A35DBCABF73C88D370E7243486B47A0C866DACD9D993D3A551BF8FF00D067DB06F67429C0CF5F9680126895989108DFCF3815992585CEE62467FE0551A1641E41070460D3BECE7D29087F92BB4EF2BB7DEAA5DDBC7670008FBB7167FA74A10332E2EA2A5CF19AA2061E9505C3623FAD2029D3D69089FF00869281895149401D54EC7CF6A48DD836E46656F506ACA352DA49D73E74931F76AB3E73F4F307E552C644D34BD993F15351BCEFC6767E7400C6BC653C8FC8D42D748DF7A20690C69950FF00CB3FD2B37559B7A80170A17F5A64B6662F4152F6A44DC63555B86CE053115E80714809D4D140C09A8E4E9401D64AD179A701BAF7A7C46DC7DE56CD68345B49A1C7C8D8A719076E7F1A4046F2E3DAAABCE493CFD0FB500880B64D3D013EB48689FB561DE379923E3A76A09657FE11814E34AE2634F5AAAE3731A00615A4C50028E29F9A403734C73F29A00FFFD9
MQTT Publish succesful
This is the ESP32-CAM script I am using:

Code: Select all

#include <WiFi.h>
#include <PubSubClient.h>
#include "DHTesp.h"
#define  DHTpin 4        //D4 of ESP32 DevKit
#define  Device_Folder   "devices"
#define  Device_Label    "esp32cam"   

const char* ssid = "mySSID";
const char* password = "myPASS";
const char* mqtt_server = "192.168.99.200";
const char* mqtt_userName = "myUser";
const char* mqtt_passKey = "myPass";  

char  MQTT_CLIENT_NAME[12];  // Receives the MAC address in setup to have a unique MQTT client Name 
char  topicSubscribe[100];
char  payload[100];
char  topic[150];
char  msg[50];
int   value = 0;
int   ledPin = 2;

// Camera related
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"

#include "fb_gfx.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "dl_lib.h"

// Camera buffer, URL and picture name
camera_fb_t *fb = NULL;

//DHTesp     dht;
WiFiClient espClient;
PubSubClient client(espClient);

void init_wifi() {
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Colects unique mac to be used as MQTT_CLIENT_NAME
  byte hardwareMAC[12];  //WIFI MAC address
  WiFi.macAddress(hardwareMAC);
  sprintf(MQTT_CLIENT_NAME,"%02x%02x%02x%02x%02x%02x\n",hardwareMAC[5], hardwareMAC[4], hardwareMAC[3], hardwareMAC[2], hardwareMAC[1], hardwareMAC[0]);  
}

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  String simpleTopic = (String(topic).substring(String(topic).indexOf(Device_Label)+String(Device_Label).length()+1,String(topic).indexOf("/lv")));
  
  Serial.print("MQTT Broker callback: ");
  Serial.print(simpleTopic);
  Serial.print(" - payload: ");
  Serial.print(message);

  if (simpleTopic == "led01"){
    if (message.toInt()==0) {
      Serial.print(" - LedOff");
      digitalWrite(ledPin, LOW);
    } else {
      Serial.print(" - LedOn");
      digitalWrite(ledPin, HIGH);
    }
  } 
  Serial.println("");    
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(MQTT_CLIENT_NAME,mqtt_userName,mqtt_passKey)) {
      Serial.println("connected");
      clientSubscribe("led01");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);     // Initialize the ledPin as an output
  Serial.begin(115200);
//  dht.setup(DHTpin, DHTesp::DHT11); //for DHT11 Connect DHT sensor to GPIO 4  
  init_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  
  // Initialize and configure camera
  camera_init();
}

void loop() {
  static long lastPublish = 0;
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if (millis() - lastPublish > 15000) {
    lastPublish = millis();
//  publishTemperature();
//  publishHumidity();
    publishPic();
  }
}

void publishTemperature(){
  float sensor;
  sprintf(topic, "/%s/%s/%s", Device_Folder, Device_Label,"temperatura");
  sensor = 32;   //dht.getTemperature();   
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, payload);
  Serial.print("Pub to MQTTServer: ");
  Serial.print(topic);
  Serial.print(" - Payload: ");
  Serial.println(payload);
  client.publish(topic, payload); 
}
    
void publishHumidity(){
  float sensor;
  sprintf(topic, "/%s/%s/%s", Device_Folder, Device_Label,"humidade");
  sensor = 80; //dht.getHumidity();   
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, payload);
  Serial.print("Pub to MQTTServer: ");
  Serial.print(topic);
  Serial.print(" - Payload: ");
  Serial.println(payload);
  client.publish(topic, payload); 
}

void clientSubscribe(char* Device){
  sprintf(topicSubscribe, "/%s/%s/%s", Device_Folder, Device_Label, Device);  
  client.subscribe(topicSubscribe); 
  Serial.print("Sub to topic: ");
  Serial.println(topicSubscribe); 
}

//void onMqttConnect(bool sessionPresent){
void publishPic(){
  static int counter=0;
  // Take picture
  take_picture();
  delay(200);  
  sprintf(topic, "/%s/%s/%s", Device_Folder, Device_Label,"imagem");
  // Publish picture
  const char* pic_buf = (const char*)(fb->buf);
  size_t length = fb->len;

  uint16_t packetIdPubTemp = client.publish( topic, pic_buf );
  Serial.println("buffer is " + String(length) + " bytes");

  // No delay result in no message sent.
  delay(200);

  for(int i=0; i<length; i++){
    printHex(pic_buf[i]);
  }
  Serial.println();
  esp_camera_fb_return(fb);   //libera memória da camera
  if( !packetIdPubTemp  ){
    Serial.println( "Sending Failed! err: " + String( packetIdPubTemp ) );
  } else {
    Serial.println("MQTT Publish succesful");
    //counter++;
  }

  if (counter == 2){
    ESP.restart();
  }
}

void printHex(uint8_t num) {
  char hexCar[2];
  sprintf(hexCar, "%02X", num);
  Serial.print(hexCar);
}

bool take_picture(){
  Serial.println("Taking picture now");

  fb = esp_camera_fb_get();  
  if(!fb)  {
    Serial.println("Camera capture failed");
    return false;
  }
  Serial.print("Camera capture success: ");
  Serial.println(fb->format);
 
  return true;
}

bool camera_init(){
  // IF USING A DIFFERENT BOARD, NEED DIFFERENT PINs
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer   = LEDC_TIMER_0;
  config.pin_d0       = 5;
  config.pin_d1       = 18;
  config.pin_d2       = 19;
  config.pin_d3       = 21;
  config.pin_d4       = 36;
  config.pin_d5       = 39;
  config.pin_d6       = 34;
  config.pin_d7       = 35;
  config.pin_xclk     = 0;
  config.pin_pclk     = 22;
  config.pin_vsync    = 25;
  config.pin_href     = 23;
  config.pin_sscb_sda = 26;
  config.pin_sscb_scl = 27;
  config.pin_pwdn     = 32;
  config.pin_reset    = -1;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  //init with high specs to pre-allocate larger buffers
  config.frame_size   = FRAMESIZE_QQVGA; // set picture size, FRAMESIZE_QQVGA = 160x120
  config.jpeg_quality = 10;            // quality of JPEG output. 0-63 lower means higher quality
  config.fb_count     = 2;

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK){
    Serial.print("Camera init failed with error 0x%x");
    Serial.println(err);
    return false;
  }

  // Change extra settings if required
  //sensor_t * s = esp_camera_sensor_get();
  //s->set_vflip(s, 0);       //flip it back
  //s->set_brightness(s, 1);  //up the blightness just a bit
  //s->set_saturation(s, -2); //lower the saturation

  else  {
    return true;
  }
  
}
Assistance welcome
Thanks
Paulo