Menu

Thursday, October 29, 2026

ESP8266 TWI and DS1307 RTC with LCD

Overview

The Two Wire Interface (TWI) is a serial communication protocol that implements only two wires - Serial Data (SDA) and Serial Clock (SCL). It was developed by Phillip. This protocol is commonly used for communicating between on-board devices at short range. It saves the number of micro-processor I/O that traditionally uses the Motorola 6800 parallel data bus. TWI able to handles up to 127 TWI slave devices connects on a single two-wire bus. Many small footprint chips use this communication protocol such as EEPROM, Real Time Clock (RTC) chip, monochrome OLED display, I/O expansion chip, RFID Reader chip, etc. 

 

ESP8266 TWI and DS1307 RTC with LCD
Example Picture

 

This protocol is easy to implement both hardware and software. Most of modern micro-controller has TWI/I2C interface. The user just needs to configure its overall operations such as clock setting, size of slave address (7-bit or 8-bit etc), sending data bytes to slave devices, and receiving data packets. Many programmers write a software TWI routine to implement this serial communication protocol. It's very easy and independence of dedicated micro-controller TWI module. It's universal because it is very easy to read and understand for most of programmer using C or Assembly language.

Arduino Wire Library

The Arduino IDE has many build-in libraries both hardware and software after finished installation. The Wire library is written in high level C++ language that is popular for its Object Oriented Programming (OOP) features.

To be able to call any function of this library, the programmer have to put, #include<Wire.h> that's already installed with Arduino IDE. These are some basic functions of this library,

Routines for Master Device Writing 

  1. Begin 
  2.  beginTransmission
  3.  write
  4.  endTransmission

Routines for Master Device Reading

  1.  requestFrom
  2.  available
  3.  read

There some build-in examples for this library. Go to File Menu > Examples > Wire, and click on any listed Sketch. 

ESP8266 TWI and DS1307 RTC with LCD
Wire Library Example

 

DS1307 Real Time Clock (RTC) Example

The time keeping chip is widely used in most modern electronic equipment. Most of them uses the TWI communication interface because it doesn't need a high speed data communication. Its clock frequency is around 100KHz that is very suitable for most of data transmission. On the other hands, those chips are placed on board communicating at very short range.

To get started I installed a third-party Real Time Clock library. Install and open an example "DS1307_Simple.ino" to set and test the DS1307 RTC chip.

ESP8266 TWI and DS1307 RTC with LCD
Open a DS1307 RTC example
 

This example will set and get the date/time calendar data from the DS1307 Real Time Clock (RTC) chip. The Arduino Wire uses the TWI 7-bit slave address. So the 7-bit TWI slave of the DS1307/DS3231 is 0x68 instead of 0xD0.
 

ESP8266 TWI and DS1307 RTC with LCD
Simple_DS1307.ino
 

The RTC data is sent over the serial terminal.

ESP8266 TWI DS1307 RTC and 16x2 Character LCD

I added a 16x2 character LCD to the NodeMCU ESP-12E Module to show date and time reading from DS1307 Real Time Clock (RTC) chip. I use the installed LiquidCrystal Library created by another author. This Arduino Library is compatible with the ESP8266 IoT chip.

Schematic

I use my DIY ESP8266 TWI board to test this example. 

ESP8266 TWI and DS1307 RTC with LCD
Schematic DIY ESP8266 TWI Board

DS1307 RTC and ESP-12E Connections

ESP-12EOn-Board DS1307
GNDGND
VCC
VIN or +3.3V
SCL
PIN D1 (GPIO5)
SDA
PIN D2 (GPIO4)

We can not share these two pins with LCD. It doesn't work.

ESP-12E and HD44780 16x2 Character LCD Connections 

I wire the 16x2 character LCD on breadboard. 


