TFT from Buydisplay with ILI9488 and FT6236 controllers -Wiring

Status
Not open for further replies.

Ripper

Well-known member
Hi guys.
A friend of mine (his english sucks) just received this fellow: http://www.buydisplay.com/default/l...lay-module-optl-touch-screen-w-breakout-board
His version is with:
-40 Pin interface
-4 Wire SPI
-Touchscreen with FT6236 controller
-Flashcard
-Fontchip ER3301
-Windbond IC chip flash 128M BIT
-VDD 5V

He wants to connect it to a Teensy 3.6 or Arduino Mega 2560, but he (and me neither) is not being able to find all the pins in the pdf they have in the product page.
For instance, what is the name for the LED pin?
Better, does anyone have a pin diagram to connect this?
I have never worked with a TFT so I am not keen on the nomenclature and abreviations. I'm also concerned if there is a need for resistors or caps in any wire, as I don't want to burn anything.
Thanks for you help.

Edit: Solved using these files:
https://github.com/prenticedavid/ILI9488/tree/david_9488

Thank you David Prentice
 
Last edited:
According to pages 11-12 of the datasheet, pins 1, 2 and 40 are the power. Those are the most important. Any mistake on those pins is likely to destroy the display, so make sure you get them right.

Before you power this thing up, try to verify it's really configured for 5V power input. The table on page 13 mentions "JP". Try to find that on the board and check it. There's almost certainly a 5 to 3.3V regulator somewhere on the board which converts your 5V power to 3.3V. None of these modern displays actually runs on 5V. When configured for 3.3V, that "JP" option probably sorts the power input of pin 2 past the regulator and lets it directly power the display electronics. Make sure that is not in place, so the 5V input gets converted to 3.3V.

This product is *NOT* 5V tolerant, according to page 14 which should I/O signal voltage maximum is 3.6V. So DO NOT connect it to Arduino Mega directly. Mega's 5 volt signals could kill the display.

Teensy 3.6 has 3.3V signals, so it should be safe to connect.

Since it's configured for 4 wire SPI, the main signals are on pins 23, 24, 25, 27, 28. Pin 29 looks like it controls the LEDs, pretty much the same as the "LED" pin documented here:

https://www.pjrc.com/store/display_ili9341.html

Whether that library for ILI9341 works with ILI9488 is a good question. I do not know. I haven't used this ILI9488 display. Everything I've written in this message is basically just guesswork from general knowledge of these sorts of displays, but not actual experience with the one you have. Hopefully it helps anyway?
 
A Big Thank You Paul.

Your post covers most of my doubts and worries. I think i can start from there.

Once again, Thank You. It's an honour to have an answer from you personally. :cool:
 
The TFT part is working fine.
Now, the next step is the touchscreen part. How can i incorporate the Ft6236 library with the ILI9488 library?
Can i just get one sketch with tft and touch and simply change the library names and eventualy pin names? For testing purposes of course, the actual project will need some more trial and error.
 
The Ili9488 library I'm using is this: https://github.com/jaretburkett/ILI9488

The FT6236 that I found and willing to use is this: https://github.com/renaudcalmont/FT6236_t3

I couldn't find a link for a sketch with these 2 libraries being used simultaneously. I'm I being a guinea pig?

I'm starting with this Arduino/Teensy thing and all I have done is my midi joystick micro-project, so I really need a bunch of help to be able to help my almost-zero-english-speaking friend.
Thanks for any help you can give me.
Best regards
Joao
 
I couldn't find a link for a sketch with these 2 libraries being used simultaneously. I'm I being a guinea pig?

It's law of probabilities. The ILI9488 is not a common controller which narrows the field of software in the public domain. Couple that with a capacitive touch screen and it is an odd pairing since the 9488 is a low cost controller and is usually found with resistive touch (cost driven). But, I don't think the risk is very high because the LCD is SPI and the touch I2C. Two different interfaces, no multiplexing of Teensy pins. That's a good thing.

Once you've confirmed all the links are set correctly (page 13 of the datasheet), I would power up the LCD and see if you have +3.3 volts between SDA/GND and SCL/GND pins. If you have voltage present, you know there are I2C pullup resistors on the LCD board and you do not need to add them to the system. If you see no voltage, you'll need to add 4.7k resistors between VCC (+3.3!) and the SDA/SCL lines. This is due to the I2C being an open drain system to allow multiple devices on the same bus, with no pullups, there is no voltage.

