This tutorial shows how to make a simple digital real time clock using ESP8266 NodeMCU board and DS3231 RTC module where time & date can be set with two push buttons connected to the NodeMCU and they are printed on Nokia 5110 LCD screen (84×48 pixel).
The DS3231 temperature is also printed on the Nokia LCD with resolution of 0.25°C (the DS3231 IC has a built-in temperature sensor).
To see how to interface NodeMCU board with Nokia 5110 LCD, visit this post:
Interfacing ESP8266 NodeMCU with Nokia 5110 LCD
Hardware Required:
- NodeMCU development board
- Nokia 5110 LCD module
- DS3231 module —-> DS3231 datasheet
- 2 x push button
- 3V coin cell battery
- Micro USB cable (for programming and powering the whole circuit)
- Breadboard
- Jumper wires
NodeMCU with DS3231 and Nokia 5110 LCD circuit:
The image below shows project circuit schematic diagram.
The Nokia 5110 LCD which is shown in the circuit diagram has 8 pins (from left to right): RST (reset), CE (chip enable), DC (or D/C: data/command), Din (data in), Clk (clock), VCC (3.3V), BL (back light) and Gnd (ground).
The Nokia 5110 LCD is connected to the NodeMCU board as follows:
RST (reset) pin is connected to pin D0 (ESP8266EX GPIO16),
CE (chip enable) pin is connected to pin D1 (ESP8266EX GPIO5),
DC (data/command) pin is connected to pin D2 (ESP8266EX GPIO4),
DIN (data in) pin is connected to pin D3 (ESP8266EX GPIO0),
CLK (clock) pin is connected to pin D4 (ESP8266EX GPIO2),
VCC and BL are connected to pin 3V3,
GND is connected to pin GND.
The DS3231 RTC module SCL (serial clock) and SDA (serial data) pins are respectively connected to NodeMCU pins D5 and D6.
The two push buttons which are connected to NodeMCU pins D7 and D8 are for setting time & date of the clock.
NodeMCU with DS3231 and Nokia 5110 LCD code:
The following Arduino code requires 3 libraries from Adafruit Industries:
The first library is a driver for the Nokia 5110 LCD (PCD8544 controller), download link is below:
Adafruit Nokia 5110 LCD library
The 2nd library is Adafruit graphics library which can be downloaded from the following link
Adafruit graphics library —-> direct link
The third library is real time clock library (for DS3231), download link is below:
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.
In the Arduino code the previous 3 libraries (and wire library) are included as shown below:
1 2 3 4 | #include <Wire.h> // include Wire library (required for I2C devices) #include <Adafruit_GFX.h> // include adafruit graphics library #include <Adafruit_PCD8544.h> // include adafruit PCD8544 (Nokia 5110) library #include <RTClib.h> // include Adafruit RTC library |
The two push buttons:
1 2 | const int button1 = D7; // button B1 is connected to NodeMCU D7 const int button2 = D8; // button B2 is connected to NodeMCU D8 |
Functions used in the code:
bool debounce (): this function is for button B1 debounce, returns 1 if button is debounced.
void RTC_display(): prints 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 | /************************************************************************** * * ESP8266 NodeMCU real time clock with Nokia 5110 LCD and DS3231. * This is a free software with NO WARRANTY. * http://simple-circuit.com/ * *************************************************************************/ #include <Wire.h> // include Wire library (required for I2C devices) #include <Adafruit_GFX.h> // include Adafruit graphics library #include <Adafruit_PCD8544.h> // include Adafruit PCD8544 (Nokia 5110) library #include <RTClib.h> // include Adafruit RTC library // Nokia 5110 LCD module connections (CLK, DIN, D/C, CS, RST) Adafruit_PCD8544 display = Adafruit_PCD8544(D4, D3, D2, D1, D0); // initialize RTC library RTC_DS3231 rtc; DateTime now; const int button1 = D7; // button B1 is connected to NodeMCU D7 const int button2 = D8; // button B2 is connected to NodeMCU D8 void setup(void) { pinMode(button1, INPUT); pinMode(button2, INPUT); // initialize the display display.begin(); // you can change the contrast around to adapt the display // for the best viewing! display.setContrast(50); display.clearDisplay(); // clear the screen and buffer display.setTextSize(1); display.setTextColor(BLACK, WHITE); display.setCursor(28, 16); display.print("TIME:"); display.setCursor(13, 32); display.print("CHIP TEMP:"); display.display(); Wire.begin(D6, D5); // set I2C pins [SDA = D6, SCL = D5], default clock is 100kHz rtc.begin(); // initialize RTC chip } // 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 dow_matrix[7][10] = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"}; byte x_pos[7] = {24, 24, 21, 15, 18, 24, 18}; static byte previous_dow = 8; // print day of the week if( previous_dow != now.dayOfTheWeek() ) { previous_dow = now.dayOfTheWeek(); display.fillRect(15, 0, 54, 8, WHITE); // draw rectangle (erase day from the display) display.setCursor(x_pos[previous_dow], 0); display.print( dow_matrix[now.dayOfTheWeek()] ); } // print date display.setCursor(12, 8); display.printf( "%02u-%02u-%04u", now.day(), now.month(), now.year() ); // print time display.setCursor(18, 24); display.printf( "%02u:%02u:%02u", now.hour(), now.minute(), now.second() ); // now update the screen display.display(); } byte edit(byte parameter) { static byte i = 0, y_pos, x_pos[5] = {12, 30, 60, 18, 36}; if(i < 3) y_pos = 8; else y_pos = 24; 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; display.setCursor(x_pos[i], y_pos); display.printf("%02u", parameter); display.display(); // update the screen delay(200); // wait 200ms } display.fillRect(x_pos[i], y_pos, 11, 8, WHITE); display.display(); // update the screen unsigned long previous_m = millis(); while( (millis() - previous_m < 250) && !digitalRead(button1) && !digitalRead(button2)) ; display.setCursor(x_pos[i], y_pos); display.printf("%02u", parameter); display.display(); // update the screen 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 } } } // main loop 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(); // display 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 uint16_t chip_temp = (uint16_t)t_msb << 2 | t_lsb >> 6; display.setCursor(15, 40); if(t_msb & 0x80) { chip_temp |= 0xFC00; display.printf( "-%02u.%02u C", abs((int)chip_temp * 25) / 100, abs((int)chip_temp * 25) % 100); } else display.printf( " %02u.%02u C", (chip_temp * 25) / 100, (chip_temp * 25) % 100); display.drawRect(53, 40, 3, 3, BLACK); // print degree symbol ( ° ) RTC_display(); delay(100); // wait 100ms } // end of code. |
The video below shows my hardware circuit test:
Worked perfectly on first try. Would like to know how to convert the temperature to Fahrenheit.
hi , it,s amazing . how i can use nodemcu to run a flc100 magnometer sensor and send data to pc ? thank you