ESP32-CAM: video surveillance with a PIR sensor on Telegram

ESP32-CAM: video surveillance with a PIR sensor on Telegram

Skip to content A programmable WiFi camera costing just a few euros that, paired with a P.I.R. motion sensor, becomes a security tool able to communicate with our smartphones through Telegram.

The topic of security and video surveillance is increasingly discussed and current, and it is a field of great importance, subject to continuous development thanks to the technological evolution we are witnessing, especially in recent years. It is precisely the refinement and development of technology that have made it possible to apply video surveillance in many sectors and contexts, down to the simplest everyday situations. In fact, today more than ever, technology aims to reduce the cost and size of the installation, so as to broaden its modes as well as its fields of use; not to mention the fact that solutions based on local networks and the Internet have been born, which have greatly extended the application possibilities.

What can we expect, then, from the new systems? Certainly a lot, since the new solutions let us use greater, simplified and extremely innovative functionality. An example of all this could be a cheap camera, lightweight, small in size, already equipped with WiFi and Bluetooth; this is exactly what AI-Thinker offers with the ESP32-Cam which, with its 40.5x27x4.5 dimensions, could be considered the “Swiss army knife” for every maker ( Fig. 1 ).

The latter, following the now well-known and indispensable board based on the ESP8266, features an ESP32 module equipped with a connector to host a separate camera module and a slot for an SD card up to a maximum of 4GB. In detail, we can note that the ESP32-Cam module is based on the ESP32, a programmable microcontroller with integrated WiFi and Bluetooth and an additional external RAM of no less than 4MB.

Not only that, the new camera connector can host an OV2640 or OV7670 module: the first comes with the module itself and has a resolution of 2 Megapixels.

On the board there is also a high-brightness LED, which can be used as a flash or as an illuminator for the scene to be captured. Naturally, the many GPIOs present on the board let us mount an external one if lighting is poor. For small applications this chip proves very robust and with great processing power, being based on two 32-bit processing cores running with a clock at 120 MHz. This last characteristic allows it to have a fairly high frame rate, obviously depending on the format and dimensions: indicatively you can reach a throughput of up to 8 JPEGs in SVGA (800×600) per second.

Let us now see how to exploit every peculiarity of this interesting device. In particular its dimensions, so small that you can build an access control system even inside a single room or a garage. All this by capturing frames for every entry.

But from a practical point of view you might ask yourself: what to do with these photos? When to check them? Examining the different levels of difficulty, in first place we find the need to capture a correct and precise image.

To do this we will build a peripheral able to share and report these accesses in real time directly on our smartphones or by populating our own private cloud.

The ESP32-Cam will take care of detecting, through the PIR motion sensor ( Fig. 3 ), the entry into the surveilled space and the movement within it.

When the latter is crossed, the PIR detects the heat radiation from the moving body and is triggered; its output, which at rest is at logic zero, will then go to a high level, activating the camera, which will store the bytes in a pointer that was previously NULL. If this structure is not populated correctly, the emergency procedure will step in and reset our device.

It only remains to understand how to notify the intrusion to the outside world and what timing to use to be able to shoot again. As for the notification we have several solutions we can exploit: for example the http/https APIs or the MQTT protocol. Both solutions open up different scenarios and can even coexist. Let us proceed in order and examine them case by case.

In our example we will use the http APIs to communicate with the Telegram server to which we will send our photo. Finally we will set a final delay so we can capture a new photo.

This can also be zero if you want to obtain a high-intensity sequence of photos. This delay, as will be seen in the code, will be very important to avoid taking photos in bursts. Naturally, if instead you are interested in shooting in rapid sequence you can omit this delay.

If a PIR motion sensor (passive infrared radar) is not available, it can be replaced with a button ( Fig. 4 ) and thus provide the trigger manually; perhaps the button contact can be replaced with a mat contact, to shoot whenever a person sets foot in a certain area, such as in front of a door.

As for the passive infrared sensor, the circuit expects that at “rest” the signal provided is at a low logic level and that it goes high in case of detection.

By connecting, instead, the button of Fig. 4 directly to the line reserved for the PIR, the behaviour will be inverted if the same is closed towards ground.

Let us now move on to putting the module into operation. Naturally, first we will create the connection for programming the firmware of the ESP32-Cam through Arduino. This step can also be done through an FTDI adapter, making the wiring, at least during the programming phase, extremely easier.

