ESP32-CAM Face Recognition for Home Automation

featured.jpg

Using face recognition to open a door or control other home automation devices

This tutorial will explain how to save enrolled images in the on-board flash so they survive the ESP32 powering off and use these saved recognitions to control devices connected to the ESP32. There are three steps.

  • Create a new partition scheme to enable persistent storage
  • Modify the CameraWebServer example sketch to save face data to the new partition
  • Use these saved recognitions to control devices connected to the ESP32

Before following this tutorial make sure your camera works by following this tutorial Ai-Thinker ESP32-CAM in the Arduino IDE

Persistent Storage Partition Scheme

A new partition scheme with persistent storage on the on-board flash is needed. You can download a scheme I created from here: https://robotzero.one/wp-content/uploads/2019/04/rzo_partitions.csv

Add this file to the directory containing the other partition schemes. This is found in one of two places, depending on how you installed the Arduino IDE.

Arduino IDE installed from the Windows Store:

C > Users > *your-user-name* > Documents > ArduinoData > packages > esp32 > hardware > esp32 > 1.0.1 > tools > partitions

Arduino IDE installed from the Arduino website:

C > Users > *your-user-name* > AppData > Local > Arduino15  > packages > esp32 > hardware > esp32 > 1.0.1 > tools > partitions

The new scheme has to be added to your ESP device in the boards manager configuration file – boards.txt. Again this is found in one of two places.

Arduino IDE installed from the Windows Store:

C > Users > *your-user-name* > Documents > ArduinoData > packages > esp32 > hardware > esp32 > 1.0.1

Arduino IDE installed from the Arduino website:

C > Users > *your-user-name* > AppData > Local > Arduino15  > packages > esp32 > hardware > esp32 > 1.0.1

Add the following three lines below the existing partitionScheme options for the esp32wrover board in this boards.txt file.

esp32wrover.menu.PartitionScheme.rzo_partition=Face Recognition (2621440 bytes with OTA)
esp32wrover.menu.PartitionScheme.rzo_partition.build.partitions=rzo_partitions
esp32wrover.menu.PartitionScheme.rzo_partition.upload.maximum_size=2621440

Close and reopen the IDE to confirm the new ‘Face Recognition’ partition scheme is available in the Tools menu.

There’s an article here that explains in much more detail how to set up a new scheme and duplicate a board definition: Partition Schemes in the Arduino IDE

Capture Face Data to Persistent Storage

The CameraWebServer example in the IDE doesn’t save enrolled faces in a way that will survive power loss. To modify it to use the new partition a few changes need to be made to the code.

In the Arduino IDE,  make a copy of your working CameraWebServer Sketch from the previous tutorial by saving it with a new file name such as CameraWebServerPermanent.

You should see three tabs in the Arduino IDE similar to the image below:

Arduino IDE Tabs

In the second tab (app_httpd.cpp) make the following changes.

After #include “fr_forward.h” (around line 24) add:

#include "fr_flash.h";

Change int8_t left_sample_face = enroll_face(&id_list, aligned_face);(&id_list, aligned_face);  (around line 178) to:

int8_t left_sample_face = enroll_face_id_to_flash(&id_list, aligned_face);

After face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES); (around line 636) add:

read_face_id_from_flash(&id_list);

Flash and run this Sketch in the same way as before. Enrolled face data is now being saved to the new partition on the flash memory.

Face Recognition Trigger Event

I’ve written a Sketch that sets a pin HIGH on the board while a known face is detected. After 5 seconds pass, if there is no recognised face the pin is set LOW. The code in the function rzoCheckForFace() in the Sketch below can be changed to whatever function you require when a face is recognised. I prefer to set pins as low during setup because mentally I think of it as ‘off’ and then set them high when I want to trigger something because I think of it as ‘on’. You can use pin 12 instead or in addition to pin 2

Paste the following code into a new sketch

#include "esp_camera.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "fr_flash.h"

#define relayPin 2 // pin 12 can also be used
unsigned long currentMillis = 0;
unsigned long openedMillis = 0;
long interval = 5000;           // open lock for ... milliseconds

