tft lcd display touch panel spi ili9341 made in china
The TFT display is a kind of LCD that is connected to each pixel using a transistor and it features low current consumption, high-quality, high-resolution and backlight. This 2.8-inch full color LCD has a narrow PCB display. The resolution is 320×280 pixels and it has a four-wire SPI interface and white backlight.
In this Arduino touch screen tutorial we will learn how to use TFT LCD Touch Screen with Arduino. You can watch the following video or read the written tutorial below.
For this tutorial I composed three examples. The first example is distance measurement using ultrasonic sensor. The output from the sensor, or the distance is printed on the screen and using the touch screen we can select the units, either centimeters or inches.
The third example is a game. Actually it’s a replica of the popular Flappy Bird game for smartphones. We can play the game using the push button or even using the touch screen itself.
As an example I am using a 3.2” TFT Touch Screen in a combination with a TFT LCD Arduino Mega Shield. We need a shield because the TFT Touch screen works at 3.3V and the Arduino Mega outputs are 5 V. For the first example I have the HC-SR04 ultrasonic sensor, then for the second example an RGB LED with three resistors and a push button for the game example. Also I had to make a custom made pin header like this, by soldering pin headers and bend on of them so I could insert them in between the Arduino Board and the TFT Shield.
Here’s the circuit schematic. We will use the GND pin, the digital pins from 8 to 13, as well as the pin number 14. As the 5V pins are already used by the TFT Screen I will use the pin number 13 as VCC, by setting it right away high in the setup section of code.
I will use the UTFT and URTouch libraries made by Henning Karlsen. Here I would like to say thanks to him for the incredible work he has done. The libraries enable really easy use of the TFT Screens, and they work with many different TFT screens sizes, shields and controllers. You can download these libraries from his website, RinkyDinkElectronics.com and also find a lot of demo examples and detailed documentation of how to use them.
After we include the libraries we need to create UTFT and URTouch objects. The parameters of these objects depends on the model of the TFT Screen and Shield and these details can be also found in the documentation of the libraries.
Next we need to define the fonts that are coming with the libraries and also define some variables needed for the program. In the setup section we need to initiate the screen and the touch, define the pin modes for the connected sensor, the led and the button, and initially call the drawHomeSreen() custom function, which will draw the home screen of the program.
So now I will explain how we can make the home screen of the program. With the setBackColor() function we need to set the background color of the text, black one in our case. Then we need to set the color to white, set the big font and using the print() function, we will print the string “Arduino TFT Tutorial” at the center of the screen and 10 pixels down the Y – Axis of the screen. Next we will set the color to red and draw the red line below the text. After that we need to set the color back to white, and print the two other strings, “by HowToMechatronics.com” using the small font and “Select Example” using the big font.
Ok next is the RGB LED Control example. If we press the second button, the drawLedControl() custom function will be called only once for drawing the graphic of that example and the setLedColor() custom function will be repeatedly called. In this function we use the touch screen to set the values of the 3 sliders from 0 to 255. With the if statements we confine the area of each slider and get the X value of the slider. So the values of the X coordinate of each slider are from 38 to 310 pixels and we need to map these values into values from 0 to 255 which will be used as a PWM signal for lighting up the LED. If you need more details how the RGB LED works you can check my particular tutorialfor that. The rest of the code in this custom function is for drawing the sliders. Back in the loop section we only have the back button which also turns off the LED when pressed.
After spending way too much time trying to figure out the touchscreen, I wanted to share what finally worked for me! First, I"ll share the pinout. Next, I"ll share the steps that worked with the eSPI library. Lastly, I"ll show you the steps using an alternative library - the XPT2046_Touchscreen library.
Let me just say it was initially confusing to me because the ILI9341 is the display, but the touchscreen is actually controlled by an XPT2046. And I struggled with connecting everything properly to an ESP-WROOM-32 ESP32 ESP-32S dev board.
5. Open the eSPI "User_Setup.h" file. This file contains the TFT_eSPI configuration. By default, I think the Arduino IDE would have installed this file (step 3 above) in this location: C:\Users\
9. Compile and upload the sketch. Given that we configured the pinout in step 6 above, there should be no need to make any changes to the code in the Touch_calibrate example.
11. On the ILI9341 screen, you should be prompted to touch each of the 4 corners of the screen to calibrate it. I recommend using the stylus since the calibration requires precise taps.
14. You"ll be happy to hear that the other TFT_eSPI examples should work right out with this same pinout. One of my favorites is TFT_Starfield. Just make sure to select an example that"s 320x240 to match the ILI9341 resolution.
8. The ILI9341 screen will be completely white, but don"t panic. The screen is supposed to be blank white because this example tests only the touch aspect of the ILI9341, not the display aspect.
The model is "TJCTM24028-SPI". The board looks like the boards on the smaller displays, but with the additional touch-ic (currently unused and not connected).
I recently ordered some of these displays. Haven"t used them yet. I made this PCB to speed things up (well, at least minimize my time spent fiddling).
Paul - that is just a more pin exposed version of the "purple test board (https://oshpark.com/shared_projects/IWylNfzD)" from the ILI9341 page? And some added components?
Ok interested, ordered boards from oshpark and some TJCTM24028-SPI displays. Seems like I spend half my development time trying to come up with a display option that does not require "time spent fiddling".
The added components are two 10K resistors, as pullups on the two CS signals. I really should have put one on the original test board"s CS signal. These bigger displays have 5 extra pins for the touch controller chip. I just routed the SPI signals and 2 pins for CS and INT. If the board works, I"ll do to the trouble of updating that OSH Park page with good documentation.
If the display actually works well, odds are good I"ll write a library for its touch controller chip and PJRC will probably start stocking this display too. We really need a somewhat larger display with touch that"s affordable. I"m hoping this will be the one!
The added components are two 10K resistors, as pullups on the two CS signals. I really should have put one on the original test board"s CS signal. These bigger displays have 5 extra pins for the touch controller chip. I just routed the SPI signals and 2 pins for CS and INT. If the board works, I"ll do to the trouble of updating that OSH Park page with good documentation.
If the display actually works well, odds are good I"ll write a library for its touch controller chip and PJRC will probably start stocking this display too. We really need a somewhat larger display with touch that"s affordable. I"m hoping this will be the one!
That looks like a nice upgrade to the ILI9341 in the store now - and only minimally higher cost? Supported touch on known good units and larger screen area ++good++. Found "some" on aliexpress not noted - assume like FrankB"s it is a Resistive touch unit like the $35 Adafruit - not Capacitive like the $45 unit?
Also ++good++ any other board that makes prototyping/connecting easier - like those from your ILI9341 YouTube Demo (https://www.youtube.com/watch?v=rL_2_D3cgFg) I asked about -
Good news, if you get any sanity check on the touch wiring I"ll proceed to order. I see you built the power side too - but running on USB in this pic - expect that works as well using the old part info?
What"s the best way to remove a soldered teensy ? Sawing the board near and between the pins with a dremel and desolder the remaing small parts ? Or are there better ways ? Under the teensy is a fully assembled memoryboard and the audioboard, then a board with the display.. all tightly soldered together :-(
No software support is needed in the library. It automatically goes low when the display is touched. It can also go low when the library reads the display. So to use it, you *stop* calling the library and then use attachInterrupt or otherwise arrange for the falling edge to wake up. Obviously you"d disable the interrupt after waking up, before you use the library again.
The rapidly switching signals for the TFT do capacitively couple to the resistive touchscreen signals. Occasionally they cause a significant error in the touch reading, and frequently they add a small amount of noise.
P#22 displays "Pressure" - is that a 3D pressure on the display value you can easily reference? If you see a high pressure value do you see less noise in the reported readings?
New 240x320 2.8" SPI TFT LCD Touch Panel Serial Port Module +PCB ILI9341 5V/3.3V (http://www.ebay.com/itm/New-240x320-2-8-SPI-TFT-LCD-Touch-Panel-Serial-Port-Module-PCB-ILI9341-5V-3-3V-/191531963190?hash=item2c9831d336#shpCntId)
Wow! That was quick. I"m still amazed these things can be so inexpensive. Just out of curiosity, how much current does this display need? I assume there is a built-in backlight, which probably draws most of the power, but if you turn off the backlight the display is probably unreadable?
Good question. I haven"t measured precisely, but a Teensy 3.2 (running at 96 MHz) and the display are together drawing approx 72 mA from my power supply.
Within the library, each measurement on each axis takes approx 8 us. Version 1.1 does 3 measurements on each axis, plus the 2 needed to determine the touch pressure. With some overheard, the whole process is probably between 70 to 75 us to read the touch sensor.
I am excited about this. I am confused though regarding choosing a ili9341 with xpt2046 touchscreen that is compatible with the OSH board pointed to by Paul.
Post #30 above has this link to a "one" row supported unit in the PJRC Store. (http://www.pjrc.com/store/display_ili9341_touch.html) It is a 2.8" board though.
The 2 row types usually have 40 pins (20 per row). Those are meant for parallel connection. They can be used with the UTFT library. The parallel interface is very fast, but it requires a lot of wires that use up nearly all the pins on Teensy.
But you"ll probably do fine to get one from China. Just make sure it has 1 row of 14 pins. Take a moment to count the number of pins in the photos. If there"s a photo of the back side where signal names are printed, compare the names to the "ILI9341 Pin" column in the connections table. There"s always some small risk when you build stuff directly from Chinese merchants, but if the photo has 14 pins and you can see the same signal names in the same order, odds are very good it"ll work.
Jon - thanks for the digikey jack part# - with my display and OSH order I"ll need to finish Digikey too for some of the 6 OSH boards. What part # did you use for the 1uF capacitor? So many parts - so many distractions.
Tim — On the older OSH test boards for the smaller non-touchscreen (https://oshpark.com/shared_projects/IWylNfzD) Paul used a surface mount 1uF 0805 capacitor - Digikey 1276-1066-1-ND.
Tim — On the older OSH test boards for the smaller non-touchscreen (https://oshpark.com/shared_projects/IWylNfzD) Paul used a surface mount 1uF 0805 capacitor - Digikey 1276-1066-1-ND.
Has anyone tried the edits to use the SD_card (https://forum.pjrc.com/threads/28106-Display_ili9341?p=72889&viewfull=1#post72889)slot as was done on the non touch ILI9341?
PJRC touch display package came today - great delivery time! - not powered up yet. I sent a note to Robin for future QC testing - If you were lucky enough to get one from the first batch - make sure glass front is secured to PCB or you could get a rude surprise. Metal frame loops may not catch the display side ears allowing it to fall out as you rotate it. Worse yet - the metal frame on one of mine was not secured to the PCB board meaning upside down the screen would drop and swing/tug on the attaching cable. Double sided tape seems to be a fix.
Internally, those little displays are held together by just a couple layers of double-sticky tape. Sometimes the tape separates during handling. Just firmly pressing the pieces will re-seat the tape.
As noted I added double-stick tape and expect it to be fine - but it shipped adhesive free, here"s pic copy of the pic I sent to Robin. The left shows no factory tape - the right shows a jumper wire I placed under the display free of the metal loops. The invoice shows a friendly smiley face that was free! And no I didn"t get the display for $8 I checked my CC. 5292
On these the adhesive holds a "very most awesome deluxe" metal frame to the PCB, the frame loops hold the display. On the other display the two metal edge loops on one side lacked tension to capture the plastic layer bumps under the glass, in rolling it over to examine it shifted free of the restraints that hold it in the frame. Actually, when I taped the frame down that unit had loose loops on one side too, they are light gauge.
Wired and working per the Connections and 100% success! (http://www.pjrc.com/store/display_ili9341_touch.html). Much nicer than when I did the ILI9341 unit - I wired to Teensy header rather than jumper wires - which worked but once apart seemed like too much effort to restore.
opps:: (~4 hours later sitting on desk) Seeing the screen go WHITE after running for some time sitting IDLE? USB output shows touch data updates but display is nothing but white screen? Just saw it a 3rd time - reverted back to original example/ILI9341Test - happened in under 10 minutes? And again in like 6 mins and then very quickly a time or two. Ran from USB charger battery - same thing. Swapped to backup display and re-powered - same Teensy and same loaded code . . . will update . . . so far so good @35+ mins.
ODD: Loaded "graphicstest" and d#1 is running that? And now back running ILI9341Test ??? Seems flakey - went white again and a reset from TYQT brought it back up - 25 minutes and counting . . . came back after an hour and it was white - restored again on TYQT reset. White again at 33 mins - came back on power cycle. I"ve seen this display go WHITE now 6 times in the last 2 hours 20 minutes. It will come back but not long. As before the Touch SPI is still active - LED blinks - and the USB gives the readings. This is the display that came unstuck from the PCB. I didn"t think much of it but when first attached I did a double upload - I thought maybe there needed to be a delay in setup - there isn"t and the other doesn"t need it and it doesn"t when it starts up working.
I didn"t get far looking into the library with the hanging display - but I did glance at RANSAC. If I read it right it seems to be designed to solve a static image alignment issue:
That case is with fixed offset images adjusting for the parallax offset. The touch problem is noisy readings - compounded by user movement - intended or not.
One thing I did was had "No Touch" print the last coordinates before it appeared. Even the boundary number reported going off all four edges had a large degree of variability. I didn"t get as far as looking at the raw numbers to see if that was as reported from hardware, or as averaged and returned.
I don"t know what return values are expected - but empirically I noticed that the dummy X and next X read are always zero when there is no touch. So after the dummy comes back zero, the next five SPI commands could be aborted as ( !touched ) - then after the SPI.endTransaction() all processing can be terminated after zraw is set zero. This cuts SPI data flow in half when there is no touch, if this is supported behavior, and then the math component goes to zero as now it is done on each update.
And perhaps in update() the assignment of msraw = now; should not be done up front, but only if there is a touch as it will delay getting back in to find the next touch.
The cool thing is the Teensy is fast and edits and recompiles are quick! Also cool I didn"t get just one display, #2 has not gone white even once, though touch worked on the white screen and I"m now needing the big screen fed by USB to scan copious data streaming - and thinking of more compares as I wrote this.
But the XPT2046 has the advantage of automatically canceling out the effect of the resistance (small voltage loss) of its transistors which drive the display, and of course it"s actually connected to the 4 wires from the panel. Those 4 wires aren"t brought to the pads on the edge of the display, so you"ve have to really butcher a display to use anything other than the XPT2046 chip.
This type of measurement is probably always going to be pretty noisy. It"s a fairly high source impedance, and there"s a matrix of switching signals to drive the TFT nearby.
The 12 bit numbers can look pretty terrible. But remember it"s nearly 3000 to 3500 across the entire width of the display. Fluctuations of 30 are only 1% of the display width. Sure it"d be nice if all 12 bit were perfect, but you have to keep some perspective about how accurately a finger can even touch a 2.8 inch display. Even 2% or 3% accuracy (of the full scale) is still better than anyone can probably touch.
Still, if anyone wants to really work on this, RANSAC or some other algorithm would be awesome on a purely technical level, even if it"s not of much practical value for the actual measurement on these small displays.
But the XPT2046 has the advantage of automatically canceling out the effect of the resistance (small voltage loss) of its transistors which drive the display, and of course it"s actually connected to the 4 wires from the panel. Those 4 wires aren"t brought to the pads on the edge of the display, so you"ve have to really butcher a display to use anything other than the XPT2046 chip.
This type of measurement is probably always going to be pretty noisy. It"s a fairly high source impedance, and there"s a matrix of switching signals to drive the TFT nearby.
The 12 bit numbers can look pretty terrible. But remember it"s nearly 3000 to 3500 across the entire width of the display. Fluctuations of 30 are only 1% of the display width. Sure it"d be nice if all 12 bit were perfect, but you have to keep some perspective about how accurately a finger can even touch a 2.8 inch display. Even 2% or 3% accuracy (of the full scale) is still better than anyone can probably touch.
Still, if anyone wants to really work on this, RANSAC or some other algorithm would be awesome on a purely technical level, even if it"s not of much practical value for the actual measurement on these small displays.
My reason for asking was I have an Adafruit 2.8 ILI9341 without Resistive Touch IC and was wondering if it would be beneficial to add a dedicated IC to it.
I wanted to know if there was a large difference in accuracy between the Touch IC and what the Teensy can do and from what Paul said there isn"t much of a difference.
Just did a Pull request from (to?) GitHub. After looking over the "constrained" random data values returned to suggest touch location I put my observations into code.
The change I made to returned X,Y is that Paul did a distance test as a paired point, which makes sense until looking at the data source and acquisition time. The three reads are under 96 SPI xfer bits apart start to end - alternated xyxyxy. We know the data is jittery and out of 6 points at least one probably wild, but calling it "paired" with one seems artificial, and one wild coordinate would get the pair tossed, even if the other coordinate better equaled a second. So I implemented diff of the 3 values as X and Y and averaged the two closest ones. In my instrumented build I was seeing about 30% of the time my pair average was unique from the initial library.
The library enforces a THRESHOLD on rapid reads of 3ms. If it was asked ts.touched(); and it replied NO, it would keep the caller from getting back in, maybe 3ms is okay. But if a caller just hits ts.getPoint(); static data is returned without attempt to update, if no touch it will still get stale data - but at least it will try in that window. Of course that window never closes when there is no touch.
For either of the above noted calls the same internal update() is done. For touched() it still does all the math and calculations after completing the 10 word SPI data cycle in all cases. In watching the data I saw that the first X value returned after the 4th transfer is ZERO when there is no touch, the first reads are for the Pressure to detect a touch. This calc was done after the SPI cycle, but if there is no X then there is no touch [empirical not from data sheet?], that means the next 4 SPI words can be skipped as the data won"t be used in any case and we can determine that there was no touch. Not reading 40% of the data and skipping all the math means the touched() call is less expensive in SPI bandwidth and cycles.
> With the initial code and my update code the touch variability is easily +/- 1 pixel so printing it at the calculated point works, but makes a little cloud there.
> I used a stylus for most of my testing, a bit better than a finger for uniformity. If you touch near both screen edges the value is read to the middle, biased some by the harder pressing part.
2> I saw the code noted the first x read was always noisy, and it is, I suppose that is from "powering down" the touch panel with the final read and getting it repowered with the first read.
Question: What is the math for mapping Touch_xy to pixels_xy? My attempt at what I thought for a linear system gets parallax error: Find the min_xy and max_xy. The pixel value for x would be: xx = (( 320 * (p.x - MinSx)) / (MaxSx - MinSx) ); But this lags at the start and accelerates and the end. Result is similar on X and Y axis. I calculate it on the fly with low/high values seen during the run to adjust some safe static start numbers.
Managed to slap together a mostly working chunk of code using the ADC library. The xpos seems to work fine, the ypos is all over the place when not being touched. Sometimes its 0 sometimes its 3000-3400, sometimes its around the midpoint. Its way to erratic for averaging to fix. Will put a scope on it tomorrow.
What is the xpos with no touch? The PJRC type direct ADC controller showed a uniform zero value on xpos - but only on the dummy and first reads. 2nd and 3rd reads on xpos are all over and all three reads have a wandering value.
What is the xpos with no touch? The PJRC type direct ADC controller showed a uniform zero value on xpos - but only on the dummy and first reads. 2nd and 3rd reads on xpos are all over and all three reads have a wandering value.
xpos stays around 900 without touching it, ypos seems to bounce I got my scope attached and it seems like there is alot of noise on the X+ and X- lines.
Pages 20 and 21 of the XPT2046 explain how they do it after reading that and then looking at the Adafruit code I figured out how its being done. One thing that is confusing is a lot of the Arduino examples for reading the screens only shows 4 resistor in a cross, but there is a 5th resistance, and its the contact resistance between the X and Y planes(pressure). The XPT2046 reads 3 of the 4 Touch pins analog values in sequence and determines the resistance(Z) between the X, Y planes and thus the amount of pressure on the screen if any. Adafruit drives 2 opposite pins High and reads the other opposite pins to determine the voltage drop across the Touch plane.
Donziboy2 - to match your findings - I read this last night but didn"t post - but it relates: http://www.unclelarry.com/?p=101 in that he discovered the 5th plane hoping he could read light touches - but until the touch is hard enough there is no circuit completed. Also describes the pressure sense. Again he shows a formula different than in the code for pressure, as in the PDF doc I saw. The code there works for touch detect - but is not linear with the math used.
I updated my PULL request to Paul with a question about the time between SPI.transfer - doing actual z detect after the data from the first two reads comes back is better than assuming the x=0 on the third read is defined behavior on all units, it also allows exit one SPI word sooner when not touched. Based on the above I think in the end the z=pressure calc should be changed when touch is detected.
My SPI question would be - the transfers are blocking as we assign a return value. If we execute "a few" instructions in code as the master before we execute the next SPI transfer is that controlled or gated by master "clocking" the transfer and not by a steady UART like clock?
Touch Detect works pretty good. Its pretty easy to detect as long as you have a rough idea of where xpos is at that time, it seems to move around some so atleast one read is needed.
On the PJRC - assume the same as OP Frank"s display: For pressure calc per the data sheet p#73 the main factor is the z2/z1. Supposing we had a steady accurate X position multiplying that by x/4096 is supposed to fix the drift as it crosses the screen. it does no correction for y.
Just looking at (z2/z-1) and expecting it to reflect on the x position I don"t see that. It changes on my display at the lightest touch seen or a firm touch - finger or spring stylus. Not only at the same point by a factor of 2 - but across the display both x and y.
I should be right on x.vs.y - as they are bits in the SPI commands - and printed in the debug spew. But it varies across both axis as well. Lowest x,y has highest z tendency on the lightest touch and it is lowest z at the highest x,y.
This is with my working #2 display - up for days. As long as it has been on #1 was off - did a power off swap and it came up white on repowering. Did a reprogram and the color is back [for 10 minutes] - but the touch works in either case - and #1 maybe better than #2,
Reads touch and maps to pixels and draws crosshairs and an "X" mostly to a bounding box. Resistive report goes beyond pixel limits. Use a stylus tip to see, mostly tracks with hardcoded edges on my screen. No dynamic calibration points.
On the PJRC - assume the same as OP Frank"s display: For pressure calc per the data sheet p#73 the main factor is the z2/z1. Supposing we had a steady accurate X position multiplying that by x/4096 is supposed to fix the drift as it crosses the screen. it does no correction for y.
Just looking at (z2/z-1) and expecting it to reflect on the x position I don"t see that. It changes on my display at the lightest touch seen or a firm touch - finger or spring stylus. Not only at the same point by a factor of 2 - but across the display both x and y.
If you don"t move your finger it is fairly accurate, the Adafruit code which i copy/pasted basically uses that formula in a different order, the outcome is the same. For my testing its very apparent when your touching the screen regardless of where you touch it, the touch values are vastly different. Based on my screwing around using uint32_t shows 0-10000(very light touch) values are only seen if the screen is being touched, the touch values from noise are 30K - 500K values. Im not using any averaging at the moment and only using 1 read per output.
The point of the math is to determine if the screen is being touched. Remember your calculating the resistance of 5 resistors that can very based on temp, position and pressure of touch and your only using 3 points at most to do it.
They do list a second formula that uses Y also. So you could make it more accurate. On my screen the Y resistance is 524 and R resistance is 288. Really accuracy with this part is not really needed, if you can determine the screen is being touched then its good enough. For me I just need to know when to ignore the x/y pos values since Y seems to be all over the place due to noise from the LCD.
I should be right on x.vs.y - as they are bits in the SPI commands - and printed in the debug spew. But it varies across both axis as well. Lowest x,y has highest z tendency on the lightest touch and it is lowest z at the highest x,y.
This is with my working #2 display - up for days. As long as it has been on #1 was off - did a power off swap and it came up white on repowering. Did a reprogram and the color is back [for 10 minutes] - but the touch works in either case - and #1 maybe better than #2,
Also your values will very based on the amount of noise your screen is putting out. If you look at the first O-scope image I posted you will see alot of noise with the CH1 and CH2 pins. Its a 15KHz square/sin wave that is coming from the display itself and much"s up the x voltages throwing the Y return values all over the place.
Indeed - no problem detecting touch - I was expecting the system would provide a more stable value - even re-reading it after x,y when looking good as noted showed no real improvement worth extra cpu cycles from what PJRC started with that I could see over just reading the z values up front as is.
The sample included stability wise seems +/- a pixel (or two) generally with the crosshair under a pointer. With a box of text big enough to read and a couple pixels border and gap - hitting the right spot should be easy. Fingers have un-calibrated hard and soft spots and even lifting off registers touch for some time shifting the mass even if it is a straight lift.
If so the Beta 1 version of 1.26 shipped with a version of XPT2046_Touchscreen that I modified. I put in a PULL request PJRC will hopefully validate as good next week.
If you want to try my updated "I:\Teensy165\hardware\teensy\avr\libraries\XPT2046 _Touchscreen\XPT2046_Touchscreen.cpp" on your 1.26 Beta 1 install file I"ll attach it. I think what I changed is noted in a prior post. Turns out one of the nits I picked made things work better for Frank in a specific case and otherwise perfectly well.
Second that... a simple widget library with a few different (simple) controls, specifically round-rect buttons, radio buttons, and check boxes, together with a touchscreen event handler, would go a long way towards helping a lot of users.
Then I"m hoping to do an interrupt LIB version to stop SPI polling for Touch. But I"ve been wondering how you attachInterrupt(TS_Pin, onTouch, FALLING); then onTouch(){ PIN___disable_irq()(TS_PIN) ... PIN___enable_irq(TS_PIN) }
That is in the ISR entry clear ONLY the PIN interrupt on TS_PIN and exit restart the interrupt? Stopping all interrupts is crazy, and it doesn"t seem that doing a detachInterrupt/attachInterrupt cycle should be needed on each touch.
@epicycloid : That version is posted for a PULL 6 days back (https://github.com/PaulStoffregen/XPT2046_Touchscreen/pull/1) - last edit was a compiler warning I saw when compiling for T3TRIS testing - Paul will do it 11/3 hopefully - just looking to get some run time on it so he can trust it.
Then I"m hoping to do an interrupt LIB version to stop SPI polling for Touch. But I"ve been wondering how you attachInterrupt(TS_Pin, onTouch, FALLING); then onTouch(){ PIN___disable_irq()(TS_PIN) ... PIN___enable_irq(TS_PIN) }
That is in the ISR entry clear ONLY the PIN interrupt on TS_PIN and exit restart the interrupt? Stopping all interrupts is crazy, and it doesn"t seem that doing a detachInterrupt/attachInterrupt cycle should be needed on each touch.
@FrankB: - there is a note about the touch hardware interrupt (https://github.com/Defragster/XPT2046_Touchscreen) that says interrupts are not that straightforward for the touch display:
However, inside your interrupt function, if the display is no longer being touched, any attempt to read the touch position will cause the interrupt pin to create another falling edge. This can lead to an infinite loop of falsely triggered interrupts. Special care is needed to avoid triggering more interrupts on the low signal due to reading the touch position.
As I read this:: This is a problem in that on TOUCH the isr triggers - then the ISR gets control to query the device it will then "read the touch position". If at any point it does that - if the TOUCH is removed it triggers yet another interrupt while still within the prior interrupt. I suppose while contact it held the INT PIN is not reset - but at the point touch is lost and it does reset - any ISR call to update() will itself trigger yet another INT - which would then call update() ... repeat until touched.
Here is an update - almost cool - whenever you touch "off" it rotates the screen and redraws. This just allows your code to pick or change orientation on the fly and properly maps the touch data to the relevant x,y pixels. It won"t clip or re-arrange things outside the pixels that are in the common 0,239 area that is in the 4 rotations. Rotations 1,3 and 2,4 work on the same constraints so that adds yet another variable to my pondering:: if buttons were tagged as such they could be duplicated for use in alternate views at updated locations, and hidden as appropriate.
I didn"t generalize the drawing code yet - everything marked "// INCORPORATE" should be go. The unique nature of this touch/toggle button needs to be incorporated as it seems cool, but wasn"t a button behavior I forsaw. But the rotate tracking uses a struct of the screen dimensions in the 4 orientations - this is similar to how buttons/frames will be defined.
With the patch to the library to swap x & y Touchpaint works pretty well. It needs to have its x & y code fixed, and then it would make a useful example addition to the XPT2046_Touchscreen library. I"ll take a crack at that.
Here are the edits I made to the TouchPaint TS_GetMap to slow the poll rate (for a solid line you draw more slowly and can get a straighter line), also put in rejection of low points without MinPressure. When I get back to my BUTTON generalization - this could make a good sample - and allow more buttons for CLEAR etc.
Paul uses a different mapping so they are not compatible. So you can"t use the Touchpaint-example from the examples-menu for "our" display without changing it.
Well, maybe I"m too late to the party with this, but here is Touchpaint with rotation set to 1 and x,y recoded so that it is correct with the XPT2046 library.
Somehow I created a branch so it is under Beta3. This is in my fork of the PJRC code so my working XPT2046_Touchscreen LIB code is there too. Hoping that makes it into the next Beta of 1.26, but Arduino 1.6.6 dropped today and not sure where it will fall out if Paul finds it a worthy update.
I modified the TouchPaint to use Button Definitions from an Array of Structs and moved the action code to functions that loop through the array to do the work. Not a general purpose solution, but drops lines of code and uncluttered the loop for sure of repeated drawRect and fillRect. You can initialize it to start on any tft.setRotation() though 2 or 4 makes sense with how the buttons are laid out.
Converted the OnOff sample to use the button array and common looping update functions (https://github.com/Defragster/XPT2046_Touchscreen/commit/f4a52dcbe166bf355c83912699df0a3074611963)
Updated onoffbutton example updated on Github (https://github.com/Defragster/XPT2046_Touchscreen/blob/25c3054e13397a18e4299d24387d643de2f683bd/examples/onoffbutton/onoffbutton.ino).
X and Y are natural as expected - it is the TouchPaint that has the values confused as they use them - I ported them to a struct unchanged and they work through rotation - but backwards - very confusing. Maybe bboyes did the corrections on that.
Hm, this will take some time, if ever.... It has little problems, like PWM (Display-Backlight) not working and if used together with Audioshield+"Connectorboard" the pins are blocking the sd-card-slot so it is not easy to replace the sd-card ...
Picture a good start to see what it was - as you know I"m looking at another ESP8266 unit - I just need to finish where I am and learn Eagle and put on it what I need. I just need to glue the power rx/tx to a raw ESP-12 layout. No audio needed and the video is a debug option - the PJRC touch OSH board would be a good start - though smaller power with SPX3819 or similar. I got the starter eagle I probably need from Constantine, but distracted by the TOUCH just now.
With 5V, the backlight is very bright (no extra R on the LED pin). I ran it for long hours now with no damage - there is a resistor on board (can"t speak for PJRC-Display, but i would think that they are the same)
GitHub updated with more touch fun : Beta3/examples/onoffbutton/onoffbutton.ino (https://github.com/Defragster/XPT2046_Touchscreen/blob/Beta3/examples/onoffbutton/onoffbutton.ino)
GitHub updated with more touch fun : Beta3/examples/onoffbutton/onoffbutton.ino (https://github.com/Defragster/XPT2046_Touchscreen/blob/Beta3/examples/onoffbutton/onoffbutton.ino)
The toggle effectively seems that way if you touch color half and slide to text half - and I do require two hits - so logic exists that it would only count if you connect those two dots.
GitHub updated: examples/onoffbutton/onoffbutton.ino (https://github.com/Defragster/XPT2046_Touchscreen/blob/Beta3/examples/onoffbutton/onoffbutton.ino)
DIFFS: Showing 1 changed file with 10 additions and 0 deletions. (https://github.com/Defragster/XPT2046_Touchscreen/commit/71139979768610eb6ad739d6bf5732b78da01596)
Paul - also this is a pretty cool post #123 is a cool TOUCH demo of windowing buttons if you want to take a 5 minute break to see what you"ve allowed us to create. Also BTW - if you have an extra minute I have that pull request on the : https://github.com/PaulStoffregen/XPT2046_Touchscreen/pull/1. I have not reverted to your B1 code to say it saves the world - but it is working for Frank and I.
I tried a hardware driven interrupt version of XPT2046_Touchscreen/ /examples/TouchPaint/TouchPaint.ino (https://github.com/Defragster/XPT2046_Touchscreen/blob/Beta3/examples/TouchPaint/TouchPaint.ino)
I punted and started up a TimerInterrupt that will check for touch and works exactly the same as I modeled the Interrupt version. Somewhere the HDW interrupt chain is broken where the timer chain thrives?
Infact with three lines swapped the hardware version works intermittently where the Timer version works well - the initial touch may take 50ms to be caught - but then input is read every 10ms during the touch. So that is polling 20 times/sec and sometimes a touch is missed. Any touch is recorded then if the user app asks or not. From there as often as the user requests touch data it will be provided during a touch - on the adjustable 10ms boundary.
Tried running the isr touch paint demo, runs until I try to draw on the screen, get a short line then the teensy hangs. I am on arduino 1.6.5 and teensyduino 1.26 beta-1 using your touch driver. Getting late ( not as young as some ) and will update to current release tomorrow.
I just posted a sample that demonstrates INTERRUPT PIN USAGE as I made it work (https://github.com/Defragster/XPT2046_Touch_Examples/blob/master/IntTouchPaintDeb/IntTouchPaintDeb.ino): https://github.com/Defragster/XPT2046_Touch_Examples/blob/master/IntTouchPaintDeb/IntTouchPaintDeb.ino
I should start a new Thread for this and I"ll be updating my prior examples and adding them to this GitHub for the Struct"ured button handling I did. I did it on the TouchPaint - but it was - like this interrupt code - just the work area to test the concept.
One of the displays I got turned out to be defective (noted above) and is being replaced - Thanks Robin! When I found I didn"t need to return it - I could HACK IT! - I was going to use it as a test bed for SDCARD access - I didn"t wire it up yet, but I found when I closed the J1 jumper the screen came back! That "component" on VCC is bypassed and it must have been the problem on my display. I suspected that might be that case as the WHITE SCREEN is what you get when you don"t power the VCC pin.
I will run my wires to the SDCARD connect soon and post my results as I also put shorts over where the three resistors were when I soldered the J1 closed. And I re-taped the display down and it is still working after running the Interrupt code [ PIN and TIMER ] overnight from a USB battery pack.
The Timer in the sample is running very fast and a well lit SPI LED - but the Interrupt device has no Touch SPI until it is touched, but the app does clear the Paint area every two seconds when not touched. This was handy for testing so I could keep testing paint on a black screen.
I also abused the lower part of the display for debug SPEW lines - made it easier to see activity ONSCREEN while I touched instead of also having to watch the USB that scrolled like crazy on interrupts.
It appears like maybe some form of interaction between the SD card SPI communications and the Touch SPI communications? Im not sure and will get out of my depth debugging the SPI code very quickly!
This does make me start wondering if there is a reason that the SD card is on its own SPI bus (i.e not connected in with either of the other buses present on the screen) but that could be for other reasons.
I took and SdFileListDump.ino and dropped at the bottom of my IntTouchPaintDeb.ino and has main setup call the renamed SD setup2() and it worked! I even called it within the touch code and it runs to USB out.
This is the display that was not getting VCC until soldered over the J1 - it is now working in full for the last 24 hours. The SD card I picked has dozens of files and it did a good directory.
NOTE: When the TOUCH triggers I queue a read for the next user code query. It does not complete a read during the interrupt. It is up to the user code to request data when the code is ready to read it. As it exists the Interrupt code prevents the need for user polling until a Touch happens - but without implementing a user callback I can"t force the user code to act on it until it sees the flag by asking for a point. And my debounce code requires two reads about the same pixel to call it good to return. Unless I make it read and buffer a few points to return - until the user code calls the touch is lost.
I will start afresh again today, remake the SPI wiring links ( those ended up isolated back during my investigations). I will load your code and try and replicate what you are dong that works !
I have "#define TFT_CS 10" on mine - and the one sample I loaded seemed to suggest "CS 4" so I went with that as I had used it on stand alone micro-SD.
Here is a pic with the SD lines in place. They are plugged into a header to make them removable. I also did the touch_int to pin 2 before the pic, and it works.
The code I used is on : github.com XPT2046_Touch_Examples/ /IntTouchPaintDeb_SD/IntTouchPaintDeb_SD.ino (https://github.com/Defragster/XPT2046_Touch_Examples/blob/master/IntTouchPaintDeb_SD/IntTouchPaintDeb_SD.ino)
It shows that I implemented interrupts about halfway. Touch is detected - but not acted on until user code asks. I may look to fix that - but I had issues and what went stable works like this - because of how I do the Touch reading and worked around the interrupt during interrupt re-entrancy prevention.
@Twinscroll , Great news - glad I could offer you encouragement and a sample. I went on blind faith and dumb luck. As you can see my board isn"t pretty - but it works. The PJRC OSH Display board puts on 10K pullups - not sure how that affects - will build one and see.
Good news is at least two of the new Touch ILI9341 screens have been edited to work per the directions that were suggested for the old Non-touch: this hardware modification may be able to get it working (https://forum.pjrc.com/threads/28106-Display_ili9341?p=72889&viewfull=1#post72889)
This color touchscreen work is so excellent: thanks to Paul, and everyone else contributing, and Adafruit for the GFX library. This has become my "go to" display for quick prototypes: with a Teensy 3.2, the purple board of Paul"s, and the 2.8" TFT.
According to the best data we could find, it is OK to run the backlight at 60 mA per LED. There are four in parallel so that means 240 mA! There is a 4.9 ohm series resistor with the ganged anodes already on the TFT board. I replaced the 100 ohm purple board resistor with 5 ohms (the smallest TH part I had) and the backlight pulls 160 mA, plenty safe I would think, and the display is SO much better with a brighter backlight. We"ll run it at 160 mA and then drop to 20 mA if there is no touch for say 15 seconds, just like tablets and cell phones dim the display.
We have spun our own board for a medical device prototype, and put a PFET at the top of the backlight anodes so we can PWM the backlight since we will run on batteries. I"ll post more about all that once I get the board up this weekend. It"s a rush project. We also have our laser driver on board, with both programmable current (capable of 700 mA or more, we are using 400 mA now) and PWM, with a closed loop servo to make the current stable and accurate. We put on 128 MBit serial flash (we can"t use the huge SD card on the display in our package), a speaker, I2C temp sensor near the FET, and a few other things. It is running off a 3S R/C model battery pack with something like 14 watt hours, so it has plenty of juice. We have switcher modules for 5V and 3.3V, and use the low cell in the pack to keep the Teensy RTC running when the power switch shuts off both regulators. Our board stacks under the LCD, with standoffs in the four corners.
When we are ready for production we can get displays from a reputable source, with the same or similar driver, so I am OK with using Chinese displays of unknown provenance for the prototypes. We"ve done some testing of 100+ hours here and so far the cheap displays are holding up well.
At the moment I"m writing test code to do some simple statistics on touches so I can decide on screen calibration and button size so that operation is reliable. We need operation with just a finger and through exam gloves too, so resistive touch might be actually better than capacitive in this case (though we plan to test cap touch also).
OK thanks...got the latest Teensyduino release and now the skitch comples and runs. I see a black outline square with the word No in the upper left corner and next to it a filled in red square. I touch them and the screen but see no changes...I"m not sure what I"m supposed to see but I guess this means my touch wiring isn"t correct?
I can run that sketch but when I touch nothing happens...I must not have my TFT wired up correctly for touch...I will try to find an example showing how to wire it for touch and double check my wiring...thanks...
I am curious, and this may highlight my level of c programming knowledge - but why would you opt to use the readData () method to obtain the touch position over the getPoint () method or vice versa?
An additional 4 pins are required for the touchscreen. For the two analog pins, we"ll use A2 and A3. For the other two connections, you can pin any two digital pins but we"ll be using D9 (shared with D/C) and D8 since they are available. We can save the one pin by sharing with D/Cbut you can"t share any other SPI pins. So basically you can get away with using only three additional pins.
I can run that sketch but when I touch nothing happens...I must not have my TFT wired up correctly for touch...I will try to find an example showing how to wire it for touch and double check my wiring...thanks...
The wiring works per the link in this thread that goes to the PJRC page: https://forum.pjrc.com/threads/30559-2-8-ILI9341-restive-touch-miso-not-connected?p=85727&viewfull=1#post85727
@Twinscroll - the two functions do the exact same behavior on the touch side -it is just a preference to the way the point is returned. ReadData takes 3 pointers and when called updates the data stored in the pointers, getPoint just returns a one pointer to the library stored structure of values. Two different ways to do the same thing, perhaps for compatibility reasons to other similar systems?
If you have the PJRC style board - the SPI pins are shared - the only unique pin per device is the Chip Select. Not sure if this snippet from the code will help see the wiring if you have the PJRC XPY2046 controlled touch.
If you have the AdaFruit hardware with real Analog values from the touch - it isn"t using the same touch controller - it would be like was used by another poster on this thread. In that case find his posts - it required directly reading and interpreting the analog values.
I"m Trying to keep it simple, so I"ve split the screen roughly down the middle - when the screen is touched I look at the value of X - if it is higher than 2000 I increase a screen count. ( so I will show the next screen ).
However, one of my other sketches that displays text (via fonts), doesn"t work now. The screen is garbled up. Is there a text/font mode I have to switch into? Or does text and graphics mixed nicely on the screen?
@rfeash737 - that is the default example code. I made a version where I generalized the buttons and then extended that to other examples: https://github.com/Defragster/XPT2046_Touch_Examples
Except I demonstrate dealing with mapping to pixels in any screen rotation. That touch paint have the screen read backwards somehow - the "onoffbutton" example is a better demo where I do more buttons and rotate the screen dynamically for example purposes.
For your purposes adding 10 on screen buttons could let you jump directly to any screen. in landscape mode the buttons would be large enough to hit and label in two rows of 5 and leave a large area to display whatever you wanted in another screen area. I diverted from the button work to get a non polling version using the interrupt pin that went pretty well, but has some anomaly.
I just moved all my examples to the new GitHub listed above as having it inside the touch screen fork of PJRC makes GitHub painful. I haven"t looked at them for some time, but left them working.
I just created this TOUCH thread for my work in progress - to minimize the pollution of this thread and the repetitious info on this and another thread: ILI9341-and-XPT2046-for-Teensy-Touchscreen-320x240-display (https://forum.pjrc.com/threads/31634-ILI9341-and-XPT2046-for-Teensy-Touchscreen-320x240-display)
Oh, the topic/issue of this thread "..miso not connected.." is solved :) (It was bad soldering of the connector between the display and pcb. Works now.)
I am curious, and this may highlight my level of c programming knowledge - but why would you opt to use the readData () method to obtain the touch position over the getPoint () method or vice versa?
We"re trying to be fully compatible with Adafruit"s touch controller library. Adafruit has those two redundant ways, so we"re doing them both as well. The only reason is because some programs use one way, others use the other way, so we need to have both for compatibility.
Question regarding the Color 320x240 TFT Display and the ILI9341 Controller Chip, do we have any capability to change the screen brightness? I"m running mine on a Teensy 3.2 using 3.3v and the display is "OK" but I was just wondering if we have any tweaking capabilities?
I recently ordered some of these displays. Haven"t used them yet. I made this PCB to speed things up (well, at least minimize my time spent fiddling).
@gsklinger - there was a second prior board from OSH without touch - if you go there and click on Paul"s projects - you can find it and it gives a BOM and more detail. The changes I saw are through hole cap on power (instead of SMD), and two added 10K resistors for pullup that are placed under the Teensy. I have those parts here now but didn"t fully build one yet. The power plug is a pain to find - I got one from DigiKey that looks like it will work - may need some editing.
@gsklinger - there was a second prior board from OSH without touch - if you go there and click on Paul"s projects - you can find it and it gives a BOM and more detail. The changes I saw are through hole cap on power (instead of SMD), and two added 10K resistors for pullup that are placed under the Teensy. I have those parts here now but didn"t fully build one yet. The power plug is a pain to find - I got one from DigiKey that looks like it will work - may need some editing.
EDIT: I dropped it down to a 47 ohm resistor and that made the LCD a little brighter and now the brightness looks "better" than with the 100 ohm resistor. In fact, I"d say the screen brightness is "excellent" now. So, maybe 47 ohms on a 3.3v board with this screen.
Paul - If you get to update the OSH Display board setup - don"t forget the FUSE link rating - I did - I just realized I adjusted the other needed parts - but left the low 0.14A PTC on my order list - so it won"t feed the T_3.2 enough current to use the new hardware - given that 5v feeds the display LED and the LDO output is 5v not 6v not sure if you would recommend .3A or .35A maybe?
@gsklinger - there was a second prior board from OSH without touch - if you go there and click on Paul"s projects - you can find it and it gives a BOM and more detail. The changes I saw are through hole cap on power (instead of SMD), and two added 10K resistors for pullup that are placed under the Teensy. I have those parts here now but didn"t fully build one yet. The power plug is a pain to find - I got one from DigiKey that looks like it will work - may need some editing.
Now, to reduce the pin usage, I connected the XPT2046 to the SPI and everything works fine, but if I connect the pin SDO_MISO of the display, the SDO_MISO data become crazy shooting continuously and autonomously incorrect values.