Keep the I2C and the SPI wires as short as possible, the shorter, the better. Develop the LCD first, then add the touch. If you have any difficulties with the touch portion, use an I2C bus scanner (Google it) to identify the address of the controller and then edit the library code to the proper address since that appears to be hard coded in the cpp file rather than defined at run time. Once the scanner can find an address, the rest of I2C is usually pretty straight forward.
 
Last edited:
Solved by David Prentice's work together with Paul's and aFewBits help.

Thank you all.

@Ripper do you mind sharing how you got the FT touch screen to work? The library you linked to has no examples
I just ordered a few units and would love to get the capacitive touch working.
 
Again an FYI - we have the ILI9488_t3 library which I have run on their display. Thought about trying it again, if it was same wiring as RA8875/RA8876 displays that I have a board that I could use,

They both use 40 pin connectors, but wiring is very different...

As for touch screen library, the one I was looking at was by Adafruit: https://github.com/adafruit/Adafruit_FT6206_Library

Which the Readme says:
This is a library for the Adafruit FT6206-Based capacitive touch screens and displays:

https://www.adafruit.com/products/1947
https://www.adafruit.com/product/1651

Also supports FT6236 chips (and maybe other compatible chips!)

And if you look at our ILI9488_t3 library you will see an example sketch:
https://github.com/mjs513/ILI9488_t3/blob/master/examples/CapTouchPaint/CapTouchPaint.ino

That uses this library.... Which I added back in October I think...
 
Again an FYI - we have the ILI9488_t3 library which I have run on their display. Thought about trying it again, if it was same wiring as RA8875/RA8876 displays that I have a board that I could use,

They both use 40 pin connectors, but wiring is very different...

As for touch screen library, the one I was looking at was by Adafruit: https://github.com/adafruit/Adafruit_FT6206_Library

Which the Readme says:


And if you look at our ILI9488_t3 library you will see an example sketch:
https://github.com/mjs513/ILI9488_t3/blob/master/examples/CapTouchPaint/CapTouchPaint.ino

That uses this library.... Which I added back in October I think...

Awesome stuff - thanks for bringing the Adafruit library to my attention.
I ordered the 3.5" bare display with 50 pin FPC. I have some breakout boards to access all the pins easily and will wire up on the breadboard. I'll follow the technical document to hopefully get it to power up and work.
 
Hi Rezo,
Sorry for not having answered in due time but i'm having issues in my life and my brain is not working as i would like it to.
I suppose KurtE's help will lead you to the right direction. I can't be very helpfull as since that time i had a disk drive broken that made me re-do all the project. I do have part of my project in the forum that can be helpful. This is the code i have in the forum (you have to adapt it to your idea - this is for a midi controller and is only part of the experiments i was doing with Oddson's help -, but the TFT/Touch part is working and easy to understand i suppose).
Code:
[COLOR=#333333]// include the ResponsiveAnalogRead library for analog smoothing[/COLOR][COLOR=#333333]#include <ResponsiveAnalogRead.h>
#include <Bounce.h>  // Bounce library makes button change detection easy
// ******CONSTANT VALUES******** - customize code behaviour here!


// SET THESE SIX VALUES FOR JOYSTICK!
const int pitchPin = 0; // PIN numbers ** MUST CHANGE!
const int modPin = 1;
const int modPin2 = 1;
const int pitchMaxRaw = 1019; // Max reading with full bend up... as raw 10-bit value
const int modMaxRaw = 1019; // Max reading full mod down


// SET THESE VALUES FOR RIBBON
//const int ribbonPin = touch_pressed; // Max reading on right side... as raw 10-bit value
const int ribbonMaxRaw = 474; // Max reading on right side... as raw 10-bit value
//


int Button1 = 0; //This is the default "Button Off" and 1 is "Button On"
int Button2 = 0; //This is the default "Button Off" and 1 is "Button On"
int OldButton1 = 0; //Variable to store button1 old value
int OldButton2 = 0; //Variable to store button2 old value
byte data1On[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf7};
byte data1Off[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7};
byte data2On[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf7};
byte data2Off[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7};
byte progMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x02, 0xf7};
byte combiMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x00, 0xf7};
byte seqMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x04, 0xf7};
byte modeRequest[] = {0xf0, 0x42, 0x30, 0x75, 0x12, 0x00, 0xf7};


const int channel = 1; // MIDI channel
const int MIDIdelay = 5; // will update MIDI only if this many milliseconds have passed
//******VARIABLES***********
// data variables and a lagged copy to compare before updating MIDI value
int pitch;
int mod;
int mod2;
int pitchRaw;
int modRaw;
int modRaw2;
int pitchLag;
int modLag;
int modLag2;
int ribbon;
int ribbonRaw;
int ribbonLag;