16x2 LCDESP-12E
GNDGND
VCCVIN
V0POT Output
RSD0 (GPIO16)
R/WGND
ED3 (GPIO0)
D4D4 (GPIO2)
D5D5 (GPIO14)
D6D6 (GPIO12
D7RX (GPIO3)
A+3.3V or VIN
KGND


The ESP-12E pin D7(RX2) and D8(TX2) can not be used with the character LCD. It's reserve for on-board serial communication with host PC.

ESP-12E Arduino Source Code

I added the LiquidCrystal library to the original RTC source code.


  1. /* for normal hardware wire use below */
  2. #include <Wire.h> // must be included here so that Arduino library object file references work
  3. #include <RtcDS1307.h>
  4. RtcDS1307<TwoWire> Rtc(Wire);
  5. /* for normal hardware wire use above */
  6. #include <LiquidCrystal.h>

  7. const int rs = 16, en = 0, d4 = 2, d5 = 14, d6 = 12, d7 = 3;
  8. LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

  9. // handy routine to return true if there was an error
  10. // but it will also print out an error message with the given topic
  11. bool wasError(const char* errorTopic = "")
  12. {
  13. uint8_t error = Rtc.LastError();
  14. if (error != 0)
  15. {
  16. // we have a communications error
  17. // see https://www.arduino.cc/reference/en/language/functions/communication/wire/endtransmission/
  18. // for what the number means
  19. Serial.print("[");
  20. Serial.print(errorTopic);
  21. Serial.print("] WIRE communications error (");
  22. Serial.print(error);
  23. Serial.print(") : ");

  24. switch (error)
  25. {
  26. case Rtc_Wire_Error_None:
  27. Serial.println("(none?!)");
  28. break;
  29. case Rtc_Wire_Error_TxBufferOverflow:
  30. Serial.println("transmit buffer overflow");
  31. break;
  32. case Rtc_Wire_Error_NoAddressableDevice:
  33. Serial.println("no device responded");
  34. break;
  35. case Rtc_Wire_Error_UnsupportedRequest:
  36. Serial.println("device doesn't support request");
  37. break;
  38. case Rtc_Wire_Error_Unspecific:
  39. Serial.println("unspecified error");
  40. break;
  41. case Rtc_Wire_Error_CommunicationTimeout:
  42. Serial.println("communications timed out");
  43. break;
  44. }
  45. return true;
  46. }
  47. return false;
  48. }


  49. void setup ()
  50. {
  51. Serial.begin(115200);

  52. Serial.print("compiled: ");
  53. Serial.print(__DATE__);
  54. Serial.println(__TIME__);
  55. //--------RTC SETUP ------------
  56. // if you are using ESP-01 then uncomment the line below to reset the pins to
  57. // the available pins for SDA, SCL
  58. // Rtc.Begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
  59. Rtc.Begin();
  60. #if defined(WIRE_HAS_TIMEOUT)
  61. Wire.setWireTimeout(3000 /* us */, true /* reset_on_timeout */);
  62. #endif

  63. RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  64. printDateTime(compiled);
  65. Serial.println();

  66. if (!Rtc.IsDateTimeValid())
  67. {
  68. if (!wasError("setup IsDateTimeValid"))
  69. {
  70. // Common Causes:
  71. // 1) first time you ran and the device wasn't running yet
  72. // 2) the battery on the device is low or even missing

  73. Serial.println("RTC lost confidence in the DateTime!");
  74. // following line sets the RTC to the date & time this sketch was compiled
  75. // it will also reset the valid flag internally unless the Rtc device is
  76. // having an issue

  77. Rtc.SetDateTime(compiled);
  78. }
  79. }

  80. if (!Rtc.GetIsRunning())
  81. {
  82. if (!wasError("setup GetIsRunning"))
  83. {
  84. Serial.println("RTC was not actively running, starting now");
  85. Rtc.SetIsRunning(true);
  86. }
  87. }

  88. RtcDateTime now = Rtc.GetDateTime();
  89. if (!wasError("setup GetDateTime"))
  90. {
  91. if (now < compiled)
  92. {
  93. Serial.println("RTC is older than compile time, updating DateTime");
  94. Rtc.SetDateTime(compiled);
  95. }
  96. else if (now > compiled)
  97. {
  98. Serial.println("RTC is newer than compile time, this is expected");
  99. }
  100. else if (now == compiled)
  101. {
  102. Serial.println("RTC is the same as compile time, while not expected all is still fine");
  103. }
  104. }

  105. // never assume the Rtc was last configured by you, so
  106. // just clear them to your needed state
  107. Rtc.SetSquareWavePin(DS1307SquareWaveOut_1Hz);
  108. wasError("setup SetSquareWavePin");
  109. lcd.begin(16, 2);
  110. lcd.clear();
  111. // Print a message to the LCD.
  112. lcd.print("ESP12-E I2C");
  113. lcd.setCursor(0, 1);
  114. lcd.print("DS1307 RTC");
  115. delay(5000);
  116. lcd.clear();
  117. }

  118. void loop ()
  119. {
  120. if (!Rtc.IsDateTimeValid())
  121. {
  122. if (!wasError("loop IsDateTimeValid"))
  123. {
  124. // Common Causes:
  125. // 1) the battery on the device is low or even missing and the power line was disconnected
  126. Serial.println("RTC lost confidence in the DateTime!");
  127. }
  128. }

  129. RtcDateTime now = Rtc.GetDateTime();
  130. if (!wasError("loop GetDateTime"))
  131. {
  132. printDateTime(now);
  133. Serial.println();
  134. }

  135. delay(800);
  136. }

  137. #define countof(a) (sizeof(a) / sizeof(a[0]))

  138. void printDateTime(const RtcDateTime& dt)
  139. {
  140. char datestring[26];

  141. snprintf_P(datestring,
  142. countof(datestring),
  143. PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
  144. dt.Month(),
  145. dt.Day(),
  146. dt.Year(),
  147. dt.Hour(),
  148. dt.Minute(),
  149. dt.Second() );
  150. Serial.print(datestring);
  151. lcd.setCursor(0, 0);
  152. lcd.print("Date: " + String(dt.Year()) + "/" + String(dt.Month()) + "/" + String(dt.Day()));
  153. lcd.setCursor(0, 1);
  154. lcd.print("Time: " + String(dt.Hour()) + ":" + String(dt.Minute()) + "/" + String(dt.Second()));
  155. }


Pictures

I tested this example using my DIY ESP8266 TWI Board.

 

ESP8266 TWI and DS1307 RTC with LCD
DIY ESP8266 TWI Board

 

ESP8266 TWI and DS1307 RTC with LCD
DIY ESP8266 TWI Board

 Video


 

  

Search This Blog

Electronics and Programming Tutorials

DIY Electronic Projects And Instruments

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (40) Analog Comparator (1) Arduino (17) ARM (32) AT89C52 (7) ATMega32 (59) ATMega644P (27) AVR (88) AVR PCB (2) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (5) Display (159) Distance Sensor (3) dot matrix (1) ds1307 (10) DS18B20 (6) ds3231 (2) ds3232 (2) dsPIC (16) dsPIC30F1010 (3) dsPIC30F2010 (15) EEPROM (5) Environment Sensor (6) ESP-12E (3) ESP32 (1) esp8266 (4) Graphical LCD (3) HD44780 (14) I2C (40) ILI9341 (1) Input/Output (85) Interrupt (22) IoT (2) IoT PCB (1) Keil (5) Keypad (16) KS0108 (3) LCD (90) LM35 (4) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) MikroC ARM (1) MikroC dsPIC (11) MikroC PIC (2) Module PCB (2) Motor (15) MPLABX (73) Nokia 5110 LCD (5) OLED (2) One-Wire (7) Oscillator (8) PCB (13) PCD8544 (3) PCF8574 (13) PIC (122) PIC12F (3) PIC16 (105) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (14) PICKit2 (1) PICMicro PCB (4) Pin Change Interrupt (1) PLL (1) PWM (12) RTC (14) SBN0064G (1) Sensor (15) SH1106 (4) Shift Register (15) Shift Registers (19) SN74HC595N (9) Software SPI (1) Software TWI (3) SPI (44) sprinf (3) ST7735 (1) STM32 (29) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (23) STM32CubeIDE (32) STM32F103C8T6 (9) STM32F103R6 (18) STM32F401CCU6 (1) SysTick (7) temperature sensor (15) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (11) UART (11) Ultrasonic (4) Voltmeter (7) WDT (1) Web Server (1) Wi-Fi (2) XC16 (2) XC8 (96)