Help! Make 2.8 tft touch shield for uno working on MEGA Problem

I bought 2.8 tft touch shield for uno
link : http://www.waveshare.com/2.8inch-TFT-Touch-Shield.htm
datasheet : http://www.waveshare.com/wiki/2.8inch_TFT_Touch_Shield#Datasheets

It perfectly works on UNO but i want to use this shield on arduino MEGA.
I should change pin connection and fix header.
I'm trying to fix header but i need help and support.

what should i fix

#if  defined(__AVR_ATmega32U4__)

#define __LCD_CS_OUT()    DDRB |= 0x40
#define __LCD_CS_CLR()    PORTB &=~ 0x40
#define __LCD_CS_SET()    PORTB |=  0x40

#define __LCD_DC_OUT()    DDRE |= 0x40
#define __LCD_DC_CLR()    PORTE &=~ 0x40
#define __LCD_DC_SET()    PORTE |=  0x40

#define __LCD_BKL_OUT()   DDRB |= 0x20
#define __LCD_BKL_OFF()   PORTB &=~ 0x20
#define __LCD_BKL_ON()    PORTB |=  0x20

#define __XPT2046_CS_DISABLE()    DDRD |= 0x10; PORTD |=  0x10

#else

#define __LCD_CS_OUT()    DDRB |= 0x04
#define __LCD_CS_CLR()    PORTB &=~ 0x04
#define __LCD_CS_SET()    PORTB |=  0x04

#define __LCD_DC_OUT()    DDRD |= 0x80
#define __LCD_DC_CLR()    PORTD &=~ 0x80
#define __LCD_DC_SET()    PORTD |=  0x80

#define __LCD_BKL_OUT()   DDRB |= 0x02
#define __LCD_BKL_OFF()   PORTB &=~ 0x02
#define __LCD_BKL_ON()    PORTB |=  0x02

#define __XPT2046_CS_DISABLE()    DDRD |= 0x10; PORTD |=  0x10

#endif

#define __LCD_WRITE_BYTE(__DATA)       SPI.transfer(__DATA)

And i have a question. what is the differences between D13D12D11 and ICSP1 pins

The Waveshare shield will work with the Mega.
You make the solder-bridges if you want to use a NUCLEO or FRDM.

The supplied “library” is a bit of a joke.
If you want to run on the Mega with “Adafruit-style” GFX methods, I can email you a library.

If you just want to use the supplied “library”

...

#if 0       // turn this on for bog-standard Arduino methods.
#define __LCD_CS_OUT()    pinMode(10, OUTPUT)
#define __LCD_CS_CLR()    digitalWrite(10, LOW)
#define __LCD_CS_SET()    digitalWrite(10, HIGH)
#define __LCD_DC_OUT()    pinMode(7, OUTPUT)
#define __LCD_DC_CLR()    digitalWrite(7, LOW)
#define __LCD_DC_SET()    digitalWrite(7, HIGH)
#define __LCD_BKL_OUT()    pinMode(9, OUTPUT)
#define __LCD_BKL_OFF()    digitalWrite(9, LOW)
#define __LCD_BKL_ON()    digitalWrite(9, HIGH)
#define __XPT2046_CS_DISABLE()   { pinMode(4, OUTPUT); digitalWrite(4, HIGH); }
#else
#if 0
#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_8BIT_SHIELD)
#define __LCD_CS_DDR      DDRB
#define __LCD_CS_PORT     PORTB
#define __LCD_CS_PIN      0
#define __LCD_DC_DDR      DDRA
#define __LCD_DC_PORT     PORTA
#define __LCD_DC_PIN      7
#define __LCD_BKL_DDR     DDRA
#define __LCD_BKL_PORT    PORTA
#define __LCD_BKL_PIN     1
#define __LCD_XPT_DDR     DDRA
#define __LCD_XPT_PORT    PORTA
#define __LCD_XPT_PIN     4
#elif defined(__AVR_ATmega2560__)
#define __LCD_CS_DDR      DDRB
#define __LCD_CS_PORT     PORTB
#define __LCD_CS_PIN      4
#define __LCD_DC_DDR      DDRH
#define __LCD_DC_PORT     PORTH
#define __LCD_DC_PIN      4
#define __LCD_BKL_DDR     DDRH
#define __LCD_BKL_PORT    PORTH
#define __LCD_BKL_PIN     6
#define __LCD_XPT_DDR     DDRG
#define __LCD_XPT_PORT    PORTG
#define __LCD_XPT_PIN     5
#elif defined(__AVR_ATmega32U4__)
#define __LCD_CS_DDR      DDRB
#define __LCD_CS_PORT     PORTB
#define __LCD_CS_PIN      6
#define __LCD_DC_DDR      DDRE
#define __LCD_DC_PORT     PORTE
#define __LCD_DC_PIN      6
#define __LCD_BKL_DDR     DDRB
#define __LCD_BKL_PORT    PORTB
#define __LCD_BKL_PIN     5
#define __LCD_XPT_DDR     DDRD
#define __LCD_XPT_PORT    PORTD
#define __LCD_XPT_PIN     4
#elif defined(__AVR_ATmega328P__)
#define __LCD_CS_DDR      DDRB
#define __LCD_CS_PORT     PORTB
#define __LCD_CS_PIN      2
#define __LCD_DC_DDR      DDRD
#define __LCD_DC_PORT     PORTD
#define __LCD_DC_PIN      7
#define __LCD_BKL_DDR     DDRB
#define __LCD_BKL_PORT    PORTB
#define __LCD_BKL_PIN     1
#define __LCD_XPT_DDR     DDRD
#define __LCD_XPT_PORT    PORTD
#define __LCD_XPT_PIN     4
#else
#error
#endif

