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;
}