As a first step let us identify the TX and RX pins on our Esp32-Cam, called respectively U0TXD and U0RXD, and we will connect them with the TX and RX pins of the Arduino. In the camera module these pins also represent the GPIO1 and GPIO3 pins.

We will connect the GND and GPIO0 pins of the latter to ground, together with the GND and RESET pins of the Arduino, and the two 5V pins to each other. For the connection we can help ourselves with a breadboard like the one in the photo. Summarising in table form what was expressed previously, we have the situation proposed in Table 1 .

The wiring diagram of the programming circuit is proposed in Fig. 5 .

Let us now add the connection with the PIR sensor: besides the power supply, that is the 3V3 and GND contacts to be brought to the respective VCC and GND of the sensor, we will bring the cable for the actuation signal, starting from pin GPIO13 ( Fig. 6 ), making the following connections:

Once the ESP32-Cam module is programmed, it is necessary to remove the connection between GPIO0 and GND. The whole circuit is powered through the Arduino Uno, that is by supplying the latter with a voltage between 8 and 12V using a stabilised power supply with a DC plug suitable for the Arduino one; the current required is in the order of 500 milliamperes.

Before proceeding with programming we should set up ArduinoIDE, that is our development environment, so we can write correctly to the module. Let us therefore open the Arduino IDE and go to File->Preferences and add in the Additional Boards Manager URLs this link https://dl.espressif.com/dl/package_esp32_index.json and click OK ( Fig. 7 ).

If you already have one or more URLs, use a comma to concatenate them, exactly as in the example. Now let’s download the board manager correctly: go to Tools -> Board: XXXX -> Boards Manager…, search for “esp32” and install the only result of the search (Fig. 8).

On exiting, select Tools -> Board: XXXX again and you will notice a new entry, ESP32 Arduino, which contains several other choices. Select ESP32 Wrover Module, after which a new line will appear in that same menu: Partition scheme, in which we will choose Huge APP (Fig. 9).

Now we have everything we need to upload the firmware to the device, so let’s connect the USB and select the correct port (that is, the one the system tells us the board is connected to) and then click Upload.

At this point we have completed the installation and configuration of the IDE, so we can upload the firmware, which we describe below.

Let’s now look at the code for the project firmware, which for the sake of brevity we will not reproduce in full here, bearing in mind that it is available for download together with the files for this issue.

We present a few excerpts of the firmware, showing in Listing 1 the most substantial part, which is the routine that handles sending the image captured by the on-board camera via Telegram.