#define __LCD_CS_OUT()    __LCD_CS_DDR |= (1<<__LCD_CS_PIN)
#define __LCD_CS_CLR()    __LCD_CS_PORT &=~ (1<<__LCD_CS_PIN)
#define __LCD_CS_SET()    __LCD_CS_PORT |=  (1<<__LCD_CS_PIN)

#define __LCD_DC_OUT()    __LCD_DC_DDR |= (1<<__LCD_DC_PIN)
#define __LCD_DC_CLR()    __LCD_DC_PORT &=~ (1<<__LCD_DC_PIN)
#define __LCD_DC_SET()    __LCD_DC_PORT |=  (1<<__LCD_DC_PIN)

#define __LCD_BKL_OUT()   __LCD_BKL_DDR |= (1<<__LCD_BKL_PIN)
#define __LCD_BKL_OFF()   __LCD_BKL_PORT &=~ (1<<__LCD_BKL_PIN)
#define __LCD_BKL_ON()    __LCD_BKL_PORT |=  (1<<__LCD_BKL_PIN)

#define __XPT2046_CS_DISABLE()   { __LCD_XPT_DDR |= (1<<__LCD_XPT_PIN); __LCD_XPT_PORT |=  (1<<__LCD_XPT_PIN); }
#endif

#define __LCD_WRITE_BYTE(__DATA)       SPI.transfer(__DATA)

...

It would seem a lot easier if you just make a regular <HX8347D.h> library

David.

thanks it works perfectly!

touch doesn't work

#ifndef __XPT2046_H
#define __XPT2046_H

#include <Arduino.h>
#include <avr/pgmspace.h>
#include <SPI.h>


#define BIT(__N)  (uint8_t)(1 << (__N))


#if  defined(__AVR_ATmega32U4__)

#define __XPT2046_CS_OUT()      DDRD |= BIT(4)
#define __XPT2046_CS_SET()      PORTD |=  BIT(4)
#define __XPT2046_CS_CLR()      PORTD &=~ BIT(4)

#define __XPT2046_IRQ_IN()      DDRD &=~ BIT(0);PORTD |=  BIT(0)
#define __XPT2046_IRQ_READ()    (PIND & BIT(0))

#define __XPT2046_WRITE_BYTE(__DATA)       SPI.transfer(__DATA)
          
#define __SD_CS_DISABLE()       DDRD |= BIT(6); PORTD |=  BIT(6)

#else

#define __XPT2046_CS_OUT()      DDRD |= BIT(4)
#define __XPT2046_CS_SET()      PORTD |=  BIT(4)
#define __XPT2046_CS_CLR()      PORTD &=~ BIT(4)

#define __XPT2046_IRQ_IN()      DDRD &=~ BIT(3);PORTD |=  BIT(3)
#define __XPT2046_IRQ_READ()    (PIND & BIT(3))

#define __XPT2046_WRITE_BYTE(__DATA)       SPI.transfer(__DATA)
          
#define __SD_CS_DISABLE()       DDRD |= BIT(5); PORTD |=  BIT(5)

