Digital Solutions
iDigole Buyer ProtectioniDigole Buyer
My shopping cart
0 Items:
Secure Checkout
Top Rated Plus
Visit Our Live Auctions
99.9% Customer's Satisfaction
Search store:
Forum : Digole Serial Display :

 Search Forum.. 
 Creat New Topic   Reply 

[SOLVED]TFT/IPS with ESP8266 ?


Screen works well on an AVR Arduino (5V), but I'm having trouble getting it to talk to an ESP8266 (tried both Sparkfun's Thing and Adafruit's breakout).  Mainly tried I2C, but also briefly gave SPI a try (no luck either).  Haven't tried serial (UART), since I'm already using it for another peripheral.  

Device seems to be receving mostly junk (based on what BusPirate in I2C sniffer mode tells me) -- same code on AVR works fine!  Also, different I2C devices on the ESP (eg a generic DS3231 RTC breakout) work fine too!.  Just the Digole + ESP8266 combo is misbehaving.

Currently stumped -- so if anyone has tried with an ESP8266 and was successful, I'd love to hear ideas.  FWIW, I have 1.6.5-947-g39819f0 of the esp8266 arduino installed (with whatever soft-I2C implementation is standard there; also tried tweaking clocks and stretch, to no avail).



RE:TFT/IPS with ESP8266 ?

 Was wondering what the resistor configuration on the input pins is (in series, pullup, etc)?  I see a 4k7 near SS and a 0 Ohm jumper near CLK (both inside a silkscreen box that reads "4.7k"), but can't tell where they go (in series?).  Also, I see a number of 75k resistors near the SPI/I2C solder jumper (connected to jumper, which I'm assuming toggles where the DATA pin goes, but can't make out connections).

For the record, 2k2 external pullups on SDA and SCL didn't help (in fact, they made the display stop working even with the AVR Arduino).


RE:TFT/IPS with ESP8266 ?

 There are 4 mode on SPI (CLK pin):

  1. Idle High, Raising edge sample in
  2. Idle High, Falling edge sample in
  3. Idle Low, Raising edge sample in
  4. Idle Low, Falling edge sample in

Our module working at mode 3.

For I2C, there are also some important setting:

  1. Adress: 7bit or 10bit
  2. Start condition
  3. Clock stretching

We use 7bit, low speed(up to 200K) and stretching clock on our modules.

RE:TFT/IPS with ESP8266 ?

