maxint-rd / mxUnifiedPCD8544_Nokia_5110_LCD

mxUnifiedIO device library for Arduino. Device specific driver for the PCD8544 Nokia 5110 LCD display, derived from the Adafruit GFX library. Use SPI shift registers or I2C I/O expanders via the mxUnifiedIO API.
Other
2 stars 0 forks source link

ESP8266 failing at high clock speed (was: After migrating from 2.4.2 to 3.0.2 it doesn't work) #2

Closed mister-Monk closed 1 year ago

mister-Monk commented 2 years ago

ESP8266 Using I2C I/O expander worked great until I upgraded to kernel 3.0.2 in the ArduinoIDE. Currently the screen is dead, the backlight does not turn on. Adafruit_PCD8544 without expander works. The same issue is present in I2C-PCF8574-PCD8544-Nokia-5110-LCD

maxint-rd commented 2 years ago

Hello @mister-Monk, thank you for submitting this issue.

I don't think I have recently tested this and probably have not used that version of the core with this library. In another project I did encounter some issues. If I remember well these were due to object initialization differences and if I recall correctly, such issue would also apply to the ESP32.

Before I can attempt to fix it, I would have to reproduce the issue. Unfortunately due to unrelated personal circumstances I don't have much spare time at the moment to take a closer look. I will keep this issue open until I have more information but it may take some time before I can be of actual help. In the mean time feel free to do some debugging yourself and if you found a fix or more findings while testing please comment in this thread.

As for a work-around I can recommend to make a portable installation of the Arduino IDE. Just extract the Arduino zip file on your harddisk and make a directory named Portable in the same directory as arduino.exe. This will allow you to install different versions of the Arduino IDE, along with its various versions of installed libraries and cores.

Kind regards, Maxint R&D

mister-Monk commented 2 years ago

I have no problem switching between Arduino IDE core versions. The question arose on our forum. "Maximize the capabilities of the ESP8266 with a limited number of GPIOs." I have tried your previous library for a long time, successfully. Yesterday I tested the "old" and "new" iteration. I think you are the only one who could do it. Unfortunately, my knowledge is only enough for the "copy-paste" action. So we look forward to when you have more free time for creativity. Sincerely, Dmitry.

mister-Monk commented 1 year ago

This problem does not give me rest. This library does not work since 2.7.0. Board 8266. It is highly likely that the expander is not working correctly, because even the backlight does not turn on.

maxint-rd commented 1 year ago

Hello @mister-Monk, thank you for reminding me of this issue. In the mean time I've been occupied with other issues, unrelated to this library. I did not work on this library since, but other libraries I worked on the past year I have used with other cores, so perhaps this is a good time to look at this issue. In the coming weeks I do have more time available than in past year.

To get this started: perhaps we can narrow this issue down a bit and first test without Adafruit GFX. Do you have an ESP8266 with a separate PCF expander (i.e. without a Nokia display attached)? Does using a PCF with just LEDs to test also give issues?

Edit to be clear: I'd like to know what hardware you have exactly, so I can try to reproduce your test environment, both on hardware and on software levels. I have two different ready made modules:

mister-Monk commented 1 year ago

PCF8574AT + Wemos D1 mini ESP8266 4 Mb + red PCB Nokia 5110 display

http://95.31.4.129/n5110pcf.jpg

http://95.31.4.129/5110_i2c.jpg

https://github.com/maxint-rd/I2C-PCF8574-PCD8544-Nokia-5110-LCD PCF8574_PCD8544 display = PCF8574_PCD8544(0x3f, 7, 6, 5, 4, 2); This is running lower than kernel 2.7.0 http://95.31.4.129/VID.mp4

https://github.com/maxint-rd/mxUnifiedPCD8544_Nokia_5110_LCD mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x3f, SDA_pin, SCL_pin); mxUnifiedPCD8544 display = mxUnifiedPCD8544(&unio, 7, 6, 5, 4, 2); And this library works, but lower than kernel 2.7.0

I repeat, starting with kernel 2.7.0, even the backlight does not turn on.

mister-Monk commented 1 year ago

I will add. Kernel 3.1.1 now. Arduino IDE doesn't throw any errors when compiling.

maxint-rd commented 1 year ago

Excellent, thank you for giving this extra information. I appreciate the effort you made to write this down, to document your connections and to upload that video. I just watched it. Good to see in it that the hardware seems okay. I'm currently setting up my test environment to reproduce your issue. Coming days I should have some time to investigate. I will try both older versions and newer versions and let you know my findings. Keep you posted...

maxint-rd commented 1 year ago

Hello again,

Yesterday I spent some time setting up a test-environment. As I couldn't find a readily available D1-mini, I used an ESP-01 in combination with the same I2C LCD expander and a red nokia display. For using the ESP-01, I had Wire initialized to use software i2C on pins SDA=2, SCL=0.

My first series of testing was using Arduino IDE 1.6.10 with ESP core version 2.5.0 (Generic ESP8266 Module). I first used the i2c_scanner sketch to verify my I2C address (#27).When the i2c_scanner sketch worked, I used the BlinkAll example to see if expanded pins would properly blink. With the nokia display attached this flashes the backlight. Then I tested the i2c_pcd example, which gave the same results as you got in your video.

Today I repeated these tests using Arduino IDE 1.8.16 with ESP core version 3.0.2 (Generic ESP8266 Module). As all tests worked without issues, they failed to reproduce your problem. This weekend I intend to do further testing and add more findings as I go along. To be continued,,,

Edit: now tested using ESP12F on white PCB using regular SDA=4 and SCL=5. Still using core 3.0.2, still no issues using board set as either Generic ESP8266 Module or using Lolin Wemos D1 mini clone...

maxint-rd commented 1 year ago

When you have time: can you test this I2C scanner sketch? It should show your expander on address 0x27 If it does, can you then try the BlinkAll example? This should blink the backlight.

In the mean time I want to test using latest version of the Arduino IDE and the 3.1.1 core that you mentioned.

maxint-rd commented 1 year ago

Latest update:

At first attempt i2c scanner and BlinkAll worked, but the i2c_pcd_test gave no output, so I thought I finally reproduced your problem. The serial monitor gave output, but the display didn't. I even used the logical analyzer to see that no I2C data was transmitted. Then I saw that silly old me forgot to use the proper I2C pins! For using default pins SDA=4 and SCL=5 the constructor should only have the I2C address as parameter and not specify the pins:

mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x27);   // with only the address specified hardware I2C is used. Arduino uses SDA=A4 and SCL=A5, ESP8266 uses SDA=GPIO4 and SCL=GPIO5
//mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x27, 2, 0);     // on ESP8266 you can also use software I2C. the ESP-01 has only 4 pins available. If you dont use serial you can use 1 (TX) and 3 (RX)

After changing that, it the display worked as it should. Could you please run the same tests and verify you call the constructor according your pinout? I'm also interested to know the results of the i2c_scanner and the BlinkAll sketches.

Edit: installed the 64bit IDE v2.0.4 on a brand new Windows 11 installation. Still testing, but getting some interesting results...

mister-Monk commented 1 year ago

Took another 8266 and expander. Adafruit GFX updated 1.11.1 => 1.11.5 mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x27); mxUnifiedPCD8544 display = mxUnifiedPCD8544(&unio, 7, 6, 5, 4, 2); Kernel 2.6.3 works, 3.1.2 doesn't.

