Arduino and DS3231 Real Time Clock: Hardware Required
Arduino and DS3231 Real Time Clock: Hardware Required
Arduino and DS3231 Real Time Clock: Hardware Required
After the interfacing of DS1307 real time clock IC with Arduino now I’m going to use
DS3231 instead of the DS1307. Related topic link is below:
Arduino real time clock with DS1307
The DS3231 is also a low cost, easy to use and highly accurate real time clock IC which
counts seconds, minutes, houres, day of the week, date, month and year. A battery can be
connected to the DS3231 to keep the time running in case of main power failure. The
DS3231 don’t need any oscillator because it has a built-in one.
Hardware Required:
Arduino board
DS3231 RTC board
1602 LCD screen
2 x push button
10K ohm variable resistor (or potentiometer)
330 ohm resistor
3V coin cell battery
Breadboard
Jumper wires
The DS3231 works with BCD format only and to convert the BCD to decimal and vise versa
I used the 2 lines below (example for minute):
// Convert BCD to decimal
minute = (minute >> 4) * 10 + (minute & 0x0F);
void DS3231_display() : displays time and calendar, before displaying time and calendar data
are converted from BCD to decimal format.
void blink_parameter() : this small function works as a delay except that it is interrupted by
the buttons B1 (connected to pin 8) and B2 (connected to pin 9). When called and without
pressing any button the total time is 10 x 25ms = 250ms. With this function we can see the
blinking of the selected parameter with a frequency of 2Hz. So a delay of 250ms comes after
the print of the selected parameter and after that delay a 2 spaces is printed which makes the
parameter disappears from the LCD and another 250ms delay comes after the print of the 2
spaces.
The complete code is below.
C
1 // Real time clock and calendar with set buttons using DS3231 and Arduino
2
3 // include LCD library code
4 #include <LiquidCrystal.h>
5 // include Wire library code (needed for I2C protocol devices)
6 #include <Wire.h>
7
8 // LCD module connections (RS, E, D4, D5, D6, D7)
9 LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
10
11 void setup() {
12 pinMode(8, INPUT_PULLUP); // button1 is connected to pin 8
13 pinMode(9, INPUT_PULLUP); // button2 is connected to pin 9
14 // set up the LCD's number of columns and rows
15 lcd.begin(16, 2);
16 Wire.begin(); // Join i2c bus
17 }
18
19 char Time[] = "TIME: : : ";
20 char Calendar[] = "DATE: / /20 ";
21 byte i, second, minute, hour, date, month, year;
22
23 void DS3231_display(){
24 // Convert BCD to decimal
25 second = (second >> 4) * 10 + (second & 0x0F);
26 minute = (minute >> 4) * 10 + (minute & 0x0F);
27 hour = (hour >> 4) * 10 + (hour & 0x0F);
28 date = (date >> 4) * 10 + (date & 0x0F);
29 month = (month >> 4) * 10 + (month & 0x0F);
30 year = (year >> 4) * 10 + (year & 0x0F);
31 // End conversion
32 Time[12] = second % 10 + 48;
33 Time[11] = second / 10 + 48;
34 Time[9] = minute % 10 + 48;
35 Time[8] = minute / 10 + 48;
36 Time[6] = hour % 10 + 48;
37 Time[5] = hour / 10 + 48;
38 Calendar[14] = year % 10 + 48;
39 Calendar[13] = year / 10 + 48;
40 Calendar[9] = month % 10 + 48;
41 Calendar[8] = month / 10 + 48;
42 Calendar[6] = date % 10 + 48;
43 Calendar[5] = date / 10 + 48;
44 lcd.setCursor(0, 0);
45 lcd.print(Time); // Display time
46 lcd.setCursor(0, 1);
47 lcd.print(Calendar); // Display calendar
48 }
49 void blink_parameter(){
50 byte j = 0;
51 while(j < 10 && digitalRead(8) && digitalRead(9)){
52 j++;
53 delay(25);
54 }
55 }
56 byte edit(byte x, byte y, byte parameter){
57 char text[3];
58 while(!digitalRead(8)); // Wait until button (pin #8) released
59 while(true){
60 while(!digitalRead(9)){ // If button (pin #9) is pressed
61 parameter++;
62 if(i == 0 && parameter > 23) // If hours > 23 ==> hours = 0
63 parameter = 0;
64 if(i == 1 && parameter > 59) // If minutes > 59 ==> minutes = 0
65 parameter = 0;
66 if(i == 2 && parameter > 31) // If date > 31 ==> date = 1
67 parameter = 1;
68 if(i == 3 && parameter > 12) // If month > 12 ==> month = 1
69 parameter = 1;
70 if(i == 4 && parameter > 99) // If year > 99 ==> year = 0
71 parameter = 0;
72 sprintf(text,"%02u", parameter);
73 lcd.setCursor(x, y);
74 lcd.print(text);
75 delay(200); // Wait 200ms
76 }
77 lcd.setCursor(x, y);
78 lcd.print(" "); // Display two spaces
79 blink_parameter();
80 sprintf(text,"%02u", parameter);
81 lcd.setCursor(x, y);
82 lcd.print(text);
83 blink_parameter();
84 if(!digitalRead(8)){ // If button (pin #8) is pressed
85 i++; // Increament 'i' for the next parameter
86 return parameter; // Return parameter value and exit
87 }
88 }
89 }
90
void loop() {
91
if(!digitalRead(8)){ // If button (pin #8) is pressed
92
i = 0;
93
hour = edit(5, 0, hour);
94
minute = edit(8, 0, minute);
95
date = edit(5, 1, date);
96
month = edit(8, 1, month);
97
year = edit(13, 1, year);
98
// Convert decimal to BCD
99
minute = ((minute / 10) << 4) + (minute % 10);
100
hour = ((hour / 10) << 4) + (hour % 10);
101
date = ((date / 10) << 4) + (date % 10);
102
month = ((month / 10) << 4) + (month % 10);
103
year = ((year / 10) << 4) + (year % 10);
104
// End conversion
105
// Write data to DS3231 RTC
106
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
107
Wire.write(0); // Send register address
108
Wire.write(0); // Reset sesonds and start oscillator
109
Wire.write(minute); // Write minute
110
Wire.write(hour); // Write hour
111
Wire.write(1); // Write day (not used)
112
Wire.write(date); // Write date
113
Wire.write(month); // Write month
114
Wire.write(year); // Write year
115
Wire.endTransmission(); // Stop transmission and release the I2C bus
116
delay(200); // Wait 200ms
117
}
118
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
119
Wire.write(0); // Send register address
120
Wire.endTransmission(false); // I2C restart
121
Wire.requestFrom(0x68, 7); // Request 7 bytes from DS3231 and release
122
I2C bus at end of reading
123
second = Wire.read(); // Read seconds from register 0
124
minute = Wire.read(); // Read minuts from register 1
125
hour = Wire.read(); // Read hour from register 2
126
Wire.read(); // Read day from register 3 (not used)
127
date = Wire.read(); // Read date from register 4
128
month = Wire.read(); // Read month from register 5
129
year = Wire.read(); // Read year from register 6
130
DS3231_display(); // Diaplay time & calendar
131
delay(50); // Wait 50ms
132
}
Downloads:
To be able to simulate this example, Proteus needs the Arduino library which can be
downloaded from the link below. After extracting the files (ARDUINO.IDX and
ARDUINO.LIB) put it in the Library folder (ex: C:\Program Files\Labcenter Electronics\
Proteus 8 Professional\LIBRARY):
Download