elapsedMillis pitchUpdate;
elapsedMillis modUpdate;
elapsedMillis modUpdate2;
elapsedMillis ribbonUpdate;


// ititialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead readPitch = {pitchPin, true};
ResponsiveAnalogRead readMod = {modPin, true};
ResponsiveAnalogRead readMod2 = {modPin2, true};


#include <Adafruit_GFX.h>    // Core graphics library


#define LCD_ROTATION  1        //should work in all rotations
#define USE_READID    0        //Adafruit and ILI9488 can't read ID
//#include <MCUFRIEND_kbv.h>     // Hardware-specific library
//MCUFRIEND_kbv tft;
//#include <Adafruit_ILI9341.h>   // Hardware-specific library
//Adafruit_ILI9341 tft(10, 9, 8);
//#include <HX8347D_kbv.h>        // Hardware-specific library
//HX8347D_kbv tft;
#include <ILI9488.h>            // Hardware-specific library
ILI9488 tft(10, 9, 8);
//#include <ILI9488_kbv.h>            // Hardware-specific library
//ILI9488_kbv tft;


extern void Touch_initialise(int aspect, int wid, int ht);
extern bool Touch_getXY(void);
bool touch_pressed;
int pixel_x, pixel_y;
boolean SW1on = false;
boolean SW2on = false;
boolean Progon = false;
boolean Combion = false;
boolean Seqon = false;
boolean ribbonCtrl = false;


// Color definitions
#define TFT_BLACK       0x0000      /*   0,   0,   0 */
#define TFT_NAVY        0x000F      /*   0,   0, 128 */
#define TFT_DARKGREEN   0x03E0      /*   0, 128,   0 */
#define TFT_DARKCYAN    0x03EF      /*   0, 128, 128 */
#define TFT_MAROON      0x7800      /* 128,   0,   0 */
#define TFT_PURPLE      0x780F      /* 128,   0, 128 */
#define TFT_OLIVE       0x7BE0      /* 128, 128,   0 */
#define TFT_LIGHTGREY   0xC618      /* 192, 192, 192 */
#define TFT_DARKGREY    0x7BEF      /* 128, 128, 128 */
#define TFT_BLUE        0x001F      /*   0,   0, 255 */
#define TFT_GREEN       0x07E0      /*   0, 255,   0 */
#define TFT_CYAN        0x07FF      /*   0, 255, 255 */
#define TFT_RED         0xF800      /* 255,   0,   0 */
#define TFT_RED2        0xF88D      /* 254,  18, 106 */
#define TFT_MAGENTA     0xF81F      /* 255,   0, 255 */
#define TFT_YELLOW      0xFFE0      /* 255, 255,   0 */
#define TFT_WHITE       0xFFFF      /* 255, 255, 255 */
#define TFT_ORANGE      0xFD20      /* 255, 165,   0 */
#define TFT_ORANGE2     0xFB20      /* 254, 102,   1 */
#define TFT_GREENYELLOW 0xAFE5      /* 173, 255,  47 */
#define TFT_PINK        0xF81F


/******************* UI details */


#define PROGFRAME_X 20
#define PROGFRAME_Y 10
#define PROGFRAME_W 90
#define PROGFRAME_H 50


#define PROGBUTTON_X PROGFRAME_X
#define PROGBUTTON_Y PROGFRAME_Y
#define PROGBUTTON_W PROGFRAME_W
#define PROGBUTTON_H PROGFRAME_H


#define COMBIFRAME_X 200
#define COMBIFRAME_Y 10
#define COMBIFRAME_W 90
#define COMBIFRAME_H 50


#define COMBIBUTTON_X COMBIFRAME_X
#define COMBIBUTTON_Y COMBIFRAME_Y
#define COMBIBUTTON_W COMBIFRAME_W
#define COMBIBUTTON_H COMBIFRAME_H


#define SEQFRAME_X 370
#define SEQFRAME_Y 10
#define SEQFRAME_W 90
#define SEQFRAME_H 50


#define SEQBUTTON_X SEQFRAME_X
#define SEQBUTTON_Y SEQFRAME_Y
#define SEQBUTTON_W SEQFRAME_W
#define SEQBUTTON_H SEQFRAME_H


#define SW1FRAME_X 90
#define SW1FRAME_Y 110
#define SW1FRAME_W 130
#define SW1FRAME_H 70


