model railroad train departure display, oled + rtc module ds

Hi, since i'm new with Arduino and i have basic knowledge of prog. language, i have some issues implementing rtc module into prepared code for train departure display. Goal is to use rtc time instead of random generated.

here is code for oled display :

// OLED Model railway Station Platform Display - Rudy B, August 2019
// 6 different messages can be shown, based on 6 inputs
// OLED SSD1306 - I2C wires: 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 COLOR_PIN  8
#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 <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// setup oled
Adafruit_SSD1306 oled(4);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
byte hour, minute, second; 
byte bg, fg, msgnr, msgnr_old, msgflag, msghour, msgminute;
unsigned long time_to_update;
float angle;

void calc_msg_time() {
 msgminute = minute + random(TMIN, TMAX);
 msghour = hour;
 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);
 pinMode(COLOR_PIN, INPUT_PULLUP);
 Serial.begin(9600);
 Wire.begin();
 oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C

// generate random startup time
 randomSeed(analogRead(A0));
 hour   = random(7, 20);
 minute = random(0, 60);
}

void loop() {

// determine background- and foreground color based on COLOR_PIN
 if(digitalRead(COLOR_PIN) == HIGH) {bg = WHITE; fg = BLACK;}
 else {bg = BLACK; fg = WHITE;}

// update time
 if(millis() > time_to_update) {
   time_to_update = millis() + 1000UL;
   second = second + 1;
   if(second == 60) {
     second = 0;
     minute = minute + 1;
   }
   if (minute == 60) {
     minute = 0;
     hour = (hour + 1) % 24;
   }
 }

// clear oled  
 oled.clearDisplay();
 oled.fillRect(0,0,127,31,bg);

// draw clock ticks
 for(int z=0; z<360;z=z+30){
   angle = (float)z / 57.3;
   int x1=(16+(sin(angle)*15));
   int y1=(15-(cos(angle)*15));
   int x2=(16+(sin(angle)*(12)));
   int y2=(15-(cos(angle)*(12)));
   oled.drawLine(x1,y1,x2,y2,fg);
 }
// draw clock second
 angle=((float)second * 6 / 57.3) ; //Convert degrees to radians  
 int x2=(16+(sin(angle)*(14)));
 int y2=(15-(cos(angle)*(14)));
 oled.drawLine(16,15,x2,y2,fg);

// draw clock minute
 angle=((float)minute * 6 / 57.3) ; //Convert degrees to radians  
 x2=(16+(sin(angle)*(12)));
 y2=(15-(cos(angle)*(12)));
 oled.drawLine(16,15,x2,y2,fg);

// draw clock hour
 angle=((float)hour * 30 + (float)minute / 2) / 57.3 ; //Convert degrees to radians  
 x2=(16+(sin(angle)*(10)));
 y2=(15-(cos(angle)*(10)));
 oled.drawLine(16,15,x2,y2,fg);

/*
// platform number
 oled.fillRect(107, 5, 19, 22, fg);
 oled.setTextSize(2);
 oled.setTextColor(bg);
 oled.setCursor(111,9);
 oled.print("3"); 
*/

// display 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("Stoptrein");
     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();
}

and this is code for rtc DS3231 module based on adafruit rtclib.h

#include <RTClib.h>
#include <Wire.h>

RTC_DS3231 rtc;

char t[32];

void setup() 
{
 Serial.begin(9600);
 Wire.begin();

 rtc.begin();
 rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
 //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
 

}

void loop()
{
 DateTime now = rtc.now();

 sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d",  now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());  
 
 Serial.print(F("Date/Time: "));
 Serial.println(t);

 delay(1000);
}

tnanks.

PrinzEugen:
Hi, since i'm new with Arduino and i have basic knowledge of prog. language, i have some issues implementing rtc module into prepared code for train departure display. Goal is to use rtc time instead of random generated.

You have not told us what your program actually does and what you want it to do that is different - so we can focus on the part that is causing a problem.

Also to make it easy for people to help you please modify your post and use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to my text editor.

...R

sorry for not using code button, i have corrected the error.

here is original project for train departure sign.

