Components and supplies
ESP32 Camera Module Development Board
Gravity BNO055+BMP280 intelligent 10DOF AHRS
Breadboard (generic)
YL-83 Rain Sensor
Jumper wires (generic)
Project description
Code
Code:
arduino
Upload to your ESP32-CAM module
1/* 'Rain Rain Go Away' Arduino project 2 Components: 3 - ESP32-CAM 4 - BMP280 sensor 5 - Rain sensor 6 - Breadboard 7 - Some jumper wires 8 9 Libraries: 10 - ArduinoJson library 11 - Universal Telegram Bot library (https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot) 12 - BMP280_DEV library by Martin Lindupp 13 14 Created on 24 September 2022 by c010blind3ngineer 15*/ 16 17/* 18 Base code by Rui Santos 19 His complete project details at https://RandomNerdTutorials.com/esp32-cam-shield-pcb-telegram/ 20 21 Project created using Brian Lough's Universal Telegram Bot Library: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 22 23 The above copyright notice and this permission notice shall be included in all 24 copies or substantial portions of the Software. 25*/ 26 27#include <WiFi.h> 28#include <WiFiClientSecure.h> 29#include "soc/soc.h" 30#include "soc/rtc_cntl_reg.h" 31#include "esp_camera.h" 32#include <UniversalTelegramBot.h> 33#include <ArduinoJson.h> 34#include <Wire.h> 35#include <BMP280_DEV.h> 36 37 38// Replace with your network credentials 39const char* ssid = "**********"; 40const char* password = "**********"; 41 42// Use @myidbot to find out the chat ID of an individual or a group 43// Also note that you need to click "start" on a bot before it can 44// message you 45String chatID = "**********"; 46 47// Initialize Telegram BOT 48String BOTtoken = "**********:****************-****************"; 49 50bool sendPhoto = false; 51 52WiFiClientSecure clientTCP; 53 54UniversalTelegramBot bot(BOTtoken, clientTCP); 55 56//CAMERA_MODEL_AI_THINKER 57#define PWDN_GPIO_NUM 32 58#define RESET_GPIO_NUM -1 59#define XCLK_GPIO_NUM 0 60#define SIOD_GPIO_NUM 26 61#define SIOC_GPIO_NUM 27 62 63#define Y9_GPIO_NUM 35 64#define Y8_GPIO_NUM 34 65#define Y7_GPIO_NUM 39 66#define Y6_GPIO_NUM 36 67#define Y5_GPIO_NUM 21 68#define Y4_GPIO_NUM 19 69#define Y3_GPIO_NUM 18 70#define Y2_GPIO_NUM 5 71#define VSYNC_GPIO_NUM 25 72#define HREF_GPIO_NUM 23 73#define PCLK_GPIO_NUM 22 74 75#define FLASH_LED_PIN 4 76bool flashState = LOW; 77 78// Rain Sensor 79bool rainDetected = false; 80 81// Define I2C Pins for BMP280 82#define I2C_SDA 14 83#define I2C_SCL 15 84BMP280_DEV bmp(I2C_SDA, I2C_SCL); 85 86 87float temperature, pressure, altitude; 88 89int botRequestDelay = 1000; // mean time between scan messages 90long lastTimeBotRan; // last time messages' scan has been done 91 92void handleNewMessages(int numNewMessages); 93String sendPhotoTelegram(); 94 95// Get BMP280 sensor readings and return them as a String variable 96String getReadings() { 97 String message = "Temperature: " + String(temperature) + " C \ 98"; 99 message += "Pressure: " + String(pressure) + " Pa \ 100"; 101 message += "Altitude: " + String(altitude) + " m \ 102"; 103 return message; 104} 105 106// Indicates when rain is detected 107static void IRAM_ATTR detectsMovement(void * arg) { 108 Serial.println("RAIN DETECTED!!!"); 109 rainDetected = true; 110} 111 112void setup() { 113 WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 114 Serial.begin(115200); 115 116 pinMode(FLASH_LED_PIN, OUTPUT); 117 digitalWrite(FLASH_LED_PIN, flashState); 118 119 Wire.begin(I2C_SDA, I2C_SCL); 120 121 WiFi.mode(WIFI_STA); 122 Serial.println(); 123 Serial.print("Connecting to "); 124 Serial.println(ssid); 125 WiFi.begin(ssid, password); 126 clientTCP.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org 127 while (WiFi.status() != WL_CONNECTED) { 128 Serial.print("."); 129 delay(500); 130 } 131 Serial.println(); 132 Serial.print("ESP32-CAM IP Address: "); 133 Serial.println(WiFi.localIP()); 134 135 camera_config_t config; 136 config.ledc_channel = LEDC_CHANNEL_0; 137 config.ledc_timer = LEDC_TIMER_0; 138 config.pin_d0 = Y2_GPIO_NUM; 139 config.pin_d1 = Y3_GPIO_NUM; 140 config.pin_d2 = Y4_GPIO_NUM; 141 config.pin_d3 = Y5_GPIO_NUM; 142 config.pin_d4 = Y6_GPIO_NUM; 143 config.pin_d5 = Y7_GPIO_NUM; 144 config.pin_d6 = Y8_GPIO_NUM; 145 config.pin_d7 = Y9_GPIO_NUM; 146 config.pin_xclk = XCLK_GPIO_NUM; 147 config.pin_pclk = PCLK_GPIO_NUM; 148 config.pin_vsync = VSYNC_GPIO_NUM; 149 config.pin_href = HREF_GPIO_NUM; 150 config.pin_sscb_sda = SIOD_GPIO_NUM; 151 config.pin_sscb_scl = SIOC_GPIO_NUM; 152 config.pin_pwdn = PWDN_GPIO_NUM; 153 config.pin_reset = RESET_GPIO_NUM; 154 config.xclk_freq_hz = 20000000; 155 config.pixel_format = PIXFORMAT_JPEG; 156 157 //init with high specs to pre-allocate larger buffers 158 if (psramFound()) { 159 config.frame_size = FRAMESIZE_UXGA; 160 config.jpeg_quality = 10; //0-63 lower number means higher quality 161 config.fb_count = 2; 162 } else { 163 config.frame_size = FRAMESIZE_SVGA; 164 config.jpeg_quality = 12; //0-63 lower number means higher quality 165 config.fb_count = 1; 166 } 167 168 // camera init 169 esp_err_t err = esp_camera_init(&config); 170 if (err != ESP_OK) { 171 Serial.printf("Camera init failed with error 0x%x", err); 172 delay(1000); 173 ESP.restart(); 174 } 175 176 // Drop down frame size for higher initial frame rate 177 sensor_t * s = esp_camera_sensor_get(); 178 s->set_framesize(s, FRAMESIZE_CIF); // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA 179 180 // Rain Sensor mode INPUT_PULLUP 181 //err = gpio_install_isr_service(0); 182 err = gpio_isr_handler_add(GPIO_NUM_13, &detectsMovement, (void *) 13); 183 if (err != ESP_OK) { 184 Serial.printf("handler add failed with error 0x%x \ \ 185", err); 186 } 187 err = gpio_set_intr_type(GPIO_NUM_13, GPIO_INTR_POSEDGE); 188 if (err != ESP_OK) { 189 Serial.printf("set intr type failed with error 0x%x \ \ 190", err); 191 } 192 193 Serial.println("Testing BMP280..."); 194 Serial.println(""); 195 if (!bmp.begin(0x76)) { 196 Serial.print("Oops...something went wrong... please check your BMP280 sensor"); 197 while (1); 198 } 199 bmp.setTimeStandby(TIME_STANDBY_2000MS); // Set the standby time to 2 seconds 200 bmp.startNormalConversion(); // Start BMP280 continuous conversion in NORMAL_MODE 201 202 Serial.print("Bot is awake"); 203 bot.sendMessage(chatID, "Bot is awake", ""); 204} 205 206void loop() { 207 // BMP280 readings need to be on loop to get accurate readings 208 bmp.getMeasurements(temperature, pressure, altitude); 209 210 if (sendPhoto) { 211 Serial.println("Preparing photo"); 212 sendPhotoTelegram(); 213 sendPhoto = false; 214 } 215 216 if (rainDetected) { 217 bot.sendMessage(chatID, "It's raining!", ""); 218 Serial.println("Rain rain go away!!"); 219 sendPhotoTelegram(); 220 rainDetected = false; 221 } 222 223 if (millis() > lastTimeBotRan + botRequestDelay) { 224 int numNewMessages = bot.getUpdates(bot.last_message_received + 1); 225 while (numNewMessages) { 226 Serial.println("got response"); 227 handleNewMessages(numNewMessages); 228 numNewMessages = bot.getUpdates(bot.last_message_received + 1); 229 } 230 lastTimeBotRan = millis(); 231 } 232} 233 234String sendPhotoTelegram() { 235 const char* myDomain = "api.telegram.org"; 236 String getAll = ""; 237 String getBody = ""; 238 239 camera_fb_t * fb = NULL; 240 fb = esp_camera_fb_get(); 241 if (!fb) { 242 Serial.println("Camera capture failed"); 243 delay(1000); 244 ESP.restart(); 245 return "Camera capture failed"; 246 } 247 248 Serial.println("Connect to " + String(myDomain)); 249 250 if (clientTCP.connect(myDomain, 443)) { 251 Serial.println("Connection successful"); 252 253 String head = "--c010blind3ngineer\ \ 254Content-Disposition: form-data; name=\\"chat_id\\"; \ \ 255\ \ 256" + chatID + "\ \ 257--c010blind3ngineer\ \ 258Content-Disposition: form-data; name=\\"photo\\"; filename=\\"esp32-cam.jpg\\"\ \ 259Content-Type: image/jpeg\ \ 260\ \ 261"; 262 String tail = "\ \ 263--c010blind3ngineer--\ \ 264"; 265 266 uint16_t imageLen = fb->len; 267 uint16_t extraLen = head.length() + tail.length(); 268 uint16_t totalLen = imageLen + extraLen; 269 270 clientTCP.println("POST /bot" + BOTtoken + "/sendPhoto HTTP/1.1"); 271 clientTCP.println("Host: " + String(myDomain)); 272 clientTCP.println("Content-Length: " + String(totalLen)); 273 clientTCP.println("Content-Type: multipart/form-data; boundary=c010blind3ngineer"); 274 clientTCP.println(); 275 clientTCP.print(head); 276 277 uint8_t *fbBuf = fb->buf; 278 size_t fbLen = fb->len; 279 for (size_t n = 0; n < fbLen; n = n + 1024) { 280 if (n + 1024 < fbLen) { 281 clientTCP.write(fbBuf, 1024); 282 fbBuf += 1024; 283 } 284 else if (fbLen % 1024 > 0) { 285 size_t remainder = fbLen % 1024; 286 clientTCP.write(fbBuf, remainder); 287 } 288 } 289 290 clientTCP.print(tail); 291 292 esp_camera_fb_return(fb); 293 294 int waitTime = 10000; // timeout 10 seconds 295 long startTimer = millis(); 296 boolean state = false; 297 298 while ((startTimer + waitTime) > millis()) { 299 Serial.print("."); 300 delay(100); 301 while (clientTCP.available()) { 302 char c = clientTCP.read(); 303 if (state == true) getBody += String(c); 304 if (c == '\n') { 305 if (getAll.length() == 0) state = true; 306 getAll = ""; 307 } 308 else if (c != '\r') 309 getAll += String(c); 310 startTimer = millis(); 311 } 312 if (getBody.length() > 0) break; 313 } 314 clientTCP.stop(); 315 Serial.println(getBody); 316 } 317 else { 318 getBody = "Connected to api.telegram.org failed."; 319 Serial.println("Connected to api.telegram.org failed."); 320 } 321 return getBody; 322} 323 324void handleNewMessages(int numNewMessages) { 325 Serial.print("Handle New Messages: "); 326 Serial.println(numNewMessages); 327 328 for (int i = 0; i < numNewMessages; i++) { 329 // Chat id of the requester 330 String chat_id = String(bot.messages[i].chat_id); 331 if (chat_id != chatID) { 332 bot.sendMessage(chat_id, "Unauthorized user", ""); 333 continue; 334 } 335 336 // Print the received message 337 String text = bot.messages[i].text; 338 Serial.println(text); 339 340 String fromName = bot.messages[i].from_name; 341 342 if (text == "/flash") { 343 flashState = !flashState; 344 digitalWrite(FLASH_LED_PIN, flashState); 345 } 346 if (text == "/photo") { 347 sendPhoto = true; 348 Serial.println("New photo request"); 349 } 350 if (text == "/readings") { 351 String readings = getReadings(); 352 bot.sendMessage(chatID, readings, ""); 353 Serial.print(temperature); 354 Serial.print(F("*C ")); 355 Serial.print(pressure); 356 Serial.print(F("hPa ")); 357 Serial.print(altitude); 358 Serial.print(F("m")); 359 } 360 if (text == "/start") { 361 String welcome = "Welcome to the ESP32-CAM Telegram bot.\ 362"; 363 welcome += "/photo : takes a new photo\ 364"; 365 welcome += "/flash : toggle flash LED\ 366"; 367 welcome += "/readings : request sensor readings\ 368\ 369"; 370 welcome += "You'll receive a photo whenever it starts to rain. \ 371"; 372 bot.sendMessage(chatID, welcome, "Markdown"); 373 } 374 } 375} 376
Repository link:
Downloadable files
Schematic:
Schematic:
Circuit:
Circuit:
Comments
Only logged in users can leave comments
c010rblind3ngineer
0 Followers
โข15 Projects
0
0