#define ENROLL_CONFIRM_TIMES 5
#define FACE_ID_SAVE_NUMBER 7

mtmn_config_t init_config()
{
  mtmn_config_t mtmn_config = {0};
  mtmn_config.min_face = 80;
  mtmn_config.pyramid = 0.7;
  mtmn_config.p_threshold.score = 0.6;
  mtmn_config.p_threshold.nms = 0.7;
  mtmn_config.r_threshold.score = 0.7;
  mtmn_config.r_threshold.nms = 0.7;
  mtmn_config.r_threshold.candidate_number = 4;
  mtmn_config.o_threshold.score = 0.7;
  mtmn_config.o_threshold.nms = 0.4;
  mtmn_config.o_threshold.candidate_number = 1;
  return mtmn_config;
}

static face_id_list id_list = {0};
dl_matrix3du_t *image_matrix =  NULL;
camera_fb_t * fb = NULL;
mtmn_config_t mtmn_config = init_config();
dl_matrix3du_t *aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3);

void setup() {
  Serial.begin(115200);

  digitalWrite(relayPin, LOW);
  pinMode(relayPin, OUTPUT);

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = 5;
  config.pin_d1 = 18;
  config.pin_d2 = 19;
  config.pin_d3 = 21;
  config.pin_d4 = 36;
  config.pin_d5 = 39;
  config.pin_d6 = 34;
  config.pin_d7 = 35;
  config.pin_xclk = 0;
  config.pin_pclk = 22;
  config.pin_vsync = 25;
  config.pin_href = 23;
  config.pin_sscb_sda = 26;
  config.pin_sscb_scl = 27;
  config.pin_pwdn = 32;
  config.pin_reset = -1;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  //drop down frame size for higher initial frame rate
  sensor_t * s = esp_camera_sensor_get();
  s->set_framesize(s, FRAMESIZE_QVGA);

  face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
  read_face_id_from_flash(&id_list);// Read current face data from on-board flash
}

void rzoCheckForFace() {
  currentMillis = millis();
  if (run_face_recognition()) { // face recognition function has returned true
    Serial.println("Face recognised");
    digitalWrite(relayPin, HIGH); //close (energise) relay
    openedMillis = millis(); //time relay closed
  }
  if (currentMillis - interval > openedMillis){ // current time - face recognised time > 5 secs
    digitalWrite(relayPin, LOW); //open relay
  }
}

bool run_face_recognition() {
  bool faceRecognised = false; // default
  int64_t start_time = esp_timer_get_time();
  fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return false;
  }

  int64_t fb_get_time = esp_timer_get_time();
  Serial.printf("Get one frame in %u ms.\n", (fb_get_time - start_time) / 1000); // this line can be commented out
  
  image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3);
  uint32_t res = fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item);
  if (!res) {
    Serial.println("to rgb888 failed");
    dl_matrix3du_free(image_matrix);
  }

  esp_camera_fb_return(fb);

  box_array_t *net_boxes = face_detect(image_matrix, &mtmn_config);

  if (net_boxes) {
    if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK) {

      int matched_id = recognize_face(&id_list, aligned_face);
      if (matched_id >= 0) {
        Serial.printf("Match Face ID: %u\n", matched_id);
        faceRecognised = true; // function will now return true
      } else {
        Serial.println("No Match Found");
        matched_id = -1;
      }
    } else {
      Serial.println("Face Not Aligned");
    }

    free(net_boxes->box);
    free(net_boxes->landmark);
    free(net_boxes);
  }

  dl_matrix3du_free(image_matrix);
  return faceRecognised;
}

void loop() {
  rzoCheckForFace();
}

When you flash and run this new Sketch you should see ‘Face recognised’  in the serial monitor when a matched face is found.

Opening a Door

The Sketch above combined with a relay or Mosfet module can be used to switch an electrical device on or off. This can be used to open or unlock a door

