{"id":98426,"date":"2020-08-12T13:31:18","date_gmt":"2020-08-12T13:31:18","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=98426"},"modified":"2025-04-11T17:28:40","modified_gmt":"2025-04-11T17:28:40","slug":"esp32-cam-shield-pcb-telegram","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cam-shield-pcb-telegram\/","title":{"rendered":"ESP32-CAM with Telegram: Take Photos, Control Outputs, Request Sensor Readings and Motion Notifications"},"content":{"rendered":"\n<p>In this project we&#8217;ll create a PCB shield for the ESP32-CAM AI-Thinker board with a PIR motion sensor, a BME280 temperature, humidity and pressure sensor and some additional exposed pins. We&#8217;ll create a Telegram bot for the ESP32-CAM that allows you to control your board from anywhere to request a photo, sensor readings or control the flash. Additionally, you&#8217;ll receive a notification with a new photo whenever motion is detected. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32-CAM with Telegram Take Photos, Control Outputs, Request Sensor Readings and Motion Notifications\" class=\"wp-image-98650\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>Alternatively, you can also follow this project by wiring the circuit on a breadboard.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Watch the Video Tutorial<\/h2>\n\n\n\n<p>This project is available in video format and in written format. You can watch the video below or you can scroll down for the written instructions.<\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/tgaqegUNNyE?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Resources<\/h3>\n\n\n\n<p>You can find all the resources needed to build this project in the links below (or you can visit the&nbsp;<a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub project<\/a>):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/master\/ESP32_CAM_Shield_PCB_Telegram\/ESP32_CAM_Shield_PCB_Telegram.ino\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32-CAM Code (Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Gerber_PCB_2020-07-07_10-25-47_2020-07-07_11-49-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Gerber files<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Project_ESP32-CAM%20Shield%20PCB_%20Telegram%20Take%20Photos%2C%20Detect%20Motion%20and%20Sensor%20Readings_2020-07-27_16-27-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\">EasyEDA project to edit the PCB<\/a><\/li>\n\n\n\n<li><strong><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Click here to download all the files<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>This project consists of three parts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"#1\" title=\"#1\">Designing and Building the PCB shield<\/a><\/li>\n\n\n\n<li><a href=\"#2\">Creating the Telegram Bot<\/a><\/li>\n\n\n\n<li><a href=\"#3\">Programming the PCB shield using Arduino IDE<\/a><\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">ESP32-CAM PCB Shield Features<\/h3>\n\n\n\n<p>The PCB shield is designed to be stacked to the ESP32-CAM. For this reason, if you want to use our PCB, you need the same ESP32-CAM board. We\u2019re using the&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-cam\/\" target=\"_blank\">ESP32-CAM AI-Thinker Module<\/a>. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Mounted.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM AI Thinker Module Shield PCB Parts Components Mounted\" class=\"wp-image-98462\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Mounted.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Mounted.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>We&#8217;re also using a <a href=\"https:\/\/makeradvisor.com\/tools\/ov2640-probes-esp32-cam\/\" target=\"_blank\" rel=\"noreferrer noopener\">camera module with a longer ribbon<\/a>. So that when you mount the shield, the camera is on the same side of the PIR motion sensor.<\/p>\n\n\n\n<p>Alternatively, you can also assemble the circuit on a breadboard.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Project Telegram Test Circuit Diagram Breadboard Wiring\" class=\"wp-image-98471\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The shield consists of:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/bme280-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME280 <\/a>temperature, humidity and pressure sensor (4 pins);<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mini-hc-sr505-pir-motion-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">Mini PIR motion sensor (AM312)<\/a>;<\/li>\n\n\n\n<li>Exposed 5V and GND pins to power up the shield and ESP32-CAM;<\/li>\n\n\n\n<li>Other exposed GPIOs if you want to add additional features.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">ESP32-CAM PCB Shield Pin Assignment<\/h3>\n\n\n\n<p>This is the pin assignment for the BME280 and PIR motion sensor on the PCB shield:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PIR Motion Sensor: <span class=\"rnthl rntcyellow\">GPIO 13<\/span><\/li>\n\n\n\n<li>BME280: <span class=\"rnthl rntcgreen\">GPIO 14<\/span> (SDA), <span class=\"rnthl rntcblue\">GPIO 15<\/span> (SCL)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">ESP32-CAM Telegram Bot<\/h3>\n\n\n\n<p>To control the ESP32-CAM shield, we&#8217;ll create a Telegram bot, so that you can monitor your ESP32-CAM from anywhere (as long as you have internet access in your smartphone). You can use the following commands to interact with your bot:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\/start<\/strong>: sends a welcome message with the valid commands to control the shield;<\/li>\n\n\n\n<li><strong>\/flash<\/strong>: toggles the ESP32-CAM LED Flash;<\/li>\n\n\n\n<li><strong>\/photo<\/strong>: takes a new photo and sends it to your Telegram account;<\/li>\n\n\n\n<li><strong>\/readings<\/strong>: requests the latest BME280 sensor readings.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"336\" height=\"600\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion-Notifications.jpg?resize=336%2C600&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32-CAM with Telegram Take Photos Control Outputs Request Sensor Readings and Motion Notifications Demonstration\" class=\"wp-image-98610\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion-Notifications.jpg?w=336&amp;quality=100&amp;strip=all&amp;ssl=1 336w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion-Notifications.jpg?resize=168%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 168w\" sizes=\"(max-width: 336px) 100vw, 336px\" \/><\/figure><\/div>\n\n\n<p>Additionally, you&#8217;ll receive a notification with a photo whenever motion is detected. Finally, only you (or any other authorized user that you want) can control the ESP32-CAM using Telegram. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1\">Testing the Circuit on a Breadboard<\/h2>\n\n\n\n<p>Before designing and building the PCB shield, it\u2019s important to test the circuit on a breadboard. If you don\u2019t want to make a PCB, you can still follow this project by assembling the circuit on a breadboard.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Project Telegram Test Circuit Diagram Breadboard Wiring\" class=\"wp-image-98471\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Project-Telegram-Test-Circuit-Diagram-Breadboard-Wiring.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Parts Required<\/h3>\n\n\n\n<p>To assemble the circuit on a breadboard you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/esp32-cam\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32-CAM AI-Thinker<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mini-hc-sr505-pir-motion-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">Mini PIR motion sensor<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/bme280-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME280<\/a>&nbsp;(4 pins)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/ftdi-programmer-board\/\" target=\"_blank\" rel=\"noreferrer noopener\">FTDI programmer<\/a> (to <a href=\"https:\/\/randomnerdtutorials.com\/program-upload-code-esp32-cam\/\">upload code<\/a>)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noreferrer noopener\">Breadboard<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jumper wires<\/a><\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<p>After gathering all the parts, assemble the circuit by following the next schematic diagram:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"970\" height=\"1238\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-BME280-PIR-Motion-Sensor-Wiring-Schematic-Diagram.jpg?resize=970%2C1238&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM with BME280 and PIR Motion Sensor Wiring Schematic Diagram\" class=\"wp-image-98449\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-BME280-PIR-Motion-Sensor-Wiring-Schematic-Diagram.jpg?w=970&amp;quality=100&amp;strip=all&amp;ssl=1 970w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-BME280-PIR-Motion-Sensor-Wiring-Schematic-Diagram.jpg?resize=235%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 235w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-BME280-PIR-Motion-Sensor-Wiring-Schematic-Diagram.jpg?resize=802%2C1024&amp;quality=100&amp;strip=all&amp;ssl=1 802w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-BME280-PIR-Motion-Sensor-Wiring-Schematic-Diagram.jpg?resize=768%2C980&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 970px) 100vw, 970px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Designing the PCB<\/h2>\n\n\n\n<p>To design the circuit and PCB, we used&nbsp;<a href=\"https:\/\/easyeda.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">EasyEDA<\/a>&nbsp;which is a browser based software to design PCBs. If you want to customize your PCB, you just need to upload the following files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Project_ESP32-CAM%20Shield%20PCB_%20Telegram%20Take%20Photos%2C%20Detect%20Motion%20and%20Sensor%20Readings_2020-07-27_16-27-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\">EasyEDA project files to edit the PCB<\/a><\/li>\n<\/ul>\n\n\n\n<p>Designing the circuit works like in any other circuit software tool, you place some components and you wire them together. Then, you assign each component to a footprint.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"563\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?resize=1200%2C563&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM PCB Shield Circuit Diagram Telegram Take Photo PIR BME280\" class=\"wp-image-98446\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?w=1312&amp;quality=100&amp;strip=all&amp;ssl=1 1312w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?resize=300%2C141&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?resize=1024%2C481&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Circuit-Diagram-Telegram-Take-Photo-PIR-BME280.png?resize=768%2C361&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure><\/div>\n\n\n<p>Having the parts assigned, place each component. When you\u2019re happy with the layout, make all the connections and route your PCB.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Telegram-Take-Photo-PIR-BME280.png?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"426\" height=\"624\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Telegram-Take-Photo-PIR-BME280.png?resize=426%2C624&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM PCB Shield Telegram Tale Photo PIR BME280\" class=\"wp-image-98447\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Telegram-Take-Photo-PIR-BME280.png?w=426&amp;quality=100&amp;strip=all&amp;ssl=1 426w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCB-Shield-Telegram-Take-Photo-PIR-BME280.png?resize=205%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 205w\" sizes=\"(max-width: 426px) 100vw, 426px\" \/><\/a><\/figure><\/div>\n\n\n<p>Save your project and export the Gerber files.<\/p>\n\n\n\n<p><strong>Note:&nbsp;<\/strong>you can grab the project files and edit them to customize the shield for your own needs.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Gerber_PCB_2020-07-07_10-25-47_2020-07-07_11-49-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Download Gerber .zip file<\/strong><\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Project_ESP32-CAM%20Shield%20PCB_%20Telegram%20Take%20Photos%2C%20Detect%20Motion%20and%20Sensor%20Readings_2020-07-27_16-27-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\">EasyEDA project to edit the PCB<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Ordering the PCBs at PCBWay<\/h2>\n\n\n\n<p>This project is sponsored by PCBWay.&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/pcbway\" target=\"_blank\" rel=\"noreferrer noopener\">PCBWay<\/a>&nbsp;is a full feature Printed Circuit Board manufacturing service.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/randomnerdtutorials.com\/pcbway\" target=\"_blank\" rel=\"noreferrer noopener\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"291\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-banner.jpg?resize=750%2C291&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Ordering the PCBs at PCBWay\" class=\"wp-image-97545\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-banner.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-banner.jpg?resize=300%2C116&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/figure><\/div>\n\n\n<p>Turn your DIY breadboard circuits into&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/pcbway\" target=\"_blank\" rel=\"noreferrer noopener\">professional PCBs<\/a>&nbsp;\u2013 get 10 boards for approximately $5 + shipping (which will vary depending on your country).<\/p>\n\n\n\n<p>Once you have your Gerber files, you can order the PCB. Follow the next steps to download the file.<\/p>\n\n\n\n<p>1. Download the Gerber files \u2013&nbsp;<a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/Gerber_PCB_2020-07-07_10-25-47_2020-07-07_11-49-04.zip\" target=\"_blank\" rel=\"noreferrer noopener\">click here to download the .zip file<\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"445\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Gerber_Files_PCB.png?resize=728%2C445&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Upload Gerber Files PCB folder\" class=\"wp-image-98584\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Gerber_Files_PCB.png?w=728&amp;quality=100&amp;strip=all&amp;ssl=1 728w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Gerber_Files_PCB.png?resize=300%2C183&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 728px) 100vw, 728px\" \/><\/figure><\/div>\n\n\n<p>2. Go to&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/pcbway\" target=\"_blank\" rel=\"noreferrer noopener\">PCBWay website<\/a>&nbsp;and open the PCB Instant Quote page.&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"504\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/1-PCBWay-Order-PCB.png?resize=900%2C504&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Order PCB open instant quote page\" class=\"wp-image-97554\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/1-PCBWay-Order-PCB.png?w=900&amp;quality=100&amp;strip=all&amp;ssl=1 900w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/1-PCBWay-Order-PCB.png?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/1-PCBWay-Order-PCB.png?resize=768%2C430&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure><\/div>\n\n\n<p>3. PCBWay can grab all the PCB details and automatically fill them for you. Use the \u201cQuick-order PCB (Autofill parameters)\u201d.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"469\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/2-PCBWay-Order-PCB-autofill-parameters.png?resize=900%2C469&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Order PCB autofill parameters\" class=\"wp-image-97555\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/2-PCBWay-Order-PCB-autofill-parameters.png?w=900&amp;quality=100&amp;strip=all&amp;ssl=1 900w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/2-PCBWay-Order-PCB-autofill-parameters.png?resize=300%2C156&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/2-PCBWay-Order-PCB-autofill-parameters.png?resize=768%2C400&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure><\/div>\n\n\n<p>4. Press the \u201c+ Add Gerber file\u201d button to upload the provided Gerber files.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"521\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/3-PCBWay-Order-PCB-gerbers-files.png?resize=939%2C521&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Order PCB add gerber file button\" class=\"wp-image-97556\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/3-PCBWay-Order-PCB-gerbers-files.png?w=939&amp;quality=100&amp;strip=all&amp;ssl=1 939w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/3-PCBWay-Order-PCB-gerbers-files.png?resize=300%2C166&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/3-PCBWay-Order-PCB-gerbers-files.png?resize=768%2C426&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n<p>And that\u2019s it. You can also use the OnlineGerberViewer to check if your PCB is looking as it should.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"828\" height=\"350\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/PCBWay-Preview-PCB.png?resize=828%2C350&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Upload Gerbers Files and PCB Online preview\" class=\"wp-image-98585\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/PCBWay-Preview-PCB.png?w=828&amp;quality=100&amp;strip=all&amp;ssl=1 828w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/PCBWay-Preview-PCB.png?resize=300%2C127&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/PCBWay-Preview-PCB.png?resize=768%2C325&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/figure><\/div>\n\n\n<p>If you aren\u2019t in a hurry, you can use the China Post shipping method to lower your cost significantly. In our opinion, we think they overestimate the China Post shipping time.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"365\" height=\"630\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/6-PCBWay-Order-PCB-china-post.png?resize=365%2C630&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Order PCB China post shipping method\" class=\"wp-image-97559\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/6-PCBWay-Order-PCB-china-post.png?w=365&amp;quality=100&amp;strip=all&amp;ssl=1 365w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/6-PCBWay-Order-PCB-china-post.png?resize=174%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 174w\" sizes=\"(max-width: 365px) 100vw, 365px\" \/><\/figure><\/div>\n\n\n<p>You can increase your PCB order quantity and change the solder mask color. I\u2019ve ordered the Blue color.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"490\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/7-PCBWay-Order-PCB-final-step.png?resize=1000%2C490&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Order PCB final step and save to cart\" class=\"wp-image-97551\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/7-PCBWay-Order-PCB-final-step.png?w=1000&amp;quality=100&amp;strip=all&amp;ssl=1 1000w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/7-PCBWay-Order-PCB-final-step.png?resize=300%2C147&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/7-PCBWay-Order-PCB-final-step.png?resize=768%2C376&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure><\/div>\n\n\n<p>Once you\u2019re ready, you can order the PCBs by clicking \u201cSave to Cart\u201d and complete your order.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unboxing<\/h2>\n\n\n\n<p>After approximately one week using the DHL shipping method, I received the PCBs at my office.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-Unboxing.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"PCBWay Unboxing\" class=\"wp-image-97576\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-Unboxing.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/PCBWay-Unboxing.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Everything comes well packed, and the PCBs are really high-quality. The letters on the silkscreen are really well-printed and easy to read. Additionally, the solder sticks easily to the pads.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Unboxing.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Shield PCB for ESP32-CAM AI Thinker Module Unboxing\" class=\"wp-image-98468\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Unboxing.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Unboxing.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Besides the PCBs, I also received some gifts (celebration of their 6th anniversary): a badge, some stickers, a t-shirt, a pen and some rulers.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCBWay-Unboxing-PCBs.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Shield PCBWay Unboxing PCBs and Gift bag\" class=\"wp-image-98465\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCBWay-Unboxing-PCBs.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-PCBWay-Unboxing-PCBs.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Soldering the Components<\/h2>\n\n\n\n<p>The next step is soldering the components to the PCB. You just need to solder female header pins. The PIR motion sensor and the BME280 will then connect to those pins.<\/p>\n\n\n\n<p>Here\u2019s a list of all the components needed to build the PCB shield:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/bme280-sensor-module\/\">1x BME280<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mini-hc-sr505-pir-motion-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x Mini PIR motion sensor<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/female-pin-header-socket\" target=\"_blank\" rel=\"noreferrer noopener\">Female pin header socket<\/a>&nbsp;(2.54 mm)<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Required.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM AI Thinker Module Shield PCB Parts Components Required\" class=\"wp-image-98463\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Required.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Parts-Components-Required.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Here\u2019s the soldering tools I\u2019ve used:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/ts80-soldering-iron-review\/\" target=\"_blank\" rel=\"noreferrer noopener\">TS80 mini portable soldering iron<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.banggood.com\/0_5mm-500g-Soldering-Wires-Welding-Iron-Rosin-Core-6040-Lead-Tin-Flux-2_0-Percent-p-1023387.html?p=MA240439985285201910\" target=\"_blank\" rel=\"noreferrer noopener\">Solder 60\/40 0.5mm diameter<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/soldering-mats-review\/\" target=\"_blank\" rel=\"noreferrer noopener\">Soldering mat<\/a><\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/TS80-Soldering-Iron-Review-Best-Portable-Soldering-Iron.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TS80 Soldering Iron Review Best Portable Soldering Iron\" class=\"wp-image-97549\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/TS80-Soldering-Iron-Review-Best-Portable-Soldering-Iron.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/TS80-Soldering-Iron-Review-Best-Portable-Soldering-Iron.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p>Read our review about the TS80 Soldering Iron:&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/ts80-soldering-iron-review\/\" target=\"_blank\">TS80 Soldering Iron Review \u2013 Best Portable Soldering Iron<\/a>.<\/p>\n\n\n\n<p>The soldering process is pretty simple as you just need to solder the headers pins. There are some exposed GPIOs in the middle of the shield. Solder pins to those GPIOs if you want to use them to connect any other peripherals.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Soldering-Parts-Components.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM AI Thinker Module Shield PCB Soldering Parts Components\" class=\"wp-image-98464\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Soldering-Parts-Components.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Soldering-Parts-Components.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Here&#8217;s how the ESP32-CAM PCB Shield looks like after assembling.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM AI Thinker Module Shield PCB Final Assembled Demonstration\" class=\"wp-image-98606\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"2\">Creating a Telegram Bot<\/h2>\n\n\n\n<p>The ESP32-CAM will interact with a Telegram bot to receive and handle the messages, and send responses to your Telegram account (sensor readings and photos). Follow the next steps to create a Telegram bot.<\/p>\n\n\n\n<p>Go to Google Play or App Store, download and install&nbsp;<strong>Telegram<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"354\" height=\"269\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-Telegram.png?resize=354%2C269&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install and Download Telegram\" class=\"wp-image-97821\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-Telegram.png?w=354&amp;quality=100&amp;strip=all&amp;ssl=1 354w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-Telegram.png?resize=300%2C228&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 354px) 100vw, 354px\" \/><\/figure><\/div>\n\n\n<p>Open Telegram and follow the next steps to create a Telegram Bot. First, search for \u201c<strong>botfather<\/strong>\u201d and click the BotFather as shown below. Or open this link <a href=\"http:\/\/t.me\/botfather\" target=\"_blank\" rel=\"noreferrer noopener\">t.me\/botfather<\/a> in your smartphone.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"362\" height=\"198\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Botfather.png?resize=362%2C198&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"botfather\" class=\"wp-image-97822\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Botfather.png?w=362&amp;quality=100&amp;strip=all&amp;ssl=1 362w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Botfather.png?resize=300%2C164&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 362px) 100vw, 362px\" \/><\/figure><\/div>\n\n\n<p>The following window should open and you\u2019ll be prompted to click the&nbsp;<strong>start<\/strong>&nbsp;button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"352\" height=\"708\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/start-bot-father-telegram.png?resize=352%2C708&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Telegram Start BotFather to Create a new Bot\" class=\"wp-image-97824\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/start-bot-father-telegram.png?w=352&amp;quality=100&amp;strip=all&amp;ssl=1 352w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/start-bot-father-telegram.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 352px) 100vw, 352px\" \/><\/figure><\/div>\n\n\n<p>Type&nbsp;<strong>\/newbot<\/strong>&nbsp;and follow the instructions to create your bot. Give it a name and username.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"354\" height=\"396\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Create-bot-Telegram-Botfather_f.png?resize=354%2C396&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Telegram BotFather Create a New Bot\" class=\"wp-image-97826\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Create-bot-Telegram-Botfather_f.png?w=354&amp;quality=100&amp;strip=all&amp;ssl=1 354w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Create-bot-Telegram-Botfather_f.png?resize=268%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 268w\" sizes=\"(max-width: 354px) 100vw, 354px\" \/><\/figure><\/div>\n\n\n<p>If your bot is successfully created, you\u2019ll receive a message with a link to access the bot and the&nbsp;<strong>bot token<\/strong>. Save the bot token because you\u2019ll need it so that the ESP32\/ESP8266 can interact with the bot.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"356\" height=\"537\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Bot-Token-Telegram-Bot-Father.png?resize=356%2C537&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Telegram BotFather Get Bot Token\" class=\"wp-image-97827\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Bot-Token-Telegram-Bot-Father.png?w=356&amp;quality=100&amp;strip=all&amp;ssl=1 356w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Bot-Token-Telegram-Bot-Father.png?resize=199%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 199w\" sizes=\"(max-width: 356px) 100vw, 356px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Get Your Telegram User ID<\/h2>\n\n\n\n<p>Anyone that knows your bot username can interact with it. To make sure that we ignore messages that are not from our Telegram account (or any authorized users), you can get your Telegram User ID. Then, when your telegram bot receives a message, the ESP can check whether the sender ID corresponds to your User ID and handle the message or ignore it.<\/p>\n\n\n\n<p>In your Telegram account, search for &#8220;IDBot&#8221; or open this link <a href=\"http:\/\/t.me\/myidbot\" target=\"_blank\" rel=\"noreferrer noopener\">t.me\/myidbot<\/a> in your smartphone.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"348\" height=\"173\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-ID-Bot.png?resize=348%2C173&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Telegram Get Chat ID with IDBot\" class=\"wp-image-97830\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-ID-Bot.png?w=348&amp;quality=100&amp;strip=all&amp;ssl=1 348w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-ID-Bot.png?resize=300%2C149&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 348px) 100vw, 348px\" \/><\/figure><\/div>\n\n\n<p>Start a conversation with that bot and type&nbsp;<strong>\/getid<\/strong>. You will get a reply back with your user ID. Save that&nbsp;<strong>user ID<\/strong>, because you\u2019ll need it later in this tutorial.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"354\" height=\"500\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Get-Chat-ID.png?resize=354%2C500&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Telegram Get Chat ID with IDBot getid\" class=\"wp-image-97836\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Get-Chat-ID.png?w=354&amp;quality=100&amp;strip=all&amp;ssl=1 354w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Telegram-Get-Chat-ID.png?resize=212%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 212w\" sizes=\"(max-width: 354px) 100vw, 354px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"3\">Preparing Arduino IDE<\/h2>\n\n\n\n<p>We\u2019ll program the&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-cam\/\" target=\"_blank\">ESP32-CAM<\/a> using Arduino IDE, so make sure you have the ESP32 add-on installed in your Arduino IDE.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing the ESP32 Board in Arduino IDE (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Universal Telegram Bot Library<\/h3>\n\n\n\n<p>To interact with the Telegram bot, we\u2019ll use the&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/witnessmenow\/Universal-Arduino-Telegram-Bot\" target=\"_blank\">Universal Telegram Bot Library<\/a>&nbsp;created by Brian Lough that provides an easy interface for the Telegram Bot API.<\/p>\n\n\n\n<p>Follow the next steps to install the latest release of the library.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/witnessmenow\/Universal-Arduino-Telegram-Bot\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Click here to download the Universal Arduino Telegram Bot library<\/a>.<\/li>\n\n\n\n<li>Go to&nbsp;<strong>Sketch&nbsp;<\/strong>&gt;&nbsp;<strong>Include Library<\/strong>&nbsp;&gt;&nbsp;<strong>Add .ZIP Library..<\/strong>.<\/li>\n\n\n\n<li>Add the library you\u2019ve just downloaded.<\/li>\n<\/ol>\n\n\n\n<p>And that\u2019s it. The library is installed.<\/p>\n\n\n\n<p><strong>Important:&nbsp;<\/strong>don\u2019t install the library through the Arduino Library Manager because it might install a deprecated version.<\/p>\n\n\n\n<p>For all the details about the library, take a look at the Universal Arduino Telegram Bot Library&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/witnessmenow\/Universal-Arduino-Telegram-Bot\" target=\"_blank\">GitHub<\/a>&nbsp;page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ArduinoJson Library<\/h3>\n\n\n\n<p>You also have to install the&nbsp;<a href=\"https:\/\/github.com\/bblanchon\" target=\"_blank\" rel=\"noreferrer noopener\">ArduinoJson<\/a>&nbsp;library. Follow the next steps to install the library.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to&nbsp;<strong>Sketch&nbsp;<\/strong>&gt;&nbsp;<strong>Include Library<\/strong>&nbsp;&gt;&nbsp;<strong>Manage Libraries<\/strong>.<\/li>\n\n\n\n<li>Search for \u201cArduinoJson\u201d.<\/li>\n\n\n\n<li>Install the library.<\/li>\n<\/ol>\n\n\n\n<p>We\u2019re using ArduinoJson library version 6.15.2.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"443\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-ArduinoJson-Library.png?resize=786%2C443&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install Arduino JSONLibrary\" class=\"wp-image-97837\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-ArduinoJson-Library.png?w=786&amp;quality=100&amp;strip=all&amp;ssl=1 786w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-ArduinoJson-Library.png?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Install-ArduinoJson-Library.png?resize=768%2C433&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">BME280 SparkFun Library<\/h3>\n\n\n\n<p>In most of our projects with the BME280 sensor, we use the Adafruit_BME280 library. However, it conflicts with some of the ESP32-CAM libraries. So, to avoid modifying the library files, we used the<a href=\"https:\/\/github.com\/sparkfun\/SparkFun_BME280_Arduino_Library\" target=\"_blank\" rel=\"noreferrer noopener\"> <strong>BME280 Sparkfun library<\/strong><\/a> instead that works well with the ESP32-CAM. Follow the next steps to install the BME280 Sparkfun library.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to&nbsp;<strong>Sketch&nbsp;<\/strong>&gt;&nbsp;<strong>Include Library<\/strong>&nbsp;&gt;&nbsp;<strong>Manage Libraries<\/strong>.<\/li>\n\n\n\n<li>Search for \u201cSparkfun BME280\u201d.<\/li>\n\n\n\n<li>Install the library.<\/li>\n<\/ol>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"443\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/Install-BME280-SparkFun-Library-Arduino-IDE.png?resize=786%2C443&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install BME280 Sparkfun Library in Arduino IDE\" class=\"wp-image-98451\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/Install-BME280-SparkFun-Library-Arduino-IDE.png?w=786&amp;quality=100&amp;strip=all&amp;ssl=1 786w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/Install-BME280-SparkFun-Library-Arduino-IDE.png?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/Install-BME280-SparkFun-Library-Arduino-IDE.png?resize=768%2C433&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Control ESP32-CAM with Telegram &#8211; Arduino Sketch<\/h2>\n\n\n\n<p>The following sketch allows you to control the ESP32-CAM using your Telegram account. You&#8217;ll also receive a notification with a photo when motion is detected.<\/p>\n\n\n\n<p>Copy the following code to your Arduino IDE. To make it work for you, you need to insert your network credentials (SSID and password), your Telegram Bot Token and your Telegram User ID.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\r\n  Rui Santos\r\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp32-cam-shield-pcb-telegram\/\r\n  \r\n  Project created using Brian Lough's Universal Telegram Bot Library: https:\/\/github.com\/witnessmenow\/Universal-Arduino-Telegram-Bot\r\n\r\n  The above copyright notice and this permission notice shall be included in all\r\n  copies or substantial portions of the Software.\r\n*\/\r\n\r\n#include &lt;WiFi.h&gt;\r\n#include &lt;WiFiClientSecure.h&gt;\r\n#include &quot;soc\/soc.h&quot;\r\n#include &quot;soc\/rtc_cntl_reg.h&quot;\r\n#include &quot;esp_camera.h&quot;\r\n#include &lt;UniversalTelegramBot.h&gt;\r\n#include &lt;ArduinoJson.h&gt;\r\n#include &lt;Wire.h&gt;\r\n#include &quot;SparkFunBME280.h&quot;\r\n\r\n\/\/ Replace with your network credentials\r\nconst char* ssid = &quot;REPLACE_WITH_YOUR_SSID&quot;;\r\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\r\n\r\n\/\/ Use @myidbot to find out the chat ID of an individual or a group\r\n\/\/ Also note that you need to click &quot;start&quot; on a bot before it can\r\n\/\/ message you\r\nString chatId = &quot;XXXXXXXXXX&quot;;\r\n\r\n\/\/ Initialize Telegram BOT\r\nString BOTtoken = &quot;XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&quot;;\r\n\r\nbool sendPhoto = false;\r\n\r\nWiFiClientSecure clientTCP;\r\n\r\nUniversalTelegramBot bot(BOTtoken, clientTCP);\r\n\r\n\/\/CAMERA_MODEL_AI_THINKER\r\n#define PWDN_GPIO_NUM     32\r\n#define RESET_GPIO_NUM    -1\r\n#define XCLK_GPIO_NUM      0\r\n#define SIOD_GPIO_NUM     26\r\n#define SIOC_GPIO_NUM     27\r\n\r\n#define Y9_GPIO_NUM       35\r\n#define Y8_GPIO_NUM       34\r\n#define Y7_GPIO_NUM       39\r\n#define Y6_GPIO_NUM       36\r\n#define Y5_GPIO_NUM       21\r\n#define Y4_GPIO_NUM       19\r\n#define Y3_GPIO_NUM       18\r\n#define Y2_GPIO_NUM        5\r\n#define VSYNC_GPIO_NUM    25\r\n#define HREF_GPIO_NUM     23\r\n#define PCLK_GPIO_NUM     22\r\n\r\n#define FLASH_LED_PIN 4\r\nbool flashState = LOW;\r\n\r\n\/\/ Motion Sensor\r\nbool motionDetected = false;\r\n\r\n\/\/ Define I2C Pins for BME280\r\n#define I2C_SDA 14\r\n#define I2C_SCL 15\r\n\r\nBME280 bme;\r\n \r\nint botRequestDelay = 1000;   \/\/ mean time between scan messages\r\nlong lastTimeBotRan;     \/\/ last time messages' scan has been done\r\n\r\nvoid handleNewMessages(int numNewMessages);\r\nString sendPhotoTelegram();\r\n\r\n\/\/ Get BME280 sensor readings and return them as a String variable\r\nString getReadings(){\r\n  float temperature, humidity;\r\n  temperature = bme.readTempC();\r\n  \/\/temperature = bme.readTempF();\r\n  humidity = bme.readFloatHumidity();\r\n  String message = &quot;Temperature: &quot; + String(temperature) + &quot; \u00baC \\n&quot;;\r\n  message += &quot;Humidity: &quot; + String (humidity) + &quot; % \\n&quot;;\r\n  return message;\r\n}\r\n\r\n\/\/ Indicates when motion is detected\r\nstatic void IRAM_ATTR detectsMovement(void * arg){\r\n  \/\/Serial.println(&quot;MOTION DETECTED!!!&quot;);\r\n  motionDetected = true;\r\n}\r\n\r\nvoid setup(){\r\n  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); \r\n  Serial.begin(115200);\r\n  \r\n  pinMode(FLASH_LED_PIN, OUTPUT);\r\n  digitalWrite(FLASH_LED_PIN, flashState);\r\n\r\n  \/\/ Init BME280 sensor\r\n  Wire.begin(I2C_SDA, I2C_SCL);\r\n  bme.settings.commInterface = I2C_MODE;\r\n  bme.settings.I2CAddress = 0x76;\r\n  bme.settings.runMode = 3;\r\n  bme.settings.tStandby = 0;\r\n  bme.settings.filter = 0;\r\n  bme.settings.tempOverSample = 1;\r\n  bme.settings.pressOverSample = 1;\r\n  bme.settings.humidOverSample = 1;\r\n  bme.begin();\r\n  \r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println();\r\n  Serial.print(&quot;Connecting to &quot;);\r\n  Serial.println(ssid);\r\n  WiFi.begin(ssid, password);\r\n  clientTCP.setCACert(TELEGRAM_CERTIFICATE_ROOT); \/\/ Add root certificate for api.telegram.org\r\n  while (WiFi.status() != WL_CONNECTED) {\r\n    Serial.print(&quot;.&quot;);\r\n    delay(500);\r\n  }\r\n  Serial.println();\r\n  Serial.print(&quot;ESP32-CAM IP Address: &quot;);\r\n  Serial.println(WiFi.localIP());\r\n\r\n  camera_config_t config;\r\n  config.ledc_channel = LEDC_CHANNEL_0;\r\n  config.ledc_timer = LEDC_TIMER_0;\r\n  config.pin_d0 = Y2_GPIO_NUM;\r\n  config.pin_d1 = Y3_GPIO_NUM;\r\n  config.pin_d2 = Y4_GPIO_NUM;\r\n  config.pin_d3 = Y5_GPIO_NUM;\r\n  config.pin_d4 = Y6_GPIO_NUM;\r\n  config.pin_d5 = Y7_GPIO_NUM;\r\n  config.pin_d6 = Y8_GPIO_NUM;\r\n  config.pin_d7 = Y9_GPIO_NUM;\r\n  config.pin_xclk = XCLK_GPIO_NUM;\r\n  config.pin_pclk = PCLK_GPIO_NUM;\r\n  config.pin_vsync = VSYNC_GPIO_NUM;\r\n  config.pin_href = HREF_GPIO_NUM;\r\n  config.pin_sccb_sda = SIOD_GPIO_NUM;\r\n  config.pin_sccb_scl = SIOC_GPIO_NUM;\r\n  config.pin_pwdn = PWDN_GPIO_NUM;\r\n  config.pin_reset = RESET_GPIO_NUM;\r\n  config.xclk_freq_hz = 20000000;\r\n  config.pixel_format = PIXFORMAT_JPEG;\r\n\r\n  \/\/init with high specs to pre-allocate larger buffers\r\n  if(psramFound()){\r\n    config.frame_size = FRAMESIZE_UXGA;\r\n    config.jpeg_quality = 10;  \/\/0-63 lower number means higher quality\r\n    config.fb_count = 2;\r\n  } else {\r\n    config.frame_size = FRAMESIZE_SVGA;\r\n    config.jpeg_quality = 12;  \/\/0-63 lower number means higher quality\r\n    config.fb_count = 1;\r\n  }\r\n  \r\n  \/\/ camera init\r\n  esp_err_t err = esp_camera_init(&amp;config);\r\n  if (err != ESP_OK) {\r\n    Serial.printf(&quot;Camera init failed with error 0x%x&quot;, err);\r\n    delay(1000);\r\n    ESP.restart();\r\n  }\r\n\r\n  \/\/ Drop down frame size for higher initial frame rate\r\n  sensor_t * s = esp_camera_sensor_get();\r\n  s-&gt;set_framesize(s, FRAMESIZE_CIF);  \/\/ UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA\r\n\r\n  \/\/ PIR Motion Sensor mode INPUT_PULLUP\r\n  \/\/err = gpio_install_isr_service(0); \r\n  err = gpio_isr_handler_add(GPIO_NUM_13, &amp;detectsMovement, (void *) 13);  \r\n  if (err != ESP_OK){\r\n    Serial.printf(&quot;handler add failed with error 0x%x \\r\\n&quot;, err); \r\n  }\r\n  err = gpio_set_intr_type(GPIO_NUM_13, GPIO_INTR_POSEDGE);\r\n  if (err != ESP_OK){\r\n    Serial.printf(&quot;set intr type failed with error 0x%x \\r\\n&quot;, err);\r\n  }\r\n}\r\n\r\nvoid loop(){\r\n  if (sendPhoto){\r\n    Serial.println(&quot;Preparing photo&quot;);\r\n    sendPhotoTelegram(); \r\n    sendPhoto = false; \r\n  }\r\n\r\n  if(motionDetected){\r\n    bot.sendMessage(chatId, &quot;Motion detected!!&quot;, &quot;&quot;);\r\n    Serial.println(&quot;Motion Detected&quot;);\r\n    sendPhotoTelegram();\r\n    motionDetected = false;\r\n  }\r\n  \r\n  if (millis() &gt; lastTimeBotRan + botRequestDelay){\r\n    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);\r\n    while (numNewMessages){\r\n      Serial.println(&quot;got response&quot;);\r\n      handleNewMessages(numNewMessages);\r\n      numNewMessages = bot.getUpdates(bot.last_message_received + 1);\r\n    }\r\n    lastTimeBotRan = millis();\r\n  }\r\n}\r\n\r\nString sendPhotoTelegram(){\r\n  const char* myDomain = &quot;api.telegram.org&quot;;\r\n  String getAll = &quot;&quot;;\r\n  String getBody = &quot;&quot;;\r\n\r\n  camera_fb_t * fb = NULL;\r\n  fb = esp_camera_fb_get();  \r\n  if(!fb) {\r\n    Serial.println(&quot;Camera capture failed&quot;);\r\n    delay(1000);\r\n    ESP.restart();\r\n    return &quot;Camera capture failed&quot;;\r\n  }  \r\n  \r\n  Serial.println(&quot;Connect to &quot; + String(myDomain));\r\n\r\n  if (clientTCP.connect(myDomain, 443)) {\r\n    Serial.println(&quot;Connection successful&quot;);\r\n    \r\n    String head = &quot;--RandomNerdTutorials\\r\\nContent-Disposition: form-data; name=\\&quot;chat_id\\&quot;; \\r\\n\\r\\n&quot; + chatId + &quot;\\r\\n--RandomNerdTutorials\\r\\nContent-Disposition: form-data; name=\\&quot;photo\\&quot;; filename=\\&quot;esp32-cam.jpg\\&quot;\\r\\nContent-Type: image\/jpeg\\r\\n\\r\\n&quot;;\r\n    String tail = &quot;\\r\\n--RandomNerdTutorials--\\r\\n&quot;;\r\n\r\n    uint16_t imageLen = fb-&gt;len;\r\n    uint16_t extraLen = head.length() + tail.length();\r\n    uint16_t totalLen = imageLen + extraLen;\r\n  \r\n    clientTCP.println(&quot;POST \/bot&quot;+BOTtoken+&quot;\/sendPhoto HTTP\/1.1&quot;);\r\n    clientTCP.println(&quot;Host: &quot; + String(myDomain));\r\n    clientTCP.println(&quot;Content-Length: &quot; + String(totalLen));\r\n    clientTCP.println(&quot;Content-Type: multipart\/form-data; boundary=RandomNerdTutorials&quot;);\r\n    clientTCP.println();\r\n    clientTCP.print(head);\r\n  \r\n    uint8_t *fbBuf = fb-&gt;buf;\r\n    size_t fbLen = fb-&gt;len;\r\n    for (size_t n=0;n&lt;fbLen;n=n+1024) {\r\n      if (n+1024&lt;fbLen) {\r\n        clientTCP.write(fbBuf, 1024);\r\n        fbBuf += 1024;\r\n      }\r\n      else if (fbLen%1024&gt;0) {\r\n        size_t remainder = fbLen%1024;\r\n        clientTCP.write(fbBuf, remainder);\r\n      }\r\n    }  \r\n    \r\n    clientTCP.print(tail);\r\n    \r\n    esp_camera_fb_return(fb);\r\n    \r\n    int waitTime = 10000;   \/\/ timeout 10 seconds\r\n    long startTimer = millis();\r\n    boolean state = false;\r\n    \r\n    while ((startTimer + waitTime) &gt; millis()){\r\n      Serial.print(&quot;.&quot;);\r\n      delay(100);      \r\n      while (clientTCP.available()) {\r\n        char c = clientTCP.read();\r\n        if (state==true) getBody += String(c);        \r\n        if (c == '\\n') {\r\n          if (getAll.length()==0) state=true; \r\n          getAll = &quot;&quot;;\r\n        } \r\n        else if (c != '\\r')\r\n          getAll += String(c);\r\n        startTimer = millis();\r\n      }\r\n      if (getBody.length()&gt;0) break;\r\n    }\r\n    clientTCP.stop();\r\n    Serial.println(getBody);\r\n  }\r\n  else {\r\n    getBody=&quot;Connected to api.telegram.org failed.&quot;;\r\n    Serial.println(&quot;Connected to api.telegram.org failed.&quot;);\r\n  }\r\n  return getBody;\r\n}\r\n\r\nvoid handleNewMessages(int numNewMessages){\r\n  Serial.print(&quot;Handle New Messages: &quot;);\r\n  Serial.println(numNewMessages);\r\n\r\n  for (int i = 0; i &lt; numNewMessages; i++){\r\n    \/\/ Chat id of the requester\r\n    String chat_id = String(bot.messages[i].chat_id);\r\n    if (chat_id != chatId){\r\n      bot.sendMessage(chat_id, &quot;Unauthorized user&quot;, &quot;&quot;);\r\n      continue;\r\n    }\r\n    \r\n    \/\/ Print the received message\r\n    String text = bot.messages[i].text;\r\n    Serial.println(text);\r\n\r\n    String fromName = bot.messages[i].from_name;\r\n\r\n    if (text == &quot;\/flash&quot;) {\r\n      flashState = !flashState;\r\n      digitalWrite(FLASH_LED_PIN, flashState);\r\n    }\r\n    if (text == &quot;\/photo&quot;) {\r\n      sendPhoto = true;\r\n      Serial.println(&quot;New photo  request&quot;);\r\n    }\r\n    if (text == &quot;\/readings&quot;){\r\n      String readings = getReadings();\r\n      bot.sendMessage(chatId, readings, &quot;&quot;);\r\n    }\r\n    if (text == &quot;\/start&quot;){\r\n      String welcome = &quot;Welcome to the ESP32-CAM Telegram bot.\\n&quot;;\r\n      welcome += &quot;\/photo : takes a new photo\\n&quot;;\r\n      welcome += &quot;\/flash : toggle flash LED\\n&quot;;\r\n      welcome += &quot;\/readings : request sensor readings\\n\\n&quot;;\r\n      welcome += &quot;You'll receive a photo whenever motion is detected.\\n&quot;;\r\n      bot.sendMessage(chatId, welcome, &quot;Markdown&quot;);\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Shield-Telegram\/raw\/master\/ESP32_CAM_Shield_PCB_Telegram\/ESP32_CAM_Shield_PCB_Telegram.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#4\" title=\"#4\">next section<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Importing Libraries<\/h2>\n\n\n\n<p>Start by importing the required libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;WiFi.h&gt;\n#include &lt;WiFiClientSecure.h&gt;\n#include \"soc\/soc.h\"\n#include \"soc\/rtc_cntl_reg.h\"\n#include \"esp_camera.h\"\n#include &lt;UniversalTelegramBot.h&gt;\n#include &lt;ArduinoJson.h&gt;\n#include &lt;Wire.h&gt;\n#include \"SparkFunBME280.h\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Network Credentials<\/h2>\n\n\n\n<p>Insert your network credentials in the following variables.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid = \"REPLACE_WITH_YOUR_SSID\";\nconst char* password = \"REPLACE_WITH_YOUR_PASSWORD\";<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Telegram User ID<\/h2>\n\n\n\n<p>Insert your Telegram chat ID on the <span class=\"rnthl rntliteral\">chatId<\/span> variable. The one you&#8217;ve got from the IDBot.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String chatId = \"XXXXXXXXXX\";<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Telegram Bot Token<\/h2>\n\n\n\n<p>Insert your Telegram Bot token you&#8217;ve got from <strong>Botfather<\/strong> on the <span class=\"rnthl rntliteral\">BOTtoken<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String BOTtoken = \"XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\";<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">sendPhoto<\/span> Boolean variable indicates whether it is time to send a new photo to your telegram account. By default, it is set to <span class=\"rnthl rntliteral\">false<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>bool sendPhoto = false;<\/code><\/pre>\n\n\n\n<p>Create a new WiFi client with <span class=\"rnthl rntliteral\">WiFiClientSecure<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFiClientSecure clientTCP;<\/code><\/pre>\n\n\n\n<p>Create a bot with the token and client defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>UniversalTelegramBot bot(BOTtoken, clientTCP);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Camera Pins<\/h3>\n\n\n\n<p>Define the pins used by the ESP32-CAM:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/CAMERA_MODEL_AI_THINKER\n#define PWDN_GPIO_NUM     32\n#define RESET_GPIO_NUM    -1\n#define XCLK_GPIO_NUM      0\n#define SIOD_GPIO_NUM     26\n#define SIOC_GPIO_NUM     27\n\n#define Y9_GPIO_NUM       35\n#define Y8_GPIO_NUM       34\n#define Y7_GPIO_NUM       39\n#define Y6_GPIO_NUM       36\n#define Y5_GPIO_NUM       21\n#define Y4_GPIO_NUM       19\n#define Y3_GPIO_NUM       18\n#define Y2_GPIO_NUM        5\n#define VSYNC_GPIO_NUM    25\n#define HREF_GPIO_NUM     23\n#define PCLK_GPIO_NUM     22<\/code><\/pre>\n\n\n\n<p>This is the pin definition for the AI-Thinker board, if you&#8217;re using another camera model, check the  pinout for your board: ESP32-CAM Camera Boards: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-camera-pin-gpios\/\">Pin and GPIOs Assignment Guide<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Flash LED<\/h3>\n\n\n\n<p>Create a variable to hold the flash LED pin (<span class=\"rnthl rntliteral\">FLASH_LED_PIN<\/span>). In the ESP32-CAM AI\u2011Thinker, the flash is connected to GPIO 4. By default, set it to <span class=\"rnthl rntliteral\">LOW<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define FLASH_LED_PIN 4\nbool flashState = LOW;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Motion Sensor<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">motionDetected<\/span> variable indicates whether motion has been detected. It is set to <span class=\"rnthl rntliteral\">false<\/span> by default.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>bool motionDetected = false;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">BME280<\/h3>\n\n\n\n<p>Define the SDA and SCL pins to be used with the BME280. <\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define I2C_SDA 14\n#define I2C_SCL 15<\/code><\/pre>\n\n\n\n<p>Create a <span class=\"rnthl rntliteral\">BME280<\/span> instance called <span class=\"rnthl rntliteral\">bme<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>BME280 bme;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Request Delay<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">botRequestDelay<\/span> and <span class=\"rnthl rntliteral\">lasTimeBotRan<\/span> variables are used to check for new Telegram messages every x number of seconds. In this case, the code will check for new messages every second (1000 milliseconds). You can change that delay time in the <span class=\"rnthl rntliteral\">botRequestDelay<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>int botRequestDelay = 1000;   \/\/ mean time between scan messages\nlong lastTimeBotRan;     \/\/ last time messages' scan has been done<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">handleNewMessages()<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">handleNewMessages()<\/span> function handles what happens when new messages arrive.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void handleNewMessages(int numNewMessages){\n  Serial.print(\"Handle New Messages: \");\n  Serial.println(numNewMessages);<\/code><\/pre>\n\n\n\n<p>Get the chat ID for that particular message and store it in the <span class=\"rnthl rntliteral\">chat_id<\/span> variable. The chat ID identifies who sent the message.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String chat_id = String(bot.messages&#091;i].chat_id);<\/code><\/pre>\n\n\n\n<p>If the <span class=\"rnthl rntliteral\">chat_id<\/span> is different from your chat ID (<span class=\"rnthl rntliteral\">chatId<\/span>), it means that someone (that is not you) has sent a message to your bot. If that&#8217;s the case, ignore the message and wait for the next message.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (chat_id != chatId){\n  bot.sendMessage(chat_id, \"Unauthorized user\", \"\");\n  continue;\n}<\/code><\/pre>\n\n\n\n<p>Otherwise, it means that the message was sent from a valid user, so we&#8217;ll save it in the <span class=\"rnthl rntliteral\">text<\/span> variable and check its content.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String text = bot.messages&#091;i].text;\nSerial.println(text);<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">from_name<\/span> variable saves the name of the sender.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String fromName = bot.messages&#091;i].from_name;<\/code><\/pre>\n\n\n\n<p>If it receives the <strong>\/flash<\/strong> message, invert the <span class=\"rnthl rntliteral\">flashState<\/span> variable and update the flash led state. If it was previously <span class=\"rnthl rntliteral\">LOW<\/span>, set it to <span class=\"rnthl rntliteral\">HIGH<\/span>. If it was previously <span class=\"rnthl rntliteral\">HIGH<\/span>, set it to <span class=\"rnthl rntliteral\">LOW<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (text == \"\/flash\") {\n  flashState = !flashState;\n  digitalWrite(FLASH_LED_PIN, flashState);\n}<\/code><\/pre>\n\n\n\n<p>If it receives the <strong>\/photo<\/strong> message, set the <span class=\"rnthl rntliteral\">sendPhoto<\/span> variable to <span class=\"rnthl rntliteral\">true<\/span>. Then, in the <span class=\"rnthl rntliteral\">loop()<\/span>, we&#8217;ll check the value of the <span class=\"rnthl rntliteral\">sendPhoto<\/span> variable and proceed accordingly.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (text == \"\/photo\") {\n  sendPhoto = true;\n  Serial.println(\"New photo request\");\n}<\/code><\/pre>\n\n\n\n<p>If it receives the <strong>\/readings<\/strong> message, call the <span class=\"rnthl rntliteral\">getReadings()<\/span> function (we&#8217;ll take a look at that function later on) and send the readings to the bot.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (text == \"\/readings\"){\n  String readings = getReadings();\n  bot.sendMessage(chatId, readings, \"\");\n}<\/code><\/pre>\n\n\n\n<p>Sending a message to the bot is very simple. You just need to use the <span class=\"rnthl rntliteral\">sendMessage()<\/span> method on the <span class=\"rnthl rntliteral\">bot<\/span> object and pass as arguments the recipient&#8217;s chat ID, the message, and the parse mode.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>bool sendMessage(String chat_id, String text, String parse_mode = \"\")<\/code><\/pre>\n\n\n\n<p>Finally, if it receives the <strong>\/start<\/strong> message, we&#8217;ll send the valid commands to control the ESP. This is useful if you happen to forget what are the commands to control your board.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (text == \"\/start\"){\n  String welcome = \"Welcome to the ESP32-CAM Telegram bot.\\n\";\n  welcome += \"\/photo : takes a new photo\\n\";\n  welcome += \"\/flash : toggle flash LED\\n\";\n  welcome += \"\/readings : request sensor readings\\n\\n\";\n  welcome += \"You'll receive a photo whenever motion is detected.\\n\";\n  bot.sendMessage(chatId, welcome, \"Markdown\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">sendPhotoTelegram()<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">sendPhotoTelegram()<\/span> function takes a photo with the ESP32-CAM.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>camera_fb_t * fb = NULL;\nfb = esp_camera_fb_get();\nif(!fb) {\n  Serial.println(\"Camera capture failed\");\n  delay(1000);\n  ESP.restart();\n  return \"Camera capture failed\";\n}<\/code><\/pre>\n\n\n\n<p>Then, it makes an HTTP POST request to send the photo to your telegram bot.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>clientTCP.println(\"POST \/bot\"+BOTtoken+\"\/sendPhoto HTTP\/1.1\");\nclientTCP.println(\"Host: \" + String(myDomain));\nclientTCP.println(\"Content-Length: \" + String(totalLen));\nclientTCP.println(\"Content-Type: multipart\/form-data; boundary=RandomNerdTutorials\");\nclientTCP.println();\nclientTCP.print(head);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">getReadings()<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">getReadings()<\/span> function requests temperature and humidity from the BME280 sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String getReadings(){\n  float temperature, humidity;\n  temperature = bme.readTempC();\n  \/\/temperature = bme.readTempF();\n  humidity = bme.readFloatHumidity();<\/code><\/pre>\n\n\n\n<p>The readings are concatenated in the <span class=\"rnthl rntliteral\">message<\/span> variable that is returned by the function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String message = \"Temperature: \" + String(temperature) + \" \u00baC \\n\";\nmessage += \"Humidity: \" + String (humidity) + \" % \\n\";\nreturn message;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">detectsMovement()<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">detectsMovement()<\/span> is a callback function that is called when motion is detected. In this case, we set the <span class=\"rnthl rntliteral\">motionDetected<\/span> variable to <span class=\"rnthl rntliteral\">true<\/span>. Then, in the <span class=\"rnthl rntliteral\">loop()<\/span>, we&#8217;ll handle what happens when there&#8217;s motion (sends a photo).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static void IRAM_ATTR detectsMovement(void * arg){\n  \/\/Serial.println(\"MOTION DETECTED!!!\");\n  motionDetected = true;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>Set the flash LED as an output and set it to its initial state.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>pinMode(FLASH_LED_PIN, OUTPUT);\ndigitalWrite(FLASH_LED_PIN, flashState);<\/code><\/pre>\n\n\n\n<p>Initialize the BME280 sensor:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Init BME280 sensor\nWire.begin(I2C_SDA, I2C_SCL);\nbme.settings.commInterface = I2C_MODE;\nbme.settings.I2CAddress = 0x76;\nbme.settings.runMode = 3;\nbme.settings.tStandby = 0;\nbme.settings.filter = 0;\nbme.settings.tempOverSample = 1;\nbme.settings.pressOverSample = 1;\nbme.settings.humidOverSample = 1;\nbme.begin();<\/code><\/pre>\n\n\n\n<p>Connect your ESP32-CAM to your local network.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFi.mode(WIFI_STA);\nSerial.println();\nSerial.print(\"Connecting to \");\nSerial.println(ssid);\nWiFi.begin(ssid, password);\nwhile (WiFi.status() != WL_CONNECTED) {\n  Serial.print(\".\");\n  delay(500);\n}\nSerial.println();\nSerial.print(\"ESP32-CAM IP Address: \");\nSerial.println(WiFi.localIP());<\/code><\/pre>\n\n\n\n<p>Configure and initialize the camera.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>camera_config_t config;\nconfig.ledc_channel = LEDC_CHANNEL_0;\nconfig.ledc_timer = LEDC_TIMER_0;\nconfig.pin_d0 = Y2_GPIO_NUM;\nconfig.pin_d1 = Y3_GPIO_NUM;\nconfig.pin_d2 = Y4_GPIO_NUM;\nconfig.pin_d3 = Y5_GPIO_NUM;\nconfig.pin_d4 = Y6_GPIO_NUM;\nconfig.pin_d5 = Y7_GPIO_NUM;\nconfig.pin_d6 = Y8_GPIO_NUM;\nconfig.pin_d7 = Y9_GPIO_NUM;\nconfig.pin_xclk = XCLK_GPIO_NUM;\nconfig.pin_pclk = PCLK_GPIO_NUM;\nconfig.pin_vsync = VSYNC_GPIO_NUM;\nconfig.pin_href = HREF_GPIO_NUM;\nconfig.pin_sccb_sda = SIOD_GPIO_NUM;\nconfig.pin_sccb_scl = SIOC_GPIO_NUM;\nconfig.pin_pwdn = PWDN_GPIO_NUM;\nconfig.pin_reset = RESET_GPIO_NUM;\nconfig.xclk_freq_hz = 20000000;\nconfig.pixel_format = PIXFORMAT_JPEG;\n\n\/\/init with high specs to pre-allocate larger buffers\nif(psramFound()){\n  config.frame_size = FRAMESIZE_UXGA;\n  config.jpeg_quality = 10;  \/\/0-63 lower number means higher quality\n  config.fb_count = 2;\n} else {\n  config.frame_size = FRAMESIZE_SVGA;\n  config.jpeg_quality = 12;  \/\/0-63 lower number means higher quality\n  config.fb_count = 1;\n}\n\n\/\/ camera init\nesp_err_t err = esp_camera_init(&amp;config);\nif (err != ESP_OK) {\n  Serial.printf(\"Camera init failed with error 0x%x\", err);\n  delay(1000);\n  ESP.restart();\n}\n\n\/\/ Drop down frame size for higher initial frame rate\nsensor_t * s = esp_camera_sensor_get();\ns->set_framesize(s, FRAMESIZE_CIF);  \/\/ UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA<\/code><\/pre>\n\n\n\n<p>Setup an interrupt on GPIO 13:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>err = gpio_isr_handler_add(GPIO_NUM_13, &amp;detectsMovement, (void *) 13);\nif (err != ESP_OK){\n  Serial.printf(\"handler add failed with error 0x%x \\r\\n\", err); \n}\nerr = gpio_set_intr_type(GPIO_NUM_13, GPIO_INTR_POSEDGE);\nif (err != ESP_OK){\n  Serial.printf(\"set intr type failed with error 0x%x \\r\\n\", err);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">loop()<\/h2>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, check the state of the <span class=\"rnthl rntliteral\">sendPhoto<\/span> variable. If it is <span class=\"rnthl rntliteral\">true<\/span>, call the <span class=\"rnthl rntliteral\">sendPhotoTelegram()<\/span> function to take and send a photo to your telegram account.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (sendPhoto){\n  Serial.println(\"Preparing photo\");\n  sendPhotoTelegram(); \n  sendPhoto = false; \n}<\/code><\/pre>\n\n\n\n<p>When it\u2019s done, set the <span class=\"rnthl rntliteral\">sendPhoto<\/span> variable to <span class=\"rnthl rntliteral\">false<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>sendPhoto = false; <\/code><\/pre>\n\n\n\n<p>When motion is detected, send a notification to your Telegram account and call the <span class=\"rnthl rntliteral\">senPhototoTelegram()<\/span> function. Then, set the <span class=\"rnthl rntliteral\">motionDetected<\/span> variable to <span class=\"rnthl rntliteral\">false<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(motionDetected){\n  bot.sendMessage(chatId, \"Motion detected!!\", \"\");\n  Serial.println(\"Motion Detected\");\n  sendPhotoTelegram();\n  motionDetected = false;\n}<\/code><\/pre>\n\n\n\n<p>Check for new Telegram messages every second.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (millis() &gt; lastTimeBotRan + botRequestDelay){\n  int numNewMessages = bot.getUpdates(bot.last_message_received + 1);\n  while (numNewMessages){\n    Serial.println(\"got response\");\n    handleNewMessages(numNewMessages);\n    numNewMessages = bot.getUpdates(bot.last_message_received + 1);\n  }\n  lastTimeBotRan = millis();\n}<\/code><\/pre>\n\n\n\n<p>When a new message arrives, call the <span class=\"rnthl rntliteral\">handleNewMessages()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>while (numNewMessages){\n  Serial.println(\"got response\");\n  handleNewMessages(numNewMessages);\n  numNewMessages = bot.getUpdates(bot.last_message_received + 1);\n}<\/code><\/pre>\n\n\n\n<p>That&#8217;s pretty much how the code works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4\">Upload Code to the ESP32-CAM<\/h2>\n\n\n\n<p>After making the necessary changes, upload the code to your ESP32-CAM (before connecting the shield). Follow the next steps to upload code or follow this tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/program-upload-code-esp32-cam\/\">How to upload code to ESP32-CAM<\/a>.<\/p>\n\n\n\n<p><strong>1)<\/strong> Wire the ESP32-CAM to the FTDI programmer as shown in the following diagram.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"877\" height=\"532\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-CAM-FTDI-programmer.png?resize=877%2C532&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM connected to an FTDI Programmer to upload program using Arduino IDE\" class=\"wp-image-159060\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-CAM-FTDI-programmer.png?w=877&amp;quality=100&amp;strip=all&amp;ssl=1 877w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-CAM-FTDI-programmer.png?resize=300%2C182&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-CAM-FTDI-programmer.png?resize=768%2C466&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 877px) 100vw, 877px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclgreen\"><strong>Note: <\/strong> the order of the FTDI pins on the diagram may not match yours. Make sure you check the silkscreen label next to each pin.<\/p>\n\n\n\n<p class=\"rntbox rntcred\"><strong>Important: <\/strong> GPIO 0&nbsp;needs to be connected to&nbsp;GND&nbsp;so that you\u2019re able to upload code.<\/p>\n\n\n\n<p><strong>2)<\/strong> Go to&nbsp;<strong>Tools&nbsp;<\/strong>&gt;&nbsp;<strong>Board&nbsp;<\/strong>and select&nbsp;<strong>AI-Thinker ESP32-CAM<\/strong>. You must have the&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/installing-the-esp32-board-in-arduino-ide-windows-instructions\/\">ESP32 add-on installed<\/a>. Otherwise, this board won\u2019t show up on the Boards menu.<\/p>\n\n\n\n<p><strong>3)<\/strong> Go to&nbsp;<strong>Tools&nbsp;<\/strong>&gt;&nbsp;<strong>Port&nbsp;<\/strong>and select the COM port the ESP32-CAM is connected to.<\/p>\n\n\n\n<p><strong>4) <\/strong>Then, click the&nbsp;<strong>Upload&nbsp;<\/strong>button in your Arduino IDE.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"32\" height=\"32\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/upload-button-arduino-ide.png?resize=32%2C32&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Program ESP32-CAM with Arduino IDE\" class=\"wp-image-91745\"\/><\/figure><\/div>\n\n\n<p><strong>5)<\/strong> When you start to see some dots on the debugging window, press the ESP32-CAM on-board RST button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1009\" height=\"91\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/dots-uploading-code.png?resize=1009%2C91&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Upload code to ESP32-CAM Connecting to Serial Port\" class=\"wp-image-91746\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/dots-uploading-code.png?w=1009&amp;quality=100&amp;strip=all&amp;ssl=1 1009w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/dots-uploading-code.png?resize=300%2C27&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/dots-uploading-code.png?resize=768%2C69&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1009px) 100vw, 1009px\" \/><\/figure><\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/02\/ESP32-CAM-Press-Click-RESET-RST-button-on-board-restart.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Press RESET RST on-board button to restart\" class=\"wp-image-93570\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/02\/ESP32-CAM-Press-Click-RESET-RST-button-on-board-restart.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/02\/ESP32-CAM-Press-Click-RESET-RST-button-on-board-restart.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>After a few seconds, the code should be successfully uploaded to your board.<\/p>\n\n\n\n<p><strong>6)<\/strong> When you see the \u201c<strong>Done uploading<\/strong>\u201d message, remove&nbsp;GPIO 0&nbsp;from&nbsp;GND.<\/p>\n\n\n\n<p>Open the Serial Monitor, press the on-board RST button, and check that the ESP32-CAM is connecting to your network without any problems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>With the code uploaded to your ESP32-CAM, attach the PCB shield and all the components. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Stack-to-AI-Thinker-Module.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Shield PCB Stack to AI Thinker Module\" class=\"wp-image-98467\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Stack-to-AI-Thinker-Module.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32-CAM-Shield-PCB-Stack-to-AI-Thinker-Module.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Apply power using the 5V and GND pins on the shield.<\/p>\n\n\n\n<p>Then, press the ESP32-CAM RST button, so that it starts running the code. <\/p>\n\n\n\n<p>Now, open your Telegram account and test your board. Send the following messages to your ESP32 Telegram bot to control your ESP32-CAM:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\/start<\/strong>: sends a welcome message with the valid commands to control the shield;<\/li>\n\n\n\n<li><strong>\/flash<\/strong>: toggles the ESP32-CAM LED Flash;<\/li>\n\n\n\n<li><strong>\/photo<\/strong>: takes a new photo and sends it to your Telegram account;<\/li>\n\n\n\n<li><strong>\/readings<\/strong>: requests the latest BME280 sensor readings.<\/li>\n<\/ul>\n\n\n\n<p>Additionally, you&#8217;ll receive a notification with a photo whenever motion is detected.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"357\" height=\"600\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion.jpg?resize=357%2C600&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32-CAM with Telegram Take Photos Control Outputs Request Sensor Readings and Motion Notifications Demonstration\" class=\"wp-image-98608\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion.jpg?w=357&amp;quality=100&amp;strip=all&amp;ssl=1 357w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-Telegram-Take-Photos-Control-Outputs-Sensor-Readings-Motion.jpg?resize=179%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 179w\" sizes=\"(max-width: 357px) 100vw, 357px\" \/><\/figure><\/div>\n\n\n<p>If you try to interact with your bot from another account, you\u2019ll get the the \u201c<strong>Unauthorized user<\/strong>\u201d message.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"352\" height=\"711\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Control-ESP32-ESP8266-Outputs-Telegram-Unauthorized-User.png?resize=352%2C711&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32 ESP8266 Outputs Telegram Unauthorized user\" class=\"wp-image-97845\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Control-ESP32-ESP8266-Outputs-Telegram-Unauthorized-User.png?w=352&amp;quality=100&amp;strip=all&amp;ssl=1 352w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/06\/Control-ESP32-ESP8266-Outputs-Telegram-Unauthorized-User.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 352px) 100vw, 352px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial we&#8217;ve created a PCB shield for the ESP32-CAM with a PIR motion sensor and BME280. This creates a more permanent circuit in a small footprint that you can put inside a small enclosure or <a href=\"https:\/\/makeradvisor.com\/dummy-fake-dome-security-camera\/\" target=\"_blank\" rel=\"noreferrer noopener\">dummy camera<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration-Fake-dummy-surveillance-camera.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM shield PCB Demonstration Fake dummy surveillance camera\" class=\"wp-image-98611\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration-Fake-dummy-surveillance-camera.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration-Fake-dummy-surveillance-camera.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>You also learned how to use your Telegram account to control your ESP32-CAM using a Telegram bot. This allows you to control and monitor your board from anywhere, as long as you have internet access in your smartphone.<\/p>\n\n\n\n<p>You can also create your own code to do any other tasks with the shield.<\/p>\n\n\n\n<p>We have other similar projects that include building and designing PCBs that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-iot-shield-pcb-dashboard\/\">ESP32 IoT Shield PCB with Dashboard for Outputs and Sensors<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-an-all-in-one-esp32-weather-station-shield\/\">Build an All-in-One ESP32 Weather Station Shield<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp8266-multisensor-shield\/\">Build a Multisensor Shield for ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/power-saving-latching-circuit\/\">EXTREME POWER SAVING with Microcontroller External Wake Up: Latching Power PCB<\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn more about the ESP32-CAM with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-projects-ebook\/\">Build ESP32-CAM Projects using Arduino IDE eBook<\/a><\/strong><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32-cam\/\">More ESP32-CAM Projects and Tutorials&#8230;<\/a><\/li>\n<\/ul>\n\n\n\n<p>We&#8217;re giving away 5 bare PCBs to someone that posts a comment below (comments might take up to 24 hours to be approved)! Simply post a comment in this blog post about what you would like to do with the PCB and you&#8217;re entered for a chance to win one of these bare PCBs. We&#8217;re currently confirm the winners and we will announce them during this weekend (August 22). So, stay tuned! <strong>[Update] the giveaway ended and the winners are: Gerald Maurer, Jason Wilkins, Svein Utne, Domenico Carvetta, and Jo\u00e3o Paulo.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project we&#8217;ll create a PCB shield for the ESP32-CAM AI-Thinker board with a PIR motion sensor, a BME280 temperature, humidity and pressure sensor and some additional exposed pins. &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32-CAM with Telegram: Take Photos, Control Outputs, Request Sensor Readings and Motion Notifications\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-shield-pcb-telegram\/#more-98426\" aria-label=\"Read more about ESP32-CAM with Telegram: Take Photos, Control Outputs, Request Sensor Readings and Motion Notifications\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":98650,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[276,281,319,264],"tags":[],"class_list":["post-98426","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","category-esp32-project","category-esp32-cam","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/08\/Control-ESP32-CAM-with-Telegram-Take-Photos-Control-Outputs-Request-Sensor-Readings-and-Motion-Notifications.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/98426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=98426"}],"version-history":[{"count":2,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/98426\/revisions"}],"predecessor-version":[{"id":168852,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/98426\/revisions\/168852"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/98650"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=98426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=98426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=98426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}