#define SW1BUTTON_X SW1FRAME_X
#define SW1BUTTON_Y SW1FRAME_Y
#define SW1BUTTON_W SW1FRAME_W
#define SW1BUTTON_H SW1FRAME_H


#define SW2FRAME_X 310
#define SW2FRAME_Y 110
#define SW2FRAME_W 130
#define SW2FRAME_H 70


#define SW2BUTTON_X SW2FRAME_X
#define SW2BUTTON_Y SW2FRAME_Y
#define SW2BUTTON_W SW2FRAME_W
#define SW2BUTTON_H SW2FRAME_H


#define RIBBONFRAME_X 10
#define RIBBONFRAME_Y 240
#define RIBBONFRAME_W 470
#define RIBBONFRAME_H 70


#define RIBBON_X RIBBONFRAME_X
#define RIBBON_Y RIBBONFRAME_Y
#define RIBBON_W RIBBONFRAME_W
#define RIBBON_H RIBBONFRAME_H


void progBtn()
{ 
  tft.drawRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_WHITE);
  tft.fillRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_WHITE);
  tft.setCursor(40, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Prog");
  usbMIDI.sendSysEx(7, modeRequest, true); //The Sysex to change to Program Mode in Korg M3
  Progon = false;
}
void combiBtn()
{ 
  tft.drawRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_WHITE);
  tft.fillRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_WHITE);
  tft.setCursor(220, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Combi");
  usbMIDI.sendSysEx(7, combiMode, true); //The Sysex to change to Combi Mode in Korg M3
  Combion = false;
}
void seqBtn()
{ 
  tft.drawRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_WHITE);
  tft.fillRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_WHITE);
  tft.setCursor(400, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Seq");
  usbMIDI.sendSysEx(7, seqMode, true); //The Sysex to change to SEQ Mode in Korg M3
  Seqon = false;
}
void sw1Btn()
{ 
  tft.drawRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_DARKGREY);
  tft.fillRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_RED);
  tft.setCursor(160, 140);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  tft.println("SW1");
  SW1on = false;
}
void sw2Btn()
{ 
  tft.drawRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_DARKGREY);
  tft.fillRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_RED);
  tft.setCursor(340,140);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  tft.println("SW2");
  SW2on = false;
}
void rbCtrl()
{ 
  tft.drawRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
  tft.fillRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
  tft.setCursor(10,240);
    //remap to output data and send if changed and MIDIdelay has lapsed since last update for that parameter
    ribbon = map(pixel_x, 11, 474, 0, 127);
    ribbon = max(ribbon, 0); // need this now that the bottom isn't zero
    ribbon = min(ribbon, 127); // cap to avoid overflow
    if (abs(ribbon - ribbonLag) > 0 && ribbonUpdate > MIDIdelay ) {
      ribbonLag = ribbon;
    usbMIDI.sendControlChange(16, ribbon, channel);
      ribbonUpdate = 0;
    }
  ribbonCtrl = false;
}




void setup(void)
{
    Serial.begin(9600);
    Serial.println(F("TFT LCD test"));


    tft.begin();


    int aspect = LCD_ROTATION;   //PORTRAIT
    tft.setRotation(aspect);
    Touch_initialise(aspect, tft.width(), tft.height());  //.kbv external function
    tft.fillScreen(TFT_BLACK);
    


    // create 'SW1 Switch'
    tft.drawRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_DARKGREY);
    tft.fillRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_RED);
    tft.setCursor(155, 140);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("SW1");


    // create 'SW2 Switch'
    tft.drawRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_DARKGREY);
    tft.fillRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_RED);
    tft.setCursor(340, 140);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("SW2");


    // create 'PROG Switch'
    tft.drawRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_DARKGREY);
    tft.fillRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_BLUE);
    tft.setCursor(40, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Prog");    


    // create 'COMBI Switch'
    tft.drawRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_DARKGREY);
    tft.fillRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_RED);
    tft.setCursor(220, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Combi");
     
    // create 'SEQ Switch'
    tft.drawRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_DARKGREY);
    tft.fillRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_YELLOW);
    tft.setCursor(400, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Seq");     


    // create 'Ribbon Emulator field'
    tft.drawRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_DARKGREY);
    tft.fillRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
}


