My TFT LCD demo ported to the Mega.

Some one asked me if I had got the old code to work, I had not.

 

Now I do, sorta…  Need more work. But it works.

Code:

// This is for the PIXNOR UNO R3 2.8 TFT Touch Screen with SD Card Socket for Arduino Board Module From Amazon
// Sold by ThinkCreator (and maybe others)
// It took a while to get the correct Libraries for it and then to calibrate the screen.
// Modified by Jon Stephenson (http://www/jonstephensonsblog.com)
// I have ONLY tested this in LANDSCAPE mode all other modes WILL NOT work.
// This is modified for the Mega.
// I used the SPFD5408 libs from github
// But the Y is reversed, fo I changed the code. It ONLY works in landscape (right now)
// with the SD card slot on the right.
// I need to change the cpp file from the TS lib to remove the inversion of the Y ax
// Basically I add or take away 200 +/- BOXSIZE to invert the Y display
// Just a quick fix for now.

// Get the libs from here: https://github.com/JoaoLopesF/SPFD5408

//#include <Adafruit_GFX.h> // Core graphics library
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
//#include <TouchScreen.h>

#include <SPFD5408_Adafruit_GFX.h> // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h> // Touch library

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define SD_CS 10

#define YP A2 // must be an analog pin, use “An” notation!
#define XM A3 // must be an analog pin, use “An” notation!
#define YM 8 // can be a digital pin
#define XP 9 // can be a digital pin

#define CALIB 1 // Set to one to get x y readings

#define TS_MINX 230 // Use the println to find out these min/max numbers
#define TS_MINY 140
#define TS_MAXX 940
#define TS_MAXY 810

// 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 320 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 320);

// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ORANGE 0xFFA5

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define BOXSIZE 40
#define PENRADIUS 2
int oldcolor, currentcolor;

void setup(void) {
Serial.begin(9600);
Serial.println(F(“Working_Paint.”));

tft.reset();

uint16_t identifier = tft.readID(); // does NOT read the correct chip So force it.
identifier = 0x9341; // This card uses the ILI9341

Serial.print(F(“LCD driver chip: “));
Serial.println(identifier, HEX);
tft.begin(identifier);

tft.setRotation(1); // landscape 320*240 , mode 2 = 240*320

// Border

drawBorder();

// Initial screen

tft.setCursor (55, 50);
tft.setTextSize (3);
tft.setTextColor(RED);
tft.println(“SPFD5408”);
tft.setCursor (65, 85);
tft.println(“Library”);
tft.setCursor (55, 150);
tft.setTextSize (2);
tft.setTextColor(BLACK);
tft.println(“TFT Paint”);

tft.setCursor (65, 200);
tft.setTextSize (1);
tft.setTextColor(BLACK);
tft.println(“Touch to proceed”);

// Wait touch

waitOneTouch();

tft.fillScreen(BLACK);

tft.fillRect(0, 200, BOXSIZE, BOXSIZE, RED);
tft.fillRect(BOXSIZE, 200, BOXSIZE, BOXSIZE, YELLOW);
tft.fillRect(BOXSIZE * 2, 200, BOXSIZE, BOXSIZE, GREEN);
tft.fillRect(BOXSIZE * 3, 200, BOXSIZE, BOXSIZE, CYAN);
tft.fillRect(BOXSIZE * 4, 200, BOXSIZE, BOXSIZE, BLUE);
tft.fillRect(BOXSIZE * 5, 200, BOXSIZE, BOXSIZE, MAGENTA);
tft.fillRect(BOXSIZE * 6, 200, BOXSIZE, BOXSIZE, WHITE);
tft.fillRect(BOXSIZE * 7, 200, BOXSIZE, BOXSIZE, ORANGE);

tft.drawRect(0, 200, BOXSIZE, BOXSIZE, WHITE);
currentcolor = RED;

pinMode(13, OUTPUT);
}

#define MINPRESSURE 100
#define MAXPRESSURE 1000

