Is there an ADC GPIO I can use on the ESP32-CAM to read and LDR?

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

Is there an ADC GPIO I can use on the ESP32-CAM to read and LDR?

Postby FBMinis » Sun Jan 17, 2021 3:28 pm

My Arduino project essentially consists of an ESP32-CAM sending a photo to my Telegram group every 15min, then goes to sleep. When it wakes up, it evaluates the "brightess level" by reading the voltage from an LDR, if the brightness level is too low (night time), it goes back to sleep; otherwise it connects to the internet, takes a photo and sends it to me.

I am aware the ADC pins of the ESP32 are distributed between ADC1 and ADC2 and that ADC2 should not be used when Wifi driver is in use. I am left with ADC1 pins 32 to 39. My camera is made by Ai-Thinker and the Arduino IDE shows it uses 32, 34, 35, 36 and 39.

I am left with GPIO33, 37 and 38. Unfortunately 37 and 38 and GPIO33 is used by Led1.

Can I unsolder LED1+resistor and use the pin as analog input? If not, what are my alternatives?

(Im not a programmer, but I can hammer code together with the help o DuckDuckGo).

Code: Select all

/*
	
    Send photo every X minutes, except during dark (analogRead LDR)
	
    Based on https://RandomNerdTutorials.com/telegram-esp32-cam-photo-arduino/
	
*/

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

// Initialize Telegram BOT
String BOTtoken = "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 = "CHAT_ID";

const char* ssid = "ssid";
const char* password = "password";

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

#define ldrPin 33


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();
	}
	
	// Drop down frame size for higher initial frame rate
	sensor_t * s = esp_camera_sensor_get();
	s->set_framesize(s, FRAMESIZE_CIF);  // 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 setup() {
	
	// Set LED Flash as output
	// pinMode(FLASH_LED_PIN, OUTPUT);
	// digitalWrite(FLASH_LED_PIN, flashState);
	
	WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
	// Init Serial Monitor
	Serial.begin(115200);
	
	// Read LDR voltage divider, GPIO33
	int sensorValue = 100 * analogRead(ldrPin) / 4095;
	Serial.print("sensorValue =");
	Serial.println(sensorValue);
	
	if (sensorValue >= 15) {
		// Config and init the camera
		configInitCamera();
		
		// 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());
		
		sendPhotoTelegram();
	}
	
	esp_sleep_enable_timer_wakeup(6e7); // 1 minute
	
	Serial.println("Going to sleep now");
	delay(1000);
	esp_deep_sleep_start();
	
}

void loop() {
	
}
Attachments
IMG_20210117_140457.jpg
IMG_20210117_140457.jpg (339.42 KiB) Viewed 7061 times
IMG_20210117_140419.jpg
IMG_20210117_140419.jpg (336.6 KiB) Viewed 7061 times

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

Re: Is there an ADC GPIO I can use on the ESP32-CAM to read and LDR?

Postby FBMinis » Tue Jan 26, 2021 2:10 pm

I unsoldered LED1 and have been using GPIO33 to read an LDR for a few days with consistently good results.

skillz43132
Posts: 2
Joined: Sat Nov 20, 2021 9:02 pm

Re: Is there an ADC GPIO I can use on the ESP32-CAM to read and LDR?

Postby skillz43132 » Wed Dec 15, 2021 4:32 am

You can simply not use the LDR, since the ESP CAM's OV-2640 has just under 2 million light sensors built-in :lol:

Just initialise the camera in greyscale at the lowest possible resolution, iterate over each (or some) of the pixels of the image, to get an average pixel brightness value. From this you can get a brightness value between 0-255.

Then you can de-initialise the camera with esp_camera_deinit().

Who is online

Users browsing this forum: No registered users and 59 guests