void loop(void)
{


  usbMIDI.read();
  if (usbMIDI.read() == 1 && usbMIDI.getType() == 7 ) {//check for sysex 
   const byte *pSysExArray = usbMIDI.getSysExArray(); //capture data
    Serial.println(*pSysExArray);
  }
    int x = -1, y = -1;   //regular pixel coordinates
    touch_pressed = Touch_getXY();  //external function
#if 0
    Serial.print("X="); Serial.print(pixel_x); 
    Serial.print(" Y="); Serial.print(pixel_y); 
    Serial.print(" Z="); Serial.print(touch_pressed); 
    Serial.println("");
#endif
    if (touch_pressed) {
        x = pixel_x;      //copy global variable
        y = pixel_y;
    }


    {
      if((x > PROGBUTTON_X) && (x < (PROGBUTTON_X + PROGBUTTON_W))) {
        if ((y > PROGBUTTON_Y) && (y <= (PROGBUTTON_Y + PROGBUTTON_H))) {
          Serial.println("PROG btn hit"); 
          delay(100); // UI debouncing
          progBtn();
        }
      }
    }
{
      if((x > COMBIBUTTON_X) && (x < (COMBIBUTTON_X + COMBIBUTTON_W))) {
        if ((y > COMBIBUTTON_Y) && (y <= (COMBIBUTTON_Y + COMBIBUTTON_H))) {
          Serial.println("Combi btn hit"); 
          delay(100); // UI debouncing
          combiBtn();
        }
      }
    }
{
      if((x > SEQBUTTON_X) && (x < (SEQBUTTON_X + SEQBUTTON_W))) {
        if ((y > SEQBUTTON_Y) && (y <= (SEQBUTTON_Y + SEQBUTTON_H))) {
          Serial.println("Seq btn hit"); 
          delay(100); // UI debouncing
          seqBtn();
        }
      }
    }
    
{
      if((x > SW1BUTTON_X) && (x < (SW1BUTTON_X + SW1BUTTON_W))) {
        if ((y > SW1BUTTON_Y) && (y <= (SW1BUTTON_Y + SW1BUTTON_H))) {
          Serial.println("SW1 btn hit"); 
          delay(100); // UI debouncing
          sw1Btn();
        }
      }
    }


{
      if((x > SW2BUTTON_X) && (x < (SW2BUTTON_X + SW2BUTTON_W))) {
        if ((y > SW2BUTTON_Y) && (y <= (SW2BUTTON_Y + SW2BUTTON_H))) {
          Serial.println("SW2 btn hit"); 
          delay(100); // UI debouncing
          sw2Btn();
        }
      }
    } 
{
      if((x > RIBBON_X) && (x < (RIBBON_X + RIBBON_W))) {
        if ((y > RIBBON_Y) && (y <= (RIBBON_Y + RIBBON_H))) {
          Serial.println("Ribbon pressed"); 
          Serial.println(pixel_x);
          Serial.println(ribbon);       
          delay(100); // UI debouncing
          rbCtrl();
        }
      }
    } 
    
  }

[/COLOR]
Kind regards,
Joao
 
Hi Rezo,
Sorry for not having answered in due time but i'm having issues in my life and my brain is not working as i would like it to.
I suppose KurtE's help will lead you to the right direction. I can't be very helpfull as since that time i had a disk drive broken that made me re-do all the project. I do have part of my project in the forum that can be helpful. This is the code i have in the forum (you have to adapt it to your idea - this is for a midi controller and is only part of the experiments i was doing with Oddson's help -, but the TFT/Touch part is working and easy to understand i suppose).
Code:
[COLOR=#333333]// include the ResponsiveAnalogRead library for analog smoothing[/COLOR][COLOR=#333333]#include <ResponsiveAnalogRead.h>
#include <Bounce.h>  // Bounce library makes button change detection easy
// ******CONSTANT VALUES******** - customize code behaviour here!


// SET THESE SIX VALUES FOR JOYSTICK!
const int pitchPin = 0; // PIN numbers ** MUST CHANGE!
const int modPin = 1;
const int modPin2 = 1;
const int pitchMaxRaw = 1019; // Max reading with full bend up... as raw 10-bit value
const int modMaxRaw = 1019; // Max reading full mod down


// SET THESE VALUES FOR RIBBON
//const int ribbonPin = touch_pressed; // Max reading on right side... as raw 10-bit value
const int ribbonMaxRaw = 474; // Max reading on right side... as raw 10-bit value
//


int Button1 = 0; //This is the default "Button Off" and 1 is "Button On"
int Button2 = 0; //This is the default "Button Off" and 1 is "Button On"
int OldButton1 = 0; //Variable to store button1 old value
int OldButton2 = 0; //Variable to store button2 old value
byte data1On[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf7};
byte data1Off[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7};
byte data2On[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf7};
byte data2Off[] = {0xf0, 0x42, 0x30, 0x75, 0x41, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7};
byte progMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x02, 0xf7};
byte combiMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x00, 0xf7};
byte seqMode[] = {0xf0, 0x42, 0x30, 0x75, 0x4E, 0x04, 0xf7};
byte modeRequest[] = {0xf0, 0x42, 0x30, 0x75, 0x12, 0x00, 0xf7};


