Any RTC chip known to work with ESP32 cam ?

sionut
Posts: 8
Joined: Tue Oct 06, 2020 10:23 am

Any RTC chip known to work with ESP32 cam ?

Postby sionut » Mon Nov 30, 2020 8:45 am

Hi,

I'm working on a project in which I want to put an ESP32-CAM in Deep Sleep and wake it only once per month, at the end of the month.
Since ESP32 doesn't have a very good internal timer (i.e. I cannot tell it to wake up exactly on the last day of the month) I would like to use a RTC.

Unfortunately DS3231 (https://www.maximintegrated.com/en/prod ... S3231.html) - which was used by others to wake up ESP32 - seem not to work with ESP32-CAM because some pins it is using are not available on the ESP32-CAM (please correct me if I'm wrong, I just started learning about this).

Does anybody know of an RTC that can work with ESP32-CAM ?

Thank you !

Radu79
Posts: 29
Joined: Tue Nov 17, 2020 9:50 pm

Re: Any RTC chip known to work with ESP32 cam ?

Postby Radu79 » Sat Dec 05, 2020 12:53 am

Why don't you just sleep it and wake up every day or so, and check if it's the last day of the month?
Btw, are you going to do any hardware modifications, like removing or replacing the LDO? Because by default it takes about 6.5 mA in deep sleep mode (-1 mA less if there is no SD card).

sionut
Posts: 8
Joined: Tue Oct 06, 2020 10:23 am

Re: Any RTC chip known to work with ESP32 cam ?

Postby sionut » Sat Dec 05, 2020 6:01 am

This would be my last resort as waking up ESP32-CAM would consume more energy and I intend to power the chip with a 3V battery. I hope to make it run on battery for at least 6 months (if I get 1 year out of that 3V battery, I would call it my success :) )

The main reason I shied away from using the internal clock was because it is not very accurate (or so I read somewhere). Using the internal clock would force me to power up the WIFI of the board every now and then and update the time from an NTP server). Since I need the ESP32 only one day per month, it would be too much power spent just for checking the time.

However, in the meantime I found that you can reassign pins internally. I was able to reassign the SCL and SDA pins to other pins that are exposed. This means that I was able to set and get the time using the DS3231 board that I already have. Now I still have to find a wake-up pin on ESP32-CAM and program DS3231 to wake up my ESP32-CAM on the desired date.
Btw, are you going to do any hardware modifications, like removing or replacing the LDO?
I'm not so advanced to do any hardware modifications. I recently started in this domain (as a hobby). I'm a programmer by formation so, luckily, not everything is new to me.
However, I see that the LDO is the voltage regulator (transforming from 5V to 3.3V). I assume that, since I will use a 3V battery, the LDO won't be used.
I intend to dig more into this matter to see how I can make the chip consume as less power as possible, but this will take some time. You know what they say: it's not the destination that matters but the voyage itself. :)

Radu79
Posts: 29
Joined: Tue Nov 17, 2020 9:50 pm

Re: Any RTC chip known to work with ESP32 cam ?

Postby Radu79 » Sat Dec 05, 2020 2:03 pm

Unfortunately, what you want to do is not possible without modifying the hardware. Read this article:
https://time4ee.com/articles.php?article_id=126

So even with those modifications, you will still have some current draw.

BTW, after you take the photo, do this:
s->set_reg(s,0xff,0xff,0x01);//banksel
s->set_reg(s,0x09,0x10,0x10);//stand by

I haven't tested it with an ampmeter, but the sensor IS dead after this command (it will wake again after a reset). I am not sure if the MCU does this by default at shutdown, but I do it after taking my pic, while saving it to card so it saves a few seconds of sensor on time.

Radu79
Posts: 29
Joined: Tue Nov 17, 2020 9:50 pm

Re: Any RTC chip known to work with ESP32 cam ?

Postby Radu79 » Sat Dec 05, 2020 2:07 pm

One other thing, why don't you just use a lifepo4 battery, with a small solar panel?

sionut
Posts: 8
Joined: Tue Oct 06, 2020 10:23 am

