How to setup DS1302 RTC module with Keypad + Arduino + LCD
Hello everyone,
In this tutorial we gonna make a project suggested by one of the viewers, which is setting up the DS1302 Real Time Clock module using a Keypad, we’re using a LCD screen to show the date and time, also helps us to set them up.
The functioning is quiet simple, the LCD is continuously showing the current time and date, when we press “*” button, it let us to set the date and time and then it shows the new value until you change them again. The code is also simple and easy to understand you can put it in your future project as I did when I made an alarm clock.
Before you start this project I recommend always to start by knowing well every module (otherwise you’ll waste a lot of time) then combine them until you get to your goal, by doing this you can easily spot a problem and find the solution, here you can check every module I used with its own tutorial:
- How to simply use DS1302 RTC module with Arduino board and LCD screen
- Arduino LCD I2C simple use and direct write from serial monitor
- Arduino uno + 4×4 Keypad Matrix + LCD i2c screen
Watch the video above for more explanations.
Wiring:

This is the wiring you can add or not that 1k resistor it depends if you have the same problem as I got (see in RTC tutorial)
Libraries:
Here below you can download all the libraries I’ve used:
- RTC Library
- LCD i2c Library
- Keypad Library (Or download it via Arduino IDE as I showed in the video)
Code:
And here’s the code I’ve used to download, or check below:
The code is very easy to understand, it’s not very optimized though… beginner level.
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
//This code is to use with DS1302 RTC module + 4*4 Keypad + LCD i2c + Arduino //After wiring the modules, the LCD will show the default date and time or the one set before //The objective of this project is that you can set the RTC module from the keypad, and sure it will stay stored //Then show it on the screen //Refer to https://surtrtech.com/ or SurtrTech youtube channel for more information #include <Keypad.h> //Libraries needed #include <virtuabotixRTC.h> #include <LiquidCrystal_I2C.h> #define I2C_ADDR 0x27 //LCD i2c stuff #define BACKLIGHT_PIN 3 #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 LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); virtuabotixRTC myRTC(2, 3, 4); //Wiring of the RTC (CLK,DAT,RST) //If you change the wiring change the pins here also const byte numRows= 4; //number of rows on the keypad const byte numCols= 4; //number of columns on the keypad //keymap defines the key pressed according to the row and columns just as appears on the keypad char keymap[numRows][numCols]= { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[numRows] = {12,11,10,9}; //Rows 0 to 3 //if you modify your pins you should modify this too byte colPins[numCols]= {8,7,6,5}; //Columns 0 to 3 int i1,i2,i3,i4; char c1,c2,c3,c4; char keypressed; //initializes an instance of the Keypad class Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols); void setup() { Serial.begin(9600); lcd.begin (16,2); //Initialize the LCD lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); lcd.home (); } void loop() { while(keypressed == NO_KEY){ //As long as no key is pressed we keep showing the date and time, I'm obliged to clear the screen everytime so the numbers don't get confused //And I should add that little delay so the screen shows correctly otherwise it didn't work for me keypressed = myKeypad.getKey(); lcd.clear(); //Here after clearing the LCD we take the time from the module and print it on the screen with usual LCD functions myRTC.updateTime(); lcd.setCursor(0,0); lcd.print(myRTC.dayofmonth); lcd.print("/"); lcd.print(myRTC.month); lcd.print("/"); lcd.print(myRTC.year); lcd.setCursor(0,1); lcd.print(myRTC.hours); lcd.print(":"); lcd.print(myRTC.minutes); lcd.print(":"); lcd.print(myRTC.seconds); delay(100); } if (keypressed == '*') //As we everytime check the key pressed we only proceed to setup if we press "*" { lcd.clear(); lcd.print(" Setup"); delay(1000); lcd.clear(); lcd.print("Setup year"); //So you can understand how this works, first it shows us "setup" then it prints "setup year" and now you can write your year normally (2-0-1-8) //It automatically passes to setting up the month...until it's finished //The keys from keypad are all considered chars (c) so we should convert them to int that's what I did then we store them (i) //We do some math and we get the year, month... as int so we can inject them to the RTC otherwise it will not be compiled //Months like April you should write 04, 03 for March... otherwise it will not pass to the next parameter //The RTC virtuabotix library is already set to not accept strange time and dates (45/17/1990) (58:90:70), and yes old dates are considered as errors char keypressed2 = myKeypad.waitForKey(); if (keypressed2 != NO_KEY && keypressed2 !='*' && keypressed2 !='#' && keypressed2 !='A' && keypressed2 !='B' && keypressed2 !='C' && keypressed2 !='D' ) { c1 = keypressed2; lcd.setCursor(0, 1); lcd.print(c1); } char keypressed3 = myKeypad.waitForKey(); if (keypressed3 != NO_KEY && keypressed3 !='*' && keypressed3 !='#' && keypressed3 !='A' && keypressed3 !='B' && keypressed3 !='C' && keypressed3 !='D' ) { c2 = keypressed3; lcd.setCursor(1, 1); lcd.print(c2); } char keypressed4 = myKeypad.waitForKey(); if (keypressed4 != NO_KEY && keypressed4 !='*' && keypressed4 !='#' && keypressed4 !='A' && keypressed4 !='B' && keypressed4 !='C' && keypressed4 !='D' ) { c3 = keypressed4; lcd.setCursor(2, 1); lcd.print(c3); } char keypressed5 = myKeypad.waitForKey(); if (keypressed5 != NO_KEY && keypressed5 !='*' && keypressed5 !='#' && keypressed5 !='A' && keypressed5 !='B' && keypressed5 !='C' && keypressed5 !='D' ) { c4 = keypressed5; lcd.setCursor(3, 1); lcd.print(c4); } i1=(c1-48)*1000; //the keys pressed are stored into chars I convert them to int then i did some multiplication to get the code as an int of xxxx i2=(c2-48)*100; i3=(c3-48)*10; i4=c4-48; int N_year=i1+i2+i3+i4; delay(500); lcd.clear(); lcd.print("Setup month"); //////////////////////////////////////////////////////////////// char keypressed6 = myKeypad.waitForKey(); // here all programs are stopped until you enter the four digits then it gets compared to the code above if (keypressed6 != NO_KEY && keypressed6 !='*' && keypressed6 !='#' && keypressed6 !='A' && keypressed6 !='B' && keypressed6 !='C' && keypressed6 !='D' ) { c1 = keypressed6; lcd.setCursor(0, 1); lcd.print(c1); } char keypressed7 = myKeypad.waitForKey(); if (keypressed7 != NO_KEY && keypressed7 !='*' && keypressed7 !='#' && keypressed7 !='A' && keypressed7 !='B' && keypressed7 !='C' && keypressed7 !='D' ) { c2 = keypressed7; lcd.setCursor(1, 1); lcd.print(c2); } i1=(c1-48)*10; i2=c2-48; int N_month=i1+i2; delay(500); lcd.clear(); lcd.print("Setup Day"); //////////////////////////////////////////////////////////////// char keypressed8 = myKeypad.waitForKey(); // here all programs are stopped until you enter the four digits then it gets compared to the code above if (keypressed8 != NO_KEY && keypressed8 !='*' && keypressed8 !='#' && keypressed8 !='A' && keypressed8 !='B' && keypressed8 !='C' && keypressed8 !='D' ) { c1 = keypressed8; lcd.setCursor(0, 1); lcd.print(c1); } char keypressed9 = myKeypad.waitForKey(); if (keypressed9 != NO_KEY && keypressed9 !='*' && keypressed9 !='#' && keypressed9 !='A' && keypressed9 !='B' && keypressed9 !='C' && keypressed9 !='D' ) { c2 = keypressed9; lcd.setCursor(1, 1); lcd.print(c2); } i1=(c1-48)*10; i2=c2-48; int N_day=i1+i2; delay(500); lcd.clear(); lcd.print("Setup hour"); ////////////////////////////////////////////////////////////////////////////////////: char keypressed10 = myKeypad.waitForKey(); // here all programs are stopped until you enter the four digits then it gets compared to the code above if (keypressed10 != NO_KEY && keypressed10 !='*' && keypressed10 !='#' && keypressed10 !='A' && keypressed10 !='B' && keypressed10 !='C' && keypressed10 !='D' ) { c1 = keypressed10; lcd.setCursor(0, 1); lcd.print(c1); } char keypressed11 = myKeypad.waitForKey(); if (keypressed11 != NO_KEY && keypressed11 !='*' && keypressed11 !='#' && keypressed11 !='A' && keypressed11 !='B' && keypressed11 !='C' && keypressed11 !='D' ) { c2 = keypressed11; lcd.setCursor(1, 1); lcd.print(c2); } i1=(c1-48)*10; i2=c2-48; int N_hour=i1+i2; delay(500); lcd.clear(); lcd.print("Setup minutes"); ////////////////////////////////////////////////////////////////////////////////////: char keypressed12 = myKeypad.waitForKey(); // here all programs are stopped until you enter the four digits then it gets compared to the code above if (keypressed12 != NO_KEY && keypressed12 !='*' && keypressed12 !='#' && keypressed12 !='A' && keypressed12 !='B' && keypressed12 !='C' && keypressed12 !='D' ) { c1 = keypressed12; lcd.setCursor(0, 1); lcd.print(c1); } char keypressed13 = myKeypad.waitForKey(); if (keypressed13 != NO_KEY && keypressed13 !='*' && keypressed13 !='#' && keypressed13 !='A' && keypressed13 !='B' && keypressed13 !='C' && keypressed13 !='D' ) { c2 = keypressed13; lcd.setCursor(1, 1); lcd.print(c2); } i1=(c1-48)*10; i2=c2-48; int N_minutes=i1+i2; delay(500); lcd.clear(); myRTC.setDS1302Time(22, N_minutes, N_hour, 1, N_day, N_month, N_year); //once we're done setting the date and time we transfer to values to the RTC module //the 22 stands for seconds you can add a setup for it too if you want //the 1 stands for day of the week, as long I don't show it on the screen I don't change it keypressed=NO_KEY; //the "*" key is stored in "keypressed" so I remove that value from it otherwise it will get me in the setup again } } |
Categories
Yassine View All
Automation and Electrical Engineer, Electronics amateur trying to share my little projects.
It does not work duuuuuuuuuuude!
If you tell me the problem I could help maybe
What about the virtualbotnixRTC Library
Sorry I don’t understand, if you want the library you can download it from the link in the article !
Hi, this looks like a great project for what I a working on. On line 21 of the code, I was wondering why you defined all of the LDC pins instead of just the SCL and SDAT pins? Without connections to them on the Arduino, does that work? I haven’t wired this up to find out yet. This is just something I noticed.
Hi, I just wired it up. I tried to compile it and it threw a couple errors. I changed LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); to LiquidCrystal_I2C lcd(I2C_ADDR,16,2);
I also deleted lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); it seemed the library didn’t recognize it.
After that it compiled without errors, but after I upload the coade, nothing displays on the LCD screen. I have double checked the wiring and everything looks good.
Hello, it seems you have a library problem… I recommend changing all LCD functions to your current library functions or change your library. You cannot use library functions with some other library.