The DS1307 is a Real Time Clock module that can be had for as little as $0,50. With a 2032 battery on board the clock keeps running without the presence of an external power supply.
The clock connects to the Arduino via the I2C lines SDA or A4 and SCL or A5.
At the top of the code we include the clock. The library can be installed via the menu Sketch > Include Library > Manage Libraries, then search for rtclib and select the one that says ‘by adafruit’.
#include <RTClib.h> // Real Time Clock library RTC_DS1307 RTC; // Creates a real time clock with the name RTC
To start reading from / writing to the clock, in setup() we write:
RTC.begin();
Date and time of the clock can be set by uploading and running a sketch that has one of these two lines in setup():
RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // set to PC time RTC.adjust(DateTime(YEAR,MONTH,DAY,HOUR,MIN,SEC)); // set a specific time
Once this code has been executed, comment both lines and upload the sketch again. Now we can read out the time using this code:
DateTime now = RTC.now(); hour = now.hour(); minute = now.minute(); second = now.second();
For our station clock we do not need year or date, but in case you want to use those in another application, they are found via now.year(), now.month() and now.day(), now.dayOfTheWeek().
Read on below the video …
Let’s add these RTC code lines to the sketch of the previous video and we have ourselves a working analog clock that displays the actual time:
// OLED Model railway Station Platform Display - Ruud Boer, August 2019 // 6 different messages can be shown, based on 6 inputs // OLED SSD1306 - RTC DS1307 - I2C connections: SDA or A4, SCL or A5 #define MSG1_PIN 2 #define MSG2_PIN 3 #define MSG3_PIN 4 #define MSG4_PIN 5 #define MSG5_PIN 6 #define MSG6_PIN 7 #define TMIN 5 // departure time of next train, minimum of random time #define TMAX 13 // departure time of next train, maximum of random time #include <Wire.h> #include <RTClib.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // setup the OLED display] Adafruit_SSD1306 oled(4); byte bg = BLACK, fg = WHITE; // background- and foreground colors byte hour, minute, second; byte msgnr, msgnr_old, msgflag, msghour, msgminute; float angle; // Define the RTC RTC_DS1307 RTC; void calc_msg_time() { msgminute = msgminute + random(TMIN, TMAX); if (msgminute > 59) { msghour = (msghour + 1) % 24; msgminute = msgminute - 60; } } void print_msg_time() { oled.setTextColor(fg); oled.setTextSize(1); oled.setCursor(40,2); if(msghour < 10) oled.print(" "); oled.print(msghour); oled.print(":"); if(msgminute < 10) oled.print("0"); oled.print(msgminute); } void setup() { pinMode(MSG1_PIN, INPUT_PULLUP); pinMode(MSG2_PIN, INPUT_PULLUP); pinMode(MSG3_PIN, INPUT_PULLUP); pinMode(MSG4_PIN, INPUT_PULLUP); pinMode(MSG5_PIN, INPUT_PULLUP); pinMode(MSG6_PIN, INPUT_PULLUP); randomSeed(analogRead(A0)); Serial.begin(9600); // IS THIS NEEDED ???? Wire.begin(); RTC.begin(); oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C // To set the clock, uncomment one of the RTC.adjust() lines // RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // set to PC time // RTC.adjust(DateTime(2019,8,22,13,42,0)); // yyyy, mm, dd, hh, mm, ss } void loop() { // RTC DateTime now = RTC.now(); hour = now.hour(); minute = now.minute(); second = now.second(); // clear oled oled.clearDisplay(); oled.fillRect(0,0,127,31,bg); // clock ticks for(int z=0; z < 360;z= z + 30){ angle = (float)z / 57.3; int x2=(16+(sin(angle)*15)); int y2=(15-(cos(angle)*15)); int x3=(16+(sin(angle)*(12))); int y3=(15-(cos(angle)*(12))); oled.drawLine(x2,y2,x3,y3,fg); } // clock second angle=((float)second * 6 / 57.3); // degrees to radians int x3=(16+(sin(angle)*(14))); int y3=(15-(cos(angle)*(14))); oled.drawLine(16,15,x3,y3,fg); // clock minute angle=((float)minute * 6 / 57.3); // degrees to radians x3=(16+(sin(angle)*(12))); y3=(15-(cos(angle)*(12))); oled.drawLine(16,15,x3,y3,fg); // clock hour angle=((float)hour * 30 + (float)minute / 2) / 57.3; //degrees to radians x3=(16+(sin(angle)*(10))); y3=(15-(cos(angle)*(10))); oled.drawLine(16,15,x3,y3,fg); // time and messages if(!digitalRead(MSG1_PIN)) msgnr = 1; if(!digitalRead(MSG2_PIN)) msgnr = 2; if(!digitalRead(MSG3_PIN)) msgnr = 3; if(!digitalRead(MSG4_PIN)) msgnr = 4; if(!digitalRead(MSG5_PIN)) msgnr = 5; if(!digitalRead(MSG6_PIN)) msgnr = 6; if(msgnr != msgnr_old) { calc_msg_time(); msgnr_old = msgnr; } print_msg_time(); switch (msgnr) { case 1: oled.setCursor(72,2); oled.print("Intercity"); // max 10 characters oled.setCursor(40,12); oled.print("Eindhoven"); // max 14 characters oled.setCursor(40,22); oled.print("via Strijp-S"); // max 14 characters break; case 2: oled.setCursor(72,2); oled.print("Sprinter"); oled.setCursor(40,12); oled.print("sHertogenbosch"); oled.setCursor(40,22); oled.print("via Boxtel"); break; case 3: oled.setCursor(72,2); oled.print("Pendel"); oled.setCursor(40,12); oled.print("Maliebaan"); oled.setCursor(40,22); oled.print("via Eindhoven"); break; case 4: oled.setCursor(72,2); oled.print("Intercity"); oled.setCursor(40,12); oled.print("Venlo"); oled.setCursor(40,22); oled.print("via Deurne"); break; case 5: oled.setCursor(72,2); oled.print("Intercity"); oled.setCursor(40,12); oled.print("Maastricht"); oled.setCursor(40,22); oled.print("via Sittard"); break; case 6: oled.setCursor(72,2); oled.print("Intercity"); oled.setCursor(40,12); oled.print("Heerlen"); oled.setCursor(40,22); oled.print("via Weert"); break; } // refresh screen oled.display(); }
The video shows it works … the Arduino, the OLED and the Real Time Clock all combined.
— 0 —
Great stuff I am a beginner in Arduino and like you clear expectations of the code keep up the good work Regards robin
LikeLike
Great work,works great, now to build it into the station.
Many thanks,
Brian
LikeLike
Have fun with it.
LikeLike
Fantastic! Next adaptation, convert it to a Fast Time Clock?
LikeLike
If you don’t base the time on a Real Time Clock module but use the internal millis() counter it’s possible to multiply with any factor you like.
LikeLike
Rudy, probably a bit beyond my level as a rank beginner, but I’ll give it a try and let you know how I make out.
LikeLike
Dick, in the code of video 40, the one without Real Time Clock module, there’s a line that says time_to_update = millis() + 1000UL; This means the clock is updated every second (1000 ms). If you want a 5 times faster clock, change 1000 into 200 … that should do it. Ten times faster, add 100.
LikeLike
Many, many thanks. I’ll give it a try tomorrow. Have a great day!
LikeLike
is there a Fritzing file to see how to make the connextions?
LikeLike
https://images.app.goo.gl/MxVMUvretMCTkmtq6
LikeLike