Ah!  So, your "mode 3" corresponds to Arduino SPI_MODE1 constant ( http://www.arduino.cc/en/Reference/SPI), right?  I don't think I tried that (I definitely tried the default SPI_MODE0 on the ESP, which has hardware SPI, not sure if I tried the same hardware SPI implementation on the Arduino).  But I did also try your soft-SPI implementation (using shiftOut), and that didn't work either on the ESP (it did on the AVR), but I didn't spend too much time on it.  In any case, I really prefer to use I2C, so..

For clock stretching on ESP8266, it seems there have been issues in the past, which should be fixed now (e.g., see https://github.com/adafruit/Adafruit_Sensor/issues/8 and linked issues from therein).  The soft-spi implementation for ESP should now support clock stretching "up to 100us".  Is that sufficient for the Digole module?  FWIW, I also tried increasing TWI_CLOCK_STRETCH in core_esp8266_si2c.c up from 800 (I think I tried up to 2400? or maybe 3200), but that didn't seem to help either.

Clock speed was 100KHz on most of my tests.  Never went above that.  I also tweaked core_esp8266_si2c.c to add an (approximately) 50KHz clock, that didn't seem to help either.

Address does not seem to be the issue; the Digole module *does* receive a few of the commands (and, e.g., occasionally displays some text).  The interesting observation here is that it's always the same text that gets displayed... weird that it's not random...  Not quite sure why. it's always the same commands that go through (apparently).

Anyway, thanks for the info so far.  I'll try to get a logic sniffer capture and see what's going on. Unfortunately I do not have a scope around.  In the meantime, if anyone has had luck with the ESP8266, I'd love to hear. :)

RE:TFT/IPS with ESP8266 ?

Quick update: not sure what I did (will have to work backwards to find out what worked), but send is now ok, at approx. 50KHz (with modified ESP Arduino core, as described before, verified with analyzer).  Also have 2k2 pullups and 270 in-series, although not sure if they are doing anything, since the ESP is supposed to have (modest?) internal pullups -- need to try 50KHz without them to see if they're still needed.

So I2C writes are ok, but reads seem to hang -- my logic analyzer shows RRNXYI written succesfully (all ACKs), then the read (for X coord) gets two bytes: 0xff (ACK) 0xff (NACK), but the next read (for Y coord) just gets one 0xff (NACK) and stops.  Any hints as to why I'm seeing this welcome. :)

But before I get to debugging that, I'm having issues with xtensa-gcc and global object dynamic initialization and/or linking, which I need to figure out first...  Argh.

RE:TFT/IPS with ESP8266 ?

Ok, getting there -- final stretch, almost there: I2C master writes work just fine, but reads get botched. Would appreciate any advice on resistor config (unfortunately I don't have a scope to check levels, rise times, etc).

I've tried all 16 combinations of: (1 & 2) 2k2 pullup on SDA & SCL, and (3 & 4) 270 in-series on SDA & SCL.  All of this is at 50KHz on ESP and default (~100KHz) on AVR.

The in-series resistors do not seem to make a difference. Now for the pullups.

On AVR: if I *have* the 2k2 pullup on SCL, then I2C master reads are corrupt. *Removing* it makes reads work.  For writes, pullup makes no difference.  Any idea why *removing* (and on just SCL, leaving it on SDA makes no difference) helps, and why just writes are unaffected?  I thought strong pullups were not a problem on I2C (beyond power consumption), and 2k2 should be within spec anyway, as far as I can tell.

On ESP: If I *don't* have the 2k2 pullup on SCL, I get bus errors.  If I add it, I get no bus errors, but reads still fail. This is what I see:

  • For the first readInt(), I get the correct address appear + two *invalid* bytes (which, interestingly, are always 0xff 0xff -- should have been touch coordinates, which I verified is the case on the AVR), followed by a NACK,
  • For the second readInt() the address + r/w flag byte (0x4f = 0x29 << 1 & 1) appears correctly on the bus, but then it is immediately followed by a NACK.
  • After that the bus is dead (no reads or writes work, until screen is power cycled again).

Any suggestions/ideas for how to configure the I2C bus, so reads works with the ESP?  Once I get reads resolved, I'm good to go!


Thanks in advance for your help!  And my apologies for any stupid questions, this is my first "real" use of I2C ever, so I'm learning... :)

PS. If you'd like logic analyzer captures, please let me know where to send..

RE:TFT/IPS with ESP8266 ?

  1.  If you using strong pullup resistor, please consider the on board MCU is working on 3.3V voltage.
  2. The I2C wires can't longer than 15cm, otherwise, the port will not working properly.

RE:TFT/IPS with ESP8266 ?

Wow, thanks for the fast reply!

Not sure what you mean by (1), "please consider on board MCU is working on 3.3V": should I try higher resistor values for pullup (ie weaker pullup)?  What would you recommend (ballpark)?  

Also, I thought 3.3V VCC should *lower* the minimum acceptable pullup resistor value, but you seem to be suggesting the opposite?  The rule of thumb I generally see, Rmin = (VCC - 0.4V)/3mA, would give 967 Ohm for 3.3V (and 1533 Ohm for 5V).

Thanks again!

RE:TFT/IPS with ESP8266 ?

 Not sure what voltage you pullup to, if it's 5.0V, there might be problem with lower resister due to the on board MCU is on 3.3V, and too much current will be inject in to MCU from pull up resistor, will cause some problem.

RE:TFT/IPS with ESP8266 ?

Ah, no. When connecting to ESP everything is 3.3V (feeding display and ESP off same 500mA regulator).  When connecting to AVR everything (at least on my side, not sure if you're stepping down for PIC) is 5V (all off of Sparkfun RedBoard's regulator).

In meantime, I shortened wires (just to be sure), and tried 4k7, 6k8, and 10k external pullups (same for both SDA and SCL), no luck.  Oddly, at least with shorter wires, now master writes work even without external pullups (just the ESP's, whatever they are, couldn't find spec).  Still no luck with master reads, for the touch X,Y positions.  Any reason the values read are all-ones (0xff -- except the address, where the master pulls down, I guess)?

FWIW, here is what the logic analyzer currently (shorter wires, no external pullups) sees after decoding a "get touch X,Y" write/read sequence (for ease of reference, N is 0x43 == 0x29 << 1, O is 0x4f == 0x29 << 1 | 1, and ÿ == 0xff):

"0","-48.00 μs","-48.00 μs","true","START",""
"1","-31.00 μs","187.00 μs","false","","N"
"2","205.00 μs","205.00 μs","true","ACK",""
"3","220.00 μs","429.00 μs","false","","R"
"4","443.00 μs","443.00 μs","true","ACK",""
"5","456.00 μs","665.00 μs","false","","P"
"6","678.00 μs","678.00 μs","true","ACK",""
"7","692.00 μs","901.00 μs","false","","N"
"8","914.00 μs","914.00 μs","true","ACK",""
"9","927.00 μs","1.14 ms","false","","X"
"10","1.15 ms","1.15 ms","true","ACK",""
"11","1.16 ms","1.37 ms","false","","Y"
"12","1.39 ms","1.39 ms","true","ACK",""
"13","1.40 ms","1.61 ms","false","","I"
"14","1.62 ms","1.62 ms","true","ACK",""
"15","1.66 ms","1.66 ms","true","STOP",""
"16","1.71 ms","1.71 ms","true","START",""
"17","1.72 ms","1.93 ms","false","","O"
"18","1.95 ms","1.95 ms","true","ACK",""
"19","1.96 ms","2.18 ms","false","","ÿ"
"20","2.19 ms","2.19 ms","true","ACK",""
"21","2.21 ms","2.42 ms","false","","ÿ"
"22","2.43 ms","2.43 ms","true","NACK",""
"23","2.47 ms","2.47 ms","true","STOP",""
"24","2.51 ms","2.51 ms","true","START",""
"25","2.53 ms","2.74 ms","false","","O"
"26","2.75 ms","2.75 ms","true","NACK",""
"27","3.34 ms","3.34 ms","true","START",""

and then bus gets stuck (SCL and SDA never go low until power cycling again).


RE:TFT/IPS with ESP8266 ?

 The "RPNXYI" will return the pen touched position instantly, if no touch happened, it usually return a value over the count of pixels, not always "0XFF".

Please try to use "RPNXYW" command, it will waiting a touch on the panel. or "RPNXYC" to waiting a click.

RE:TFT/IPS with ESP8266 ?

I'm triggering this immediately after a touch interrupt (ISR just sets a volatile flag, and main loop immediately asks for X,Y when that flag is set -- in any case, it's the exact same code that consistently runs fine when compiled for AVR).  Also tried the blocking version (as you suggested), though, no difference.

It seems that, when writing back to the master, the display never pulls SDA down after ACKing the first request.  

In more detail:  When the first read request comes from the master, the slave ACKs address + r/w bit (pulls SDA low), then SDA remains high during data transmission from slave (display) side, hence the 0xffs.  During this stage, ACKs/NACKs come from master (which pulls SDA low ok).  But upon next read request, when the slave is supposed to pull SDA down to ACK the read request, it never does (SDA is still stuck high), hence the final NACK on the second read request.  After that, I think it's readInt failing or whatever (doesn't mater, I think).

So, I now think playing with pullups is chasing red herrings.  It's likely related to the soft-I2C implementation on the ESP.  I'll need to compare to the analyzer captures from AVR (which works fine) and see if there are any timing differences, I think.  Argh.


EDIT: Also, note that, if the issue was that there was no touch, the second readInt() should also return an out-of-bounds value, and not get stuck.  But it's just getting stuck (as described above).  So clearly something deeper is going on.

RE:TFT/IPS with ESP8266 ?

FWIW, following up on previous post, here is the raw capture as well:

The raw capture is in OpenBench analyzer client (http://ols.lxtreme.nl/) format.

Perhaps someone else can see something in the timings more easily than I could, since I'm new to all of this... :)

RE:TFT/IPS with ESP8266 ?

Aha, I think I found the issue:  it seems that when the display gets it's *first* read request, after ACKing the address + read bit transmission, it keeps SCL low for about 600ms (that's ms, not us!!).  The ESP soft-I2C protocol implementation definitely cannot deal with such a stretch!  After the first byte written from the client, the stretch is reasonable.

Let me confirm this by trying to tweak the ESP's soft-I2C implementation to deal with this.  But I'm pretty sure now that this is the cause.  Or perhaps I can bit-bang a fake request upon startup (and avoid messing with the Arduino ESP core libs).  

Or is there some way to force the display to do it's touchscreen initializations earlier (wildly guessing that's what's going on in those 600ms, perhaps? :), and not as part of the first I2C response?

Thanks again!

RE:TFT/IPS with ESP8266 ?

 600ms is too long, I don't think the module will stretch the SCK so long, what I know is after receiving the read pen position command, the module will run the A/D for touch panel, then map the position to pixel, then send the X,Y values constaintly, the 4 bytes will send out, 1st 2 bytes is X, and last 2 bytes is Y, your master controller must ACK after each byte, if not, the module will waiting until you ACK.

The problem looks that your master controller sent another read request for reading Y, don't do it, just read 4 bytes continuely.

RE:TFT/IPS with ESP8266 ?

Erm, sorry, my eyes must be getting crossed, after looking at signals for several hrs straight :) not sure where the 600ms came from.  It's more like 2ms (which again is more than the 100us max stretch the ESP soft-i2c can handle).

