Is that not-very-optimized 8 bit library actually faster than optimized SPI?
/***************************************************
This is our touchscreen painting example for the Adafruit HX8357 Breakout
----> http://www.adafruit.com/products/2050
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
/** NOT FOR USE WITH THE TOUCH SHIELD, ONLY FOR THE 3.5" BREAKOUT! **/
#include <Adafruit_GFX.h> // Core graphics library
#include <SPI.h>
#include "Adafruit_ILI9341.h" // Hardware-specific library
#include "TouchScreen.h"
// These are the four touchscreen analog pins
#define YP A2 // must be an analog pin, use "An" notation!
#define XM A3 // must be an analog pin, use "An" notation!
#define YM 6 // can be a digital pin
#define XP 7 // can be a digital pin
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 110
#define TS_MINY 80
#define TS_MAXX 900
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000
// The display uses hardware SPI, plus #9 & #10
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
void setup(void) {
Serial.begin(115200);
Serial.println(F("Touch Paint!"));
tft.begin();
tft.fillScreen(ILI9341_BLACK);
// make the color selection boxes
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, ILI9341_BLACK);
tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
// select the current color 'red'
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
currentcolor = ILI9341_RED;
}
void loop()
{
// Retrieve a point
TSPoint p = ts.getPoint();
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z < MINPRESSURE || p.z > MAXPRESSURE) {
return;
}
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
// Scale from ~0->1000 to tft.width using the calibration #'s
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
Serial.print("("); Serial.print(p.x);
Serial.print(", "); Serial.print(p.y);
Serial.println(")");
if (p.y < BOXSIZE) {
oldcolor = currentcolor;
if (p.x < BOXSIZE) {
currentcolor = ILI9341_RED;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*2) {
currentcolor = ILI9341_YELLOW;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*3) {
currentcolor = ILI9341_GREEN;
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*4) {
currentcolor = ILI9341_CYAN;
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*5) {
currentcolor = ILI9341_BLUE;
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*6) {
currentcolor = ILI9341_MAGENTA;
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*7) {
currentcolor = ILI9341_WHITE;
tft.drawRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
} else if (p.x < BOXSIZE*8) {
currentcolor = ILI9341_BLACK;
tft.drawRect(BOXSIZE*7, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
}
if (oldcolor != currentcolor) {
if (oldcolor == ILI9341_RED)
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
if (oldcolor == ILI9341_YELLOW)
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
if (oldcolor == ILI9341_GREEN)
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
if (oldcolor == ILI9341_CYAN)
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
if (oldcolor == ILI9341_BLUE)
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
if (oldcolor == ILI9341_MAGENTA)
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
if (oldcolor == ILI9341_WHITE)
tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
if (oldcolor == ILI9341_BLACK)
tft.fillRect(BOXSIZE*7, 0, BOXSIZE, BOXSIZE, ILI9341_BLACK);
}
}
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
}
}
In file included from C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/wiring.h:33:0,
from C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/wiring_private.h:7,
from C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen\TouchScreen.cpp:7:
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h: In function 'void digitalWriteFast(uint8_t, uint8_t)':
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h:1328:24: error: 'portSetRegister' was not declared in this scope
*portSetRegister(pin) = digitalPinToBitMask(pin);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h:1328:51: error: 'digitalPinToBitMask' was not declared in this scope
*portSetRegister(pin) = digitalPinToBitMask(pin);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h:1330:26: error: 'portClearRegister' was not declared in this scope
*portClearRegister(pin) = digitalPinToBitMask(pin);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h:1330:53: error: 'digitalPinToBitMask' was not declared in this scope
*portClearRegister(pin) = digitalPinToBitMask(pin);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h: In function 'uint8_t digitalReadFast(uint8_t)':
C:\arduino\arduino-1.6.5\hardware\teensy\avr\cores\teensy3/core_pins.h:1432:32: error: 'portInputRegister' was not declared in this scope
return *portInputRegister(pin);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen\TouchScreen.cpp: In member function 'TSPoint TouchScreen::getPoint()':
C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen\TouchScreen.cpp:61:41: error: 'digitalPinToPort' was not declared in this scope
uint8_t xp_port = digitalPinToPort(_xp);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen\TouchScreen.cpp:66:43: error: 'digitalPinToBitMask' was not declared in this scope
uint8_t xp_pin = digitalPinToBitMask(_xp);
^
C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen\TouchScreen.cpp:77:30: error: 'portOutputRegister' was not declared in this scope
*portOutputRegister(yp_port) &= ~yp_pin;
^
Multiple libraries were found for "TouchScreen.h"
Used: C:\arduino\arduino-1.6.5\hardware\teensy\avr\libraries\TouchScreen
Not used: C:\arduino\arduino-1.6.5\libraries\Touch-Screen-Library-master
Error compiling.
I've made a number of fixes to this Touchscreen library. Here's the latest code:
https://github.com/PaulStoffregen/TouchScreen
This version works *much* better. The original code wasn't allowing settling time for the signals, which is unnecessary for slow AVR. Teensy 3.2's CPU and ADC are so fast that it was measuring before the signals were stable. This lib also had a signal validity check that was too strict. This relaxed check allows much better sensitivity.
I've made a number of fixes to this Touchscreen library. Here's the latest code:
https://github.com/PaulStoffregen/TouchScreen
This version works *much* better. The original code wasn't allowing settling time for the signals, which is unnecessary for slow AVR. Teensy 3.2's CPU and ADC are so fast that it was measuring before the signals were stable. This lib also had a signal validity check that was too strict. This relaxed check allows much better sensitivity.
I have the Adafruit 3.5" TFT HX8357D and a Teensy 3.2. Here I was about to complain that it wasn't working when I started by checking my wiring. The wiring was wrong. Doh. Fixing that gives me a screen running using SPI, Paul's library and the graphicstest example.
However, I've the same problem that others have reported. Hardware SPI causes the code to crash, quite possibly at tft.begin(). Software SPI runs fine, although so so slowly...
By that, I mean that this doesn't work:
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
This does work:
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
At which point I go huh? Coz I'm using the usual pins:
#define TFT_MOSI 11
#define TFT_MISO 12
#define TFT_CLK 13
// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
#define TFT_MOSI 11
#define TFT_MISO 12
#define TFT_CLK 13
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
The display is using 16 bit bus mode and needs about 20 Teensy pins. As far as I know there is no existing library for Teensy.
No, the display won't work with the Adafruit_ILI9341 library. The reason is that the Adafruit_ILI9341 uses the SPI interface for the display and your display is configured for a 16 bit interface.
oh,.. i understand :/ .. hmm.. is there a shield or some other solution for that? what would I need to get this working? or should i buy a other display?
EDIT:
would this shield help? https://www.amazon.de/XCSOURCE-Schirm-Erweiterungs-Arduino-TE519/dp/B01IKHN3ZS/ref=sr_1_25?ie=UTF8&qid=1483950362&sr=8-25&keywords=tft+arduino+mega
please correct me if i am wrong, but is the VIN-pin on the teensy 3.2 not 5v ??A quick glance shows that this shield expects/sends 5v signalling (since the Mega runs on 5v). So you would need to do the appropriate level shifting to convert the Teensy 3.3v signals (both ways) to 5v, and then the shield converts them back to 3.3v.
please correct me if i am wrong, but is the VIN-pin on the teensy 3.2 not 5v ??
Hi Michael
thanks for the explanation.. yes I do feed the teensy via USB.. therefor my VIN is 5v
I have wired the display directly to the teensy 3.2 .. the backlight seems to work when 5V and GND is connected.. but the rest..sorry i am a completely noob at this.. not :/ .. and i completely do not know where to start..
i mean, .. how would i wire it? .. do i have to use all pins?
That's why I think it would be simpler to look for a supported display. Where to start? You would need to get the datasheet to find the pin assignments and what the commands are for the display. If the code for the Mega shield is available, you could potentially use it as a starting place for writing your code, unless it is hard-wired to the Mega using assembly code that won't port easily to the Teensy.
Some displays have an option to switch to 4 pin SPI mode, in which case you would wire the appropriate switch high/low (and use the appropriate SPI library). But if it doesn't have a SPI mode or there isn't a SPI library for the display, you are in for a tough slog.