In the last Arduino project I built a simple real time clock using DS1307 RTC and ST7735 TFT display (link is below) and in this project I’m going to show how to build a real time clock with RTC chip temperature monitor using Arduino, DS3231 RTC and the same display (ST7735 TFT).
The ST7735 TFT is a color display which has a resolution of 128×160 pixel and it communicates with the master device using SPI (Serial Peripheral Interface) protocol.
The DS3231 is more accurate than the DS1307 due to its built-in temperature sensor. It also (the DS3231) keeps time running even if the main power source is down (with the help of 3V battery). It also uses I2C interface to communicate with the master device which is in this case the Arduino.
To see how to interface Arduino with ST7735 TFT display, visit the following post:
Arduino ST7735 1.8″ TFT display example
To see how to interface Arduino with DS1307 RTC and ST7735 color TFT display, take a look at this post:
Arduino Real time clock with ST7735 color TFT and DS1307
Hardware Required:
- Arduino board
- ST7735S (ST7735R) TFT screen
- DS3231 module —-> DS3231 datasheet
- 5 x 1k ohm resistor
- 2 x push button
- 3V coin cell battery
- Breadboard
- Jumper wires
Arduino clock with ST7735 display and DS3231 RTC circuit:
The image below shows project circuit schematic diagram.
The ST7735S shown in project circuit diagram has 8 pins: (from right to left): RST (reset), CE (chip enable), DC (or D/C: data/command), DIN (data in), CLK (clock), VCC (5V or 3.3V), BL (back light) and Gnd (ground).
Normally the ST7735 display works with 3.3V only, but many boards of this display have a built-in 3.3V regulator (AMS1117 3V3) like the one shown in the circuit diagram. This regulator supplies the display controller with 3.3V from 5V source.
All Arduino UNO board output pins are 5V, connecting a 5V pin directly to the ST7735 display board may damage its controller circuit. To avoid that, I connected each control line of the display to the Arduino board through 1k ohm resistor.
So, the ST7735 display is connected to the Arduino board as follows (each one through 1k resistor):
RST pin is connected to Arduino digital pin 8,
CS pin is connected to Arduino digital pin 9,
D/C pin is connected to Arduino digital pin 10,
DIN pin is connected to Arduino digital pin 11,
CLK pin is connected to Arduino digital pin 13.
The DS3231 RTC module SDA (serial data) and SCL (serial clock) pins are respectively connected to Arduino A4 and A5 pins (ATmega328P hardware I2C module pins).
The two push buttons which are connected to Arduino digital pins 6 and 7 are for setting time & date of the clock.
Arduino clock with ST7735 display and DS3231 RTC code:
The following Arduino code requires 3 libraries from Adafruit Industries:
Adafruit ST7735 display library
Adafruit graphics library —-> direct link
Adafruit RTC library —-> direct link
After the download, go to Arduino IDE —> Sketch —> Include Library —> Add .ZIP Library … and browse for the .zip file (previously downloaded).
The same thing for the other library files.
So, in the code there are total of 4 libraries, they’re included as follows:
1 2 3 4 | #include <Wire.h> // include Arduino Wire library (required for I2C devices) #include <Adafruit_GFX.h> // include Adafruit graphics library #include <Adafruit_ST7735.h> // include Adafruit ST7735 TFT library #include <RTClib.h> // include Adafruit RTC library |
The ST7735 TFT display is connected to Arduino hardware SPI module pins (clock and data), the other pins which are: RST (reset), CS (chip select) and DC (data/command) are defined as shown below:
1 2 3 | #define TFT_RST 8 // TFT RST pin is connected to arduino pin 8 #define TFT_CS 9 // TFT CS pin is connected to arduino pin 9 #define TFT_DC 10 // TFT DC pin is connected to arduino pin 10 |
And the two push buttons are defined in the code as:
1 2 3 | // button definitions #define button1 7 // button B1 is connected to Arduino pin 9 #define button2 6 // button B2 is connected to Arduino pin 8 |
Functions used in the code:
bool debounce (): this function is for button B1 debounce, returns 1 if button is debounced.
void RTC_display(): displays day of the week, date and time on the display.
byte edit(byte parameter): this function is for setting the real time clock, returns the edited parameter.
Rest of code is described through comments.
Full Arduino code:
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 | /* * Arduino real time clock using DS3231 and ST7735 color TFT (128x160 pixel) * This is a free software with NO WARRANTY. * http://simple-circuit.com/ */ #include <Wire.h> // include Arduino Wire library (required for I2C devices) #include <Adafruit_GFX.h> // include Adafruit graphics library #include <Adafruit_ST7735.h> // include Adafruit ST7735 TFT library #include <RTClib.h> // include Adafruit RTC library #define TFT_RST 8 // TFT RST pin is connected to arduino pin 8 #define TFT_CS 9 // TFT CS pin is connected to arduino pin 9 #define TFT_DC 10 // TFT DC pin is connected to arduino pin 10 // initialize ST7735 TFT library Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // initialize RTC library RTC_DS3231 rtc; DateTime now; // buttons definition #define button1 7 // button B1 is connected to Arduino pin 7 #define button2 6 // button B2 is connected to Arduino pin 6 void setup(void) { pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); rtc.begin(); // initialize RTC chip tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); // fill screen with black color tft.drawFastHLine(0, 20, tft.width(), ST7735_BLUE); // draw horizontal blue line at position (0, 44) tft.drawFastHLine(0, 75, tft.width(), ST7735_BLUE); // draw horizontal blue line at position (0, 44) tft.drawFastHLine(0, 130, tft.width(), ST7735_BLUE); // draw horizontal blue line at position (0, 102) tft.setTextColor(ST7735_WHITE, ST7735_BLACK); // set text color to white and black background tft.setTextSize(1); // text size = 1 tft.setCursor(4, 0); // move cursor to position (4, 10) pixel tft.print("ARDUINO + ST7735 TFT"); tft.setCursor(28, 10); // move cursor to position (28, 27) pixel tft.print("+ DS3231 RTC"); tft.setCursor(14, 134); // move cursor to position (28, 27) pixel tft.print("CHIP TEMPERATURE:"); tft.setTextSize(2); // text size = 2 tft.setTextColor(ST7735_MAGENTA, ST7735_BLACK); // set text color to magneta and black background tft.setCursor(37, 84); // move cursor to position (37, 112) pixel tft.print("TIME:"); } // a small function for button1 (B1) debounce bool debounce () { byte count = 0; for(byte i = 0; i < 5; i++) { if ( !digitalRead(button1) ) count++; delay(10); } if(count > 2) return 1; else return 0; } void RTC_display() { char _buffer[11]; char dow_matrix[7][10] = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"}; byte x_pos[7] = {29, 29, 23, 11, 17, 29, 17}; static byte previous_dow = 8; // print day of the week if( previous_dow != now.dayOfTheWeek() ) { previous_dow = now.dayOfTheWeek(); tft.fillRect(11, 55, 108, 14, ST7735_BLACK); // draw rectangle (erase day from the display) tft.setCursor(x_pos[previous_dow], 29); tft.setTextColor(ST7735_CYAN, ST7735_BLACK); // set text color to cyan and black background tft.print( dow_matrix[now.dayOfTheWeek()] ); } // print date sprintf( _buffer, "%02u-%02u-%04u", now.day(), now.month(), now.year() ); tft.setCursor(4, 52); tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); // set text color to yellow and black background tft.print(_buffer); // print time sprintf( _buffer, "%02u:%02u:%02u", now.hour(), now.minute(), now.second() ); tft.setCursor(16, 107); tft.setTextColor(ST7735_GREEN, ST7735_BLACK); // set text color to green and black background tft.print(_buffer); } byte edit(byte parameter) { static byte i = 0, y_pos, x_pos[5] = {4, 40, 100, 16, 52}; char text[3]; sprintf(text,"%02u", parameter); if(i < 3) { tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); // set text color to green and black background y_pos = 52; } else { tft.setTextColor(ST7735_GREEN, ST7735_BLACK); // set text color to yellow and black background y_pos = 107; } while( debounce() ); // call debounce function (wait for B1 to be released) while(true) { while( !digitalRead(button2) ) { // while B2 is pressed parameter++; if(i == 0 && parameter > 31) // if day > 31 ==> day = 1 parameter = 1; if(i == 1 && parameter > 12) // If month > 12 ==> month = 1 parameter = 1; if(i == 2 && parameter > 99) // If year > 99 ==> year = 0 parameter = 0; if(i == 3 && parameter > 23) // if hours > 23 ==> hours = 0 parameter = 0; if(i == 4 && parameter > 59) // if minutes > 59 ==> minutes = 0 parameter = 0; sprintf(text,"%02u", parameter); tft.setCursor(x_pos[i], y_pos); tft.print(text); delay(200); // wait 200ms } tft.fillRect(x_pos[i], y_pos, 22, 14, ST7735_BLACK); unsigned long previous_m = millis(); while( (millis() - previous_m < 250) && digitalRead(button1) && digitalRead(button2)) ; tft.setCursor(x_pos[i], y_pos); tft.print(text); previous_m = millis(); while( (millis() - previous_m < 250) && digitalRead(button1) && digitalRead(button2)) ; if(!digitalRead(button1)) { // if button B1 is pressed i = (i + 1) % 5; // increment 'i' for the next parameter return parameter; // return parameter value and exit } } } void loop() { if( !digitalRead(button1) ) // if B1 is pressed if( debounce() ) // call debounce function (make sure B1 is pressed) { while( debounce() ); // call debounce function (wait for B1 to be released) byte day = edit( now.day() ); // edit date byte month = edit( now.month() ); // edit month byte year = edit( now.year() - 2000 ); // edit year byte hour = edit( now.hour() ); // edit hours byte minute = edit( now.minute() ); // edit minutes // write time & date data to the RTC chip rtc.adjust(DateTime(2000 + year, month, day, hour, minute, 0)); while(debounce()); // call debounce function (wait for button B1 to be released) } now = rtc.now(); // read current time and date from the RTC chip RTC_display(); // diaplay time & calendar // read chip temperature Wire.beginTransmission(0x68); // start I2C protocol with DS3231 address Wire.write(0x11); // send register address (temperature MSB) Wire.endTransmission(false); // I2C restart Wire.requestFrom(0x68, 2); // request 2 bytes from DS3231 and release I2C bus at end of reading byte t_msb = Wire.read(); // read temperature MSB byte t_lsb = Wire.read(); // read temperature LSB // print chip temperature char _buffer[6]; uint16_t chip_temp = (uint16_t)t_msb << 2 | t_lsb >> 6; if(t_msb & 0x80) { chip_temp |= 0xFC00; sprintf(_buffer, "-%02u.%02u", abs((int)chip_temp * 25) / 100, abs((int)chip_temp * 25) % 100); } else sprintf(_buffer, " %02u.%02u", (chip_temp * 25) / 100, (chip_temp * 25) % 100); tft.setCursor(11, 146); tft.setTextColor(ST7735_RED, ST7735_BLACK); // set text color to red and black background tft.print(_buffer); tft.drawCircle(90, 148, 2, ST7735_RED); // print degree symbol ( ° ) tft.setCursor(95, 146); tft.print("C"); delay(100); // wait 100ms } // end of code. |
The following video shows my protoboard circuit:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.
Hi, I built your project and it works very well.
Now I wish I could rotate the screen horizontally.
Could you give me some instructions on how to do it?
Thank you.
Hi again
Fixed the problem
It must have been a power issue
I connected the UNO to an external power supply and the display works perfectly.
Thanks for the great project
Hi
I built this project following all of the instructions.
It works brilliantly!! So its a big thumbs up and well done.
I only have one issue is that the display on the day and the date seems to flash like its throbbing.
Have i done something wrong?