i2c_pcd_test Scanning... I2C device found at address 0x27 done [1:5114ms] [2:0ms] [3:11ms] [5:12ms] [7:138ms] [8:12ms]

BlinkAll ... http://95.31.4.129/pcfALL.jpg Kernel 2.6.3 works, 3.1.2 doesn't. http://95.31.4.129/VID_pcf263.mp4

The search led to the library https://github.com/xreef/PCF8574_library It works... http://95.31.4.129/VID_xreef.mp4

maxint-rd commented 1 year ago

Hmm. Interesting findings! Thank you for this addition.

In my test on the new Windows 11, using IDE 2.0.4, core 3.1.2, latest libraries. I first saw nothing on the i2c_pcd_test. Uploaded I2C_scanner and it failed... Then I wiggled the wires and it worked! Recompiled i2c_pcd_test with some minor changes in the test script and it still worked. No issues on any of the tests... (I did notice that de IDE 2.0.4 unfortunately doesn't support portable mode).

The BlinkAll in your video showed an interesting pattern, but that's due to the wiring. No issues there, except that you say it isn't working in kernel 3.1.2... :-(

It the if i2c_scanning works, then connections from MCU to PCF are okay. Your timing output of the i2c_pcd_test is deviating a lot from what it should be: [1:723ms] [2:2ms] [3:220ms] [5:220ms] [7:2641ms] [8:220ms] Note the much longer time on [1] and the much shorter times on the other testcases. I would love to see the output of a logical analyzer...

As an additional test I disconnected the I2C wires to look at the the output. It gave these: [1:124ms] [2:0ms] [3:23ms] [4:24ms] [5:23ms] [7:279ms] [8:23ms] ([4] is the extra test I added). The logical analyzer shows that times are actually shorter as no further bytes are exchanged by the Wire library when communication of the first transaction byte is not acknowledged (NAK vs ACK).

Note that although [1] is not as long as yours, the others are also too short, but about twice as long as yours. This suggests to me that you are running your ESP at a higher clock speed. It that true? I've been testing at the default 80MHz clock-speed. Are you running at 160MHz? In test years ago I found that high speeds may cause communication errors. You can set the I2C speed to something slower using the begin method: unio.begin(100000L); // use 100K I2C speed Note that on a higher clocked ESP, the default I2C speed can be up to 1MHz. I noticed that recent ESP cores use a lower maximum speed than when I developed the library. The logical analyzer now showed a speed of roughly 390KHz for my ESP8266, even when set to higher I2C speed. If you have the time, could you please run a test of the blink-all using lower clock speed and/or lower I2C speed?

What method did you use to compile with the 3.1.2 kernel? Do you use a portable installation? When running the i2c_pcd_test with incorrect constructor parameters, the output also gives short times. You mention you're using the default constructor. Could you perhaps also check the alternative constructor call?

//mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x27);   // with only the address ESP8266 uses SDA=GPIO4 and SCL=GPIO5
mxUnifiedPCF8574 unio = mxUnifiedPCF8574(0x27, 4, 5);     // on ESP8266 you can specify alternative I2C pins

Finally I will have a look at the library you mention. I'm curious to know what is different to make it behave differently, As I still cannot reproduce your problem, I cannot provide a true fix, but only offer suggestions and do further testing.

maxint-rd commented 1 year ago

Additional question: which Arduino IDE version are you using and which board definition? In a comment on the Xreef library I read they had an issue with specifying ESP8266 pin, caused by a difference in parameter types with the Wire library (int vs. uint8_t). My library could have the same, but then it's strangely effecting only your installation and neither of mine. Weird...

mister-Monk commented 1 year ago

And you are absolutely right! I changed the cpu frequency from 160 to 80. It works! Returned 160, and set unio.begin(100000L); - works, but draws slowly. Set unio.begin(450000L); - works, draws quickly. i2c

maxint-rd commented 1 year ago

Hey, that's great news! Congratulations! Feels a lot better now, knowing the cause. This issue bothered me quite a lot these past days. Trying everything, yet not being able to reproduce was very frustrating. I guess slowly but surely our testing narrowed the issue down. Hooray! (BTW, I did see that unlike mine, the Xreef library doesn't set a higher speed for the PCF),.

100K and 400K are kind of standard speeds for I2C. Most I2C devices support 100K, many support 400K, some support higher speeds. To complete this puzzle for now, I looked at the datasheet. On page 15 off the Rev. 5 - 27 May 2013 PCF8574/PCF8574A Product Data Sheet it clearly list this maximum I2C clock speed: fSCL SCL clock frequency - - 100 kHz Duh... It's amazing that we got working results at much higher speeds :-)

Knowing this, I think I may need to change the default speed setting for ESP8266 and higher in my PCF library. While at it I should also test different I2C speeds on the ESP32. (My code only sets higher speed on the ESP8266). Perhaps 400K is still working under many circumstances, but higher is clearly not reliable. If you look at the source code of my library, you can read this comment: "// 400000L (400kHz) seems stable speed on ESP8266@80Mzh, faster (1MHz) is possible, but perhaps less stable". I have the feeling this comment was foreshadowing yet not quite sufficient warning me for the time I spent past few days...

On a side note: In some other project I use a sketch that can scan the I2C bus, and also test the maximum speed of I2C connections. I really need to find that board and check out the actual maximum speed of my PCF module...

mister-Monk commented 1 year ago

https://github.com/esp8266/Arduino/issues/7327 http://95.31.4.129/vID_clocki2c.mp4

maxint-rd commented 1 year ago

Good find! From reading that topic it seems we've been kind of bumping into a known brick wall. Nice clock you made! I like how you show the seconds between the large digits.

I found my I2C tester and gave it a go. It has the LGT8F32P running at 32MHz clock speed. The sketch was made for Atmel compatibles and changes the TWBR register to adjust the I2C frequency. It repeatedly increases speed and calls Wire.beginTransmission() and Wire.endTransmission() reading the result for ACK or NAK status. On the PCF8574T LCD driver it reported a maximum speed of 444kHz, on my PCF8574AT it reported 470kHz as a maximum. At higher frequencies it detects communication failures and then checks to see if the highest speed found seems reliable. Both definitely can run faster than that 100KHz specified by the datasheet!

When modifying that I2C tester sketch for the ESP8266 (latest core) it can use Wire.setClock() to change speed, but actual speed might be lower than specified. An 80MHz ESP apparently has limited speed (for my ESP 390kHz), even when set faster. Running at 160MHz it runs faster I2C speeds, but has problems recovering from too high speeds. It won't scan anymore until I reset the ESP twice (after first reset it hangs!). The reported maximum is a lot higher (up to 770KHz), but I doubt that is correct. Judging the instability it can cause, I guess the coded limit is a good choice made by the core developers.

Edit: Doubting the reported I2C speed values I ran the i2c_pcd_test at different speeds. I noted that setting the I2C speed to 400 on a 160MHz ESP gave an actual speed of 327kHz, The setting seems quite different from the actual speed. Setting it to 100 gave 74kHz, 500 gave 421 kHz, 600 gave 533kHz, 700 gave 667Khz and 750 gave 695Khz. That 74kHz at 100 translates to about 4KHz SPI speed to the Nokia display, giving slow screen updates indeed. That 695kHz surprisingly still worked by the way and translated to rapid screen updates at 38kHz at the Nokia. Look at these measurements: [1:221ms] [2:1ms] [3:119ms] [5:120ms] [7:1434ms] [8:119ms] Setting speed to 800 finally gave errors in the display, followed by no show at all. Switching speed back still no show, not even at setting it to 100. Reset didn't help either. I had to power it all off to get things working again! In conclusion: use higher settings at your own risk!

Based on all this I will change my PCF library sometime soon, to use lower default speed on the ESP. Users can change that speed, but it will be less high by default. Thank you for your extensive contribution which helps me to improve this library.

maxint-rd commented 1 year ago

Small addition regarding I2C speeds:

I found that my ESP8266 running at 160 MHz supports I2C speeds up to 750 kHz and that it is limited to that speed even when set higher using Wire.setClock(). When running at 80 MHz, the limit is about 390 kHz. When choosing a lower speed, the actual speed deviates quite a bit and i saw more deviation at lower speeds. For example: when set to 100, the actual speed was 73 kHz and when set to 20 kHz it was a mere 14 kHz. At 750, the actual I2C speed was very close to 750 kHz.

Another surprise found while testing the speed of my PCF8574 module: it responded well, even when testing that very high speed. Although the datasheet states a maximum of 100 kHz, the chip could very well prove to be usable at higher speeds! (Use at your own risk).

My LGT8F328P based tester apparently has a lower speed limit than the ESP8266 @160MHz. Some day I will also try to test even higher I2C speeds, eg. using an ESP32 @240MHz or some other and even faster MCU.