A picture is worth a thousand words (this is from the AVR, where I2C works fine!):  [EDIT: Link to uncropped image: http://i.imgur.com/rDgak7o.png]

It's the ~2ms stretch upon the first byte (and only the first byte; compare against second byte, you can't even see it at this zoom level) that the ESP barfs on, apparently.

Also, it seems that the ESP soft-i2c implementation hardcodes a NACK on the last byte read, no idea why (see line 173 in: https://github.com/esp8266/Arduino/blob/esp8266/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c#L173; the true/false argument to twi_read_byte() is whether to send a nack or not, respectively).

Still haven't figured out how not to barf on this stretch, but it seems from what you say that those NACKs will be a problem (the AVR ACKs everything instead... hm; CORRECTION: it also NACKs the last byte...).

EDIT2: Doing two separate 2-byte reads (rather than one 4-byte read) works fine on the AVR, but I'll give your suggestion a go as well.  Let me try changing the NACKs to ACKs first...  But if the soft-I2C implementation just barges along, ignoring the stretch, then just changing that true argument to false may not do too much (it'll pull down SCL to ACK, but probably at a random point in time, from the PICs viewpoint) -- anyway, let's see.

RE:TFT/IPS with ESP8266 ?

Ok, partial progress: your comment about ADC time was helpful!  Just added a delay(10) right after sending the RPNXY{I,W} command and before calling readInt() and... I get one pair of correct X,Y coordinates (since the 2ms ADC conversion does not stretch the clock now, I guess)!!  That's the good news (and I reverted back all experimental changes to soft-I2C implementation, still works).  The bad news is that all subsequent reads fail again.  