String alerts2Telegram(String token, String chat_id) { const char* myDomain = “api.telegram.org”; String getAll=””, getBody = “”; camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if(!fb) { Serial.println(“Camera capture failed”); delay(1000); ESP.restart(); return “Camera capture failed”; } WiFiClientSecure client_tcp; if (client_tcp.connect(myDomain, 443)) { Serial.println(“Connected to ” + String(myDomain)); String head = “–India\r\nContent-Disposition: form-data; name=\”chat_id\”; \r\n\r\n” + chat_id + “\r\n–India\r\nContent-Disposition: form-data; name=\”photo\”; filename=\”esp32-cam.jpg\”\r\nContent-Type: image/jpeg\r\n\r\n”; String tail = “\r\n–India–\r\n”; uint16_t imageLen = fb->len; uint16_t extraLen = head.length() + tail.length(); uint16_t totalLen = imageLen + extraLen; client_tcp.println(“POST /bot”+token+”/sendPhoto HTTP/1.1”); client_tcp.println(“Host: ” + String(myDomain)); client_tcp.println(“Content-Length: ” + String(totalLen)); client_tcp.println(“Content-Type: multipart/form-data; boundary=India”); client_tcp.println(); client_tcp.print(head); uint8_t *fbBuf = fb->buf; size_t fbLen = fb->len; for (size_t n=0;n<fbLen;n=n+1024) { if (n+1024<fbLen) { client_tcp.write(fbBuf, 1024); fbBuf += 1024; } else if (fbLen24>0) { size_t remainder = fbLen24; client_tcp.write(fbBuf, remainder); } } client_tcp.print(tail); esp_camera_fb_return(fb); int waitTime = 10000; // timeout 10 seconds long startTime = millis(); boolean state = false; while ((startTime + waitTime) > millis()) { Serial.print(“.”); delay(100); while (client_tcp.available()) { char c = client_tcp.read(); if (c == ‘\n’) { if (getAll.length()==0) state=true; getAll = “”; } else if (c != ‘\r’) getAll += String(c); if (state==true) getBody += String(c); startTime = millis(); } if (getBody.length()>0) break; } client_tcp.stop(); Serial.println(getBody); } else { getBody = “Connection to telegram failed.”; Serial.println(“Connection to telegram failed.”); } return getBody; }

Below we show the first portion of code, which defines the pins used to drive the camera: note that all the pins are connected “internally” on the board except for pin 13, which is external and to which the PIR motion sensor is connected. This definition is handled by these lines of code:

#define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 int gpioPIR = 13; //PIR Motion Sensor

In the loop cycle the state of the PIR is checked; when the sensor output goes high (1) the routine “alerts2Telegram” is called:

void loop() { pinMode(gpioPIR, INPUT_PULLUP); int v = digitalRead(gpioPIR); if (v==1){ alerts2Telegram(token, chat_id); delay(5000); } delay(500); }

As you can see from the comments in the code, the first four constants must be changed respectively to your own WiFi credentials and two other parameters provided instead by Telegram.

So let’s retrieve those last two values. Open the Telegram app on your smartphone and tap the magnifying glass to search for BotFather (Fig. 10).

Through this chat we can create our first bot, that is, a non-human user capable of performing actions of varying complexity; if you prefer, a robot… So let’s open the BotFather chat, type /newbot and follow the on-screen instructions.

At the end of the procedure we will be issued the token to substitute in our third constant, namely token (Fig. 11).

Let’s now get the last constant, so tap the magnifying glass again and search for the bot we just created: once found, just open it and press Start. It would also be a good idea to write something in this chat and send it. In our case we just write “Hello” and send the message.

Now open a browser session and paste the following link:

https://api.telegram.org/bot<BOTToken>/getUpdates where BOTToken is exactly the token extracted in the previous step. In response to this action, the browser will show a json, that is, a data structure formatted in a certain way, similar to the following:

{ “ok”:true, “result”:[ { “update_id”:YYYYYY, “message”:{ “message_id”:18, “from”:{ “id”:XXXXXXXX, “is_bot”:false, “first_name”:”YOUR FULL TELEGRAM NAME”, “username”:”YOUR TELEGRAM USERNAME”, “language_code”:”it” }, “chat”:{ “id”: XXXXXXXX, “first_name”:”YOUR FULL TELEGRAM NAME”, “username”:”YOUR TELEGRAM USERNAME”, “type”:”private” }, “date”:1600324371, “text”:”Hello” } } ] }

This structure is the interactions with the bot by users. We are interested in the id of the chat where we just sent “Hello”, that is, the one in bold in the example. This ID is exactly the last piece we needed to substitute for chat_id in the code.

Now that we have managed to get a basic solution for access control, it would be appropriate to have remote control of it, not just a mere visualization. It would be useful to be able to operate this control without needing to be physically there to turn the device on and off.

To do this, having a web server is essential. It can be a space rented through services such as Aruba, Register or other similar services, or simply a Raspberry Pi connected to the network with a LAMP base, that is, a solution featuring a Unix/Linux base, an http server engine and a PHP language for writing the scripts.

Actually LAMP is the acronym of its components and would include the Linux operating system, Apache (http server engine), MySql (database engine) and finally the PHP/Python language. In our case the database is superfluous but it could be a more correct and advanced solution.

Inside our server we will put three files: lock.php, lock.txt and finally read.php. The first is the “writer” service, that is, the one that will set the state of our device. Here is the code:

<?php echo getcwd(); $myfile = fopen(“lock.txt”, “w”) or die(“Unable to open file!”); $txt = $_GET[‘status’]; fwrite($myfile, $txt); fclose($myfile); ?>

The second is the file we will use as a database, which contains the state of our device: it is simply a text file in which to put the state “on” or “off”. By default we will set it to “on”.

And finally we have the “reader” service, that is, the one that, inserted into the code of our ESP32, will read the remote state and trigger the notifications or not. Below is the code for the latter:

<?php $myfile = fopen(“lock.txt”, “r”) or die(“Unable to open file!”); echo fread($myfile,filesize(“lock.txt”)); fclose($myfile); ?>

So one might wonder how the code of our ESP32Cam will change; well, very little, because in fact we will simply have to add a new check in addition to the existing one for the Telegram connection.

Here, in fact, we need to insert a call to the reading service so that we can work out which state we are in and whether the photo that has just been taken is of interest to us or not.

Let’s see how to modify it: in the upper part of the code, where the various includes are, we need to add this line:

#include <WiFi.h> #include <WiFiClientSecure.h> #include <HTTPClient.h> #include “soc/soc.h” #include “soc/rtc_cntl_reg.h” #include “esp_camera.h”

Now let’s add the check alongside the Telegram connection. Inside the alerts2Telegram function we will in fact add this instruction:

String alerts2Telegram(String token, String chat_id) { const char* myDomain = “api.telegram.org”; String getAll=””, getBody = “”; camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if(!fb) { Serial.println(“Camera capture failed”); delay(1000); ESP.restart(); return “Camera capture failed”; } WiFiClientSecure client_tcp; if (client_tcp.connect(myDomain, 443) && control()) { Serial.println(“Connected to “+String(myDomain));

Finally, let’s create the control function mentioned in the previous step and add it at the end of the whole code:

boolean control(){ HTTPClient http; boolean ret = false; String serverPath = “http://SERVER_ADDRESS/read.php”; http.begin(serverPath.c_str()); int httpResponseCode = http.GET(); if (httpResponseCode>0) { Serial.print(“HTTP Response code: “); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println(payload); if(payload==”on”){ ret = true; } } else { Serial.print(“Error code: “); Serial.println(httpResponseCode); } http.end(); return ret; }

As you can see, with just a few extra lines we have made the control of the device remote.

Now all we have to do is call the following URL from an ordinary browser:

http:// SERVER_ADDRESS /lock.php?status=on

to activate it, while to deactivate it we change the status value from on to off.

Well, let’s end the description of this project dedicated to Telegram-assisted video surveillance here; what we have given you are development ideas that can be customised to your needs, starting from the firmware and the basic hardware, which as you have seen is very simple, being reduced practically to the ESP32-Cam module and a presence sensor.

If you’d like to increase the security of your garage door, or you are just interested in learning more about cryptography, then read on! At its core, this project is simply about a secure wireless button. This could be used to trigger any number of things, so we hope it can inspire message security on…

https://youtu.be/BccGnfM-dbk We continue with the Pi Zero dashcam project and in this post, we take care of file management while also adding some enhancements in the process. This project is almost complete and we will be carrying out road tests in next week’s post/video. More info Build it yourself Boards, sensors and kits for projects…

In the previous posts we presented the project of an an embedded MP3, capable of playing and recording audio sequences by means of appropriate commands. The interaction modes, as well as the communication interfaces cover a wide range of possibilities, for example it is possible to easily use UART, USB, I²C or bit banging on…

  Here we take advantage of Telegram bots for the development of a thermostat that may be controlled from a smartphone, by means of simple instant messages.   Even though social networks and instant messaging services established themselves and spread rapidly, in the last years, many people do not go any further from Whatsapp and…

  Using a SitePlayer SP1 module, it is possible to control four optoisolated inputs and four relay outputs through an Internet web page. The usage of this module is recommended for industrial and home automation.   SitePlayer module is a web server which, as soon as it is connected to the Internet or to an…

OpenMotics – an truly open source, Hardware and Software system – is off to a great start in the domotics market: maybe someone finally got it well that Open source can be used to conquer fragmented markets! OpenMotics: your modern, open source home automation at a reasonable price that’s easy to use! Anyone building or…

Open-Electronics.org is the brainchild of a world leader in hobby electronics Futura Group srl. Open-Electronics.org is devoted to support development, hacking and playing with electronics: we share exciting open projects and create amazing products!

Open-Electronics.org is not just a container of ideas: it is also a web site lead by a team of engineers and geeks who will take part in the discussions and give support.

Our mission is to become a reference Open Source hacking site with ideas and feedback aimed to enrich the community.

We use cookies to count visits and to remember which page or campaign an order came from. No advertising or profiling cookies. You can change your mind at any time from the "Cookies" link at the bottom of every page. Details in our Cookie policy.

📰 Original Source Attribution

Reported by open-electronics.org.

Read Original Report at open-electronics.org ↗
Share: WhatsApp WhatsApp
💬

Comments (0)

Join the Conversation

No comments yet. Be the first to share your opinion!

You may like