#endif

this is entry of XPT2046.h

#ifndef __TOUCH_H_
#define __TOUCH_H_

#include <Arduino.h>
#include <avr/pgmspace.h>


#define TP_PRESS_DOWN           0x80
#define TP_PRESSED              0x40

and this is Touch.h

Hi everybody!

I have the same problem as in this thread.

@david_prentice could you post the "Adafruit-style" libraries you were talking about ? or just the corrected and working touch libraries ?

Is the sd card module works ?

You can see the regular Waveshare examples adapted for a public Arduino library called <HX8347.h> from GitHub Waveshare_HX8347D
The Waveshare examples “work” but the methods are unconventional.

Most Arduino Graphics programs use Adafruit_GFX methods.
I have attached a ZIP file of a library that uses Adafruit_GFX methods.

Note that your Shield can NOT read its ID. Nor can it read GRAM memory.

David.

HX8347D_kbv.zip (18.8 KB)

Everything works as it should. Since the last time I was working on this set. But I miss one functionality. Can we create a function in the example "TouchPanel" which after calling by tact switch save the currently drawn image as a bitmap 320x240 on an SD card?
I tried to dismantle decompressing (reading) bitmaps in example "HX8347D_BMP" and reverse the action, but I lack the skills. @david_prentice , what do you think? whether it's a good way?

Yes, it is fairly straightforward. Just create a BMP file on your SD. Read the screen memory (in small chunks) with readGRAM() and store it in the BMP file.

If you choose the correct BMP format, you can store the 16-bit Pixels directly. Most AVR BMP renderers expect 24-bit colour. So you would just convert 16-bit to 24-bit.

Note that a Uno is pretty short of SRAM when you want to have SD and pixel buffers.

David.

Ok, so I tried to adjust to your guidance. I found a similar topic

and I modified it to HX8347D_kbv.h libraries, I think the problem is with readPixel because I get the black bitmaps. When i hardcoded i.e red color, bitmap is red.

PS:I uncoment the readGRAM implementation before.

What I’m doing wrong ?

#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_GFX.h>
#include <HX8347D_kbv.h>
#include <Stream.h>
#include <stdint.h>


const byte SD_CS = 5;

const int w = 240;     // image width in pixels
const int h = 320;     // height

char str[] = "kielok_piyk64ny.bmp";

const unsigned int GREY = 0xDF1C;
const unsigned int LTRED = 0xFE79;
const unsigned int DKGREEN = 0x1BE0;
uint16_t g_identifier;

SdFat SD;
File outFile;

HX8347D_kbv tft;

void setup()
{
 Serial.begin(9600);
    uint32_t when = millis();
    //    while (!Serial) ;   //hangs a Leonardo until you connect a Serial
    if (!Serial) delay(1);           //allow some time for Leonardo
    Serial.println("Serial took " + String((millis() - when)) + "ms to start");
    static uint16_t identifier;
    //    tft.reset();                 //we can't read ID on 9341 until begin()
    g_identifier = tft.readID(); //
    Serial.print("ID = 0x");
    Serial.println(g_identifier, HEX);
    //if (g_identifier == 0x00D3 || g_identifier == 0xD3D3) g_identifier = 0x9481; // write-only shield
    //if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial
//    g_identifier = 0x9329;                             // force ID
    tft.begin(g_identifier);

  
 /* uint16_t ID;
  ID = tft.readID();
  tft.begin(ID);*/

  // print some objects on TFT to be captured in BMP
  tft.setRotation(3);
  tft.setTextSize(3);
 

  tft.fillRect(150, 150, 30, 30, GREY);
  tft.fillRect(30, 150, 30, 30, LTRED);
  tft.fillRect(150, 30, 30, 30, DKGREEN);
 
  tft.setCursor(50, 50);
  tft.print("hello world");
  // end test print to TFT
 
  //Serial.begin(115200);
  //Serial.println("starting");
 
  //init SD Card
  if (!SD.begin(SD_CS))
  {
    Serial.println("err strtng SD");
    while (1);    //If failed, stop here
  }

  Serial.println("working");
  GrabImage(str);
  Serial.println("done");
 
  tft.setCursor(100, 100);
  tft.print("Done");
}

