Digole
©DIGITAL
SOLUTIONS

Serial Display emulator    New Display User manual

Forum login or
Login:
Password:
  
Forum Catagory
Digole Serial Display (210)
  12864 LCD/OLED module (22)
  24064 LCD module (3)
  Color LCD Modules (28)
  Color OLED module (20)
  Online Emulater (5)
  Universal GLCD module (1)
  Universal Text LCD module (2)
Mini Display Panels (0)
  Mini LCDs (0)
  Mini OLEDs (0)
Pattern Drive Module (0)
~Buy & Sell on Digole (2)
~Others~ (5)
Forum : Digole Serial Display :

 Search Forum.. 
 Creat New Topic   Reply 

Let Digole Serial Display work with ESP8266 at I2C

NOTE(Aug. 2023): Use Arduino IDE 2.x.x and Digole new Arduino lib will fix this I2C issue

The ESP8266 doesn't have hardware I2C port, the lib for Arduino used software I2C to accomlish the function, this is a limitation (not a bug) in the lib when reading data from slave:
if the slave can't prepare data in 230us, the read function will exit without any warning, this makes the ESP8266 can't work with all slow I2C device, for reading a touch panel click, it my need to wait much longer time till the touch panel pressed.

Some user give a solution by using:
Wire.setClockStretchLimit(40000);
to let the read function waiting up to 40ms, but this may work with other slow I2C slave, not work with this device like touch panel.
Our solution is to modify the low level I2C funciton in file: core_esp8266_si2c.c.
In this file, there is a function:

static bool twi_read_bit(void) {
  uint32_t i = 0;
  SCL_LOW();
  SDA_HIGH();

  twi_delay(twi_dcount+2);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  bool bit = SDA_READ();
  twi_delay(twi_dcount);
  return bit;
}
You can see the code: "while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);", it just wait a limited time to slave to prepare the data, so we need to change it wait until the slave ready, and doesn't matter how long, as the following code:  

while (SCL_READ() == 0) yield();
 
After this changing, the ESP8266 will work with any kind of "slow" I2C slave then!

The new function should like this:

static bool twi_read_bit(void) {
  uint32_t i = 0;
  SCL_LOW();
  SDA_HIGH();
  twi_delay(twi_dcount+2);
  SCL_HIGH();
//  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  while (SCL_READ() == 0) yield();
  bool bit = SDA_READ();
  twi_delay(twi_dcount);
  return bit;
}
 
If you think this solution help you any way, please follow up with a "Thanks!" : )

 UPDATED: 2020/01/08

For new version of Arduino, seach for "core_esp8266_si2c.cpp"---on Mac OS, it is at a HIDEN folder name "Library", if you can't see the folder, Google "show hiden file on Mac". The full path: ~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.2/cores/esp8266

Search function of "void WAIT_CLOCK_STRETCH" in file, and change it to:
 
inline void WAIT_CLOCK_STRETCH()
    {
while(!SCL_READ())
 yield();
//        for (unsigned int t = 0; !SCL_READ() && (t < twi_clockStretchLimit); t++)
//        {
//        }
    }
This change will let the read data function waiting unlimited time with slow I2V slave device.

RE:Let Digole Serial Display work with ESP8266 at I2C

 I cannot begin to describe the level of frustration I was experiencing trying to get my 2.4" LCD touch screen to work with my ESP8266. I could write to it fine but all attempts to read data from it were either causing my ESP8266 to crash or return bogus data. I was seeing this in both UART and i2c modes (primarily interested in i2c). Right as I was about to give up and look for another vendor for a serial touch screen LCD I found a post that lead me to this thread and ever since I modified my core_esp8266_si2c.c file as described in this post thinge are now working 100%. Thanks to the engineers/coders that identified this solution and posted it here!

Copyright Digole Digital Solutions/Digole Technologies Inc., 2008-2024. All rights reserved.
Powered by Digole