RTC with ESP32
RTC with ESP32
Copied RTC code from this site . Worked ok; see below:
Worked OK without battery, but seems to get time from OS when compiling. Does not keep running with power off and seems to revert to previous time when compiled. That's ok.
x Time string Time string is 2023-1-21 3:5:36 now working with "sprintf".
Time string is 2023-1-21 3:5:36
Time string is 2023-1-21 3:5:36Time string is 2023-1-21 3:5:36 (Plus other stuff gets printed.)/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-rtc Sat Nov 2 12:51:10 NZDT 2024 playing 01 */ #include <RTClib.h> #include <stdio.h> RTC_DS3231 rtc; char daysOfWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; char buffer[100]; void setup () { Serial.begin(9600); // SETUP RTC MODULE if (! rtc.begin()) { Serial.println("RTC module is NOT found"); Serial.flush(); while (1); } // automatically sets the RTC to the date & time on PC this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // manually sets the RTC with an explicit date & time, for example to set // January 21, 2021 at 3am you would call: rtc.adjust(DateTime(2023, 1, 21, 3, 3, 3)); } void loop () { DateTime now = rtc.now(); // Serial.println("now=.."); // Serial.println(now); int k = now.year(); Serial.println(k); printf("%s\n", buffer); Serial.print("ESP32 RTC Date Time: "); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(" ("); Serial.print(daysOfWeek[now.dayOfTheWeek()]); Serial.print(") "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.println(now.second(), DEC); Serial.println(rtc.getTemperature()); float pi = 3.14159; sprintf(buffer, "The value of pi is %.2f.", pi); printf("%s\n", buffer); sprintf(buffer,"The year is %d",now.year()); printf("%s\n", buffer); sprintf(buffer,"Time string is %d-%d-%d %d:%d:%d",now.year(), now.month(), now.day(), now.hour(),now.minute(),now.second()); delay(1000); // delay 1 seconds }The version below comments out RTC clock setting so that the date and time are taken from the battery backed up RTC memory.First you set the time with this line:rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));Then you comment it out and recompile. It will keep the date and time for a long time internally./* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-rtc Sat Nov 2 12:51:10 NZDT 2024 playing 01 */ #include <RTClib.h> #include <stdio.h> RTC_DS3231 rtc; char daysOfWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; char buffer[100]; void setup () { Serial.begin(9600); // SETUP RTC MODULE if (! rtc.begin()) { Serial.println("RTC module is NOT found"); Serial.flush(); while (1); } // automatically sets the RTC to the date & time on PC this sketch was compiled // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // manually sets the RTC with an explicit date & time, for example to set // January 21, 2021 at 3am you would call: // rtc.adjust(DateTime(2023, 3, 3, 3, 3, 3)); } void loop () { DateTime now = rtc.now(); // Serial.println("now=.."); // Serial.println(now); int k = now.year(); Serial.println(k); printf("%s\n", buffer); Serial.print("ESP32 RTC Date Time: "); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(" ("); Serial.print(daysOfWeek[now.dayOfTheWeek()]); Serial.print(") "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.println(now.second(), DEC); Serial.println(rtc.getTemperature()); float pi = 3.14159; sprintf(buffer, "The value of pi is %.2f.", pi); printf("%s\n", buffer); sprintf(buffer,"The year is %d",now.year()); printf("%s\n", buffer); sprintf(buffer,"Time string is %d-%d-%d %d:%d:%d",now.year(), now.month(), now.day(), now.hour(),now.minute(),now.second()); Serial.println(now.timestamp()); delay(1000); // delay 1 seconds }#include <Wire.h> void setup() { Wire.begin(); Serial.begin(115200); } void loop() { displayDateTimeTemperatureOnSerial(); delay(1000); } void displayDateTimeTemperatureOnSerial() { // Read the date and time Wire.beginTransmission(0x68); Wire.write(0); // Start reading from address 0 (seconds) Wire.endTransmission(); Wire.requestFrom(0x68, 7); // Request seconds, minutes, hours, day, date, month, year if (Wire.available()) { byte seconds = bcdToDec(Wire.read() & 0x7F); // Mask the high bit of seconds byte minutes = bcdToDec(Wire.read() & 0x7F); byte hourRegister = Wire.read(); byte hours; bool isPM = false; bool is12HourMode = hourRegister & 0x40; // Check if DS3231 is in 12-hour mode if (is12HourMode) { isPM = hourRegister & 0x20; // Check if it's PM hours = bcdToDec(hourRegister & 0x1F); // Mask the high three bits for 12-hour mode } else { hours = bcdToDec(hourRegister & 0x3F); // 24-hour mode, mask the high two bits } byte day = bcdToDec(Wire.read()); byte date = bcdToDec(Wire.read()); byte month = bcdToDec(Wire.read()); int year = 2000 + bcdToDec(Wire.read()); // Read the temperature Wire.beginTransmission(0x68); Wire.write(0x11); // Start reading from temperature register Wire.endTransmission(); Wire.requestFrom(0x68, 2); byte tempMSB = Wire.read(); byte tempLSB = Wire.read(); float temperatureC = (tempMSB << 8 | tempLSB) / 256.0; float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; // Convert to Fahrenheit // Print to Serial Monitor Serial.print("Date: "); Serial.print(year); Serial.print("-"); Serial.print(month); Serial.print("-"); Serial.print(date); Serial.print(" "); Serial.println(dayOfWeekToStr(day)); Serial.print("Time: "); Serial.print(hours); Serial.print(":"); if (minutes < 10) Serial.print("0"); Serial.print(minutes); Serial.print(":"); if (seconds < 10) Serial.print("0"); Serial.print(seconds); Serial.print(is12HourMode ? (isPM ? " PM" : " AM") : ""); // Empty string if in 24-hour mode Serial.println(); Serial.print("Temp: "); Serial.print(temperatureC); Serial.print(" C / "); Serial.print(temperatureF); Serial.println(" F"); Serial.println(); Serial.println(); } } byte bcdToDec(byte val) { return ((val / 16 * 10) + (val % 16)); } String dayOfWeekToStr(byte dayOfWeek) { switch (dayOfWeek) { case 1: return "Monday "; case 2: return "Tuesday "; case 3: return "Wednesday"; case 4: return "Thursday "; case 5: return "Friday "; case 6: return "Saturday "; case 7: return "Sunday "; default: return "Err "; } }----------------below reads and displays all regs in raw hex form --------based on code from here//16Rudolf2#include <Wire.h>void setup() {Wire.begin();Serial.begin(115200);}void loop() {displayDateTimeTemperatureOnSerial();// readRegs();readRegs2();delay(1000);}void displayDateTimeTemperatureOnSerial() {// Read the date and timeWire.beginTransmission(0x68);Wire.write(0); // Start reading from address 0 (seconds)Wire.endTransmission();Wire.requestFrom(0x68, 7); // Request seconds, minutes, hours, day, date, month, yearif (Wire.available()) {byte seconds = bcdToDec(Wire.read() & 0x7F); // Mask the high bit of secondsbyte minutes = bcdToDec(Wire.read() & 0x7F);byte hourRegister = Wire.read();byte hours;bool isPM = false;bool is12HourMode = hourRegister & 0x40; // Check if DS3231 is in 12-hour modeif (is12HourMode) {isPM = hourRegister & 0x20; // Check if it's PMhours = bcdToDec(hourRegister & 0x1F); // Mask the high three bits for 12-hour mode} else {hours = bcdToDec(hourRegister & 0x3F); // 24-hour mode, mask the high two bits}byte day = bcdToDec(Wire.read());byte date = bcdToDec(Wire.read());byte month = bcdToDec(Wire.read());int year = 2000 + bcdToDec(Wire.read());// Read the temperatureWire.beginTransmission(0x68);Wire.write(0x11); // Start reading from temperature registerWire.endTransmission();Wire.requestFrom(0x68, 2);byte tempMSB = Wire.read();byte tempLSB = Wire.read();float temperatureC = (tempMSB << 8 | tempLSB) / 256.0;float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; // Convert to FahrenheitSerial.printf(" MSB,LSb of temp %X %X \n", tempMSB, tempLSB);// Print to Serial MonitorSerial.print("Date: ");Serial.print(year);Serial.print("-");Serial.print(month);Serial.print("-");Serial.print(date);Serial.print(" ");Serial.println(dayOfWeekToStr(day));Serial.print("Time: ");Serial.print(hours);Serial.print(":");if (minutes < 10) Serial.print("0");Serial.print(minutes);Serial.print(":");if (seconds < 10) Serial.print("0");Serial.print(seconds);Serial.print(is12HourMode ? (isPM ? " PM" : " AM") : ""); // Empty string if in 24-hour modeSerial.println();Serial.print("Temp: ");Serial.print(temperatureC);Serial.print(" C / ");Serial.print(temperatureF);Serial.println(" F");Serial.println();Serial.println();}}byte bcdToDec(byte val) {return ((val / 16 * 10) + (val % 16));}String dayOfWeekToStr(byte dayOfWeek) {switch (dayOfWeek) {case 1: return "Monday ";case 2: return "Tuesday ";case 3: return "Wednesday";case 4: return "Thursday ";case 5: return "Friday ";case 6: return "Saturday ";case 7: return "Sunday ";default: return "Err ";}}//Now start Pb routine to read registers of RTCvoid readRegs(void) {// Read the registersWire.beginTransmission(0x68);Wire.write(0); // Start reading from temperature registerWire.endTransmission(); //locks in valuesWire.requestFrom(0x68,3);byte k = Wire.read();Serial.print("First read ");Serial.println(k,HEX);k = Wire.read();Serial.print("Second read ");Serial.println(k,HEX);k = Wire.read();Serial.printf("Third is %x \n",k);}void readRegs2(void) {// Read the registersWire.beginTransmission(0x68);Wire.write(0); // Start reading from temperature registerWire.endTransmission(); //locks in valuesWire.requestFrom(0x68,19);for (int i=0;i<19;i++) {byte k = Wire.read();Serial.printf("Register %X is %x \n",i,k);}}Square wave enums : But just found out "M" version only does 1Hz on SQW pin.
enum Ds3231SqwPinMode {
DS3231_OFF = 0x1C, DS3231_SquareWave1Hz = 0x00, DS3231_SquareWave1kHz = 0x08, DS3231_SquareWave4kHz = 0x10,
DS3231_SquareWave8kHz = 0x18
enum Ds3231Alarm1Mode {
DS3231_A1_PerSecond = 0x0F, DS3231_A1_Second = 0x0E, DS3231_A1_Minute = 0x0C, DS3231_A1_Hour = 0x08,
DS3231_A1_Date = 0x00, DS3231_A1_Day = 0x10The following outputs any frequency up to about 80KHz on GPIO16,17,5 and into counting pin GPIO18.It also receives input from the 32KHz sqw pin on the DS3231 and gets about 32761 edges, wher it shoulbe 32768. Not bad.Timer 1 was used in various frequencies. Stpped outputting sensible values whendown to about 6us. Not having much time to loop for 1000 millies as it was being interruptedover 80K times a second. Code follows:/*38Copyright (c) 2017 pcbreflux. All Rights Reserved.WorksTue Nov 19 11:35:26 NZDT 2024 worked. Counts bounces on GPIO18*Mon Nov 11 12:10:29 NZDT 2024* This program is free software: you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation, version 3.** This program is distributed in the hope that it will be useful, but* WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program. If not, see <http://www.gnu.org/licenses/>. ** :%s/foo/bar/gc*/#define BUTTON_PIN 18 // The ESP32 pin GPIO21 connected to the button Worked 7/11/hw_timer_t * timer0 = NULL;hw_timer_t * timer1 = NULL;hw_timer_t * timer2 = NULL;portMUX_TYPE timerMux0 = portMUX_INITIALIZER_UNLOCKED;portMUX_TYPE timerMux1 = portMUX_INITIALIZER_UNLOCKED;portMUX_TYPE timerMux2 = portMUX_INITIALIZER_UNLOCKED;volatile uint8_t led1stat = 0;volatile uint8_t led2stat = 0;volatile uint8_t led3stat = 0;volatile bool buttonPressed = false; // use volatile for variable that is accessed from inside and outside ISRvolatile long numEdges=0;void IRAM_ATTR handleButtonPress();void IRAM_ATTR onTimer0(){// Critical Code hereportENTER_CRITICAL_ISR(&timerMux0);led1stat=1-led1stat;digitalWrite(16, led1stat); // turn the LED on or offportEXIT_CRITICAL_ISR(&timerMux0);}void IRAM_ATTR onTimer1(){// Critical Code hereportENTER_CRITICAL_ISR(&timerMux1);led2stat=1-led2stat;digitalWrite(17, led2stat); // turn the LED on or offportEXIT_CRITICAL_ISR(&timerMux1);}void IRAM_ATTR onTimer2(){// Critical Code hereportENTER_CRITICAL_ISR(&timerMux2);led3stat=1-led3stat;digitalWrite(5, led3stat); // turn the LED on or offportEXIT_CRITICAL_ISR(&timerMux2);}void setup() {Serial.begin(115200);pinMode(17, OUTPUT);pinMode(16, OUTPUT);pinMode(5, OUTPUT);pinMode(BUTTON_PIN, INPUT_PULLUP);digitalWrite(17, LOW); // turn the LED off by making the voltage LOWdigitalWrite(16, LOW); // turn the LED off by making the voltage LOWdigitalWrite(5, LOW); // turn the LED off by making the voltage LOWSerial.println("start timer 1");timer1 = timerBegin(1000000); // timer 1, MWDT clock period = 12.5 ns * TIMGn_Tx_WDT_CLK_PRESCALE -> 12.5 ns * 80 -> 1000 ns = 1 us, countUptimerAttachInterrupt(timer1, &onTimer1 ); // edge (not level) triggeredtimerAlarm(timer1, 100, true,0); // 10 * 1 us = 10us, autoreload true//timerAlarm(timer1, 250000, true,0); // 250000 * 1 us = 250 ms, autoreload trueSerial.println("start timer 0");timer0 = timerBegin(1000000); // timer 0, MWDT clock period = 12.5 ns * TIMGn_Tx_WDT_CLK_PRESCALE -> 12.5 ns * 80 -> 1000 ns = 1 us, countUptimerAttachInterrupt(timer0, &onTimer0 ); // edge (not level) triggeredtimerAlarm(timer0, 1000000, true,0); // 1000000 * 1 us = 1 s, autoreload trueSerial.println("start timer 2");timer2 = timerBegin(1000000); // timer 2, MWDT clock period = 12.5 ns * TIMGn_Tx_WDT_CLK_PRESCALE -> 12.5 ns * 80 -> 1000 ns = 1 us, countUptimerAttachInterrupt(timer2, &onTimer2 ); // edge (not level) triggeredtimerAlarm(timer2, 750000, true,0); // 750000 * 1 us = 750 ms, autoreload true// at least enable the timer alarms/*timerAlarmEnable(timer0); // enabletimerAlarmEnable(timer1); // enabletimerAlarmEnable(timer2); // enable*///attachInterrupt(digitalPinToInterrupt(0), handleButtonPress, FALLING);attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING);}void loop() {// nope nothing here// vTaskDelay(portMAX_DELAY); // wait as much as posible ...long target = millis() +1000;long ctr =0;numEdges = 0;while(millis() < target){ctr++;} //takes 1 secondSerial.printf("Number of edges on GPIO0 is %lu \n",numEdges,numEdges);Serial.printf("Number of loops is %ul\n ",ctr);}// Interrupt Service Routine (ISR)void IRAM_ATTR handleButtonPress() {// Serial.println("Button pressed!"); // do NOT use function that takes long time to executenumEdges++;}
ESP32 RTC Date Time: 2023/1/21 (Saturday) 3:5:36
14.75
The value of pi is 3.14.
The year is 2023
2023
Time string is 2023-1-21 3:5:36
ESP32 RTC Date Time: 2023/1/21 (Saturday) 3:5:37
14.75
The value of pi is 3.14.
The year is 2023
2023


Comments
Post a Comment