Arduino NANO, ESP32-CAM, and RFID

hello everyone, I'm currently designing a project using Arduino Nano, ESP32-Cam, and also RFID.
The concept is that when RFID succeeds in receiving the appropriate tag, it will send a message to the Arduino Nano and forward it to the ESP32-Cam, so that later the ESP32-Cam can take a picture and then send it to the telegram bot that was created.
For now, the Arduino Nano + RFID program has been successfully run and also for the ESP32-Cam program it has also succeeded in sending images to Telegram, but it has not been triggered by Arduino Nano + RFID. I'm currently confused in solving this problem, please help me :slight_smile:

this is the program code for Arduino Nano + RFID :

#include <SPI.h>
#include <MFRC522.h>

#include <SoftwareSerial.h>
 
#define SS_PIN 10
#define RST_PIN 9
#define LED_G 3 //define green LED pin
#define LED_R 2 //define red LED
#define RELAY 4 //relay pin
#define BUZZER 6 //buzzer pin
#define ACCESS_DELAY 2000
#define DENIED_DELAY 1000
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

// Arduino UNO
SoftwareSerial mySerial(4,5); //RX 4 TX 5

void setup() 
{
  Serial.begin(9600);   // Initiate a serial communication
  mySerial.begin(9600);     // Initiate Serial RFID
  SPI.begin();          // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  pinMode(LED_G, OUTPUT); 
  pinMode(LED_R, OUTPUT);
  pinMode(RELAY, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  noTone(BUZZER);
  digitalWrite(RELAY, HIGH);
  Serial.println("Put your card to the reader...");
  Serial.println();

}
void loop() 
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "*************") //Custom this content
  {
    Serial.println("Authorized access");
    Serial.println();
    mySerial.println("Authorized access");
    mySerial.println();
    delay(500);
    digitalWrite(LED_G, HIGH);
    delay(ACCESS_DELAY);
    digitalWrite(LED_G, LOW);
  }
 
 else   {
    Serial.println(" Access denied");
    mySerial.println(" Access denied");
    digitalWrite(LED_R, HIGH);
    digitalWrite(BUZZER, HIGH);
    delay(100);
    delay(DENIED_DELAY);
    digitalWrite(LED_R, LOW);
    digitalWrite(BUZZER, LOW);
  }
}

this is the program code for ESP32-Cam :

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
#include <Wire.h>

//isi dengan alamat dan password wifi kalian
const char* ssid = "************";
const char* password = "************";

String BOTtoken = "************"; 
String chatId = "*****************";

bool sendPhoto = false;

WiFiClientSecure clientTCP;

UniversalTelegramBot bot(BOTtoken, clientTCP);

//CAMERA_MODEL_AI_THINKER
#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

#define FLASHpin 4
bool flashState = LOW;
// bool adaGerakan = false;
int botRequestDelay = 1000;   // setiap 1 detik akan check bot
long lastTimeBotRan;    

void handleNewMessages(int numNewMessages);
String sendPhotoTelegram();

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2,14); //RX = 2, TX = 14
char receivedString[50];

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

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 
  pinMode(FLASHpin, OUTPUT);
  digitalWrite(FLASHpin, flashState);


  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("menghubungkan wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  clientTCP.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("ESP32-CAM IP Address: ");
  Serial.println(WiFi.localIP());

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  //init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;  //0-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;  //0-63 lower number means higher quality
    config.fb_count = 1;
  }
  
  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    delay(1000);
    ESP.restart();
  }

  // Drop down frame size for higher initial frame rate
  sensor_t * s = esp_camera_sensor_get();
  s->set_framesize(s, FRAMESIZE_SVGA);  // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA
}