void GrabImage(char* str)
{
  byte VH, VL;
  int i, j = 0;

  //Create the File
  outFile = SD.open(str, FILE_WRITE);
  if (! outFile) {
    Serial.println("err opng file");
    return;
  };

  unsigned char bmFlHdr[14] = {
    'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0
  };
  // 54 = std total "old" Windows BMP file header size = 14 + 40
 
  unsigned char bmInHdr[40] = {
    40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0
  };   
  // 40 = info header size
  //  1 = num of color planes
  // 16 = bits per pixel
  // all other header info = 0, including RI_RGB (no compr), DPI resolution

  unsigned long fileSize = 2ul * h * w + 54; // pix data + 54 byte hdr
 
  bmFlHdr[ 2] = (unsigned char)(fileSize      ); // all ints stored little-endian
  bmFlHdr[ 3] = (unsigned char)(fileSize >>  8); // i.e., LSB first
  bmFlHdr[ 4] = (unsigned char)(fileSize >> 16);
  bmFlHdr[ 5] = (unsigned char)(fileSize >> 24);

  bmInHdr[ 4] = (unsigned char)(       w      );
  bmInHdr[ 5] = (unsigned char)(       w >>  8);
  bmInHdr[ 6] = (unsigned char)(       w >> 16);
  bmInHdr[ 7] = (unsigned char)(       w >> 24);
  bmInHdr[ 8] = (unsigned char)(       h      );
  bmInHdr[ 9] = (unsigned char)(       h >>  8);
  bmInHdr[10] = (unsigned char)(       h >> 16);
  bmInHdr[11] = (unsigned char)(       h >> 24);

  outFile.write(bmFlHdr, sizeof(bmFlHdr));
  outFile.write(bmInHdr, sizeof(bmInHdr));

  for (i = h; i > 0; i--) {
    for (j = 0; j < w; j++) {

    uint16_t rgb = tft.readPixel(j,i); // get pix color in rgb565 format
     
 
 /*
 
      //Test color, Red in RGB888   
  // it works
 byte r = 255;
 byte g = 0;
 byte b = 0;
 //Convert RGB888 to RGB565
 unsigned short rgb =  ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3))) ;
 
     */
 
 
      VH = (rgb & 0xFF00) >> 8; // High Byte
      VL = rgb & 0x00FF;        // Low Byte
     
      //RGB565 to RGB555 conversion... 555 is default for uncompressed BMP
      //this conversion is from ...topic=177361.0 and has not been verified
      VL = (VH << 7) | ((VL & 0xC0) >> 1) | (VL & 0x1f);
      VH = VH >> 1;
     
      //Write image data to file, low byte first
      outFile.write(VL);
      outFile.write(VH);
    }
  }
  //Close the file
  outFile.close();
}

void loop()
{

}

My apologies. I reply to multiple threads. Mostly regarding MCUFRIEND_kbv library.

This thread is about Waveshare HX8347D shields. These are NOT readable. MISO is not connected to the TFT. Anyway, the Himax HX8347-D is not readable via SPI. (from memory, the HX8347-G, HX8347-I are readable by SPI)

The HX8347_kbv class has readPixel() and readGRAM() methods but they are not functional. As can be seen from my standard graphictest_kbv.ino sketch.

David.

Ok, Thanks for your help anyway.
So there is no other option to take a snapshot for this hardware?

No. Your Waveshare is not readable.

The ILI9341 SPI modules are readable. Some of them come with XPT2046 Touch Controllers.

However, the cheap Ebay modules are 3.3V and do not come in a Shield.

David.

i have 2.8 inch tft touch module with HX8347D lcd controller ie waveshare. How can i make touch option with this shield and to store the values from touch option to sd card on this shield.If this is not possible with this shield please refer a touch shield suitable for this store of values in sd card with touch values.

I presume you are using waveshare 2.8inch-TFT-Touch-Shield

There is a GFX style library on GitHub HX8347D_kbv
And a modified Waveshare style library on GitHub Waveshare_HX8347D_kbv

This shield contains a regular XPT2046 controller. There are several XPT2046 libraries e.g. XPT2046_Touchscreen.h

I suggest that you sit down and design your sketch on paper.

Then write the code and test it.
If you have a problem, you can post your code with design notes. Readers can only help you if they know what you want to do.

David.

Hello everyone,

its a pretty old Thread, but i hope to still get some support.
I want to use my Sparkfun Micro Pro with the Waveshare 2.8" Touch TFT.

I included the Waveshare_HX8347D_kbv library to my IDE.

First i want to use the DisplayGraphic Sketch, but nothing except the Backlight works.

