How to use DS1307 RTC with Arduino and LCD/OLED
Hi, and welcome to this tutorial, it’s about another RTC (Real Time Clock) module, it’s the DS1307, previously I did a tutorial about the DS1302, and a project where I set it up using a keypad, then an Alarm Clock project based on that module, I also did a tutorial about the DS3132 RTC module.
But today we’re about the DS1307, and I’m gonna use it with Arduino UNO board and I’ll also use a LCD i²c screen and OLED display, to show time and date in different formats.
“The DS1307 serial real-time clock (RTC) is a low power, full binary-coded decimal (BCD) clock/calendar plus 56 bytes of NV SRAM. Address and data are transferred serially through an I2C, bidirectional bus. The clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for leap year.”
– MaximeIntegrated datasheet
Hardware and parts
For this tutorial I’ll be using the following parts, usual Arduino Uno board, OLED i2c display, LCD i2c display and of course the DS1307 RTC module, along side some jump wires and a breadboard:
Wirings
Wiring 1: with LCD i2c
For the LCD i²c version, both are connected with 5v and they both share A4/A5 for SDA/SCL
Wiring 2: with OLED i2c
For the OLED version they both share 5V and A4/A5 for SDA/SCL
Libraries
- DS1307 RTC library: – Download here from Github or Download Here.
- Time Library Download here from Github or Download Here.
- LCD i²c library: Download here LCD i²c NewLiquidCrystal library.
- OLED libraries:
- Adafruit OLED SSD1306 library: Download here from Github or Donwload here.
- Adafruit GFX Library Download here from Github or Download here.
Codes
Make sure to check the video tutorial above to know what code does what, or check the pictures below.
Code 1: Library example – SetTime
Important !! First time you must wire the module and upload the “SetTime” example, it sets the module to the compiling time of the code which is technically your real time and date. And here are the codes I’ve made for the LCD and OLED: Download here 3 LCD codes, Download here 3 OLED codes, or check below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> const char *monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; tmElements_t tm; void setup() { bool parse=false; bool config=false; // get the date and time the compiler was run if (getDate(__DATE__) && getTime(__TIME__)) { parse = true; // and configure the RTC with this info if (RTC.write(tm)) { config = true; } } Serial.begin(9600); while (!Serial) ; // wait for Arduino Serial Monitor delay(200); if (parse && config) { Serial.print("DS1307 configured Time="); Serial.print(__TIME__); Serial.print(", Date="); Serial.println(__DATE__); } else if (parse) { Serial.println("DS1307 Communication Error :-{"); Serial.println("Please check your circuitry"); } else { Serial.print("Could not parse info from the compiler, Time=\""); Serial.print(__TIME__); Serial.print("\", Date=\""); Serial.print(__DATE__); Serial.println("\""); } } void loop() { } bool getTime(const char *str) { int Hour, Min, Sec; if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false; tm.Hour = Hour; tm.Minute = Min; tm.Second = Sec; return true; } bool getDate(const char *str) { char Month[12]; int Day, Year; uint8_t monthIndex; if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false; for (monthIndex = 0; monthIndex < 12; monthIndex++) { if (strcmp(Month, monthName[monthIndex]) == 0) break; } if (monthIndex >= 12) return false; tm.Day = Day; tm.Month = monthIndex + 1; tm.Year = CalendarYrToTm(Year); return true; } |
N.B: If you are testing the module with multiple things it’s better to close the “SetTime” example, open it again and upload to the board, otherwise your module will be programmed with the first time the “SetTime” example was compiled, and you may think that your module doesn’t work well !!
Code 2: LCD code 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
/* This code is to use with DS1307 RTC and LCD i²c screen * It displays the time and date H:M:s D/M/Y as simple format 24h * Refer to http://www.surtrtech.com for more details */ #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define I2C_ADDR 0x27 //I2C adress, you should use the code to scan the adress first (0x27) here #define BACKLIGHT_PIN 3 // Declaring LCD Pins #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 tmElements_t tm; //RTC instance LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); void setup() { lcd.begin (16,2); lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); //Lighting backlight lcd.home(); lcd.print("Hi"); //Hi :D delay(1000); } void loop() { lcd.clear(); if (RTC.read(tm)) { //If there's a correct reading lcd.print(tm.Hour); lcd.print(':'); lcd.print(tm.Minute); lcd.print(':'); lcd.print(tm.Second); lcd.setCursor(0,1); lcd.print(tm.Day); lcd.print('/'); lcd.print(tm.Month); lcd.print('/'); lcd.print(tmYearToCalendar(tm.Year)); } delay(1000); } |
Code 3: LCD code 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
/* This code is to use with DS1307 RTC and LCD i²c screen * It displays the time and date HH:MM:ss DD/MM/YY 24h as 2 digits format e.g: 02 instead of 2 * Refer to http://www.surtrtech.com for more details */ #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define I2C_ADDR 0x27 //I2C adress, you should use the code to scan the adress first (0x27) here #define BACKLIGHT_PIN 3 // Declaring LCD Pins #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 tmElements_t tm; LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); void setup() { lcd.begin (16,2); lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); //Lighting backlight lcd.home(); lcd.print("Hi"); delay(1000); } void loop() { lcd.clear(); if (RTC.read(tm)) { print2digits(tm.Hour); lcd.print(':'); print2digits(tm.Minute); lcd.print(':'); print2digits(tm.Second); lcd.setCursor(0,1); print2digits(tm.Day); lcd.print('/'); print2digits(tm.Month); lcd.print('/'); lcd.print(tmYearToCalendar(tm.Year)); } delay(1000); } void print2digits(int number) { //Testing on the number before displaying it if (number >= 0 && number < 10) { //if it's 0<=x<10 we add a 0 before e.g: 4 -> 04 lcd.print('0'); } lcd.print(number); } |
Code 4: LCD code 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/* This code is to use with DS1307 RTC and LCD i²c screen * It displays the time and date H:M:s M/D/Y as 12h format with the display of am/pm * Refer to http://www.surtrtech.com for more details */ #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define I2C_ADDR 0x27 //I2C adress, you should use the code to scan the adress first (0x27) here #define BACKLIGHT_PIN 3 // Declaring LCD Pins #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 bool a; tmElements_t tm; LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); void setup() { lcd.begin (16,2); lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); //Lighting backlight lcd.home(); lcd.print("Hi"); delay(1000); } void loop() { lcd.clear(); if (RTC.read(tm)) { ampm(tm.Hour); //To show the hour we call a function ampm lcd.print(':'); lcd.print(tm.Minute); lcd.print(':'); lcd.print(tm.Second); if(a==true) lcd.print(" am"); if(a==false) lcd.print(" pm"); lcd.setCursor(0,1); lcd.print(tm.Month); lcd.print('/'); lcd.print(tm.Day); lcd.print('/'); lcd.print(tmYearToCalendar(tm.Year)); } delay(1000); } void ampm(int Hour){ //ampm function takes the hour value 0-23 if(Hour==0){ //if it's 0 it becomes 12 Hour=12; a=true; //true if it's am, false otherwise lcd.print(Hour); } else if(Hour>0 && Hour<12){ a=true; //normal value lcd.print(Hour); } else if(Hour==12){ a=false; //changing to pm lcd.print(Hour); } else if(Hour>12){ Hour=Hour-12; //substract 12 to bring it back to 1,2,3,... a=false; lcd.print(Hour); } } |
Code 5: OLED code 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/* This code works with DS1307 RTC with OLED display * It displays the time and date in a simple 24h format H:M:s D/M/Y * Refer to http://www.surtrtech.com for more details */ #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display) tmElements_t tm; void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display display.clearDisplay(); display.display(); } void loop() { RTC.read(tm); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(17,0); display.print(tm.Hour); display.print(":"); display.print(tm.Minute); display.print(":"); display.print(tm.Second); display.setCursor(17,17); display.print(tm.Day); display.print('/'); display.print(tm.Month); display.print('/'); display.print(tmYearToCalendar(tm.Year)); display.display(); delay(1000); display.clearDisplay(); } |
Code 6: OLED code 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
/* This code works with DS1307 RTC with OLED display * It displays the time and date in a 12h format H:M:s M/D/Y with the displaying of am/pm * Refer to http://www.surtrtech.com for more details */ #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) bool a; Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display) tmElements_t tm; void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display display.clearDisplay(); display.display(); } void loop() { RTC.read(tm); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(17,0); ampm(tm.Hour); display.print(":"); display.print(tm.Minute); display.print(":"); display.print(tm.Second); display.setTextSize(1); if(a==true) display.print("am"); if(a==false) display.print("pm"); display.setCursor(17,17); display.setTextSize(2); display.print(tm.Month); display.print('/'); display.print(tm.Day); display.print('/'); display.print(tmYearToCalendar(tm.Year)); display.display(); delay(1000); display.clearDisplay(); } void ampm(int Hour){ //ampm function takes the hour value 0-23 if(Hour==0){ //if it's 0 it becomes 12 Hour=12; a=true; //true if it's am, false otherwise display.print(Hour); } else if(Hour>0 && Hour<12){ a=true; //normal value display.print(Hour); } else if(Hour==12){ a=false; //changing to pm display.print(Hour); } else if(Hour>12){ Hour=Hour-12; //substract 12 to bring it back to 1,2,3,... a=false; display.print(Hour); } } |
Code 7: OLED code 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
/* This code works with DS1307 RTC with OLED display * It displays the time and date in a 12h format H:M M/D then Year with the displaying of am/pm and blinking ":" * Refer to http://www.surtrtech.com for more details */ #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) bool a,points; int x=0; Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display) tmElements_t tm; void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display display.clearDisplay(); display.display(); } void loop() { RTC.read(tm); x=tm.Second%2; //Dividing the seconds value by 2 and store the rest value, it's either 0 or 1 display.setTextSize(3); display.setTextColor(WHITE); display.setCursor(0,10); ampm(tm.Hour); if(x==0) //if x=0 we don't display the ":" display.print(" "); if(x==1) //if x=1 we display it, so for every 1s we display or not the ":" display.print(":"); display.print(tm.Minute); display.setTextSize(1); display.setCursor(50,0); if(a==true) display.print(" am"); if(a==false) display.print(" pm"); display.setCursor(90,5); display.setTextSize(2); display.print(tm.Month); display.print('/'); display.print(tm.Day); display.setCursor(95,23); display.setTextSize(1); display.print(tmYearToCalendar(tm.Year)); display.display(); display.clearDisplay(); } void ampm(int Hour){ //ampm function takes the hour value 0-23 if(Hour==0){ //if it's 0 it becomes 12 Hour=12; a=true; //true if it's am, false otherwise display.print(Hour); } else if(Hour>0 && Hour<12){ a=true; //normal value display.print(Hour); } else if(Hour==12){ a=false; //changing to pm display.print(Hour); } else if(Hour>12){ Hour=Hour-12; //substract 12 to bring it back to 1,2,3,... a=false; display.print(Hour); } } |
Tests
LCD tests:
And for the OLED
That’s it for this RTC module, if you have any problem feel free to get in touch!
Categories
Yassine View All
Automation and Electrical Engineer, Electronics amateur trying to share my little projects.
Hey can you tell me how to change the code for OLED 128*64?
SCREEN_HEIGHT 32 make it 64, then you’ll have more space to play with when using SetCursor function…
Hİ ,
Your project is done ! Thank you 😉
https://ibb.co/F07XdQy
Regards…
how to interface 20×4 16-pin lcd display in code2