// OLED Model railway Station Platform Display - Rudy B, August 2019
// 6 different messages can be shown, based on 6 inputs
// OLED SSD1306 - I2C wires: 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 COLOR_PIN  8
#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 <RTClib.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

RTC_DS3231 rtc;

char t[32];


// setup oled
Adafruit_SSD1306 oled(4);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
byte hour, minute, second; 
byte bg, fg, msgnr, msgnr_old, msgflag, msghour, msgminute;
unsigned long time_to_update;
float angle;

void calc_msg_time() {
 msgminute = minute + random(TMIN, TMAX);  //?????????
 msghour = hour;
 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);
 pinMode(COLOR_PIN, INPUT_PULLUP);
 Serial.begin(9600);
 Wire.begin();
 oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C
 rtc.begin();
 rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

// generate random startup time ?????????
 randomSeed(analogRead(A0));
 hour   = random(7, 20);
 minute = random(0, 60);
}

void loop() {

DateTime now = rtc.now();

sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d",  now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());  

Serial.print(F("Date/Time: "));
Serial.println(t);

delay(1000);

// determine background- and foreground color based on COLOR_PIN
 if(digitalRead(COLOR_PIN) == HIGH) {bg = WHITE; fg = BLACK;}
 else {bg = BLACK; fg = WHITE;}

// update time
 if(millis() > time_to_update) {
   time_to_update = millis() + 1000UL;
   second = second + 1;
   if(second == 60) {
     second = 0;
     minute = minute + 1;
   }
   if (minute == 60) {
     minute = 0;
     hour = (hour + 1) % 24;
   }
 }

// clear oled  
 oled.clearDisplay();
 oled.fillRect(0,0,127,31,bg);

// draw clock ticks
 for(int z=0; z<360;z=z+30){
   angle = (float)z / 57.3;
   int x1=(16+(sin(angle)*15));
   int y1=(15-(cos(angle)*15));
   int x2=(16+(sin(angle)*(12)));
   int y2=(15-(cos(angle)*(12)));
   oled.drawLine(x1,y1,x2,y2,fg);
 }
// draw clock second
 angle=((float)second * 6 / 57.3) ; //Convert degrees to radians  
 int x2=(16+(sin(angle)*(14)));
 int y2=(15-(cos(angle)*(14)));
 oled.drawLine(16,15,x2,y2,fg);

// draw clock minute
 angle=((float)minute * 6 / 57.3) ; //Convert degrees to radians  
 x2=(16+(sin(angle)*(12)));
 y2=(15-(cos(angle)*(12)));
 oled.drawLine(16,15,x2,y2,fg);

// draw clock hour
 angle=((float)hour * 30 + (float)minute / 2) / 57.3 ; //Convert degrees to radians  
 x2=(16+(sin(angle)*(10)));
 y2=(15-(cos(angle)*(10)));
 oled.drawLine(16,15,x2,y2,fg);

/*
// platform number
 oled.fillRect(107, 5, 19, 22, fg);
 oled.setTextSize(2);
 oled.setTextColor(bg);
 oled.setCursor(111,9);
 oled.print("3"); 
*/

// display 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("Stoptrein");
     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();
}

i have used question marks for lines which need to be corrected, as far i'm concerned.

PrinzEugen:
i have used question marks for lines which need to be corrected, as far i'm concerned.

Without worrying about how to write the code, what do you want to happen in place of this line

msgminute = minute + random(TMIN, TMAX);

If you can get the date and time from the RTC as a single number it will probably be easier to work with. If not I suggest converting the hours and minutes to a number of minutes since midnight. Or do it with seconds if you need greater accuracy.

Separately, I'm surprised that a RTC has a role with a model railway - I thought they usually use speeded-up time and millis() would be good enough for that.

...R

i just need real time clock on display, and random train departure.

extra feature option: pin 9 for slide show of all lines, triggered by switch, with delay of 30sec for one line (case).

PrinzEugen:
extra feature option: pin 9 for slide show of all lines, triggered by switch, with delay of 30sec for one line (case).

Leave the extras for later - one thing at a time.

i just need real time clock on display, and random train departure.

As I don't really know how the thing works now, this comment does not explain what you want.