const int channel = 1; // MIDI channel
const int MIDIdelay = 5; // will update MIDI only if this many milliseconds have passed
//******VARIABLES***********
// data variables and a lagged copy to compare before updating MIDI value
int pitch;
int mod;
int mod2;
int pitchRaw;
int modRaw;
int modRaw2;
int pitchLag;
int modLag;
int modLag2;
int ribbon;
int ribbonRaw;
int ribbonLag;


elapsedMillis pitchUpdate;
elapsedMillis modUpdate;
elapsedMillis modUpdate2;
elapsedMillis ribbonUpdate;


// ititialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead readPitch = {pitchPin, true};
ResponsiveAnalogRead readMod = {modPin, true};
ResponsiveAnalogRead readMod2 = {modPin2, true};


#include <Adafruit_GFX.h>    // Core graphics library


#define LCD_ROTATION  1        //should work in all rotations
#define USE_READID    0        //Adafruit and ILI9488 can't read ID
//#include <MCUFRIEND_kbv.h>     // Hardware-specific library
//MCUFRIEND_kbv tft;
//#include <Adafruit_ILI9341.h>   // Hardware-specific library
//Adafruit_ILI9341 tft(10, 9, 8);
//#include <HX8347D_kbv.h>        // Hardware-specific library
//HX8347D_kbv tft;
#include <ILI9488.h>            // Hardware-specific library
ILI9488 tft(10, 9, 8);
//#include <ILI9488_kbv.h>            // Hardware-specific library
//ILI9488_kbv tft;


extern void Touch_initialise(int aspect, int wid, int ht);
extern bool Touch_getXY(void);
bool touch_pressed;
int pixel_x, pixel_y;
boolean SW1on = false;
boolean SW2on = false;
boolean Progon = false;
boolean Combion = false;
boolean Seqon = false;
boolean ribbonCtrl = false;


// Color definitions
#define TFT_BLACK       0x0000      /*   0,   0,   0 */
#define TFT_NAVY        0x000F      /*   0,   0, 128 */
#define TFT_DARKGREEN   0x03E0      /*   0, 128,   0 */
#define TFT_DARKCYAN    0x03EF      /*   0, 128, 128 */
#define TFT_MAROON      0x7800      /* 128,   0,   0 */
#define TFT_PURPLE      0x780F      /* 128,   0, 128 */
#define TFT_OLIVE       0x7BE0      /* 128, 128,   0 */
#define TFT_LIGHTGREY   0xC618      /* 192, 192, 192 */
#define TFT_DARKGREY    0x7BEF      /* 128, 128, 128 */
#define TFT_BLUE        0x001F      /*   0,   0, 255 */
#define TFT_GREEN       0x07E0      /*   0, 255,   0 */
#define TFT_CYAN        0x07FF      /*   0, 255, 255 */
#define TFT_RED         0xF800      /* 255,   0,   0 */
#define TFT_RED2        0xF88D      /* 254,  18, 106 */
#define TFT_MAGENTA     0xF81F      /* 255,   0, 255 */
#define TFT_YELLOW      0xFFE0      /* 255, 255,   0 */
#define TFT_WHITE       0xFFFF      /* 255, 255, 255 */
#define TFT_ORANGE      0xFD20      /* 255, 165,   0 */
#define TFT_ORANGE2     0xFB20      /* 254, 102,   1 */
#define TFT_GREENYELLOW 0xAFE5      /* 173, 255,  47 */
#define TFT_PINK        0xF81F


/******************* UI details */


#define PROGFRAME_X 20
#define PROGFRAME_Y 10
#define PROGFRAME_W 90
#define PROGFRAME_H 50


#define PROGBUTTON_X PROGFRAME_X
#define PROGBUTTON_Y PROGFRAME_Y
#define PROGBUTTON_W PROGFRAME_W
#define PROGBUTTON_H PROGFRAME_H


#define COMBIFRAME_X 200
#define COMBIFRAME_Y 10
#define COMBIFRAME_W 90
#define COMBIFRAME_H 50


#define COMBIBUTTON_X COMBIFRAME_X
#define COMBIBUTTON_Y COMBIFRAME_Y
#define COMBIBUTTON_W COMBIFRAME_W
#define COMBIBUTTON_H COMBIFRAME_H