Unfortunately, my OLS capture buffer is not long enough to see past the first (now successful) read.  Blindly tried adding a delay(10) after the readInt() as well (basically my code loops, polling touchscreen, so it can update UI buttons to an active state while being touched, and finally emit a "press" event and redraw buttons as inactive when the finger is off the screen for some time threshold, I think 100ms).  

Any additional insights as to what may be causing the subsequent reads to fail...?  I have a headache, so I think I'll stop for now... :)  thanks again!

RE:TFT/IPS with ESP8266 ?

 If you need to read another pair of X,Y, send "RPNXYI" or "RPNXYW" again.

RE:TFT/IPS with ESP8266 ?

 Yes, I mean the reads fail after I send another RPNXY{I,W}, even with the delay (to, hopefully, account for the stretch caused by ADC conversion).  Sorry for not clarifying (thought it's obvious).

BTW, RPNXYW is trickier to implement -- as I understand, it stretches the clock anyway (beyond ADC time).  Not quite sure how you implement a blocking read over I2C, but anyway, I don't need that.

In the meantime, I've found several posts by ppl ripping their hair out over at the esp8266 forums about reads from slaves failing (although the hair-ripping seems to end around June or so, when an update to the libs was pushed), so perhaps I'll take this over there.  Even if Digole's I2C implementation is not fully standards compliant (and, after ~2 days of Googling, I'm not sure there is such a thing as "fully-compliant I2C" :) ), ESP (or, rather, Arduino's soft-i2c driver for it) should handle it (AVR does!..).

Since I2C on the ESP seems to be a longer adventure than I expected: is there an alternative way to read the touchscreen (e.g., access the touchscreen driver directly? if yes, how?).


RE:TFT/IPS with ESP8266 ?

Ok, filed this: https://github.com/esp8266/Arduino/issues/727.

More detailed captures there; if you can spot a difference that might suggest a fix for the ESP's I2C implementation, let me know.

RE:TFT/IPS with ESP8266 ?

I've been having the same problem with my display. I'm using a Teensy 3.1, which is 32 bit, 3.3 volt, and runs up to 96 Mhz.

I was able to get a few successful reads with 10k pullup resistors, but it would never work right for long.

I've finally gotten it to work right by running the Teensy at only 16Mhz, which is the same speed my Nano runs at. It works fine with 4.7k pullup resistors at this speed. Even coding in delays did not help at the higher speed.

There must be something happening too fast for the digole at a lower level, maybe in the wire library.  My other device connected to the same i2c pins works fine at 96Mhz.

I don't know what speed the ESP runs at, but thought this might help you find a solution.

RE:TFT/IPS with ESP8266 ?

Thanks for sharing your experience!  Hm, weird, the I2C bus is running at 100KHz (and I took it down to  50KHz too), the CPU clock shouldn't have anything to do with it.

For the record, the ESP runs at 80MHz (and a few boards have an option of 160MHz).  AFAIK those are the only two possible clock speeds (but I may be wrong) -- it kind of makes sense, since lowering the clock will likely make it too slow to process the wifi protocols.

In the meantime, I switched to serial, and it didn't work at first.  Just found out that the Digole gets stuck if it's sent invalid character sequences and never recovers. The ESP seems to briefly go into bootloader mode (?) upon powerup (even without GPIO0 pulled low), sending "junk" characters.  So, it *does* work, but one out of 10 times.  I think I may have to hack a three-finger salute (Ctrl-Alt-Del :) for the Digole with an external MOSFET on VCC or sth.  Sigh..

Out of curiosity, did you have any issues with I2C writes, or those worked fine for you even at full CPU clock?

RE:TFT/IPS with ESP8266 ?

 If you using SPI, you better active SS pin, otherwise, the SPI port will lost the Synchronize if any noise injected.

You can reset the module by shorting the 2 pins (one RST to MCU, one GND) on the push button's footprint (the reset push button didn't solder on the board).

