RTC doesn't work with Rotary Encoder

Hello, I want to change the time of my RTC-module with a rotary-encoder.
The problem I'm facing right now, is that when I turn the Rotary, my RTC stops working properly, it either stops completely or changes the seconds to 0.
Does someone have a solution or an idea how I could fix this?
Thank you in advance

#include "RTClib.h"
#include <Encoder.h>

//Definition Encoder
Encoder Drehtaster (20,21);
long DTRotation;
long DTRotationAlt = 0;
//Definition Encoder Drucktaster
const int SW = 19;

//Definiton RTC
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};


void setup() {
    Serial.begin(9600);
    #ifndef ESP8266;
    while (!Serial); // wait for serial port to connect. Needed for native USB
    #endif
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
    }
    Serial.println("Setting the time...");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
     rtc.adjust(DateTime(2023, 3, 18, 1, 1, 1));
    // This line sets the RTC with an explicit date & time, for example to set   
  }


void loop() {
  // put your main code here, to run repeatedly:
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println(); 
    updateEncoder();
}





hi!
could you please provide details (technical reference, and eventually link to the datasheet) for:

  • the rotary encoder
  • the rtc

wich model of arduino board you use?
Can you join a schematic of the circuit?

EDIT: note the following line

will reset the date/time in your rtc at each reset of the board. You probably want to set up the RTC once, then comment this line and upload again the sketch (so the date/time are stored by the rtc and won't reset).

as it it said, your code (displaying time) will be done repeatedly. and very (very) quickly. It should be appropriate to display thoses infos less often, like once per sec with an adequate use of the timer (avoid delay() as it is a blocking function)

And finally, how do you use the rotary? except for the line updateEncoder();, your code shows no use of the rotary value. You can just expect it is refreshed continuously.

1 Like

Hey Pete I use GIAK KY-040 (https://www.rcscomponents.kiev.ua/datasheets/ky-040-datasheet.pdf) as rotary and the DS3231 (https://www.analog.com/media/en/technical-documentation/data-sheets/ds3231.pdf) as RTC. I work on a Arduino MEGA board. The rotary isnt in the code yet, but I want to navigate a menu on a display and adjust the time when I'm in a certain menu.
The thing with reset of the Time is okay for now, and I going to change that when i finalize the code.

Thank you for your quick response!

good.
we must agree I didn't really help you on your specific issue. I have in mind timing interference between I2C communication but no clues.
The datasheet and detailled characteristic may help other with more experience to visualize the problem.

My best advice is: put a timer to display time only in a periodic way, not at each loop occurence. Easy for you? I can write you a quick example if needed.

EDIT: cool project. you did well coding few steps and try. Baby steps and frequent debugging are your best friends to learn!

1 Like

Thank you, a quick example would be nice to have!

let's go!

const int interval = 1000; // 1sec in milliseconds
unsigned long time_stamp;

setup(){

// do what you need
time_stamp = millis(); // you set up your data with the actual value of millis()
}

loop(){

if (millis()-time_stamp>interval){
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 Serial.print('/');
..... // display what ever you want

time_stamp = millis(); // to reset the timer. if not: occured once only
}
// the rest of your code
}

should be close enough to the RTC example, but without the blocking function delay(). This way, your code is running for other tasks (randomly choosed: read the rotary as fast as possible).

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.