#define SEQFRAME_X 370
#define SEQFRAME_Y 10
#define SEQFRAME_W 90
#define SEQFRAME_H 50


#define SEQBUTTON_X SEQFRAME_X
#define SEQBUTTON_Y SEQFRAME_Y
#define SEQBUTTON_W SEQFRAME_W
#define SEQBUTTON_H SEQFRAME_H


#define SW1FRAME_X 90
#define SW1FRAME_Y 110
#define SW1FRAME_W 130
#define SW1FRAME_H 70


#define SW1BUTTON_X SW1FRAME_X
#define SW1BUTTON_Y SW1FRAME_Y
#define SW1BUTTON_W SW1FRAME_W
#define SW1BUTTON_H SW1FRAME_H


#define SW2FRAME_X 310
#define SW2FRAME_Y 110
#define SW2FRAME_W 130
#define SW2FRAME_H 70


#define SW2BUTTON_X SW2FRAME_X
#define SW2BUTTON_Y SW2FRAME_Y
#define SW2BUTTON_W SW2FRAME_W
#define SW2BUTTON_H SW2FRAME_H


#define RIBBONFRAME_X 10
#define RIBBONFRAME_Y 240
#define RIBBONFRAME_W 470
#define RIBBONFRAME_H 70


#define RIBBON_X RIBBONFRAME_X
#define RIBBON_Y RIBBONFRAME_Y
#define RIBBON_W RIBBONFRAME_W
#define RIBBON_H RIBBONFRAME_H


void progBtn()
{ 
  tft.drawRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_WHITE);
  tft.fillRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_WHITE);
  tft.setCursor(40, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Prog");
  usbMIDI.sendSysEx(7, modeRequest, true); //The Sysex to change to Program Mode in Korg M3
  Progon = false;
}
void combiBtn()
{ 
  tft.drawRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_WHITE);
  tft.fillRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_WHITE);
  tft.setCursor(220, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Combi");
  usbMIDI.sendSysEx(7, combiMode, true); //The Sysex to change to Combi Mode in Korg M3
  Combion = false;
}
void seqBtn()
{ 
  tft.drawRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_WHITE);
  tft.fillRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_WHITE);
  tft.setCursor(400, 25);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  tft.println("Seq");
  usbMIDI.sendSysEx(7, seqMode, true); //The Sysex to change to SEQ Mode in Korg M3
  Seqon = false;
}
void sw1Btn()
{ 
  tft.drawRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_DARKGREY);
  tft.fillRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_RED);
  tft.setCursor(160, 140);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  tft.println("SW1");
  SW1on = false;
}
void sw2Btn()
{ 
  tft.drawRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_DARKGREY);
  tft.fillRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_RED);
  tft.setCursor(340,140);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  tft.println("SW2");
  SW2on = false;
}
void rbCtrl()
{ 
  tft.drawRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
  tft.fillRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
  tft.setCursor(10,240);
    //remap to output data and send if changed and MIDIdelay has lapsed since last update for that parameter
    ribbon = map(pixel_x, 11, 474, 0, 127);
    ribbon = max(ribbon, 0); // need this now that the bottom isn't zero
    ribbon = min(ribbon, 127); // cap to avoid overflow
    if (abs(ribbon - ribbonLag) > 0 && ribbonUpdate > MIDIdelay ) {
      ribbonLag = ribbon;
    usbMIDI.sendControlChange(16, ribbon, channel);
      ribbonUpdate = 0;
    }
  ribbonCtrl = false;
}




