ILI9341 touchscreen LCD Library

I got a few QVGA LCD’s with resistive touchscreen for an ongoing project. All that was left to do was putting the driver code together. The LCD code part was very much similar to my previous work on the ILI9163 but this time I went for faster SPI communication (also due to the bigger resolution). The microcontroller – an Atmega128 – uses normal SPI transfer and the external quartz crystal is 16MHz for faster LCD display. Remember that the ILI9341 requires 3.3V and according to the datasheet it is not 5V tolerant. My tests show it will tolerate 5V but will only work with 3.3V. So the entire atmega128 microcontroller board was powered at 3.3V, and it was nice to see the atmega128a can run at 16MHz with so little voltage.

The touchscreen part required some additional work, and due to mechanical assembly of the sensing layer over the display, certain offsets can produce wrong coordinates, so we’ll need calibration (but only for the more sensitive applications).
ili9341_library_3 ili9341_library_2
These boards also have an SDCard slot and another SPI interface for it, at the top. I didn’t use it for this application.
The LCD interface has 9pins, while the touchscreen uses 5 (the T_ pins). To configure and use all these pins, I took advantage of my DigitalPin class, versatile when it comes to both output and input application.

DigitalPin	pinDC(&PORTC, PC4), pinRESET(&PORTC, PC5), pinCS(&PORTC, PC6),
			touchIRQ(&PORTA, PA0), touchDO(&PORTA, PA1), touchDI(&PORTA, PA2), touchCS(&PORTA, PA3),touchCLK(&PORTA, PA4);
ILI9341 	lcd;
TouchScreen	touch;

Using these, the initialisation part was done with just a few lines of code, clean and elegant:

lcd.init(&pinDC, &pinRESET, &pinCS);
lcd.setRotation(ILI9341::ROT0);
touch.init(&touchCLK, &touchCS, &touchDI, &touchDO, &touchIRQ);

Using the ILI9341 library, the entire code gets as simple as:

lcd.drawClear(BLACK);
// draw color picker buttons
for (int i=0;i<5;i++) {
	lcd.drawRectFilled(buttons[i][0],buttons[i][1],buttons[i][2],buttons[i][3],buttons[i][4]);
}
while (1) {
	// check if there is a click
	uint16_t x = 0, y = 0;
	if (touch.isData() && touch.read(&x, &y)) {
		for (int i=0;i<5;i++)
			// check if click was in any of the few colored rectangles
			if (x > buttons[i][0] && x < buttons[i][0] + buttons[i][2] &&
					y > buttons[i][1] && y < buttons[i][1] + buttons[i][3])
				penColor = buttons[i][4]; // if a match is found, save color
		// on click draw with current color
		lcd.drawRectFilled(x, y, 10, 10, penColor);
	}
	// draw some text but only once per second
	if (cmdRefreshText) {
		char tmp[255] = {0};
		sprintf(tmp, "%02u:%02u %03d %03d %04X", time.getMin(), time.getSec(), x, y, penColor);
		lcd.drawString(0, textY(18,2), tmp, 2, YELLOW, BLACK);
		lcd.drawString(0, textY(19,2), "www.pocketmagic.net", 2, RED, BLACK);
		cmdRefreshText = false;
	}
}

Getting the code

This software library is available as open source, licensed under the LGPL license. To understand what you can and what you can't do with this code, have a look here. The code itself is availablehere , and on Github. The code comes with the demo paint application seen in the video. Use it as a starting point. For any questions, feel free to contact me by mail, or using the comments section below.

This article has 1 Comment

Leave a Reply