void loop(){
  if (mySerial.available()) {
    char receivedChar = mySerial.read();
    static int index = 0;

    if (receivedChar != '\n') {
      receivedString[index] = receivedChar;
      index++;
      receivedString[index] = '\0'; // Menambahkan karakter null terminator pada akhir string
    } else {
      // Membandingkan string yang diterima dengan string yang diinginkan
      if (strcmp(receivedString, "Authorized access") == 0) {
        // Kode yang akan dijalankan jika ada akses yang diotorisasi
        Serial.println("Message : Authorized access");
        sendPhotoTelegram();
        sendPhoto = false;
      } else if (strcmp(receivedString, "Message :  Access denied") == 0) {
        // Kode yang akan dijalankan jika akses ditolak
        Serial.print(" Access denied");
        sendPhotoTelegram();
        bot.sendMessage(chatId, "Perobaan Masuk Illegal Telah Dilakukan!!","");
        sendPhoto = false;
      }

      // Reset array karakter dan indeks
      memset(receivedString, 0, sizeof(receivedString));
      index = 0;
    }
  }

  if (sendPhoto){
    Serial.println("persiapan foto");
    sendPhotoTelegram(); 
    sendPhoto = false; 
  }
  
  if (millis() > lastTimeBotRan + botRequestDelay){
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    while (numNewMessages){
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    lastTimeBotRan = millis();
  }
}

String sendPhotoTelegram(){
  const char* myDomain = "api.telegram.org";
  String getAll = "";
  String getBody = "";

  camera_fb_t * fb = NULL;
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("kamera gagal ambil gambar");
    delay(1000);
    ESP.restart();
    return "kamera gagal ambil gambar";
  }  
  
  Serial.println("Connect to " + String(myDomain));

  if (clientTCP.connect(myDomain, 443)) {
    Serial.println("berhasil terhubung");
    
    String head = "--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"chat_id\"; \r\n\r\n" + chatId + "\r\n--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"esp32-cam.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
    String tail = "\r\n--RandomNerdTutorials--\r\n";

    uint16_t imageLen = fb->len;
    uint16_t extraLen = head.length() + tail.length();
    uint16_t totalLen = imageLen + extraLen;
  
    clientTCP.println("POST /bot"+BOTtoken+"/sendPhoto HTTP/1.1");
    clientTCP.println("Host: " + String(myDomain));
    clientTCP.println("Content-Length: " + String(totalLen));
    clientTCP.println("Content-Type: multipart/form-data; boundary=RandomNerdTutorials");
    clientTCP.println();
    clientTCP.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) {
        clientTCP.write(fbBuf, 1024);
        fbBuf += 1024;
      }
      else if (fbLen%1024>0) {
        size_t remainder = fbLen%1024;
        clientTCP.write(fbBuf, remainder);
      }
    }  
    
    clientTCP.print(tail);
    
    esp_camera_fb_return(fb);
    
    int waitTime = 10000;   // timeout 10 seconds
    long startTimer = millis();
    boolean state = false;
    
    while ((startTimer + waitTime) > millis()){
      Serial.print(".");
      delay(100);      
      while (clientTCP.available()) {
        char c = clientTCP.read();
        if (state==true) getBody += String(c);        
        if (c == '\n') {
          if (getAll.length()==0) state=true; 
          getAll = "";
        } 
        else if (c != '\r')
          getAll += String(c);
        startTimer = millis();
      }
      if (getBody.length()>0) break;
    }
    clientTCP.stop();
    Serial.println(getBody);
  }
  else {
    getBody="Connected to api.telegram.org failed.";
    Serial.println("Connected to api.telegram.org failed.");
  }
  return getBody;
}

void handleNewMessages(int numNewMessages){
  Serial.print("Handle New Messages: ");
  Serial.println(numNewMessages);

  for (int i = 0; i < numNewMessages; i++){
    // Chat id of the requester
    String chat_id = String(bot.messages[i].chat_id);
    if (chat_id != chatId){
      bot.sendMessage(chat_id, "Unauthorized user", "");
      continue;
    }
    
    // Print the received message
    String text = bot.messages[i].text;
    Serial.println(text);

    String fromName = bot.messages[i].from_name;


    if (text == "/flash") {
      flashState = !flashState;
      digitalWrite(FLASHpin, flashState);
    }
    if (text == "/foto") {
      sendPhoto = true;
      Serial.println("New photo  request");
    }
    if (text == "/start"){
      String welcome = "at-mo production\n";
      welcome += "klik tulisan biru\n";
      welcome += "/foto : untuk ambil gambar langsung\n";
      welcome += "/flash : untuk on off lampu flash\n";
      welcome += "system ini otomatis kirim foto saat terjadi gerakan.\n";
      bot.sendMessage(chatId, welcome, "Markdown");
    }
  }
}

You have no code doing it.

The Nano pins runs at 5V, the ESP32-Cam pins operate at 3.3V. You can not just tie them together.

It seems cumbersome to send a complete message like "Message : Authorized access" to the ESP32-Cam just to get it to send a picture. A simple "0" or "1" would be sufficient. You could also just connect a digital line (with voltage level shifting) to signal time for a picture.

1 Like

I don't know if this is true or not, but if I run the ESP32-Cam at 3.3v, it won't run. However, when I changed it to 5v, the new ESP32-Cam could work as usual

I have tried to make the trigger like the code above, but it doesn't work. I'm still confused about the main concept of this serial communication, is what I'm doing right now or is there a correction?

The 5V pin on the ESP32CAM, needs to be connected to around 5V.

The ESP32CAM then has a regulator which converts the 5V to 3.3V that the ESP32CAM runs at.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.