#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;
}
}