I'm still waiting for the last few components to arrive before I can build the controller, however one thing I wanted to do first is test my chosen LCD with the Teensy microcontroller. I've never used a TFT LCD with Arduino or Teensy before, so I first wanted to make sure that I could get the desired functionality and performance out of the LCD.
The LCD I am using is a 2.4" 320x240 TFT LCD with a ILI9341 controller chip which appears to be based off of an Adafruit design, which can be used with a Teensy-optimised Adafruit_ILI9341 library for better performance.
Connections
To connect the LCD to the Teensy 3.6 board I followed the connections guide on the Teensy website:
ILI9341 Pin | Teensy 3.x / LC Pin | Notes |
VCC | VIN | Power: 3.6 to 5.5 volts |
GND | GND | |
CS | 10 | Alternate Pins: 9, 15, 20, 21 |
RESET | +3.3V | |
D/C | 9 | Alternate Pins: 10, 15, 20, 21 |
SDI (MOSI) | 11 (DOUT) | |
SCK | 13 (SCK) | |
LED | VIN | Use 100 ohm resistor |
SDO (MISO) | 12 (DIN) |
Arduino Library
I decided to use the Teensy-optimised Adafruit_ILI9341 library over the standard Adafruit_ILI9341 library due to the demonstrated increased frame rate and performance of the former. I downloaded the library from the Github page and followed the provided instructions to install it into the Arduino software.
Using the library
After a quick online search I couldn't find any decent tutorials on using the LCD's Arduino library to draw shapes (which is mostly what I want the LCD to do), however after dissecting the example sketches that come with the library it became quite clear how to do it. The best source to find out what functionality is provided is the library's main header file, which shows all the functions that library provides such as drawRect, fillRect, fillCircle, and many more.
Test/Example Code
To test the LCD and Arduino library I decided to attempt to create a simple Teensy sketch that draws eight sliders on the LCD that each change their value from a MIDI CC message received over USB-MIDI - something that the final controller software will need to do.
Below is the code I created to do this. See the comments in the code to see how it works. The exact MIDI CC numbers I am using in this test code match the default CCs that the KORG nanoKONTROL MIDI controller sends from it's sliders (see the below example video). If you would like to upload this to a Teensy yourself, you'll need to set the 'USB Type' to 'MIDI' in the tools menu.
#include "ILI9341_t3.h"
// TFT pins
const uint8_t TFT_DC = 9;
const uint8_t TFT_CS = 10;
// Use hardware SPI (#13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3 (TFT_CS, TFT_DC);
const int LCD_FRAME_RATE = 30;
long previousMillis = 0;
const int BCKGND_COLOUR = ILI9341_BLACK;
const int SLIDER_COLOUR = ILI9341_RED;
const int SLIDER_BCKGND_COLOUR = ILI9341_DARKGREY;
const int SLIDER_WIDTH = 20;
const int SLIDER_MAX_SIZE = 127;
const int SLIDER_SPACING = 40;
const uint8_t NUM_OF_SLIDERS = 8;
const uint8_t SLIDER_CC_NUMS[NUM_OF_SLIDERS] = {2, 3, 4, 5, 6, 8, 9, 12};
int sliderValue[NUM_OF_SLIDERS] = {0};
int prevSliderValue[NUM_OF_SLIDERS] = {0};
uint8_t midiCcValue[NUM_OF_SLIDERS] = {0};
uint8_t prevMidiCcValue[NUM_OF_SLIDERS] = {0};
void setup()
{
tft.begin();
tft.setRotation (3);
tft.fillScreen (BCKGND_COLOUR);
//draw a vertical rectangle 'slider' at the bottom of the screen
for (uint8_t i = 0; i < NUM_OF_SLIDERS; i++)
tft.fillRect (i * SLIDER_SPACING, tft.height() - SLIDER_MAX_SIZE, SLIDER_WIDTH, SLIDER_MAX_SIZE, SLIDER_BCKGND_COLOUR);
usbMIDI.setHandleControlChange(ProcessMidiControlChange);
}
void loop()
{
//Read from USB MIDI-in
usbMIDI.read();
//update the LCD display at the set frame rate
if ((millis() - previousMillis) > (1000.0 / (float)LCD_FRAME_RATE))
{
updateDisplay();
previousMillis = millis();
}
}
void ProcessMidiControlChange (byte channel, byte control, byte value)
{
for (uint8_t i = 0; i < NUM_OF_SLIDERS; i++)
{
if (control == SLIDER_CC_NUMS[i])
{
midiCcValue[i] = value;
if (midiCcValue[i] != prevMidiCcValue[i])
{
//set the new value for the slider
sliderValue[i] = midiCcValue[i];
prevMidiCcValue[i] = midiCcValue[i];
} //if (midiCcValue[i] != prevMidiCcValue[i])
} //if (control == SLIDER_CC_NUMS[i])
} //for (uint8_t i = 0; i < NUM_OF_SLIDERS; i++)
}
void updateDisplay()
{
for (uint8_t i = 0; i < NUM_OF_SLIDERS; i++)
{
//if the slider value needs updating
if (sliderValue[i] != prevSliderValue[i])
{
if (sliderValue[i] > prevSliderValue[i])
{
//increase the size of the slider by drawing the value difference on the top
tft.fillRect (i * SLIDER_SPACING, tft.height() - sliderValue[i], SLIDER_WIDTH, sliderValue[i] - prevSliderValue[i], SLIDER_COLOUR);
}
else
{
//decrease the size of the slider by 'clearing' the value difference from the top
tft.fillRect (i * SLIDER_SPACING, tft.height() - prevSliderValue[i], SLIDER_WIDTH, prevSliderValue[i] - sliderValue[i], SLIDER_BCKGND_COLOUR);
}
prevSliderValue[i] = sliderValue[i];
} //if (sliderValue[i] != prevSliderValue[i])
} //for (uint8_t i = 0; i < NUM_OF_SLIDERS; i++)
}
Example Video
Below is an example video of the above code running on a Teensy 3.6, using a KORG nanoKONTROL USB-MIDI controller as the MIDI input device, with MIDI messages being routed from the nanoKONTROL to the Teensy using my MacBook running the MIDI Patchbay software.
Based off of the performance of this test code, I am confident that this LCD will be perfect for this project.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
OK, I'm stupid. I did not connect the reset pint to 3.3v. Its work well. : )
Are you sure? yes | no
Hi Liam,
I tried a more stable cabling, but unfortunately the display still doesn't work well. I also tested your menu system with 3 encoders. I noticed that the display is stable until I move the encoders.
As I move it goes away in image and whiteness. The error does not always occur immediately. At some point, multiple rotations are possible until the error occurs. Maybe you have any idea where to look for the bug? After implementing the spi.h directory, the display is more stable to load (the image did not always appear before).
Are you sure? yes | no
I have Teensy 3.6 and ILI9341 SPI 2.2"QVGA. Ok. Maybe it's just a cabling problem. I’m doing a new, more secure cabling and we’ll see. Thanks.
Are you sure? yes | no
Hi Liam!
I implemented your code and converted it a bit to read analogRead ( ). It works nicely. I am grateful for sharing. Unfortunately, with the ILI9341_t3 driver, the code works uncertainly. Works well with the factory Adafruit ILI9341. Have you experienced anything like this? Thanks
Are you sure? yes | no
Hi Gandrasg, glad to hear the code helped! I had no issues whatsoever using ILI9341_t3 however I have not used it again since this project which was over two years ago now. Possibly new issues with updates to the driver code or with the specific board or screen you're using?
Are you sure? yes | no