Here is my Pinning:

Micro Pro Waveshare TFT
14 MISO
15 SCLK
16 MOSI
10 LCD_CS
9 LCD_BL
7 LCD_DC
4 TP_CS

Here is my code:

#include <HX8347D.h>
#include <HX8347D_pins.h>
//#include <Touch.h>
//#include <XPT2046.h>

#include <stdint.h>
#include <SPI.h>

void setup()
{
    SPI.setDataMode(SPI_MODE3);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV4);
    SPI.begin();
    
    Tft.lcd_init();                                      // init TFT library
    
    Tft.lcd_draw_rect(30, 40, 150, 100, RED);
    Tft.lcd_draw_circle(120, 160, 50, BLUE);
    Tft.lcd_draw_line(30, 40, 180, 140, RED);
    
    Tft.lcd_draw_line(30, 220, 210, 240, RED);
    Tft.lcd_draw_line(30, 220, 120, 280, RED);
    Tft.lcd_draw_line(120, 280, 210, 240, RED);
}

void loop()
{
  
}

EDIT: Do i have do edit something in the HX8347D.h librabry?

#if 0      // turn this on for bog-standard Arduino methods.
#define __LCD_CS_OUT()    pinMode(10, OUTPUT)
#define __LCD_CS_CLR()    digitalWrite(10, LOW)
#define __LCD_CS_SET()    digitalWrite(10, HIGH)
#define __LCD_DC_OUT()    pinMode(7, OUTPUT)
#define __LCD_DC_CLR()    digitalWrite(7, LOW)
#define __LCD_DC_SET()    digitalWrite(7, HIGH)
#define __LCD_BKL_OUT()    pinMode(9, OUTPUT)
#define __LCD_BKL_OFF()    digitalWrite(9, LOW)
#define __LCD_BKL_ON()    digitalWrite(9, HIGH)
#define __XPT2046_CS_DISABLE()   { pinMode(4, OUTPUT); digitalWrite(4, HIGH); }
#else
#include "HX8347D_pins.h"
#endif

#define __LCD_WRITE_BYTE(__DATA)       SPI.transfer(__DATA)

Thats my first Arduino Project, and the Displays makes me crazy…
Hope to get some help here.

best regards Philipp

It looks as if your wiring is the regular Leonardo wiring.

Micro Pro Waveshare TFT
14 MISO
15 SCLK
16 MOSI
10 LCD_CS
9 LCD_BL
7 LCD_DC
4 TP_CS

The Micro Pro seems to be a Leonardo without proper Arduino headers.

It also looks as if my PC was using a "tidy up" Branch. I have merged this back into "master" Branch (just now).

I suggest that you delete your HX8347D_kbv directory and re-install "master" from GitHub.

David.

Exactly, its a Leonardo, just smaller, and not all uC Pins are used.

Ok, so you would recommend not to use the Waveshare librarie like you mentioned here,
but instead the GFX style library?

david_prentice:
There is a GFX style library on GitHub HX8347D_kbv
And a modified Waveshare style library on GitHub Waveshare_HX8347D_kbv

David.

I downloaded the "HX8347D_kbv" Master Branch from here: GitHub - prenticedavid/HX8347D_kbv: Regular Adafruit_GFX style library
and copied the librarie files into: C:\Users\xxx\Documents\Arduino\libraries\HX8347D_kbv-master

But the examples are not working, do i still have to define the Pins or something else?
Sorry for that maybe stupid questions, but i think the combination of Micro Pro and the Waveshare
Display was not the best decision for the first project...

God invented Shields. God invented males and females.

If you own a regular Uno, Mega, Leo, Nano-Every the library examples should work straight out of the box.
You do not touch anything.

I have just plugged the shield into a Leo clone. Run the HX8347D_kbv graphictest_kbv example. Works fine.

I suggest that you try a regular Arduino first.
Report any problems.

Then try with your Micro Pro.

David.

david_prentice:
God invented Shields. God invented males and females.

I know that, but for my project i needed a much smaller uC than an Uno/Leonardo.
I've connected everything with jumper wires.

At the moment i only have that Micro Pro, thats my first Arduino project ever...,
so no other hardware available.
But i ordered this morning a UNO from AzDelivery, it will arrive probably tomorrow
evening, i will test everything with this first.

Thank you for your support!
I will leave a comment when my UNO arrived and i've tested everything.