The diagram below shows the wiring for a opening a lock. From the Sketch above, when a face is recognised, pin IO2 is set HIGH and the relay closes so current flows from the high voltage power supply to the electric door lock.

ESP32-CAM Door Lock Relay

While setting up and testing a project like this you might prefer to have the serial device connected as below

ESP32-CAM Door Lock Relay with USB

The door lock in this example could be anything you want to temporarily supply power to.

The project will work with many relay and Mosfet modules that have a 3v input such as the items below. The opto isolated Mosfet module (green connectors) needed the resistor bypassed. The smaller red one works with just the signal and ground connected.

These are available from eBay: Basic Mosfet | Opto Isolated Mosfet | Opto isolated 3v Relay

There’s lots of options for controlling a high voltage device from the ESP32 and it is important to understand the dangers to yourself and the ESP32 if you use the wrong solution.  The mechanical relay board is rated for higher voltages but I personally wouldn’t use mains electricity with a device like this.

Deleting Faces from the Memory

If you need to clear the stored faces, paste and upload the Sketch below

#include "esp_camera.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "fr_flash.h"

#define ENROLL_CONFIRM_TIMES 5
#define FACE_ID_SAVE_NUMBER 7

static face_id_list id_list = {0};

void setup() {
  Serial.begin(115200);
  face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
  read_face_id_from_flash(&id_list);// Read current face data from on-board flash
  Serial.println("Faces Read"); 
  while ( delete_face_id_in_flash(&id_list) > -1 ){
        Serial.println("Deleting Face");
  }
        Serial.println("All Deleted");  
}

void loop() {
}

I have some more tutorials like this coming. Feel free to buy me a coffee to help development 😉 .

References

Event trigger for IDF: https://github.com/espressif/esp-who/blob/master/examples/single_chip/recognition_with_command_line/main/app_facenet.c
In-depth relay information: https://www.youtube.com/watch?v=d9evR-K6FAY