void setup(void)
{
    Serial.begin(9600);
    Serial.println(F("TFT LCD test"));


    tft.begin();


    int aspect = LCD_ROTATION;   //PORTRAIT
    tft.setRotation(aspect);
    Touch_initialise(aspect, tft.width(), tft.height());  //.kbv external function
    tft.fillScreen(TFT_BLACK);
    


    // create 'SW1 Switch'
    tft.drawRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_DARKGREY);
    tft.fillRect(SW1BUTTON_X, SW1BUTTON_Y, SW1BUTTON_W, SW1BUTTON_H, TFT_RED);
    tft.setCursor(155, 140);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("SW1");


    // create 'SW2 Switch'
    tft.drawRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_DARKGREY);
    tft.fillRect(SW2BUTTON_X, SW2BUTTON_Y, SW2BUTTON_W, SW2BUTTON_H, TFT_RED);
    tft.setCursor(340, 140);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("SW2");


    // create 'PROG Switch'
    tft.drawRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_DARKGREY);
    tft.fillRect(PROGBUTTON_X, PROGBUTTON_Y, PROGBUTTON_W, PROGBUTTON_H, TFT_BLUE);
    tft.setCursor(40, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Prog");    


    // create 'COMBI Switch'
    tft.drawRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_DARKGREY);
    tft.fillRect(COMBIBUTTON_X, COMBIBUTTON_Y, COMBIBUTTON_W, COMBIBUTTON_H, TFT_RED);
    tft.setCursor(220, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Combi");
     
    // create 'SEQ Switch'
    tft.drawRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_DARKGREY);
    tft.fillRect(SEQBUTTON_X, SEQBUTTON_Y, SEQBUTTON_W, SEQBUTTON_H, TFT_YELLOW);
    tft.setCursor(400, 25);
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2);
    tft.print("Seq");     


    // create 'Ribbon Emulator field'
    tft.drawRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_DARKGREY);
    tft.fillRect(RIBBON_X, RIBBON_Y, RIBBON_W, RIBBON_H, TFT_LIGHTGREY);
}


void loop(void)
{


  usbMIDI.read();
  if (usbMIDI.read() == 1 && usbMIDI.getType() == 7 ) {//check for sysex 
   const byte *pSysExArray = usbMIDI.getSysExArray(); //capture data
    Serial.println(*pSysExArray);
  }
    int x = -1, y = -1;   //regular pixel coordinates
    touch_pressed = Touch_getXY();  //external function
#if 0
    Serial.print("X="); Serial.print(pixel_x); 
    Serial.print(" Y="); Serial.print(pixel_y); 
    Serial.print(" Z="); Serial.print(touch_pressed); 
    Serial.println("");
#endif
    if (touch_pressed) {
        x = pixel_x;      //copy global variable
        y = pixel_y;
    }


    {
      if((x > PROGBUTTON_X) && (x < (PROGBUTTON_X + PROGBUTTON_W))) {
        if ((y > PROGBUTTON_Y) && (y <= (PROGBUTTON_Y + PROGBUTTON_H))) {
          Serial.println("PROG btn hit"); 
          delay(100); // UI debouncing
          progBtn();
        }
      }
    }
{
      if((x > COMBIBUTTON_X) && (x < (COMBIBUTTON_X + COMBIBUTTON_W))) {
        if ((y > COMBIBUTTON_Y) && (y <= (COMBIBUTTON_Y + COMBIBUTTON_H))) {
          Serial.println("Combi btn hit"); 
          delay(100); // UI debouncing
          combiBtn();
        }
      }
    }
{
      if((x > SEQBUTTON_X) && (x < (SEQBUTTON_X + SEQBUTTON_W))) {
        if ((y > SEQBUTTON_Y) && (y <= (SEQBUTTON_Y + SEQBUTTON_H))) {
          Serial.println("Seq btn hit"); 
          delay(100); // UI debouncing
          seqBtn();
        }
      }
    }
    
{
      if((x > SW1BUTTON_X) && (x < (SW1BUTTON_X + SW1BUTTON_W))) {
        if ((y > SW1BUTTON_Y) && (y <= (SW1BUTTON_Y + SW1BUTTON_H))) {
          Serial.println("SW1 btn hit"); 
          delay(100); // UI debouncing
          sw1Btn();
        }
      }
    }


{
      if((x > SW2BUTTON_X) && (x < (SW2BUTTON_X + SW2BUTTON_W))) {
        if ((y > SW2BUTTON_Y) && (y <= (SW2BUTTON_Y + SW2BUTTON_H))) {
          Serial.println("SW2 btn hit"); 
          delay(100); // UI debouncing
          sw2Btn();
        }
      }
    } 
{
      if((x > RIBBON_X) && (x < (RIBBON_X + RIBBON_W))) {
        if ((y > RIBBON_Y) && (y <= (RIBBON_Y + RIBBON_H))) {
          Serial.println("Ribbon pressed"); 
          Serial.println(pixel_x);
          Serial.println(ribbon);       
          delay(100); // UI debouncing
          rbCtrl();
        }
      }
    } 
    
  }

[/COLOR]
Kind regards,
Joao


Joao, no need to apologize - I just spent the night in the ER myself! I hope you are able to get things sorted out as soon as possible, and be back on track with no worries to care for!

Thank you very much for the code, will come in very handy! Screens are arriving on Sunday (yay!) and I'm quite excited to start testing!

Cheers,
David
 
Status
Not open for further replies.
Back
Top