void loop()
{
digitalWrite(13, HIGH);
// Recently Point was renamed TSPoint in the TouchScreen library
// If you are using an older version of the library, use the
// commented definition instead.
// Point p = ts.getPoint();
TSPoint p = ts.getPoint();

p.y = 1023 – p.y;

digitalWrite(13, LOW);

// if sharing pins, you’ll need to fix the directions of the touchscreen pins

pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);

// we have some minimum pressure we consider ‘valid’
// pressure of 0 means no pressing!

if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

// To calibrate the display by changing the MINX/Y and MAXY/X
if ( CALIB == 1 ) {
Serial.print(“X = “); Serial.print(p.x);
Serial.print(“\tY = “); Serial.print(p.y);
Serial.print(“\n”);
}

if (p.y > (TS_MAXY)) {
Serial.println(“erase”);
// press the bottom of the screen to erase
tft.fillRect(0, 0, tft.width(), tft.height() – BOXSIZE, BLACK);
}

if ( CALIB == 1 ) {
Serial.print(“Yin = “); Serial.print(p.y);
Serial.print(“\t”);
}

// scale from 0->1023 to tft.width

p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());;

if ( CALIB == 1 ) {
Serial.print(“Yout = “); Serial.print(p.y);
Serial.print(“\n”);
}