50 Replies to “ESP32-CAM Face Recognition for Home Automation”

  1. Mel says:

    You’ve used IO2 or 12 for the relay control. Aren’t these pins also used for SD card? I’m looking for any module pins that are “free”, seem to be scarce commodity; conflicts with flash LED, SD etc.; idea would be to use an external PIR to save jpeg to SD card, or means to display image remotely. Also would this module work with the OV2640 fisheye camera?

    1. WordBot says:

      Yeah.. All the pins are assigned to something. Those two seem to be useable for other things but probably not at the same time as using the SD reader. I’ve got a tutorial in progress for writing to the micro-SD or uploading. Not sure about the fisheye.. there’s a few of the little OV2640 cameras and I’m not sure the cables are the same.

  2. Vitor Faeda Dalto says:

    Hello, there is no way of sending the face recognition data/trigger via web?
    Like a FTT ?
    I would like to send a message to Home Assistant, inside it it’s easier to make any action.
    Is that possible ?
    Here is an exemple:
    Individual 1 appears in front of the camera ->
    ESP sends package to my arduino IP -> action 1 speaker says “hello individual 1”, action 2 August Smart Lock opens the door.
    It’s possible ?
    Thanks

    1. WordBot says:

      Hi, what’s FTT? Rather than making a pin go high or low on the board you want it to send an HTTP request to a device on your network? Yep.. should be possible. I have a Sonoff device arriving soon so I’ll do a tutorial for that. Should be easy enough to change it to point to an Arduino.

      EDIT: Sonoff tutorial here: https://robotzero.one/unlock-door-face-detection-sonoff/

  3. Mikk7310 says:

    Hello, great tutorial, thanks! How can I delete the stored face?

    1. WordBot says:

      Hi, thanks! I’ve added a Sketch at the end of the article that deletes the stored faces.

  4. Jose Godinho says:

    Hello
    Excellent tutorial, albeit a lot of people were ask the same, would it be possible, instead of change the GPIO state, send a MQTT info about the face recognized?

    I think that would entitle to several coffees

    Regards

    Jose Godinho

    1. WordBot says:

      Hi, How are you using MQTT in your application?

  5. kwluk717 says:

    Hi,
    Do you think is it possible to save the face information to SD card so we can recognize other people by replaced the card ? Thank you.

    1. WordBot says:

      Hi, it’s on my list of things to look into.

  6. Didace says:

    hello Sir! after following your instructions I tried to run the given sketch for triggering the relay when a recognized face is detected but on serial I get
    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:2
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1100
    load:0x40078000,len:9232
    load:0x40080400,len:6412
    entry 0x400806a8
    E (1719) fr_flash: Not found

    1. WordBot says:

      Hi, Did you follow the whole tutorial including setting up a new partition and adding some faces to the device?

  7. kami says:

    Hi,
    have you tested the OTA Update? I cannot get it running? I also got problems to attach an interrupt. Have you tried this?
    Thanks a lot.

    Cu kami

    1. WordBot says:

      I’ve not tested OTA but I’m not sure if there’s space on the ESP32-CAM to store the sketch, faces and have space for an OTA partition. Reading the pins is hard, or maybe not even possible if you want to use Wifi https://desire.giesecke.tk/index.php/2018/01/30/adc2-channel-cannot-be-used-when-wifi-is-in-use/ I would love to be proved wrong on this!

  8. kami says:

    Hi, thanks a lot for the answer. In the partition table there is space for ota. I will try it on the weekend.

    Can you give me some information about the broken face recognition in 1.0.2?

    Thanks a lot.

    Cu kami

    1. WordBot says:

      There’s supposed to be a new Arduino IDE board setup for ESP32 release soon. Hopefully that will fix it.

  9. En says:

    Hi,
    I use your source code, always show me this error,

    exit status 1
    ‘mtmn_config_t’ does not name a type

    Have you ever encountered this problem?

    1. WordBot says:

      Hi, Which version of the ESP32 libraries are you using? library version

  10. En says:

    thanks reply, also version1.0.1

  11. En says:

    have you install other #include ?
    maybe #include “mtmn.h” or something else ?

  12. En says:

    I JUST FIX IT!!!!
    It’s the Filename Extension,
    I change .ino to .h

  13. WordBot says:

    which file did you change .ino to .h?

  14. En says:

    the new sketch I paste from the chapter “Face Recognition Trigger Event”,
    I encounter a new problem. relayPin have no response

  15. En says:

    I didn’t see ‘Face recognised’ in the serial monitor,
    I create a new sketch as 123.h, and put it in a file with other sketch(CamerawWebserver.ino, app_http.cpp, camera_index.h),
    Is that correct?

    sorry for bothering

  16. En says:

    I figure it out, sorry for stupid question lol

  17. Ridoillah says:

    what esp32cam method use for face recognition ?

    1. WordBot says:

      MobileFace – https://github.com/espressif/esp-who scroll down for details

  18. Paulo Freitas says:

    Olá
    Como eu faço para colocar as faces conhecidas no ESP, não entendi esta parte, o restante está configurado e parece estar funcionando.

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1100
    load:0x40078000,len:9232
    load:0x40080400,len:6400
    entry 0x400806a8
    E (1716) fr_flash: No ID Infomation
    Get one frame in 69 ms.
    Get one frame in 61 ms.
    Get one frame in 56 ms.
    Get one frame in 55 ms.
    Get one frame in 55 ms.

    1. WordBot says:

      Hi, Have you saved some faces by following the part Capture Face Data to Persistent Storage?

  19. Denis says:

    Ok first of thank you for a great project….I followed everything step by step and everything went without a hitch but there is a problem …. when i go to enroll faces nothing happens ( i am using ESP32 version 1.0.1 on the Arduino IDE)
    Of course i am toggling the buttons for facial recognition and detection
    on the serial monitor i do get this in the beginning……… E (5628) fr_flash: Not found

    What an i doing wrong how can i enroll faces
    Thanks again
    Denis

    1. WordBot says:

      Hi, Does the normal CameraWebServer example work for you. Can you enrol a face and it recognise it? If that works try with the edits in this tutorial (including the new partition scheme) and see if you can enrol faces.

  20. Denis says:

    No i get that back the original sketch does detect faces i tried it again and it took a while but it did register my face
    Denis

  21. Denis says:

    Ok so i got it flashed again per your instructions now the face detection works just fine … detection that is….. and it says Intruder Alert when there is no face registered.
    When i click on Enroll Face (just once) it starts this wired loop that goes exactly like this: “Note from Sample 4 jumps to Sample 7”
    ID(0) Sample 1
    ID(0) Sample 2
    ID(0) Sample 3
    ID(0) Sample 4
    ID(0) Sample 7 than it moves to ID (1) Sample 1 though 4 than jumps to 7 than on ID(2) Sample 1 through for jump to 7 up to ID 5 and back again in a loop.

    When you stop this process that does not finish by itself by switching off face detection and recognition and you start it back on again it says Intruder Alert like it has not saved any images.

    Whats causing this behavior and how do we fix it….by the way with the stock sketch it saves and recognizes the faces just fine

    thank you for your help
    Denis

  22. WordBot says:

    I’m not sure why it’s doing that. Are you using the new partition? I wonder if it can’t save the ‘face’.

    Is there anything in the serial monitor?

  23. Denis says:

    Where is the new partition ??
    I am using the downloaded one from the instructions above
    https://robotzero.one/wp-content/uploads/2019/04/rzo_partitions.csv

    …. is there a new csv??

    I am also adding the three lines into board.txt
    “`esp32wrover.menu.PartitionScheme.rzo_partition=Face Recognition (2621440 bytes with OTA)
    esp32wrover.menu.PartitionScheme.rzo_partition.build.partitions=rzo_partitions
    esp32wrover.menu.PartitionScheme.rzo_partition.upload.maximum_size=2621440 “`

    One think i have noticed is when the camera reboots it gives the following error
    E (52290 Could not Load (or Could not find): fr_flash.h
    in the serial monitor other than that it just keeps displaying the data for the captured frames on the serial monitor.

    So i think the above error is causing that issue ….what is that??

    Denis

    1. WordBot says:

      > E (52290 Could not Load (or Could not find): fr_flash.h
      Is that the exact error? fr_flash.h is a file needed for the sketch to run but it shouldn’t compile if it doesn’t exist.

      If the error message mentions fr_flash is missing it’s because the ESP32 can’t find the partition to store the face data. Did you select the new partition similar to this screen capture: https://robotzero.one/wp-content/uploads/2019/04/arduino-ide-custom-partition-scheme.jpg ?

  24. FrenchyRic says:

    I had the same error (Fr_flash.h missing), you have to select: tools -> Partition scheme -> Face Recognition (xxx Bytes with OTA)

  25. Denis says:

    Ok well the Partision Scheme with Face Recognition (xxx Bytes with OTA) seems to be fixing the problem of the fr_flash.h missing and there are no there errors. So it seems like it will work but still i can not test it successfully and can not store a face id yet. Because either the wifi connectivity gets extremely bad when uploading this code or the camera slows down i cant really tell.
    When i start the camera feed it will show one or two frames than it wont even get a frame per second so it will loose connectivity the web page with the webserver there is no way to run facial recognition and store face id’s.

    I will try to go back to the stock sketch and test the wifi again maybe it has gone crazy but with the stock code the face recognition and the cam was previously working very well.

    Anyone else having this issue ??

    Denis

  26. Denis says:

    Here is the serial monitor out put …note the fps
    Also the wifi access point is like 10 feet away

    WiFi connected
    E (6595) fr_flash: No ID Infomation
    Starting web server on port: ’80’
    Starting stream server on port: ’81’
    Camera Ready! Use ‘http://192.168.1.17’ to connect
    MJPG: 8994B 170ms (5.9fps), AVG: 170ms (5.9fps), 0+0+0+0=0 0
    MJPG: 8869B 1341ms (0.7fps), AVG: 755ms (1.3fps), 0+0+0+0=0 0
    MJPG: 8892B 4264ms (0.2fps), AVG: 1925ms (0.5fps), 0+0+0+0=0 0
    MJPG: 7850B 3524ms (0.3fps), AVG: 2324ms (0.4fps), 0+0+0+0=0 0
    MJPG: 5589B 540ms (1.9fps), AVG: 1967ms (0.5fps), 0+0+0+0=0 0
    MJPG: 8501B 3638ms (0.3fps), AVG: 2246ms (0.4fps), 0+0+0+0=0 0
    MJPG: 10435B 2149ms (0.5fps), AVG: 2232ms (0.4fps), 0+0+0+0=0 0

  27. Denis says:

    It looks like Circuit Board Antenna Connected… not the external one ….but i do have an external antenna connected to it should i take it off and see whats up??

    1. WordBot says:

      You could try but if it’s not connected to anything it shouldn’t affect the signal. If you can it might be better to move the jumper so the external antenna is connected. I found the WiFi really affects the FPS.

  28. Rolly says:

    Hello!

    Great article, I wish you can do a sketch where the face maintenance (add and delete) and detetion are included.

    1. WordBot says:

      Hi,
      You can use this tutorial to manage the faces in the system: https://robotzero.one/esp-who-recognition-with-names You could either switch between the two sketches or take the code from the tutorial above and combine them.

  29. Denis says:

    Hello again
    I followed everything step by step, double checked and triple checked, re-flashed it a couple of times too…i solved the problem with the wifi dropping frames but still no facial recognition when i use your code and partition after i click on Enroll Face nothing happens and i can confirm that the recognition works with the stock sketch
    When i go step by step to your screen shot here https://robotzero.one/wp-content/uploads/2019/04/arduino-ide-custom-partition-scheme.jpg i see that your Board says Robot Zero One is that just for you guys developing cause we do not have that board and the other settings that your board has…..i am of course selecting the partition scheme with Face Recognition (2621440 bytes with OTA)

    What should we do next there is no error when you reset the board on the serial monitor other than this:
    E (7651) fr_flash: No ID Infomation
    Which i guess it means that there is not face id stored yet.

    Thanks again
    Denis

    1. WordBot says:

      The ‘Robot Zero One’ board is just a copy of the esp32wrover board. I did it like that in the other tutorial to make it less likely that people would break something. I don’t know why it’s not working for you. I’ll try to find time to make a video this week to show the process.

  30. SeJeong says:

    Hello.
    Thank you for your great work.
    I’d like to chage the relay module to servo motor because I want to control the door model by servo motor.
    If I just chage the module and put the the line which are “#include “, “Servo relayPin;”, could it work?

    1. WordBot says:

      Hi, I’m adding a general servo tutorial tomorrow. With a servo motor you have to tell it how far to turn. Probably in your case you would add a function to the Sketch that when run, turns the servo enough for the door to open, waits for a certain time and then turns the servo back to close the door.

  31. Nothing2Fancy says:

    Does anybody know how I can augment this code to trigger a dfplayer (a cheap broken out mp3 player,) by sending a hexadecimal number command to serial tx/rx? (That’s how you play certain audio files from the onboard sd-card.)

    I am trying to make a smart(ish) doorbell system that would recognize houshold members and greet them, by name, upon ringing the doorbell (or in this case activating a momentary button switch) which would first check the database for a saved face, play a file associated with said person, then ring a bell by way of either closing a relay or playing a different file (like a sample of Big Ben for instance) to a speaker on the inside of the door.)

    A visitor without a saved face would have a file played implying an unknown person is calling. I would also really like to be able to text a live snapshot with Telegram. Having Alexa chime in (pun intended, …sadly,) would also be pretty cool and in lieu of using an actual doorbell.

  32. Denis says:

    Let me know on the video or if you have time please let me send you the cam and a prepaid return envelope and you can trouble shoot it hands on ….i am desperate and i really need to get this project complete as it fits my situation perfectly

    Thank you i have tried everything and the board just wont recognize faces after flashed with your sketch

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top