From 2dc7e9ec7973c37532cef25448f331b01db258dc Mon Sep 17 00:00:00 2001 From: eleksir Date: Fri, 7 Feb 2025 19:14:46 +0300 Subject: [PATCH] Init battery for ds3231 explicitly, code style fixes --- simpleclock.ino | 148 +++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 78 deletions(-) diff --git a/simpleclock.ino b/simpleclock.ino index 054e3f9..10d0825 100644 --- a/simpleclock.ino +++ b/simpleclock.ino @@ -1,32 +1,26 @@ -/* - * 7 Segment 4 Digits clock with digit point separator +/* 7 Segment 4 Digits clock with digit point separator. * - * It uses display module with common anode and DS1307 RTC module to enhance - * time keeping ability of Atmega 328p based Arduino Nano microcontroller and - * 2 buttons for adjusting time. - */ + * It uses display module with common anode and DS1307/DS3231 RTC module to + * enhance time keeping ability of Atmega 328p based Arduino Nano + * microcontroller and 2 buttons for adjusting time. */ -/* - * uRTCLib +/* uRTCLib * https://github.com/Naguissa/uRTCLib - * it has support for both DS1307 and DS3231, that i own. - * It is more fat than ds1307-dedicated or ds3231-dedicated lib, but i do not - * want to invent wheel if i have one. - */ + * it has support for both DS1307 and DS3231, that I have. + * It is more fat than ds1307-dedicated or ds3231-dedicated lib, but I do not + * want to re-invent wheel if I have one. */ #include -/* - * SevSeg +/* SevSeg * https://github.com/DeanIsMe/SevSeg - * it has simple api and ideally works in my case - */ + * it has simple api and ideally works in my case. */ #include -/* disable time compensation - * as we borrow more accurate chrystal and solder it to rtc breakboard +/* Disable time compensation. + * At last we borrow more accurate chrystal and solder it to rtc breakboard. */ //#define TIMECOMP -/* 0.5 second/day compensation flag */ +// 0.5 second/day compensation flag. //#define OFIVECOMP #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -35,7 +29,7 @@ uRTCLib clock; SevSeg Display; -/* push button stuff */ +// Push button stuff. const long initial_delay = 600; // wait a bit before spin numbers const long adjust_interval = 200; // delay between consecutive number increments const long bounce_delay = 20; // contact bounce compensation @@ -44,118 +38,123 @@ const int min_btn = A1; // put minute adjusting button on A1 lane volatile bool btn_pushed = false; // is button pushed? unsigned long previousPushTimer = 0; -/* dot blinking stuff */ +// Dot blinking stuff. volatile bool dot = true; #ifdef TIMECOMP -/* time inaccuracy compensation flag */ +// Time inaccuracy compensation flag. volatile bool compflag1 = true; volatile bool compflag2 = false; -const uint8_t timeSkew = 9; // assume that clock runs faster than should +const uint8_t timeSkew = 9; // Assume that clock runs faster than should. #ifdef OFIVECOMP -volatile bool timeSkewEven = false; // comp. 1 additional second per 2 days +volatile bool timeSkewEven = false; // Comp. 1 additional second per 2 days. #endif #endif -/* ambient light compensation aka night mode */ +// Ambient light compensation aka night mode. const int photoPin = A2; volatile bool measureAmbLight = true; -unsigned int ambLight = 0; // actual value -unsigned int ambLight2 = 0; // previous med. value -unsigned int ambLight3 = 0; // pre-previous med. value +unsigned int ambLight = 0; // Actual value. unsigned long previousLightTimer = 0; -const long refresh_interval = 40; // refresh rate 25Hz +const long refresh_interval = 40; // Refresh rate 25Hz. -/* time vars */ +// Time vars. volatile uint8_t mysecond; volatile uint8_t myminute; volatile uint8_t myhour; -/* rtc sync flag */ +// RTC sync flag. volatile bool rtcsync = true; void setup() { - // setup display + // Setup display. byte hardwareConfig = COMMON_ANODE; byte numDigits = 4; byte digitPins[] = {9, 10, 11, 12}; byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 13}; bool resistorsOnSegments = true; // 8 resistors, 330 Ohms each /* updateWithDelays defaults to false and it is recommended value, - * but i was unable to make my display to change brightness notably with + * but I was unable to make my display to change brightness notably with * recommended value, so i have to use updateWithDelays=true, - * in this case brightness gets changed. - */ + * in this case brightness gets changed. */ bool updateWithDelays = true; - /* without it there is visual bug at 0 o'clock, and in current version - * of SevSeg' setChars() does not dots at all */ + /* Without it there is visual bug at 0 o'clock, and in current version + * of SevSeg' setChars() does not dots at all. */ bool leadingZeros = false; Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros); Display.setBrightness(100); - // setup clock + // Init i2c bus and setup clock address. Wire.begin(); clock.set_rtc_address(0x68); - // if rtc returns incorrect time, reset it to some default value + // If rtc returns incorrect time, reset it to some default values. clock.refresh(); + if (clock.lostPower()) { + clock.set(30, 52, 15, 6, 23, 2, 19); // Saturday, 23 Feb 2019 15:52:30 + clock.lostPowerClear(); + } + if ((clock.hour() > 23) || (clock.minute() > 59)) { clock.set(30, 52, 15, 6, 23, 2, 19); // Saturday, 23 Feb 2019 15:52:30 } - // setup control buttons + /* In case of ds1307 this will be noop, but ds3231/ds3232 sometimes does + * not enable battery by default. */ + clock.enableBattery(); + + // Setup control buttons. pinMode(hrs_btn, INPUT_PULLUP); pinMode(min_btn, INPUT_PULLUP); -/* Timer stuff - * timer0 being used in millis() micros() delay() etc, it has 8 bit resolution - * timer2 being used in analogWrite() tone() notone(), it has 8 bit resolution - * timer1 being used in servo lib has 16 bit resolution - * We'll use timer1, since we have no mechanical parts and don't need servo lib - */ - // initialize timer1 - noInterrupts(); // disable all interrupts + /* Timer stuff. + * timer0 being used in millis() micros() delay() etc, it has 8 bit resolution. + * timer2 being used in analogWrite() tone() notone(), it has 8 bit resolution. + * timer1 being used in servo lib has 16 bit resolution. + * We'll use timer1, since we have no mechanical parts and don't need servo lib */ + + // Initialize timer1. + noInterrupts(); // Disable all interrupts. TCCR1A = 0; TCCR1B = 0; - TCNT1 = 34286; // preload timer 65536-16MHz/256/2Hz + TCNT1 = 34286; // Preload timer 65536-16MHz/256/2Hz TCCR1B |= (1 << CS12); // 256 prescaler - TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt - interrupts(); // enable all interrupts + TIMSK1 |= (1 << TOIE1); // Enable timer overflow interrupt. + interrupts(); // Enable all interrupts. -/* increase sampling rate of analogRead() - * by setting an ADC prescale from 128 to 16, so it takes less time to read - * sensor - */ + /* Increase sampling rate of analogRead() + * by setting an ADC prescale from 128 to 16, so it takes less time to read + * sensor. */ sbi(ADCSRA, ADPS2); cbi(ADCSRA, ADPS1); cbi(ADCSRA, ADPS0); - // setup ambient brigtness sensor + // Setup ambient brigtness sensor. pinMode(photoPin, INPUT); ambLight = analogRead(photoPin); } ISR(TIMER1_OVF_vect) { -/* Feed clock twice per second */ - TCNT1 = 34286; // preload timer - // do not read rtc if time beng adjusted by buttons + // Feed clock twice per second. + TCNT1 = 34286; // Preload timer. + // Do not read rtc if time beng adjusted by buttons. (btn_pushed) ? rtcsync : rtcsync = true; -/* Also switch dot */ + // Also switch dot. if (dot) dot = false; else dot = true; #ifdef TIMECOMP -/* time compensation magic */ + // Time compensation magic. if ((myhour == 21) and (myminute == 21) and (mysecond == 21) and (compflag2)) { compflag1 = true; @@ -176,11 +175,9 @@ void loop() unsigned long currentMillis = millis(); #ifdef TIMECOMP -/* - * Let's implement time compenstion for individual rtc module time - * charachteristics. In in my case quartz resonator as inaccurate as - * about +9.5 seconds per 24 hours - */ + /* Let's implement time compensation for individual rtc module time + * characteristics. In in my case quartz resonator as inaccurate as + * about +9.5 seconds per 24 hours. */ if (compflag1 && compflag2) { #ifdef OFIVECOMP if (timeSkewEven) { @@ -221,7 +218,7 @@ void loop() rtcsync = false; } - // push button magic + // Push button magic. if ((!btn_pushed) and ((digitalRead(hrs_btn) == LOW) or (digitalRead(min_btn) == LOW))) { if (currentMillis - previousPushTimer >= initial_delay) { @@ -278,15 +275,13 @@ void loop() (previousLightTimer > currentMillis)) { // millis() reset every ~49 days previousLightTimer = currentMillis; ambLight = analogRead(photoPin); - ambLight = (ambLight + ambLight2 + ambLight3) / 3; -/* Ambient light compensation - * ambLight can be in range of 0..1023, if it 910+, it has point to use - * fullbright. - * Use table comparsion (not function of ambLight) because of non-linear - * charachteristics of led indicator, that cannot be described via simple - * formula. - */ + /* Ambient light compensation. + * ambLight can be in range of 0..1023, if it 910+, it has point to use + * fullbright. + * Use table comparsion (not function of ambLight) because of non-linear + * characteristics of led indicator, that cannot be described via simple + * formula. */ if (ambLight >= 910) { Display.setBrightness(100); } else if ((ambLight < 900) and (ambLight >= 860)) { @@ -320,9 +315,6 @@ void loop() } else if (ambLight < 100) { Display.setBrightness(-22); } - - ambLight3 = ambLight2; - ambLight2 = ambLight; } Display.refreshDisplay();