It think the present system updates the minutes value by a random amount. Do you just want the RTC to update the minutes value one-real-minute-at-a-time?

You also need to explain how the train departures are dealt with now and what you want to happen in future.

...R

ok, train departures are in range of (tmin 5,tmax 13 minutes for departure from current time, is it rtc.now ?) when train leaves, next departure (example case2) is announced and so on until case 6, then starts loop.

with 6 manual switches, initial departure is selected.

thats all. nothing more.

visual sign for clock project is in attach.

Image from Reply #7 so we don't have to download it. See this Simple Image Posting Guide

...R

PrinzEugen:
ok, train departures are in range of (tmin 5,tmax 13 minutes for departure from current time, is it rtc.now ?) when train leaves, next departure (example case2) is announced and so on until case 6, then starts loop.

with 6 manual switches, initial departure is selected.

thats all. nothing more.

I'm sure that makes perfect sense for you because you are totally familiar with your train system and what you want it to do. But it is almost meaningless to me (and I do have model trains) because all I know about your problem is the 6 lines of info about it you have provided in this Thread. I think I have written more about it than you have.

I suspect you are not thinking about the problem at the level of detail needed for programming. Computers are incredibly stupid so you must tell them every little detail. How much programming experience do you have? Did you write the program in your Original Post?

...R

im looking for help to implement code in already written project by someone else. I have no experience in programming, so if you have time to write any code regarding this i'll be greatful, it would mean much to me.

Thanks.

ps. 3 lines will do the job.

PrinzEugen:
I have no experience in programming,

[ ... ]

ps. 3 lines will do the job.

Those two comments do not sit well together - without experience how can you know how many lines of code are required.

so if you have time to write any code regarding this i'll be greatful, it would mean much to me.

If you just want someone to write some program code for you then please ask in the Gigs and Collaborations section of the Forum and be prepared to pay. However the first thing you will need to do (and which you have failed to do here) is describe in fine detail what you want.

If you want to learn how to do programming yourself I will try to help. However I have asked you some very specific questions in Replies #4 and #6 that you have not yet responded to.

...R

in short:
If you are willing to have your project done, please go and hire a programmer. No need to explain different cases in this free project, because you don’t know nothing about programming. I can't give you a single example, just help you to do program by yourself, which in my opinion I doubt you can, since you can't even follow the rules for posting.

You just can't walk into forum and asking for someone to write you a code, even if they share same hobby.

It's beginning to feel as if you are more interested in having a grievance than in having your problem solved. If so, you won't be the first, but thankfully those people don't appear on the Forum very often.

PrinzEugen:
in short:
If you are willing to have your project done, please go and hire a programmer.

I did not say it in a dismissive way like that - please don't misinterpret me.

No need to explain different cases in this free project, because you don’t know nothing about programming.

Again, this does not represent what I said. And I don't know what you mean by "different cases in this free project".

I can't give you a single example, just help you to do program by yourself, which in my opinion I doubt you can, since you can't even follow the rules for posting.

That is also misrepresenting me. If you answer my questions, or at least start a dialogue about them, we might make some progress.

You just can't walk into forum and asking for someone to write you a code, even if they share same hobby.

I don't know what you are trying to say with this.

As I mentioned in Reply #11 this Forum works in two ways. If you want help with writing your own program this is the place. If you just want someone to write (or modify) a program for you then the Gigs and Collaborations section is the place to go.

...R

Assuming you have hooked up the RTC and run the Adafruit program posted and it works, I think what you want to do is:

Step 1: Edit the code for the display to include the RTC library and create a RTC_DS3231 object.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>

RTC_DS3231 rtc;

Step 2: Remove the randomizing code and replace it with a call to the RTC library.

// generate random startup time
/*
 randomSeed(analogRead(A0));
 hour   = random(7, 20);
 minute = random(0, 60);
*/

 DateTime now = rtc.now();
 hour   = now.hour();
 minute = now.minute();

thank you , i appreciate it, no errors in compiling so far. now lets burn breadboard.

results:

  1. time is being calculated again after the restart which was previously set
  2. after half minute, display shows only clock, no departure sign