RE:TFT/IPS with ESP8266 ?

Thanks! Three things:

First, solution for serial boot is simpler:

Serial.setDebugOutput(0);   // not sure if it does anything
Serial.println();  // this seems to do the trick!

seems to get the display module "alive" again, after the boot messages (see, e.g., this post on the ESP forums; apparently these cannot be turned off).  Yeah, the MOSFET idea was harebrained... :)

Second, thanks for the reset info!  That's very valuable to know (I think I saw it in some other post, and had forgotten; perhaps include in the manual?).  Did I say my MOSFET switch idea was harebrained?... :)

Finally, not sure what you mean "keep SS active".  Do you mean it should always be low, even when not communicating (which would preclude other SPI devices on the same bus)? I keep it high, and pull it low at the beginning of an SPI transaction, then after all is done, set it high again.  Which is what I see your bit-banged SPI implementation (DigoleSerial library) is doing also.  However, as I mentioned before, I spent about 15min total with SPI (trying both soft and hardware SPI -- but not sure I was using the correct mode for hardware SPI, etc). Anyway.

So, anyway, it seems I finally have a working configuration! Yay!  (When I'm in a masochistic enough mood, I may try to investigate I2C again... but I doubt :).

Thanks again.

RE:TFT/IPS with ESP8266 ?

 Sorry, it's my fault, I mean you need to use SS pin to Synchronize data, pull low when start sending, and pull high when end sending.

RE:TFT/IPS with ESP8266 ?

"Out of curiosity, did you have any issues with I2C writes, or those worked fine for you even at full CPU clock?"

The writes worked fine at the higher CPU speed.

I was able to get the reads working with CPU speed up to 48Mhz, but no faster than that. The I2C speed should have been 100k with all the CPU speeds.

I switched my display to serial and it now works at the higher CPU speeds.


One more thing: I had to put in a delay( I used 3000 mSec) before calling the mydisp.begin function when using serial. The digole goes through some process at power-up that needs to be finished before the mydisp.begin will work with serial.  The display worked without the delay when it was powered up previous to a reboot, but not when the display and microcontroller were powered-up at the same time.


Copyright Digole Digital Solutions, 2008-2021. All rights reserved.
Powered by Victor Sun