├── Images ├── ESP32-CAM.jpg ├── M01P01_PowerSupply.fzz ├── M01P01_PowerSupply_bb.png ├── M01P02_NodeMCU_Sensors.fzz ├── M01P02_NodeMCU_Sensors_bb.png ├── M02P01_Programming.fzz ├── M02P01_Programming_bb.png ├── M02P02_Running.fzz ├── M02P02_Running_bb.png ├── Modulo_01_Parte01_Alimentacao_bb.png ├── Modulo_01_Parte02_NodeMCU_Sensores_bb.png ├── Modulo_02_Parte01_Programacao_bb.png ├── Modulo_02_Parte02_Execucao_bb.png ├── Pic_01_ESP8266_MQTT.jpg ├── Pic_02_PowerSupplyAndBattery.jpg ├── Pic_03_ESP8266BattCharger.jpg ├── Pic_04_ESP32-CAM.jpg ├── Pic_05_ESP8266_Select.PNG ├── Pic_06_MosquittoMQTT.PNG ├── Pic_07_MyMQTT.png ├── Pic_08_ESP32-CAM_Select.PNG ├── Pic_09_ESP32-CAM_Programming.jpg ├── Pic_10_Output_M02_MonitorSerial.PNG ├── Pic_11_Output_WebServer.PNG ├── Pic_12_Output_Ngrok.PNG └── Pic_13_Output_ServWebNgrok.PNG ├── Module01_ESP8266_Sensors └── Module01_ESP8266_Sensors.ino ├── Module02_ESP32CAM_WebServer ├── Module02_ESP32CAM_WebServer.ino └── PAG_WEB.h ├── README.md ├── Relatorio_Projeto_ServidorWeb_Sensores_Camera.html ├── Relatorio_Projeto_ServidorWeb_Sensores_Camera.md ├── Relatorio_Projeto_ServidorWeb_Sensores_Camera.pdf ├── Report_WebServer_ESP32-CAM_Sensors.html ├── Report_WebServer_ESP32-CAM_Sensors.md └── Report_WebServer_ESP32-CAM_Sensors.pdf /Images/ESP32-CAM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/ESP32-CAM.jpg -------------------------------------------------------------------------------- /Images/M01P01_PowerSupply.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M01P01_PowerSupply.fzz -------------------------------------------------------------------------------- /Images/M01P01_PowerSupply_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M01P01_PowerSupply_bb.png -------------------------------------------------------------------------------- /Images/M01P02_NodeMCU_Sensors.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M01P02_NodeMCU_Sensors.fzz -------------------------------------------------------------------------------- /Images/M01P02_NodeMCU_Sensors_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M01P02_NodeMCU_Sensors_bb.png -------------------------------------------------------------------------------- /Images/M02P01_Programming.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M02P01_Programming.fzz -------------------------------------------------------------------------------- /Images/M02P01_Programming_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M02P01_Programming_bb.png -------------------------------------------------------------------------------- /Images/M02P02_Running.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M02P02_Running.fzz -------------------------------------------------------------------------------- /Images/M02P02_Running_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/M02P02_Running_bb.png -------------------------------------------------------------------------------- /Images/Modulo_01_Parte01_Alimentacao_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Modulo_01_Parte01_Alimentacao_bb.png -------------------------------------------------------------------------------- /Images/Modulo_01_Parte02_NodeMCU_Sensores_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Modulo_01_Parte02_NodeMCU_Sensores_bb.png -------------------------------------------------------------------------------- /Images/Modulo_02_Parte01_Programacao_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Modulo_02_Parte01_Programacao_bb.png -------------------------------------------------------------------------------- /Images/Modulo_02_Parte02_Execucao_bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Modulo_02_Parte02_Execucao_bb.png -------------------------------------------------------------------------------- /Images/Pic_01_ESP8266_MQTT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_01_ESP8266_MQTT.jpg -------------------------------------------------------------------------------- /Images/Pic_02_PowerSupplyAndBattery.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_02_PowerSupplyAndBattery.jpg -------------------------------------------------------------------------------- /Images/Pic_03_ESP8266BattCharger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_03_ESP8266BattCharger.jpg -------------------------------------------------------------------------------- /Images/Pic_04_ESP32-CAM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_04_ESP32-CAM.jpg -------------------------------------------------------------------------------- /Images/Pic_05_ESP8266_Select.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_05_ESP8266_Select.PNG -------------------------------------------------------------------------------- /Images/Pic_06_MosquittoMQTT.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_06_MosquittoMQTT.PNG -------------------------------------------------------------------------------- /Images/Pic_07_MyMQTT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_07_MyMQTT.png -------------------------------------------------------------------------------- /Images/Pic_08_ESP32-CAM_Select.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_08_ESP32-CAM_Select.PNG -------------------------------------------------------------------------------- /Images/Pic_09_ESP32-CAM_Programming.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_09_ESP32-CAM_Programming.jpg -------------------------------------------------------------------------------- /Images/Pic_10_Output_M02_MonitorSerial.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_10_Output_M02_MonitorSerial.PNG -------------------------------------------------------------------------------- /Images/Pic_11_Output_WebServer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_11_Output_WebServer.PNG -------------------------------------------------------------------------------- /Images/Pic_12_Output_Ngrok.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_12_Output_Ngrok.PNG -------------------------------------------------------------------------------- /Images/Pic_13_Output_ServWebNgrok.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Images/Pic_13_Output_ServWebNgrok.PNG -------------------------------------------------------------------------------- /Module01_ESP8266_Sensors/Module01_ESP8266_Sensors.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Module01_ESP8266_Sensors.ino 3 | * --> Circuit using an ESP8266, a BMP280 module and a LDR 4 | * --> Reads the sensors and publish in a MQTT server. 5 | */ 6 | 7 | 8 | // --> Required Libraries 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | 17 | 18 | /***************************************************** 19 | ** Constants and global variables ** 20 | *****************************************************/ 21 | #define LDR_PIN A0 22 | #define NETWORK_SSID "YOUR WI-FI NETWORK SSID" 23 | #define NETWORK_PASS "YOUR WI-FI NETWORK PASSWORD" 24 | #define MQTT_SERVER "192.168.0.7" //IP from RPi in the Wi-Fi network 25 | #define MQTT_PORT 1883 26 | 27 | #define BMP280_I2C_ADDRESS 0x76 //I2C address of the BMP280 module 28 | 29 | //--> Global-Scope variables: 30 | float temp, pressure; 31 | unsigned int adc_ldr; 32 | unsigned long lastMillis = 0; 33 | 34 | 35 | // --> Objetos para controlar aos dispositivos usados aqui 36 | WiFiClient espClient; //--> Wi-Fi client 37 | PubSubClient mqtt_client(espClient); //--> Configurar o servidor MQTT 38 | Adafruit_BMP280 bmp; //Objeto para acessar os recursos do sensor BMP280: 39 | 40 | 41 | // --> Function prototypes: 42 | void connect_esp8266_wifi_network(char* network_ssid, char* network_pass); 43 | void connect_mqtt_server( void ); 44 | void read_ldr_sensor( void ); 45 | void read_bmp280_sensors( void ); 46 | 47 | 48 | 49 | 50 | /****************** 51 | ** setup() ** 52 | ******************/ 53 | void setup() { 54 | //Begin the Monitor Serial 55 | Serial.begin(115200); 56 | 57 | // Initialize sensors: 58 | pinMode(LDR_PIN, INPUT); //LDR sensor 59 | bmp.begin(BMP280_I2C_ADDRESS); //BMP280 sensor module 60 | 61 | // --> Connect to the Wi-Fi Network (Using constants defined in global scope) 62 | connect_esp8266_wifi_network(NETWORK_SSID, NETWORK_PASS); 63 | 64 | // --> Set the MQTT server 65 | mqtt_client.setServer(MQTT_SERVER, MQTT_PORT); 66 | 67 | //--> Se conectar ao servidor MQTT 68 | connect_mqtt_server(); 69 | } 70 | 71 | 72 | 73 | 74 | /**************** 75 | ** loop() ** 76 | ****************/ 77 | void loop() { 78 | mqtt_client.loop(); 79 | delay(10); // <- fixes some issues with WiFi stability 80 | 81 | if(!mqtt_client.connected()) { 82 | connect_mqtt_server(); 83 | } 84 | 85 | // Publicar mensagens a cada 10s. 86 | if( (millis() - lastMillis) > 10000 ){ 87 | //--> Read the sensors 88 | read_ldr_sensor(); 89 | read_bmp280_sensors(); 90 | 91 | //--> Publish the sensor readings: 92 | mqtt_client.publish("sensors/temp", String(temp).c_str()); 93 | delay(500); 94 | 95 | mqtt_client.publish("sensors/pressure", String(pressure).c_str()); 96 | delay(500); 97 | 98 | mqtt_client.publish("sensors/adc_ldr", String(adc_ldr).c_str()); 99 | delay(500); 100 | 101 | //--> Refresh 'lastMillis' 102 | lastMillis = millis(); 103 | } 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | /**************************************** 112 | ** connect_esp8266_wifi_network() ** 113 | ****************************************/ 114 | void connect_esp8266_wifi_network(char* network_ssid, char* network_pass){ 115 | Serial.println(""); 116 | // Connect to the Wi-Fi network 117 | WiFi.begin(network_ssid, network_pass); 118 | Serial.print("Connecting to "); 119 | Serial.println(network_ssid); 120 | while(WiFi.status() != WL_CONNECTED){ 121 | Serial.print("."); 122 | delay(500); 123 | } 124 | Serial.println("\nConected!"); 125 | // --> Show IP and MAC Address: 126 | Serial.print("IP Address: "); 127 | Serial.println(WiFi.localIP()); 128 | Serial.print("MAC Address: "); 129 | Serial.println(WiFi.macAddress()); 130 | Serial.println("\n"); 131 | } 132 | 133 | 134 | 135 | /**************************** 136 | ** connect_mqtt_server() ** 137 | ****************************/ 138 | void connect_mqtt_server( void ){ 139 | Serial.print("Checking Wi-Fi"); 140 | while( WiFi.status() != WL_CONNECTED ) { 141 | Serial.print("."); 142 | delay(500); 143 | } 144 | 145 | while (!mqtt_client.connected()) { 146 | Serial.println("\nConnecting to the MQTT server..."); 147 | if (mqtt_client.connect("sensors")){ 148 | Serial.print(F("Connected to the MQTT server in ")); 149 | Serial.print(MQTT_SERVER); 150 | Serial.print(":"); 151 | Serial.println(MQTT_PORT); 152 | } 153 | else{ 154 | Serial.print("Fail in connecting to the MQTT server [rc = "); 155 | Serial.print(mqtt_client.state()); 156 | Serial.println("]. Trying again in 5s."); 157 | // Wait 5 seconds before retrying 158 | delay(5000); 159 | } 160 | } 161 | } 162 | 163 | 164 | 165 | 166 | /**************************************** 167 | ** read_ldr_sensor() ** 168 | ****************************************/ 169 | void read_ldr_sensor( void ){ 170 | adc_ldr = analogRead(LDR_PIN); 171 | } 172 | 173 | 174 | /**************************************** 175 | ** read_bmp280_sensors() ** 176 | ****************************************/ 177 | void read_bmp280_sensors( void ){ 178 | temp = bmp.readTemperature(); //Temperature in Celsius 179 | pressure = bmp.readPressure()/100.0; //pressure en hPa (in hundreds of Pascals) 180 | } 181 | -------------------------------------------------------------------------------- /Module02_ESP32CAM_WebServer/Module02_ESP32CAM_WebServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Module02_ESP32CAM_WebServer.ino 3 | * --> Runs the web server showing the last picture taken and the sensor readings published in the MQTT server 4 | * 5 | */ 6 | 7 | 8 | /***************************** 9 | ** Required libraries ** 10 | *****************************/ 11 | #include "esp_camera.h" 12 | #include "esp_timer.h" 13 | #include "img_converters.h" 14 | #include "Arduino.h" 15 | #include "fb_gfx.h" 16 | #include "fd_forward.h" 17 | #include "fr_forward.h" 18 | #include "soc/soc.h" // Disable brownour problems 19 | #include "soc/rtc_cntl_reg.h" // Disable brownour problems 20 | #include "dl_lib.h" 21 | #include "driver/rtc_io.h" 22 | #include "WiFi.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "PAG_WEB.h" //Header Filewith the HTML code of the web server page 29 | #include 30 | 31 | 32 | 33 | 34 | /******************************************************************************* 35 | ** Constantes referentes aos pinos da camera conectados internamente no ESP32 ** 36 | *******************************************************************************/ 37 | // --> Pins from the OV2640 camera module (CAMERA_MODEL_AI_THINKER) 38 | #define PWDN_GPIO_NUM 32 39 | #define RESET_GPIO_NUM -1 // RESET pin is not available 40 | #define XCLK_GPIO_NUM 0 41 | #define SIOD_GPIO_NUM 26 //SDA pin - 'GPIO 26' 42 | #define SIOC_GPIO_NUM 27 //SCL pin - 'GPIO 26' 43 | 44 | #define Y9_GPIO_NUM 35 //D7 pin - 'GPIO 35' 45 | #define Y8_GPIO_NUM 34 //D6 pin - 'GPIO 34' 46 | #define Y7_GPIO_NUM 39 //D5 pin - 'GPIO 39' 47 | #define Y6_GPIO_NUM 36 //D4 pin - 'GPIO 36' 48 | #define Y5_GPIO_NUM 21 //D3 pin - 'GPIO 21' 49 | #define Y4_GPIO_NUM 19 //D2 pin - 'GPIO 19' 50 | #define Y3_GPIO_NUM 18 //D1 pin - 'GPIO 18' 51 | #define Y2_GPIO_NUM 5 //D0 pin - 'GPIO 5' 52 | #define VSYNC_GPIO_NUM 25 53 | #define HREF_GPIO_NUM 23 54 | #define PCLK_GPIO_NUM 22 55 | 56 | 57 | 58 | 59 | /***************************************************** 60 | ** Constants and global variables ** 61 | *****************************************************/ 62 | #define INTERVAL 5 * 60 * 1000 // Interval between the pictures: 5 min 63 | #define NETWORK_SSID "YOUR WI-FI NETWORK SSID" 64 | #define NETWORK_PASS "YOUR WI-FI NETWORK PASSWORD" 65 | #define MQTT_SERVER "192.168.0.7" //IP from RPi in the Wi-Fi network 66 | #define MQTT_PORT 1883 67 | 68 | 69 | /* --> Time-Zone adjustment (in seconds): 70 | --> Difference, in seconds, between the hour in this time-zone and the time in Greenwich 71 | --> Brasilia TZ (GMT -3) = -3600 * 3 = -10800 */ 72 | #define TZ_ADJUST -10800 73 | // --> Nome do arquivo onde serao inseridos os dados 74 | #define FILE_PHOTO "/Photo.jpg" 75 | 76 | 77 | //--> Global-Scope variables: 78 | camera_config_t CONFIG_CAM; // OV2640 camera configuration 79 | unsigned long lastMillis = 0; 80 | String formattedDate; 81 | String dayStamp; 82 | String timeStamp; 83 | String strTemp = "XX", strPressure = "XX", strADCldr = "XX", strLastMessage = ""; 84 | 85 | 86 | // --> Objects from the classes available in the imported header files 87 | WiFiUDP ntpUDP; 88 | NTPClient timeClient(ntpUDP); //NTP client: 89 | AsyncWebServer server(8888); // Server on port 8888. The Ngrok service doesn't work in port '80' 90 | WiFiClient espClient; 91 | PubSubClient mqtt_client(espClient); //--> MQTT Server 92 | 93 | 94 | // --> Function prototypes: 95 | void connect_esp32_wifi_network( void ); 96 | void ov2640_camera_module_configurations( void ); 97 | void initialize_spiffs( void ); 98 | bool verify_picture_taken( fs::FS &fs ); 99 | void take_picture_save_spiffs( void ); 100 | void getTimeStamp( void ); 101 | String processor(const String& var); 102 | void connect_mqtt_server( void ); 103 | void messageReceived(char* topic, byte* payload, unsigned int length); 104 | void write_received_message(String topicName, byte* payload, unsigned int length); 105 | void call_take_picture_functions( void ); 106 | 107 | 108 | 109 | 110 | 111 | /****************** 112 | ** setup() ** 113 | ******************/ 114 | void setup() { 115 | delay(5000); 116 | // Turn-off the 'browout detector' 117 | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 118 | 119 | // --> Flash pin 120 | pinMode(4, OUTPUT); 121 | digitalWrite(4, LOW); 122 | 123 | // --> Monitor Serial 124 | Serial.begin(115200); 125 | Serial.println("Initializing..."); 126 | 127 | // --> SPIFFS: 128 | initialize_spiffs(); 129 | 130 | // --> OV2640 camera module 131 | ov2640_camera_module_configurations(); 132 | 133 | // --> Connect to the Wi-Fi Network 134 | connect_esp32_wifi_network(); 135 | 136 | //--> Iniiialize the NTP client 137 | Serial.print("Initializing the NTP (Network Time Protocol) client..."); 138 | timeClient.begin(); 139 | timeClient.setTimeOffset(TZ_ADJUST); 140 | Serial.println("Ok!"); 141 | 142 | // --> Set-up the MQTT server 143 | mqtt_client.setServer(MQTT_SERVER, MQTT_PORT); 144 | 145 | // --> Define the 'messageReceived()' funtion as the callback function 146 | mqtt_client.setCallback(messageReceived); 147 | 148 | //--> Connect to the MQTT server 149 | connect_mqtt_server(); 150 | 151 | // --> Define the routes for the asynchronous web server: 152 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { 153 | request->send_P(200, "text/html", index_html, processor); 154 | }); 155 | 156 | // Last picture taken: 157 | server.on("/photo_cam", HTTP_GET, [](AsyncWebServerRequest * request) { 158 | request->send(SPIFFS, FILE_PHOTO, "image/jpg"); 159 | }); 160 | 161 | // Date: 162 | server.on("/date_photo", HTTP_GET, [](AsyncWebServerRequest * request) { 163 | request->send_P(200, "text/plain", formattedDate.c_str()); 164 | }); 165 | 166 | // Hour: 167 | server.on("/hour_photo", HTTP_GET, [](AsyncWebServerRequest * request) { 168 | request->send_P(200, "text/plain", timeStamp.c_str()); 169 | }); 170 | 171 | // Temperature: 172 | server.on("/temp", HTTP_GET, [](AsyncWebServerRequest * request) { 173 | request->send_P(200, "text/plain", strTemp.c_str()); 174 | }); 175 | 176 | // Pressure: 177 | server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest * request) { 178 | request->send_P(200, "text/plain", strPressure.c_str()); 179 | }); 180 | 181 | // ADC from the LDR: 182 | server.on("/adc_ldr", HTTP_GET, [](AsyncWebServerRequest * request) { 183 | request->send_P(200, "text/plain", strADCldr.c_str()); 184 | }); 185 | 186 | // --> Initialize the asyncronous web server 187 | server.begin(); 188 | 189 | Serial.println("Ok!\n"); 190 | 191 | //--> First call to 'call_take_picture_functions()' 192 | call_take_picture_functions(); 193 | } 194 | 195 | 196 | 197 | 198 | /**************** 199 | ** loop() ** 200 | ****************/ 201 | void loop() { 202 | mqtt_client.loop(); 203 | delay(10); // <- fixes some issues with WiFi stability 204 | 205 | 206 | if ( !mqtt_client.connected() ) { 207 | connect_mqtt_server(); 208 | } 209 | 210 | //--> Take a picture every 'INTERVAL' seconds 211 | if ( (millis() - lastMillis) > INTERVAL ) { 212 | call_take_picture_functions(); 213 | lastMillis = millis(); // Refresh 'lastMillis' 214 | } 215 | } 216 | 217 | 218 | 219 | /**************************************** 220 | ** connect_esp32_wifi_network() ** 221 | ****************************************/ 222 | void connect_esp32_wifi_network( void ) { 223 | // Connect to the Wi-Fi network 224 | WiFi.begin(NETWORK_SSID, NETWORK_PASS); 225 | Serial.print("Connecting to "); 226 | Serial.println(NETWORK_SSID); 227 | while (WiFi.status() != WL_CONNECTED) { 228 | Serial.print("."); 229 | delay(500); 230 | } 231 | Serial.println("\nConected!"); 232 | // Show IP and MAC Address: 233 | Serial.print("IP Address: "); 234 | Serial.println(WiFi.localIP()); 235 | Serial.print("MAC Address: "); 236 | Serial.println(WiFi.macAddress()); 237 | Serial.println("\n"); 238 | } 239 | 240 | 241 | 242 | 243 | 244 | /**************************************************** 245 | ** ov2640_camera_module_configurations() ** 246 | ****************************************************/ 247 | void ov2640_camera_module_configurations( void ) { 248 | Serial.print("Inicializing the OV2640 camera module..."); 249 | 250 | // --> OV2640 camera configuration 251 | CONFIG_CAM.ledc_channel = LEDC_CHANNEL_0; 252 | CONFIG_CAM.ledc_timer = LEDC_TIMER_0; 253 | CONFIG_CAM.pin_d0 = Y2_GPIO_NUM; 254 | CONFIG_CAM.pin_d1 = Y3_GPIO_NUM; 255 | CONFIG_CAM.pin_d2 = Y4_GPIO_NUM; 256 | CONFIG_CAM.pin_d3 = Y5_GPIO_NUM; 257 | CONFIG_CAM.pin_d4 = Y6_GPIO_NUM; 258 | CONFIG_CAM.pin_d5 = Y7_GPIO_NUM; 259 | CONFIG_CAM.pin_d6 = Y8_GPIO_NUM; 260 | CONFIG_CAM.pin_d7 = Y9_GPIO_NUM; 261 | CONFIG_CAM.pin_xclk = XCLK_GPIO_NUM; 262 | CONFIG_CAM.pin_pclk = PCLK_GPIO_NUM; 263 | CONFIG_CAM.pin_vsync = VSYNC_GPIO_NUM; 264 | CONFIG_CAM.pin_href = HREF_GPIO_NUM; 265 | CONFIG_CAM.pin_sscb_sda = SIOD_GPIO_NUM; 266 | CONFIG_CAM.pin_sscb_scl = SIOC_GPIO_NUM; 267 | CONFIG_CAM.pin_pwdn = PWDN_GPIO_NUM; 268 | CONFIG_CAM.pin_reset = RESET_GPIO_NUM; 269 | CONFIG_CAM.xclk_freq_hz = 20000000; 270 | CONFIG_CAM.pixel_format = PIXFORMAT_JPEG; 271 | 272 | 273 | // --> Frame size: 274 | if (psramFound()) { 275 | CONFIG_CAM.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA 276 | CONFIG_CAM.jpeg_quality = 10; 277 | CONFIG_CAM.fb_count = 2; 278 | } 279 | else { 280 | CONFIG_CAM.frame_size = FRAMESIZE_SVGA; 281 | CONFIG_CAM.jpeg_quality = 12; 282 | CONFIG_CAM.fb_count = 1; 283 | } 284 | 285 | // --> Initialize the camera module 286 | esp_err_t err = esp_camera_init(&CONFIG_CAM); 287 | if (err != ESP_OK) { 288 | Serial.printf("Camera init failed with error 0x%x", err); 289 | return; 290 | } 291 | 292 | Serial.println("Ok!"); 293 | } 294 | 295 | 296 | 297 | 298 | /************************************* 299 | ** Funcao initialize_spiffs() ** 300 | *************************************/ 301 | void initialize_spiffs( void ) { 302 | // Initialize the SPIFFS file system 303 | Serial.print("Initializing the SPIFFS file system..."); 304 | if (!SPIFFS.begin( true )) { 305 | Serial.println("ERROR"); 306 | return; 307 | } 308 | else { 309 | delay(500); 310 | Serial.println("Ok!"); 311 | } 312 | } 313 | 314 | 315 | 316 | /**************************************** 317 | ** verify_picture_taken() ** 318 | ****************************************/ 319 | bool verify_picture_taken( fs::FS &fs ) { 320 | File f_pic = fs.open( FILE_PHOTO ); 321 | unsigned int pic_sz = f_pic.size(); 322 | return ( pic_sz > 100 ); 323 | } 324 | 325 | 326 | 327 | /**************************************** 328 | ** take_picture_save_spiffs() ** 329 | ****************************************/ 330 | void take_picture_save_spiffs( void ) { 331 | //--> Turn on the flash 332 | digitalWrite(4, HIGH); 333 | camera_fb_t * fb = NULL; // pointer 334 | bool ok = 0; // Boolean indicating if the picture has been taken correctly 335 | 336 | do { 337 | // Take a picture with the camera 338 | Serial.println("Taking a picture..."); 339 | 340 | fb = esp_camera_fb_get(); 341 | if (!fb) { 342 | Serial.println("Camera capture failed"); 343 | return; 344 | } 345 | 346 | // Picture file name 347 | Serial.printf("Picture file name: %s\n", FILE_PHOTO); 348 | File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE); 349 | 350 | // Insert the data in the picture file 351 | if (!file) { 352 | Serial.println("Failed to open file in writing mode"); 353 | } 354 | else { 355 | file.write(fb->buf, fb->len); // payload (image), payload length 356 | Serial.print("The picture has been saved in "); 357 | Serial.print(FILE_PHOTO); 358 | Serial.print(" - Size: "); 359 | Serial.print(file.size()); 360 | Serial.println(" bytes"); 361 | } 362 | // Close the file 363 | file.close(); 364 | esp_camera_fb_return(fb); 365 | 366 | // --> Verify wether the file has been correctly saved in SPIFFS: 367 | ok = verify_picture_taken( SPIFFS ); 368 | } while ( !ok ); 369 | 370 | // --> Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4 371 | digitalWrite(4, LOW); 372 | 373 | } 374 | 375 | 376 | 377 | /**************************************** 378 | ** getTimeStamp() ** 379 | ****************************************/ 380 | void getTimeStamp( void ) { 381 | while (!timeClient.update()) { 382 | timeClient.forceUpdate(); 383 | } 384 | 385 | // --> Date format in 'formattedDate': 2018-05-28T16:00:13Z 386 | // --> Its needed to extract the date and the time 387 | formattedDate = timeClient.getFormattedDate(); 388 | Serial.println(formattedDate); 389 | 390 | // --> Extract the date 391 | int splitT = formattedDate.indexOf("T"); //Position of the character 'T' in the string 392 | dayStamp = formattedDate.substring(0, splitT); 393 | Serial.println(dayStamp); 394 | 395 | // --> Extract the hour 396 | timeStamp = formattedDate.substring(splitT + 1, formattedDate.length() - 1); 397 | Serial.println(timeStamp); 398 | } 399 | 400 | 401 | 402 | /**************************************** 403 | ** processor() ** 404 | ****************************************/ 405 | String processor(const String& var) { 406 | //--> If 'var' is DATE_PHOTO: 407 | if (var == "DATE_PHOTO") { 408 | return dayStamp; 409 | } 410 | //--> If 'var' is HOUR_PHOTO: 411 | else if (var == "HOUR_PHOTO") { 412 | return timeStamp; 413 | } 414 | //--> If 'var' is TEMPERATURE: 415 | else if (var == "TEMPERATURE") { 416 | return strTemp; 417 | } 418 | //--> If 'var' is PRESSURE: 419 | else if (var == "PRESSURE") { 420 | return strPressure; 421 | } 422 | //--> If 'var' is ADC_LDR: 423 | else if (var == "ADC_LDR") { 424 | return strADCldr; 425 | } 426 | 427 | return String(); 428 | } 429 | 430 | 431 | 432 | /*********************************** 433 | ** connect_mqtt_server() ** 434 | ***********************************/ 435 | void connect_mqtt_server( void ) { 436 | while (!mqtt_client.connected()) { 437 | Serial.println("\nConnecting to the MQTT server..."); 438 | if (mqtt_client.connect("sensorReadings")) { 439 | Serial.print(F("Connected to the MQTT server in ")); 440 | Serial.print(MQTT_SERVER); 441 | Serial.print(":"); 442 | Serial.println(MQTT_PORT); 443 | 444 | // Subscribe to the topics 445 | mqtt_client.subscribe("sensors/temp"); 446 | mqtt_client.subscribe("sensors/pressure"); 447 | mqtt_client.subscribe("sensors/adc_ldr"); 448 | } 449 | else { 450 | Serial.print("Fail in connecting to the MQTT server [rc = "); 451 | Serial.print(mqtt_client.state()); 452 | Serial.println("]. Trying again in 5s."); 453 | // Wait 5 seconds before retrying 454 | delay(5000); 455 | } 456 | } 457 | } 458 | 459 | 460 | 461 | 462 | /******************************* 463 | ** messageReceived() ** 464 | *******************************/ 465 | void messageReceived(char* topic, byte* payload, unsigned int length) { 466 | String topicName = String(topic); 467 | 468 | // --> Inserir o conteudo de 'payload' em um array de caracteres 469 | char content[30]; 470 | for ( unsigned int i = 0; i < length; i++ ) { 471 | content[i] = static_cast( payload[i] ); 472 | } 473 | content[length] = '\0'; 474 | 475 | // Write the received message 476 | write_received_message(topicName, payload, length); 477 | 478 | //--> Topic 'sensors/temp' 479 | if (topicName == "sensors/temp") { 480 | strTemp = String(content); 481 | } 482 | //--> Topic 'sensors/pressure' 483 | else if (topicName == "sensors/pressure") { 484 | strPressure = String(content); 485 | } 486 | //--> Topic 'sensors/adc_ldr' 487 | else if (topicName == "sensors/adc_ldr") { 488 | strADCldr = String(content); 489 | } 490 | } 491 | 492 | 493 | 494 | 495 | /******************************** 496 | ** write_received_message() ** 497 | ********************************/ 498 | void write_received_message(String topicName, byte* payload, unsigned int length) { 499 | // Write the topic name: 500 | Serial.print("Received message ["); 501 | Serial.print(topicName); 502 | Serial.print("] - "); 503 | String msg = ""; 504 | // Write the message in the 'payload[]' array 505 | for ( unsigned int i = 0; i < length; i++ ) { 506 | Serial.print(static_cast(payload[i])); 507 | msg = msg + String(payload[i]); 508 | } 509 | Serial.println(""); 510 | 511 | //Ultima mensagem 512 | strLastMessage = "Received message [" + topicName + "] - " + msg; 513 | } 514 | 515 | 516 | 517 | 518 | 519 | /******************************************* 520 | ** call_take_picture_functions() ** 521 | *******************************************/ 522 | void call_take_picture_functions( void ) { 523 | take_picture_save_spiffs(); //Take a picture and save it in the SPIFFS 524 | getTimeStamp(); // Get the date and time 525 | Serial.println(""); 526 | } 527 | -------------------------------------------------------------------------------- /Module02_ESP32CAM_WebServer/PAG_WEB.h: -------------------------------------------------------------------------------- 1 | /* PAG_WEB.h 2 | * --> Header file with the template of the HTML code of the web server run on ESP32-CAM 3 | */ 4 | 5 | 6 | const char index_html[] PROGMEM = R"rawliteral( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | Web Server ESP32-CAM 23 | 24 | 25 | 26 | 27 |

