Fun with Arduino 41 Station Platform Display with Real Time Clock DS1307.

DS1307-AT24C32The 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 —

 

 

 

 

10 thoughts on “Fun with Arduino 41 Station Platform Display with Real Time Clock DS1307.

    • 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.

      Like

      • 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.

        Like

      • 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.

        Like

Leave a comment