ESP32-CAM not behaving accordingly to analogRead condition

FBMinis
Posts: 15
Joined: Sun Jan 17, 2021 1:08 pm

ESP32-CAM not behaving accordingly to analogRead condition

Postby FBMinis » Thu Jan 28, 2021 1:24 am

My project consists of an ESP32-CAM that is supposed to take a photo and send a message if it's bright enough,« then go to sleep for 15min and repeat.

It begins by taking an average of 10 reading from the ADC, then proceeds to connect to wifi and sends the data if the value is above a certain threshold, otherwise it goes back to sleep for 15min.

The problem I'm getting is that if I turn on the device in dark conditions, sometimes it doesn't boot. Also, if I turn it on in bright conditions and it boots properly, when I turn off the lights in the room for a while to test, it sometimes does not get back to sending data.

I don't know if it's due to the if/else condition or something else.

Here is the code: https://codeshare.io/aYg8ZQ

Code: Select all

#include <Arduino.h>
#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>

// Wifi credencials
const char* ssid = "";
const char* password = "";

// Telegram credencials
String BOTtoken = "";  // your Bot Token (Get from Botfather)
// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
String CHAT_ID = "";

// Get average rssi
float wifiStrength;
const int numberPoints = 7;
// Get average value from analog input GPIO33 using similar function to rssi
float LDRvalue;

WiFiClientSecure clientTCP;
UniversalTelegramBot bot(BOTtoken, clientTCP);

#define FLASH_LED_PIN 4
bool flashState = LOW;

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

void setup() {
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
   
    // Init Serial Monitor
    //  Serial.begin(115200);
   
    // Set LED Flash as output and keep it Low to avoid trouble
    pinMode(FLASH_LED_PIN, OUTPUT);
    digitalWrite(FLASH_LED_PIN, flashState);
   
    configInitCamera();
   
    // LDRvalue = getLDR(numberPoints);
    // Simply get the average of 10 readings from the LDR voltage divider
    int LDRvalue = 0;
    for (int i = 0; i < 10; i++) {
        LDRvalue = LDRvalue + analogRead(33);
    }
    LDRvalue = LDRvalue / 10;
    LDRvalue = LDRvalue * 100 / 4095; // simple percentage
   
    // If bright enough, connect to wifi, send photo and message with LDR and RSSI values
    if (LDRvalue >= 15) {
       
        connectToWIfi();
       
        wifiStrength = getStrength(numberPoints);
       
        sendPhotoTelegram();
       
        // Send message to Telegram
        String message = "LDR: " + String(LDRvalue) + " %" + "\n"; // bool sendMessage(String chat_id, String text, String parse_mode = "");
        message += "rssi: " + String(wifiStrength) + " dBm" + "\n";
        bot.sendMessage(CHAT_ID, message, "");
    }
   
    // Bright or not bright enough, go to sleep, wake up after 15min and go again
    esp_sleep_enable_timer_wakeup(9e+8); //6e+7 1min in microseconds, 9e+8 15min in microseconds
    Serial.println("Going to sleep now");
    delay(1000);
    esp_deep_sleep_start();
    Serial.println("This will never be printed");
}

void loop() {
   
}

void configInitCamera() {
    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();
    }
   
    sensor_t * s = esp_camera_sensor_get();
   
    // Adjusting exposure here did not work for me
    //    s->set_brightness(s, 0);     // -2 to 2
    //    s->set_contrast(s, 0);       // -2 to 2
    //    s->set_saturation(s, 0);     // -2 to 2
    s->set_special_effect(s, 2); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
    //    s->set_whitebal(s, 0);       // 0 = disable , 1 = enable
    //    s->set_awb_gain(s, 0);       // 0 = disable , 1 = enable
    //    s->set_wb_mode(s, 2);        // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
    //    s->set_exposure_ctrl(s, 1);  // 0 = disable , 1 = enable
    //    s->set_aec2(s, 1);           // 0 = disable , 1 = enable
    //    s->set_ae_level(s, 0);       // -2 to 2
    //    s->set_aec_value(s, 1200);    // 0 to 1200
    //    s->set_gain_ctrl(s, 1);      // 0 = disable , 1 = enable
    //    s->set_agc_gain(s, 2);       // 0 to 30
    //    s->set_gainceiling(s, (gainceiling_t)0);  // 0 to 6
    //    s->set_bpc(s, 0);            // 0 = disable , 1 = enable
    //    s->set_wpc(s, 0);            // 0 = disable , 1 = enable
    //    s->set_raw_gma(s, 0);        // 0 = disable , 1 = enable
    //    s->set_lenc(s, 0);           // 0 = disable , 1 = enable
    //    s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
    //    s->set_vflip(s, 0);          // 0 = disable , 1 = enable
    //    s->set_dcw(s, 1);            // 0 = disable , 1 = enable
    //    s->set_colorbar(s, 0);       // 0 = disable , 1 = enable
   
    // adjust photos to 800x600
    s->set_framesize(s, FRAMESIZE_SVGA);  // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA
}

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("Camera capture failed");
        delay(1000);
        ESP.restart();
        return "Camera capture failed";
    }
   
    Serial.println("Connect to " + String(myDomain));
   
   
    if (clientTCP.connect(myDomain, 443)) {
        Serial.println("Connection successful");
       
        String head = "--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"chat_id\"; \r\n\r\n" + CHAT_ID + "\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 (c == '\n')
                {
                    if (getAll.length() == 0) state = true;
                    getAll = "";
                }
                else if (c != '\r')
                getAll += String(c);
                if (state == true) getBody += 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 connectToWIfi() {
    // Connect to Wi-Fi
    WiFi.mode(WIFI_STA);
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    Serial.println();
    Serial.print("ESP32-CAM IP Address: ");
    Serial.println(WiFi.localIP());
}

// Take measurements of the Wi-Fi strength and return the average result.
int getStrength(int points) {
    long rssi = 0;
    long averageRSSI = 0;
   
    for (int i = 0; i < points; i++) {
        rssi += WiFi.RSSI();
        delay(20);
    }
   
    averageRSSI = rssi / points;
    return averageRSSI;
}

// Take measurements of analog input GPIO33 and return average result
int getLDR(int points) {
    long ldrReadings = 0;
    long averageLDR = 0;
   
    for (int i = 0; i < points; i++) {
        ldrReadings += analogRead(33);
        delay(20);
    }
   
    averageLDR = ldrReadings / points;
    averageLDR = averageLDR * 100 / 4095; // simple percentage
    return averageLDR;
}

Who is online

Users browsing this forum: Majestic-12 [Bot] and 66 guests