Web Server Using the ESP32-CAM:

28 | 29 | 30 |

Date of the last photo: %DATE_PHOTO%

31 |

Time of the last photo:: %HOUR_PHOTO%

32 |

Temperature: %TEMPERATURE%ºC

33 |

Pressure: %PRESSURE%hPa

34 |

Level of Ilumination from the LDR ([0, 1023]): %ADC_LDR%

35 | 36 | 37 |

Picture saved in the SPIFFS:

38 |
39 | 40 |
41 | 42 | 43 | 44 | 45 | 101 | )rawliteral"; 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32-CAM Web Server publishing the last picture saved in the SPIFFS and publishing data from a MQTT server 2 | 3 | 4 | ![Web server](./Images/Pic_11_Output_WebServer.PNG) 5 | 6 | 7 | - This repo contains the code for a web server, using the ESP32-CAM, which publishes the last picture taken by the camera. 8 | - The picture is saved on the SPIFFS of the ESP32-CAM. It only saves one picture (everytime that a picture is taken, it replaces the existing one). 9 | - The web server page shows the last picture taken by the camera and also shows some sensor readings. 10 | - Once I had problems in connecting the sensors to the ESP32-CAM, the ESP8266 module is connected to the sensors, and publish the readings in a MQTT server running in my Raspberry Pi. 11 | - The ESP32-CAM connects to this MQTT server and publish the sensor readingsa in the web server page. 12 | - This project was built over the idea shown in https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card/ 13 | 14 | 15 | -------------------------------------------------------------------------------- /Relatorio_Projeto_ServidorWeb_Sensores_Camera.md: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | pdf_document: default 4 | html_document: default 5 | --- 6 | # Relatório - Projeto - Servidor Web para publicação de uma foto e dados de sensores 7 | 8 | 9 | # 1 - Partes do Projeto e componentes utilizados: 10 | 11 | ## 1.1 - As três partes do projeto: 12 | - 1 - Circuito usando placa de desenvolvimento 'NodeMCU V1.0' - SoC ESP12-E (com microcontrolador ESP8266). 13 | - Lê os dados de temperatura e pressão do módulo BMP280 e o valor analógico do sensor de iluminação (fotoresistor). 14 | - Os dados dos sensores são enviados para o servidor MQTT. 15 | - O NodeMCU é alimentado por meio de uma bateria 18650. 16 | - A bateria é carregada por meio de painéis solares. 17 | - 2 - Módulo ESP32-CAM: 18 | - Tira uma foto a cada 5 minutos. Ele apenas armazena a última foto tirada. 19 | - Esse módulo também hospeda o servidor web com a página que mostra os dados dos sensores e a ultima foto tirada com a câmera. 20 | - Na memória flash do ESP32-CAM somente é armazenada a foto mostrada na página. 21 | - O código HTML da página web é gerado nas funções do _sketch_ enviado para o ESP32-Cam. 22 | - 3 - Computador executando o **Moquitto MQTT** e o programa Ngrok. 23 | - No caso aqui, os programas estão instalados em um Raspberry Pi. 24 | - Entretanto, qualquer computador com Windows pode fazer exatamente a mesma coisa. Somente é necessário instalar os programas mencionados. 25 | - **Mosquitto MQTT**: É o programa que recebe os dados das leituras dos sensores, realizadas no NodeMCU ESP8266, e envia essas informações ao ESP32-CAM para incluir as leituras realizadas na página web gerada. 26 | - **Ngrok**: é o serviço de internet que faz com que o servidor web do ESP32-CAM fique disponível na internet. 27 | - Necessário criar uma conta no site. 28 | - O site disponibiliza uma versão gratuita e, também, recursos pagos. 29 | - Os recursos usados aqui foram os gratuitos. 30 | 31 | 32 | ## 1.2 - Componentes utilizados no projeto: 33 | ![Foto_01](./Images/M01P01_PowerSupply_bb.png) 34 | 35 | - 1 - **NodeMCU (ESP12-E) com os sensores**: 36 | - 1x Módulo de desenvolvimento NodeMCU 1.0 (SoC ESP12-E, com o chip ESP8266). 37 | - 1x sensor de temperatura e pressão BMP280 38 | - 1x sensor de iluminação (fotoresistor). 39 | - 1x resistor de 4.7K 40 | - 1x regulador de tensão DC-DC _Step-Up_ USB (de 0.9-5v para 5v, 600mA). 41 | - 1x bateria 18650 (4.2V, 9800mAh). 42 | - 1x Módulo carregador de baterias Li-ion **TP4056**, **COM PROTEÇÃO**. 43 | - 4x paineis solares de 6V (embora o máximo que consegui medir foi pouco mais de 5V), 1W. 44 | - 2x Cabos USB-A e Micro-USB. **Basta ser um cabo para alimentação. Não precisa dos recursos de transferência de dados**. 45 | 46 | ![Foto_02](./Images/ESP32-CAM.jpg) 47 | 48 | - 2 - **Módulo ESP32-CAM com o servidor Web**: 49 | - 1x Módulo ESP32-CAM 50 | - 1x Módulo programador **FT232R FTDI** (o ESP32-CAM não é programado de forma direta como nas placas NodeMCU). 51 | - 1x Uma fonte de 5V 52 | 53 | 54 | 55 | # 2 - Diagramas e fotos dos circuitos: 56 | 57 | 58 | ## 2.1 - Parte 1 - ESP8266 e sensores 59 | 60 | 61 | ### 2.1.1 - Alimentação (painéis solares) 62 | ![Foto_03](./Images/Pic_02_PowerSupplyAndBattery.jpg) 63 | ![Foto_04](./Images/Modulo_01_Parte01_Alimentacao_bb.png) 64 | 65 | 66 | ### 2.1.2 - NodeMCU e Sensores 67 | ![Foto_03](./Images/Pic_03_ESP8266BattCharger.jpg) 68 | ![Foto_04](./Images/Modulo_01_Parte02_NodeMCU_Sensores_bb.png) 69 | 70 | 71 | ### 2.1.3 - Selecionar o NodeMCU no Arduino IDE 72 | ![Foto_05](./Images/Pic_05_ESP8266_Select.PNG) 73 | 74 | 75 | ### 2.1.4 - Servidor MQTT: 76 | ![Subscrever Tópico no Mosquitto](./Images/Pic_06_MosquittoMQTT.PNG) 77 | 78 | - Os valores retornados pelas leituras dos sensores são publicados no servidor MQTT executado no Raspberry Pi. 79 | - O programa usado aqui é o **Moquito MQTT Broker**. 80 | - A imagem acima mostra o resultado de uma subscrição ao tópico **`sensors/temp`**. 81 | 82 | ![MyMQTT (Android) Screenshot](./Images/Pic_07_MyMQTT.png) 83 | 84 | - Alternativamente, as leituras de um tópico MQTT também podem ser apresentadas no aplicativo **MyMQTT** (Android). 85 | - A imagem acima mostra o MyMQTT recebendo os dados do servidor MQTT executado no Raspberry Pi. 86 | - Os tópicos subscritos foram: 87 | - **`sensors/temp`**. 88 | - **`sensors/pressure`**. 89 | - **`sensors/adc_ldr`**. 90 | 91 | 92 | 93 | ## 2.2 - Parte 2 - ESP32-CAM 94 | 95 | 96 | ### 2.2.1 - Programação do ESP32-CAM 97 | ![Foto_06](./Images/Modulo_02_Parte01_Programacao_bb.png) 98 | ![Foto_07](./Images/Pic_09_ESP32-CAM_Programming.jpg) 99 | 100 | - O ESP32-CAM precisa de ser programado através de um programador FTDI. 101 | - Nas imagens acima, ele está sendo programado usando um módulo **FT232R FTDI**. 102 | - No momento de programar o ESP32-CAM, colocá-lo em _boot mode_, **conectando os pinos `IO0` e `GND`**. 103 | 104 | 105 | ### 2.2.2 - Selecionando o ESP32-CAM no Arduino IDE: 106 | ![Img_09](./Images/Pic_08_ESP32-CAM_Select.PNG) 107 | 108 | 109 | ### 2.2.3 - Execução 110 | ![Foto_08](./Images/Modulo_02_Parte02_Execucao_bb.png) 111 | ![Foto_09](./Images/Pic_04_ESP32-CAM.jpg) 112 | 113 | - Para executar o _sketch_ enviado para o ESP32-CAM, basta remover o fio conectando os pinos `IO0` e `GND`. 114 | 115 | 116 | ### 2.2.4 - O Servidor Web no ESP32-CAM: 117 | ![Img_10](./Images/Pic_10_Output_M02_MonitorSerial.PNG) 118 | ![Img_11](./Images/Pic_11_Output_WebServer.PNG) 119 | 120 | - Como mostra o output no Arduino IDE, o sevidor web está disponível na rede Wi-Fi no endereço **`192.168.0.9:8888`**. 121 | 122 | 123 | ### 2.2.5 - O serviço de redirecionamento Ngrok: 124 | ![Img_12](./Images/Pic_12_Output_Ngrok.PNG) 125 | ![Img_13](./Images/Pic_13_Output_ServWebNgrok.PNG) 126 | 127 | - Antes de realizar o procedimento, se cadastrar no site do Ngrok, baixar, instalar e configurar o programa do Ngrok. 128 | - Procedimento: 129 | - 1 - Ir para o diretório onde o Ngrok está instalado (no Windows, caso tenha adicionado o caminho para o executável do Ngrok à variável de ambiente `PATH`, esse procedimento não é necessário). 130 | - 2 - Executar Ngrok especificando o endereo do servidor web na rede Wi-Fi: 131 | - **Raspberry Pi**: `./ngrok tcp 192.168.0.9:8888` 132 | - **Windows Power Shell**: `ngrok tcp 192.168.0.9:8888` 133 | - Lembrando que o endereço especificado nos comandos acima somente valem no caso do endereço de IP do ESP32-CAM na rede Wi-Fi ser `192.168.0.9`. 134 | - O output mostrado na primeira imagem mostra que o endereço de internet para acessar o servidor web em qualquer lugar é: **`http://0.tcp.ngrok.io:19298/` **. 135 | 136 | -------------------------------------------------------------------------------- /Relatorio_Projeto_ServidorWeb_Sensores_Camera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Relatorio_Projeto_ServidorWeb_Sensores_Camera.pdf -------------------------------------------------------------------------------- /Report_WebServer_ESP32-CAM_Sensors.md: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | pdf_document: default 4 | html_document: default 5 | --- 6 | # Project - Web server publishing ESP32-CAM pictures and sensor data readings from a MQTT server: 7 | 8 | 9 | # 1 - Project Modules and Required Parts: 10 | 11 | ## 1.1 - The three modules of the project: 12 | - 1 - Module using the 'NodeMCU V1.0' board with SoC ESP12-E (with ESP8266 microcontroller). 13 | - Reads the temperature (in ºC) and air pressure (in hPa) from the BMP280 module and the ADC value from the Light Dependent Resistor (LDR). 14 | - The data read from the sensors are sent to the MQTT server. 15 | - The NodeMCU is power-supplied by a 18650 battery. 16 | - The 18650 battery is charged by a TP4056 module and four solar panels. 17 | - 2 - ESP32-CAM Module: 18 | - Take a picture every five minutes. It just stores the last picture taken, in the SPIFFS memory of the ESP32-CAM. 19 | - This module hosts the web server HTML page which shows the last picture taken and the sensor data. 20 | - The HTML code of the wep page is generated in a function of the sketch of this module. 21 | - The template of the web page is hosted in the header file 'PAG_WEB.h' 22 | - 3 - PC executing **Moquitto MQTT** and Ngrok. 23 | - Here, I used a Raspberry Pi with the necessary software installed. 24 | - But its not a requisite to use a Raspberry Pi here. Any computer with windows will do the same thing. It just needs the required software. 25 | - **Mosquitto MQTT**: Its the MQTT server program. It receives the published data from the NodeMCU ESP8266 and sends the published data to the ESP32-CAM (the subscriber). 26 | - **Ngrok**: Its the internet server which redirects the ESP32-CAM web server to the internet. 27 | - It requires an account in the Ngrok site. 28 | - It offers some free services, like the one shown here. But the site has some paid services too. 29 | - I'm using here only its free services. 30 | 31 | 32 | ## 1.2 - Parts used in each module of the project: 33 | ![Img_01](./Images/M01P01_PowerSupply_bb.png) 34 | 35 | - 1 - **NodeMCU (ESP12-E) with the sensors**: 36 | - 1x NodeMCU 1.0 module (SoC ESP12-E, with the ESP8266 microcontroller). 37 | - 1x BMP280 sensor module (temperature and air pressure) 38 | - 1x light dependent resistor (LDR). 39 | - 1x 4.7K resistor. 40 | - 1x DC-DC step-up USB voltage regulator (from 0.9-5V to 5V - 600 mA - with a USB-A output). 41 | - 1x 18650 battery (4.2V, 9800mAh). 42 | - 1x Li-ion battery charger module **TP4056**, **WITH PROTECTION**. 43 | - 4x 1W 6V solar panels (the specifications told that they were 6V panels, but my measurements showed 5V-2.15V). 44 | - 2x USB cables, with a USB-A and a USB Micro-B terminals. **A charging-only cable does this service very well**. 45 | 46 | ![Img_02](./Images/ESP32-CAM.jpg) 47 | 48 | - 2 - **Módulo ESP32-CAM with the web server**: 49 | - 1x ESP32-CAM module 50 | - 1x **FT232R FTDI** programmer (the ESP32-CAM doesn't contain a CP2101 chip to transfer the sketches to it). 51 | - 1x 5V DC power supply. 52 | 53 | 54 | # 2 - Diagrams and photos: 55 | 56 | 57 | ## 2.1 - Part 1 - ESP8266 and sensors 58 | 59 | 60 | ### 2.1.1 - Power Supply (solar panels and battery charger) 61 | ![Img_03](./Images/M01P01_PowerSupply_bb.png) 62 | ![Img_04](./Images/Pic_02_PowerSupplyAndBattery.jpg) 63 | 64 | 65 | ### 2.1.2 - NodeMCU and Sensores 66 | ![Img_05](./Images/M01P02_NodeMCU_Sensors_bb.png) 67 | ![Img_06](./Images/Pic_03_ESP8266BattCharger.jpg) 68 | 69 | 70 | ### 2.1.3 - Selecting the NodeMCU board in Arduino IDE 71 | ![Selecting the NodeMCU board in Arduino IDE](./Images/Pic_05_ESP8266_Select.PNG) 72 | 73 | 74 | ### 2.1.4 - MQTT Server: 75 | ![Subscribing to a Topic in Mosquitto](./Images/Pic_06_MosquittoMQTT.PNG) 76 | 77 | - The sensor readings are published in the MQTT Server running on Raspberry Pi. 78 | - The MQTT server program used here is the **Moquito MQTT Broker**. 79 | - The picture above shows the result of a subscription to the topic **`sensors/temp`**. 80 | 81 | ![MyMQTT (Android) Screenshot](./Images/Pic_07_MyMQTT.png) 82 | 83 | - Alternativelly, you can subscribe for a MQTT with the **MyMQTT** App (Android). 84 | - The image above shows the result on the MyMQTT App, after connecting to my MQTT server in Raspberry Pi and subscribint to the following topics: 85 | - **`sensors/temp`**. 86 | - **`sensors/pressure`**. 87 | - **`sensors/adc_ldr`**. 88 | 89 | 90 | ## 2.2 - Part 2 - ESP32-CAM 91 | 92 | 93 | ### 2.2.1 - Programming the ESP32-CAM with the FT232R FTDI 94 | ![Img_07](./Images/M02P01_Programming_bb.png) 95 | ![Img_08](./Images/Pic_09_ESP32-CAM_Programming.jpg) 96 | 97 | - The image above shows hw to connect the ESP32-CAM to the FT232R FTDI programmer. 98 | - The **`IO0`** pin of the ESP32-CAM must be connected to the **`GND`** pin of the ESP32-CAM. 99 | 100 | 101 | ### 2.2.2 - Selecting the ESP32-CAM in Arduino IDE: 102 | ![Img_09](./Images/Pic_08_ESP32-CAM_Select.PNG) 103 | 104 | 105 | ### 2.2.3 - Running the sketch 106 | ![Img_08](./Images/M02P02_Running_bb.png) 107 | ![Img_09](./Images/Pic_04_ESP32-CAM.jpg) 108 | 109 | - I Used here an broken Arduino UNO, whose power-supply pins were the only pins working. 110 | - But any 5V DC power-supply will do the same. 111 | - Don't forget to remove the wire connecting the pins `IO0` and `GND`. 112 | 113 | 114 | ### 2.2.4 - The ESP32-CAM Web server: 115 | ![Img_10](./Images/Pic_10_Output_M02_MonitorSerial.PNG) 116 | ![Img_11](./Images/Pic_11_Output_WebServer.PNG) 117 | 118 | - The first image above shows the output in Monitor Serial of the Arduino IDE. 119 | - The ESP32-CAM IP address in my Wi-Fi network is **192.168.0.9**. 120 | - To access the web server (second image above), just type in your internet browser the IP address of the ESP32-CAM and the port number (in my case, **`192.168.0.9:8888`**). 121 | 122 | 123 | ### 2.2.5 - The Ngrok redirection service: 124 | ![Img_12](./Images/Pic_12_Output_Ngrok.PNG) 125 | ![Img_13](./Images/Pic_13_Output_ServWebNgrok.PNG) 126 | 127 | - After install and configure the Ngrok program in your Raspberry Pi or PC, and with the web server of the ESP32-CAM running, you can execute the Ngrok to make the web server available in the internet. 128 | - In Raspberry Pi: 129 | - Go to the folder where the Ngrok program is installed: `cd /home/pi/Downloads` (Or the folder which you installed it). 130 | - Execute Ngrok: 131 | - **Raspberry Pi**: `./ngrok tcp 192.168.0.9:8888` 132 | - **Windows Power Shell**: `ngrok tcp 192.168.0.9:8888` 133 | - The ouput shown in the first image above shows that my web server is available in the address `http://0.tcp.ngrok.io:19298/` 134 | - To access your web server outside your Wi-Fi network, just type this address (`http://0.tcp.ngrok.io:19298/` ) in any internet browseer. 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Report_WebServer_ESP32-CAM_Sensors.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT/51f3707ae0fb30ac72fddd7eba8d30b276b83eed/Report_WebServer_ESP32-CAM_Sensors.pdf --------------------------------------------------------------------------------