if (p.y > BOXSIZE + 200) {
oldcolor = currentcolor;

if (p.x < BOXSIZE) {
currentcolor = RED;
tft.drawRect(0, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 2) {
currentcolor = YELLOW;
tft.drawRect(BOXSIZE, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 3) {
currentcolor = GREEN;
tft.drawRect(BOXSIZE * 2, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 4) {
currentcolor = CYAN;
tft.drawRect(BOXSIZE * 3, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 5) {
currentcolor = BLUE;
tft.drawRect(BOXSIZE * 4, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 6) {
currentcolor = MAGENTA;
tft.drawRect(BOXSIZE * 5, 200, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 7) {
currentcolor = WHITE;
tft.drawRect(BOXSIZE * 6, 200, BOXSIZE, BOXSIZE, BLUE);
} else if (p.x < BOXSIZE * 8) {
currentcolor = ORANGE;
tft.drawRect(BOXSIZE * 7, 200, BOXSIZE, BOXSIZE, WHITE);
}

if (oldcolor != currentcolor) {
if (oldcolor == RED) tft.fillRect(0, 200, BOXSIZE, BOXSIZE, RED);
if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 200, BOXSIZE, BOXSIZE, YELLOW);
if (oldcolor == GREEN) tft.fillRect(BOXSIZE * 2, 200, BOXSIZE, BOXSIZE, GREEN);
if (oldcolor == CYAN) tft.fillRect(BOXSIZE * 3, 200, BOXSIZE, BOXSIZE, CYAN);
if (oldcolor == BLUE) tft.fillRect(BOXSIZE * 4, 200, BOXSIZE, BOXSIZE, BLUE);
if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE * 5, 200, BOXSIZE, BOXSIZE, MAGENTA);
if (oldcolor == WHITE) tft.fillRect(BOXSIZE * 6, 200, BOXSIZE, BOXSIZE, WHITE);
if (oldcolor == ORANGE) tft.fillRect(BOXSIZE * 7, 200, BOXSIZE, BOXSIZE, ORANGE);
}
}
if (((p.y + PENRADIUS) < (tft.height()- BOXSIZE)) && ((p.y – PENRADIUS) < tft.height())) {
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
}
}
}

// Wait one touch

TSPoint waitOneTouch() {

// wait 1 touch to exit function

TSPoint p;

do {
p= ts.getPoint();

pinMode(XM, OUTPUT); //Pins configures again for TFT control
pinMode(YP, OUTPUT);

} while((p.z < MINPRESSURE )|| (p.z > MAXPRESSURE));

return p;
}
void drawBorder () {

// Draw a border

uint16_t width = tft.width() – 1;
uint16_t height = tft.height() – 1;
uint8_t border = 10;

tft.fillScreen(RED);
tft.fillRect(border, border, (width – border * 2), (height – border * 2), WHITE);

}

 

Enjoy…

9 Comments

  1. Hello,

    my name is Danilo and i’m working on a project with 4 rfid readers and a Pixor uno 2.8 tft touch screen, controlled by arduino Mega 2560.
    First of all, I want to THANK YOU for your code, I’ve spent many days looking around to get my screen working.
    Now your are the only one who can help me.. did you ever try to get an image from sd card? I’m on this problem for other days and I don’t really know what to try more..
    Always the same error, when I try SD.begin(53) command it fails.

    Hope to hear from you and many thanks again for your previous support.

    Danilo

  2. Hi
    I am using the same PIxnor 2.8 LCD bought at Amazon from Thinkcreator.
    Funny my touch input works well on my MEGA only if remove the line
    p.y = 1023 – p.y;
    Otherwise I have inverted movement on one axis.
    What I cannot make work in any way is the SD card reader.
    It’s not about picture format, cannot even recognize there is a card there.
    On MEGA, using the shield provided directly attached to the board, theory says that should use sofware SPI and SD.begin(10), while keeping 53 as OUTPUT.
    I tried both software SPI and standard hardware SPI (connecting the shield via cables)but no luck.

    • Not sure about the display sd card access on the mega, but on another RTC/SD card I had to run jumpers from the Uno SCL/SDA over to the other SCL/SDA Mega contacts.

    • Hello Antonio, hello Jon
      I did finally succeed to get the sd card work!!
      I had to go to the SD library and make a little change.

      – Download and import the SD library by Adafruit (https://github.com/adafruit/SD);
      – Go to the library folder (eg: “C:User*Your name*DocumentsArduinolibrariesSD-master”)
      – Open “utility” folder and then both files: ‘Sd2Card.cpp’ and ‘Sd2Card.h’
      – Now the main point: COMMENT the line “#define USE_SPI _LIB” in BOTH files and change from “#define MEGA_SOFT_SPI 0” to “#define MEGA_SOFT_SPI 1”.

      Those let you to use the software SPI.

      Now it’s my turn… 🙂

      PROBLEM:
      it takes something like 5/6 seconds to display an image…. line by line… it’s the slowest display ever :D; it happens because the software spi I guess.
      Is it not possible to make it work by using hardware SPI for both LCD and SD card reader??
      I think I can improve the speed somehow even by software, but I don’t know how… do you have any idea? I red somewhere something like “Make parallel connection to the LCD instead of serial (if possible on LCD)”; do you think this could be my/our case?

      Hope to hear from you soon and I’m happy to share my situation with someone who is experiencing something similar too 😀

      Danilo

      • Dear Danilo
        It is indeed quite slow. I have been thinkering under the hood of the libraries from Adafruit and did understand a bit about what is going on there.
        All this because I would like touch screen to work also with an Arduino Due, but so far all I gor are a bunch of errors while compiling.
        I guess the libraries are a bit dated and are not up to speed with the latest developments of the development environment.
        My idea would be to modify the driver so that it will be optimized only for this screen and Arduino Mega and Due.
        It is interesting to look at the pinmagic.h file, basicaly it is a layer that will “translate” the pin mapping for the different platforms.
        Lot of bit shifting going on there… and I am quite sure that to do it directly could save some time, at the price of loss of compatibility with different shields.
        Please remember that 320x240x16 bit is equal to 150 Kbytes and it’s a lot of data to process in the small memory of these board.
        I will try the SD card later and let you know about results.

        Ciao!

  3. Sorry I have not contributed to this thread but as you can see I have been working on other things. The SPI Lib takes parallel data (your picture) converts it to serial data, sends it over to the SPI display card that then converts it back to parallel data to the display chip. All taking a lot of time. The real way to go is straight parallel from the card to the display. IMO
    Jon

Leave a Reply

Your email address will not be published.


*