Re: Any RTC chip known to work with ESP32 cam ?

Postby sionut » Sat Dec 05, 2020 3:22 pm

Your answer shows that you dedicated some time to this problem. I really appreciate that you pointed me to that resource as I searched the internet a lot and that page didn't come up in my results. It is very useful !
Unfortunately my beginner skills in electronics are a showstopper if we discuss about modifying the board. :)

More details about my project: my water meters are placed in a small, dark place where it's hard to reach. I prefer to set that camera in there and make it send a picture of those meters at the end of the month, when I have to report the actual readings. So a solar panel wouldn't help..

I read the article about the power consumption and it looks like I HAVE to change to board if I want to use a battery (because the camera doesn't turn off completely).

Radu79
Posts: 29
Joined: Tue Nov 17, 2020 9:50 pm

Re: Any RTC chip known to work with ESP32 cam ?

Postby Radu79 » Sat Dec 05, 2020 6:20 pm

Yeah, I have some other plans with this board (a hidden time lapse camera that I put in public places to create timelapse videos of life in general). I didn't get to the hardware part yet, I am still working at the software (ov2640 is not very well documented, so I had to do a lot of work to document the registers I need in order to get acceptable photos).

If you don't plan to use an SD card, and put the camera to sleep with that code I provided, and remove the LDO (no much electronic skills needed, just use a soldering iron and some tweezers), you might be able to get it to run a few months on a lifepo4 battery. But use an ampmeter to see how much current it uses.

agussupriadi
Posts: 2
Joined: Sun Dec 13, 2020 7:36 pm

Re: Any RTC chip known to work with ESP32 cam ?

Postby agussupriadi » Fri Dec 18, 2020 8:45 am

sionut wrote:
Sat Dec 05, 2020 6:01 am
This would be my last resort as waking up ESP32-CAM would consume more energy and I intend to power the chip with a 3V battery. I hope to make it run on battery for at least 6 months (if I get 1 year out of that 3V battery, I would call it my success :) )

The main reason I shied away from using the internal clock was because it is not very accurate (or so I read somewhere). Using the internal clock would force me to power up the WIFI of the board every now and then and update the time from an NTP server). Since I need the ESP32 only one day per month, it would be too much power spent just for checking the time.

However, in the meantime I found that you can reassign pins internally. I was able to reassign the SCL and SDA pins to other pins that are exposed. This means that I was able to set and get the time using the DS3231 board that I already have. Now I still have to find a wake-up pin on ESP32-CAM and program DS3231 to wake up my ESP32-CAM on the desired date.
Btw, are you going to do any hardware modifications, like removing or replacing the LDO?
I'm not so advanced to do any hardware modifications. I recently started in this domain (as a hobby). I'm a programmer by formation so, luckily, not everything is new to me.
However, I see that the LDO is the voltage regulator (transforming from 5V to 3.3V). I assume that, since I will use a 3V battery, the LDO won't be used.
I intend to dig more into this matter to see how I can make the chip consume as less power as possible, but this will take some time. You know what they say: it's not the destination that matters but the voyage itself. :)


Hello, I am so sorry before, my English language is not so good.

I am still looking for the way to reassign the SCL and SDA pins from ESP32-cam. I want to connect RTC DS3231/DS1307 and use SD card too. Please Sir, if You have any tutorial about this problem let Me know, I would really appreciate it. Thank you.

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

Re: Any RTC chip known to work with ESP32 cam ?

Postby FBMinis » Sat Feb 20, 2021 4:48 pm

I am using the DS3231 through i2C, it interacts with a p-channel mosfet. The DS3231 board we find online consumed 1.5mA while the system is off (until the alarm comes), but after removing some components I got 3uA: removed resistor blocks, eeprom chip and cut Pin 2 of the DS3231 (this way the chip works from the 2032 battery only).

here is the code:

Code: Select all

/*========================================================= 
ESP32-Cam captures a photo and sends it to Telegram everytime the DS3231 alarm is tripped
Remove resistor blocks and eeprom chip from DS3231 board. Cut VCC pin (2). Place 10K pullups on GPIO14 and GPIO15.
3uA current consumption until alarm time, 100uA without cutting VCC pin.

http://asciiflow.com/

                3.3V
                 +
                 |
                 +-----------+
                +-+          | S
            10k | |     | +--+
                +++     |    |
                 |    G | +  |
      +----------+------|-+--+  AO3401 p-channel mosfet
      |                 |
      |                 | +
      |                 | +--+
      |                      |D
      |                      |
      |       +---+----------+
      |    10K|   |          |
+-----+---+  +++ +++   +-----+---+
|   SQW   |  | | | |10K| ESP32CAM|
|         |  | | | |   |         |
|  DS3231 |  +++ +++   |         |
|         |   |   |    |         |
|     SDA +---+--------+IO14     |
|         |       |    |         |
|     SCL +-------+----+IO15     |
|         |            |         |
+-----+---+            +----+----+
      |                     |
      +-----------+---------+
                  |
                  +
                GROUND

Everything about ESP32-CAM:
https://RandomNerdTutorials.com/telegram-esp32-cam-photo-arduino/

lowpower with DS3231:
https://thecavepearlproject.org/read-the-blog/ (ds3231 mod pictures)
https://sites.google.com/site/wayneholder/low-power-techniques-for-arduino

Libraries:
https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
https://github.com/adafruit/RTClib

IMPORTANT!!!
- Select Board "AI Thinker ESP32-CAM"
- GPIO 0 must be connected to GND to upload a sketch
- After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode 
=========================================================*/

#include "Arduino.h"

#include <RTClib.h>
RTC_DS3231 rtc;
#define DS3231_I2C_ADDRESS 0x68
#define DS3231_CONTROL_REG 0x0E

#include <Wire.h>
#define I2C_SDA 14
#define I2C_SDL 15

#include "esp_camera.h"
#include "driver/rtc_io.h"
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems

// Wifi and Telegram stuff
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>

const char* ssid = "0000";
const char* password = "0000";
String BOTtoken = "0000";  // your Bot Token (Get from Botfather)
String CHAT_ID = "0000"; // Use @myidbot to find chat ID, individual or in group, then start bot

WiFiClientSecure clientTCP;
UniversalTelegramBot bot(BOTtoken, clientTCP);

// Pin definition for 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 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_UXGA);  // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA

s->set_whitebal(s, 1);       // 0 = disable , 1 = enable
s->set_awb_gain(s, 1);       // 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, 0);           // 0 = disable , 1 = enable
//s->set_ae_level(s, 2);       // -2 to 2
//s->set_aec_value(s, 1200);    // 0 to 1200
s->set_gain_ctrl(s, 0);      // 0 = disable , 1 = enable
s->set_agc_gain(s, 0);       // 0 to 30
s->set_gainceiling(s, (gainceiling_t)6);  // 0 to 6
s->set_bpc(s, 1);            // 0 = disable , 1 = enable
s->set_wpc(s, 1);            // 0 = disable , 1 = enable
s->set_raw_gma(s, 1);        // 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, 0);            // 0 = disable , 1 = enable
s->set_colorbar(s, 0);       // 0 = disable , 1 = enable
}

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 (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 setup() {

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

//Serial.begin(9600);
Serial.setDebugOutput(true);

Wire.begin(I2C_SDA, I2C_SDL);

// initializing the rtc
if (!rtc.begin()) {
Serial.println("Couldn't find RTC!");
Serial.flush();
abort();
}

// clearClockTrigger(); 
enableRTCAlarmsonBackupBattery(); // only needed if you cut the Vcc pin supplying power to the DS3231 chip to run clock from coincell

if (rtc.lostPower()) {
// this will adjust to the date and time at compilation
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

rtc.disable32K(); // we don't need the 32K Pin, so disable it

// set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
// if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
//  rtc.clearAlarm(1);
//  rtc.clearAlarm(2);

rtc.writeSqwPinMode(DS3231_OFF); // stop oscillating signals at SQW Pin otherwise setAlarm1 will fail

// turn off alarm 2 (in case it isn't off already)
// again, this isn't done at reboot, so a previously set alarm could easily go overlooked
rtc.disableAlarm(2);

configInitCamera(); // Config and init the camera

// 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(); // Capture the image and send it to Telegram

// schedule an alarm 60 seconds in the future
if (!rtc.setAlarm1(
rtc.now() + TimeSpan(60),
DS3231_A1_Second // this mode triggers the alarm when the seconds match. See Doxygen for other options
)) {
Serial.println("Error, alarm wasn't set!");
} else {
Serial.println("Alarm will happen in 60 seconds!");
}

// print current time
char date[10] = "hh:mm:ss";
rtc.now().toString(date);
Serial.print("current time: ");
Serial.println(date);

Serial.println("be right back");

// set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
// if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
// SQW becomes HIGH, P-MOSFET opens, power to the ESP2CAM is cut
rtc.clearAlarm(1);
rtc.clearAlarm(2);

/* // capture a frame (test)
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";
}
// do something with the photo

// end of do something with the photo

esp_camera_fb_return(fb); */


/* // wake up from external source (LOW pulse on GPIO13)
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
Serial.println("Going to sleep now");
delay(1000);
esp_deep_sleep_start();
Serial.println("This will never be printed"); */
}

void loop() {
}

/* static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) 
{
Wire.beginTransmission(addr);
Wire.write((byte)reg);
Wire.endTransmission();

Wire.requestFrom(addr, (byte)1);
return Wire.read();
} */

// Enable Battery-Backed Square-Wave Enable on the DS3231 RTC module:
// Bit 6 (Battery-Backed Square-Wave Enable) of DS3231_CONTROL_REG 0x0E, can be set to 1
// When set to 1, it forces the wake-up alarms to occur when running the RTC from the back up battery alone.
// [note: This bit is usually disabled (logic 0) when power is FIRST applied]
// https://github.com/EKMallon/Utilities/blob/master/setTme/setTme.ino

void enableRTCAlarmsonBackupBattery() {
Wire.beginTransmission(DS3231_I2C_ADDRESS);      // Attention device at RTC address 0x68
Wire.write(DS3231_CONTROL_REG);                  // move the memory pointer to CONTROL_REGister
Wire.endTransmission();                          // complete the ‘move memory pointer’ transaction
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);         // request data from register
byte resisterData = Wire.read();                 // byte from registerAddress
bitSet(resisterData, 6);                         // Change bit 6 to a 1 to enable
Wire.beginTransmission(DS3231_I2C_ADDRESS);      // Attention device at RTC address 0x68
Wire.write(DS3231_CONTROL_REG);                  // target the CONTROL_REGister
Wire.write(resisterData);                        // put changed byte back into CONTROL_REG
Wire.endTransmission();
}

/* // clearClockTrigger function needed to acheive low sleep currents with DS3231 Vcc Pin cut
// from http://forum.arduino.cc/index.php?topic=109062.0

void clearClockTrigger() {          
Wire.beginTransmission(0x68);   //Tell devices on the bus we are talking to the DS3231
Wire.write(0x0F);               //Tell the device which address we want to read or write
Wire.endTransmission();         //Before you can write to and clear the alarm flag
Wire.requestFrom(0x68,1);       //you have to read the flag first! Read one byte
Wire.read();                    //Read one byte - we are not interest in actually using it
Wire.beginTransmission(0x68);   //Tell devices on the bus we are talking to the DS3231
Wire.write(0x0F);               //Status Register: Bit 3: zero disables 32kHz, Bit 7: zero enables the main oscilator
Wire.write(0b00000000);         //Bit1: zero clears Alarm 2 Flag (A2F), Bit 0: zero clears Alarm 1 Flag (A1F)
Wire.endTransmission();
}
*/

sionut
Posts: 8
Joined: Tue Oct 06, 2020 10:23 am

Re: Any RTC chip known to work with ESP32 cam ?

Postby sionut » Mon Feb 22, 2021 1:03 pm

That's great ! Could you share a picture too ?

Who is online

Users browsing this forum: Google [Bot] and 72 guests