Added modified version of AdaFruit_ILI9341 library, based on work by Matthias (@madias on the Arduino forum). Also includes a small speed optimization to call nonstandard spi::write(byte) function, as this gives around 20% speed improvement. Note SPI clock rate, chosen my @madias, of DIV_2 is 36Mhz, which exceeds the publish maximum spi clock of 10Mhz, however it seems to work with most devices
This commit is contained in:
parent
ac742edbd7
commit
3bc36db069
|
@ -0,0 +1,654 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our library for the Adafruit ILI9341 Breakout and Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
#include "Adafruit_ILI9341.h"
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "pins_arduino.h"
|
||||||
|
#include "wiring_private.h"
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
// Constructor when using software SPI. All output pins are configurable.
|
||||||
|
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
|
||||||
|
int8_t sclk, int8_t rst, int8_t miso) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
|
||||||
|
_cs = cs;
|
||||||
|
_dc = dc;
|
||||||
|
_mosi = mosi;
|
||||||
|
_miso = miso;
|
||||||
|
_sclk = sclk;
|
||||||
|
_rst = rst;
|
||||||
|
hwSPI = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor when using hardware SPI. Faster, but must use SPI pins
|
||||||
|
// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.)
|
||||||
|
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
|
||||||
|
_cs = cs;
|
||||||
|
_dc = dc;
|
||||||
|
_rst = rst;
|
||||||
|
hwSPI = true;
|
||||||
|
_mosi = _sclk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::spiwrite(uint8_t c) {
|
||||||
|
|
||||||
|
//Serial.print("0x"); Serial.print(c, HEX); Serial.print(", ");
|
||||||
|
|
||||||
|
if (hwSPI) {
|
||||||
|
#if defined (__AVR__)
|
||||||
|
uint8_t backupSPCR = SPCR;
|
||||||
|
SPCR = mySPCR;
|
||||||
|
SPDR = c;
|
||||||
|
while(!(SPSR & _BV(SPIF)));
|
||||||
|
SPCR = backupSPCR;
|
||||||
|
#elif defined(TEENSYDUINO)
|
||||||
|
SPI.transfer(c);
|
||||||
|
#elif defined (__STM32F1__)
|
||||||
|
SPI.write(c);// Faster than transfer as we don't need to read
|
||||||
|
#elif defined (__arm__)
|
||||||
|
SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
|
||||||
|
SPI.setBitOrder(MSBFIRST);
|
||||||
|
SPI.setDataMode(SPI_MODE0);
|
||||||
|
SPI.transfer(c);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// Fast SPI bitbang swiped from LPD8806 library
|
||||||
|
for(uint8_t bit = 0x80; bit; bit >>= 1) {
|
||||||
|
if(c & bit) {
|
||||||
|
//digitalWrite(_mosi, HIGH);
|
||||||
|
*mosiport |= mosipinmask;
|
||||||
|
} else {
|
||||||
|
//digitalWrite(_mosi, LOW);
|
||||||
|
*mosiport &= ~mosipinmask;
|
||||||
|
}
|
||||||
|
//digitalWrite(_sclk, HIGH);
|
||||||
|
*clkport |= clkpinmask;
|
||||||
|
//digitalWrite(_sclk, LOW);
|
||||||
|
*clkport &= ~clkpinmask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::writecommand(uint8_t c) {
|
||||||
|
*dcport &= ~dcpinmask;
|
||||||
|
//digitalWrite(_dc, LOW);
|
||||||
|
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
|
||||||
|
//digitalWrite(_sclk, LOW);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
|
||||||
|
spiwrite(c);
|
||||||
|
|
||||||
|
*csport |= cspinmask;
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::writedata(uint8_t c) {
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
|
||||||
|
//digitalWrite(_sclk, LOW);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
|
||||||
|
spiwrite(c);
|
||||||
|
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
*csport |= cspinmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the SPI library has transaction support, these functions
|
||||||
|
// establish settings and protect from interference from other
|
||||||
|
// libraries. Otherwise, they simply do nothing.
|
||||||
|
#ifdef SPI_HAS_TRANSACTION
|
||||||
|
static inline void spi_begin(void) __attribute__((always_inline));
|
||||||
|
static inline void spi_begin(void) {
|
||||||
|
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
|
||||||
|
}
|
||||||
|
static inline void spi_end(void) __attribute__((always_inline));
|
||||||
|
static inline void spi_end(void) {
|
||||||
|
SPI.endTransaction();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define spi_begin()
|
||||||
|
#define spi_end()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Rather than a bazillion writecommand() and writedata() calls, screen
|
||||||
|
// initialization commands and arguments are organized in these tables
|
||||||
|
// stored in PROGMEM. The table may look bulky, but that's mostly the
|
||||||
|
// formatting -- storage-wise this is hundreds of bytes more compact
|
||||||
|
// than the equivalent code. Companion function follows.
|
||||||
|
#define DELAY 0x80
|
||||||
|
|
||||||
|
|
||||||
|
// Companion code to the above tables. Reads and issues
|
||||||
|
// a series of LCD commands stored in PROGMEM byte array.
|
||||||
|
void Adafruit_ILI9341::commandList(uint8_t *addr) {
|
||||||
|
|
||||||
|
uint8_t numCommands, numArgs;
|
||||||
|
uint16_t ms;
|
||||||
|
|
||||||
|
numCommands = pgm_read_byte(addr++); // Number of commands to follow
|
||||||
|
while(numCommands--) { // For each command...
|
||||||
|
writecommand(pgm_read_byte(addr++)); // Read, issue command
|
||||||
|
numArgs = pgm_read_byte(addr++); // Number of args to follow
|
||||||
|
ms = numArgs & DELAY; // If hibit set, delay follows args
|
||||||
|
numArgs &= ~DELAY; // Mask out delay bit
|
||||||
|
while(numArgs--) { // For each argument...
|
||||||
|
writedata(pgm_read_byte(addr++)); // Read, issue argument
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ms) {
|
||||||
|
ms = pgm_read_byte(addr++); // Read post-command delay time (ms)
|
||||||
|
if(ms == 255) ms = 500; // If 255, delay for 500 ms
|
||||||
|
delay(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::begin(void) {
|
||||||
|
if (_rst > 0) {
|
||||||
|
pinMode(_rst, OUTPUT);
|
||||||
|
digitalWrite(_rst, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
pinMode(_dc, OUTPUT);
|
||||||
|
pinMode(_cs, OUTPUT);
|
||||||
|
csport = portOutputRegister(digitalPinToPort(_cs));
|
||||||
|
cspinmask = digitalPinToBitMask(_cs);
|
||||||
|
dcport = portOutputRegister(digitalPinToPort(_dc));
|
||||||
|
dcpinmask = digitalPinToBitMask(_dc);
|
||||||
|
|
||||||
|
if(hwSPI) { // Using hardware SPI
|
||||||
|
#if defined (__AVR__)
|
||||||
|
SPI.begin();
|
||||||
|
SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz (full! speed!)
|
||||||
|
SPI.setBitOrder(MSBFIRST);
|
||||||
|
SPI.setDataMode(SPI_MODE0);
|
||||||
|
mySPCR = SPCR;
|
||||||
|
#elif defined(TEENSYDUINO) || defined (__STM32F1__)
|
||||||
|
SPI.begin();
|
||||||
|
SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz (full! speed!)
|
||||||
|
SPI.setBitOrder(MSBFIRST);
|
||||||
|
SPI.setDataMode(SPI_MODE0);
|
||||||
|
#elif defined (__arm__)
|
||||||
|
SPI.begin();
|
||||||
|
SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
|
||||||
|
SPI.setBitOrder(MSBFIRST);
|
||||||
|
SPI.setDataMode(SPI_MODE0);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
pinMode(_sclk, OUTPUT);
|
||||||
|
pinMode(_mosi, OUTPUT);
|
||||||
|
pinMode(_miso, INPUT);
|
||||||
|
clkport = portOutputRegister(digitalPinToPort(_sclk));
|
||||||
|
clkpinmask = digitalPinToBitMask(_sclk);
|
||||||
|
mosiport = portOutputRegister(digitalPinToPort(_mosi));
|
||||||
|
mosipinmask = digitalPinToBitMask(_mosi);
|
||||||
|
*clkport &= ~clkpinmask;
|
||||||
|
*mosiport &= ~mosipinmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toggle RST low to reset
|
||||||
|
if (_rst > 0) {
|
||||||
|
digitalWrite(_rst, HIGH);
|
||||||
|
delay(5);
|
||||||
|
digitalWrite(_rst, LOW);
|
||||||
|
delay(20);
|
||||||
|
digitalWrite(_rst, HIGH);
|
||||||
|
delay(150);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint8_t x = readcommand8(ILI9341_RDMODE);
|
||||||
|
Serial.print("\nDisplay Power Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = readcommand8(ILI9341_RDMADCTL);
|
||||||
|
Serial.print("\nMADCTL Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = readcommand8(ILI9341_RDPIXFMT);
|
||||||
|
Serial.print("\nPixel Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = readcommand8(ILI9341_RDIMGFMT);
|
||||||
|
Serial.print("\nImage Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = readcommand8(ILI9341_RDSELFDIAG);
|
||||||
|
Serial.print("\nSelf Diagnostic: 0x"); Serial.println(x, HEX);
|
||||||
|
*/
|
||||||
|
//if(cmdList) commandList(cmdList);
|
||||||
|
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
writecommand(0xEF);
|
||||||
|
writedata(0x03);
|
||||||
|
writedata(0x80);
|
||||||
|
writedata(0x02);
|
||||||
|
|
||||||
|
writecommand(0xCF);
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0XC1);
|
||||||
|
writedata(0X30);
|
||||||
|
|
||||||
|
writecommand(0xED);
|
||||||
|
writedata(0x64);
|
||||||
|
writedata(0x03);
|
||||||
|
writedata(0X12);
|
||||||
|
writedata(0X81);
|
||||||
|
|
||||||
|
writecommand(0xE8);
|
||||||
|
writedata(0x85);
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0x78);
|
||||||
|
|
||||||
|
writecommand(0xCB);
|
||||||
|
writedata(0x39);
|
||||||
|
writedata(0x2C);
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0x34);
|
||||||
|
writedata(0x02);
|
||||||
|
|
||||||
|
writecommand(0xF7);
|
||||||
|
writedata(0x20);
|
||||||
|
|
||||||
|
writecommand(0xEA);
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0x00);
|
||||||
|
|
||||||
|
writecommand(ILI9341_PWCTR1); //Power control
|
||||||
|
writedata(0x23); //VRH[5:0]
|
||||||
|
|
||||||
|
writecommand(ILI9341_PWCTR2); //Power control
|
||||||
|
writedata(0x10); //SAP[2:0];BT[3:0]
|
||||||
|
|
||||||
|
writecommand(ILI9341_VMCTR1); //VCM control
|
||||||
|
writedata(0x3e); //¶Ô±È¶Èµ÷½Ú
|
||||||
|
writedata(0x28);
|
||||||
|
|
||||||
|
writecommand(ILI9341_VMCTR2); //VCM control2
|
||||||
|
writedata(0x86); //--
|
||||||
|
|
||||||
|
writecommand(ILI9341_MADCTL); // Memory Access Control
|
||||||
|
writedata(0x48);
|
||||||
|
|
||||||
|
writecommand(ILI9341_PIXFMT);
|
||||||
|
writedata(0x55);
|
||||||
|
|
||||||
|
writecommand(ILI9341_FRMCTR1);
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0x18);
|
||||||
|
|
||||||
|
writecommand(ILI9341_DFUNCTR); // Display Function Control
|
||||||
|
writedata(0x08);
|
||||||
|
writedata(0x82);
|
||||||
|
writedata(0x27);
|
||||||
|
|
||||||
|
writecommand(0xF2); // 3Gamma Function Disable
|
||||||
|
writedata(0x00);
|
||||||
|
|
||||||
|
writecommand(ILI9341_GAMMASET); //Gamma curve selected
|
||||||
|
writedata(0x01);
|
||||||
|
|
||||||
|
writecommand(ILI9341_GMCTRP1); //Set Gamma
|
||||||
|
writedata(0x0F);
|
||||||
|
writedata(0x31);
|
||||||
|
writedata(0x2B);
|
||||||
|
writedata(0x0C);
|
||||||
|
writedata(0x0E);
|
||||||
|
writedata(0x08);
|
||||||
|
writedata(0x4E);
|
||||||
|
writedata(0xF1);
|
||||||
|
writedata(0x37);
|
||||||
|
writedata(0x07);
|
||||||
|
writedata(0x10);
|
||||||
|
writedata(0x03);
|
||||||
|
writedata(0x0E);
|
||||||
|
writedata(0x09);
|
||||||
|
writedata(0x00);
|
||||||
|
|
||||||
|
writecommand(ILI9341_GMCTRN1); //Set Gamma
|
||||||
|
writedata(0x00);
|
||||||
|
writedata(0x0E);
|
||||||
|
writedata(0x14);
|
||||||
|
writedata(0x03);
|
||||||
|
writedata(0x11);
|
||||||
|
writedata(0x07);
|
||||||
|
writedata(0x31);
|
||||||
|
writedata(0xC1);
|
||||||
|
writedata(0x48);
|
||||||
|
writedata(0x08);
|
||||||
|
writedata(0x0F);
|
||||||
|
writedata(0x0C);
|
||||||
|
writedata(0x31);
|
||||||
|
writedata(0x36);
|
||||||
|
writedata(0x0F);
|
||||||
|
|
||||||
|
writecommand(ILI9341_SLPOUT); //Exit Sleep
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
delay(120);
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
writecommand(ILI9341_DISPON); //Display on
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
|
||||||
|
uint16_t y1) {
|
||||||
|
|
||||||
|
writecommand(ILI9341_CASET); // Column addr set
|
||||||
|
writedata(x0 >> 8);
|
||||||
|
writedata(x0 & 0xFF); // XSTART
|
||||||
|
writedata(x1 >> 8);
|
||||||
|
writedata(x1 & 0xFF); // XEND
|
||||||
|
|
||||||
|
writecommand(ILI9341_PASET); // Row addr set
|
||||||
|
writedata(y0>>8);
|
||||||
|
writedata(y0); // YSTART
|
||||||
|
writedata(y1>>8);
|
||||||
|
writedata(y1); // YEND
|
||||||
|
|
||||||
|
writecommand(ILI9341_RAMWR); // write to RAM
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::pushColor(uint16_t color) {
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
|
||||||
|
spiwrite(color >> 8);
|
||||||
|
spiwrite(color);
|
||||||
|
|
||||||
|
*csport |= cspinmask;
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||||
|
|
||||||
|
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
|
||||||
|
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
setAddrWindow(x,y,x+1,y+1);
|
||||||
|
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
|
||||||
|
spiwrite(color >> 8);
|
||||||
|
spiwrite(color);
|
||||||
|
|
||||||
|
*csport |= cspinmask;
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h,
|
||||||
|
uint16_t color) {
|
||||||
|
|
||||||
|
// Rudimentary clipping
|
||||||
|
if((x >= _width) || (y >= _height)) return;
|
||||||
|
|
||||||
|
if((y+h-1) >= _height)
|
||||||
|
h = _height-y;
|
||||||
|
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
setAddrWindow(x, y, x, y+h-1);
|
||||||
|
|
||||||
|
uint8_t hi = color >> 8, lo = color;
|
||||||
|
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
|
||||||
|
while (h--) {
|
||||||
|
spiwrite(hi);
|
||||||
|
spiwrite(lo);
|
||||||
|
}
|
||||||
|
*csport |= cspinmask;
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||||
|
uint16_t color) {
|
||||||
|
|
||||||
|
// Rudimentary clipping
|
||||||
|
if((x >= _width) || (y >= _height)) return;
|
||||||
|
if((x+w-1) >= _width) w = _width-x;
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
setAddrWindow(x, y, x+w-1, y);
|
||||||
|
|
||||||
|
uint8_t hi = color >> 8, lo = color;
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
while (w--) {
|
||||||
|
spiwrite(hi);
|
||||||
|
spiwrite(lo);
|
||||||
|
}
|
||||||
|
*csport |= cspinmask;
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::fillScreen(uint16_t color) {
|
||||||
|
fillRect(0, 0, _width, _height, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill a rectangle
|
||||||
|
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
|
||||||
|
uint16_t color) {
|
||||||
|
|
||||||
|
// rudimentary clipping (drawChar w/big text requires this)
|
||||||
|
if((x >= _width) || (y >= _height)) return;
|
||||||
|
if((x + w - 1) >= _width) w = _width - x;
|
||||||
|
if((y + h - 1) >= _height) h = _height - y;
|
||||||
|
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
setAddrWindow(x, y, x+w-1, y+h-1);
|
||||||
|
|
||||||
|
uint8_t hi = color >> 8, lo = color;
|
||||||
|
|
||||||
|
*dcport |= dcpinmask;
|
||||||
|
//digitalWrite(_dc, HIGH);
|
||||||
|
*csport &= ~cspinmask;
|
||||||
|
//digitalWrite(_cs, LOW);
|
||||||
|
|
||||||
|
for(y=h; y>0; y--) {
|
||||||
|
for(x=w; x>0; x--) {
|
||||||
|
spiwrite(hi);
|
||||||
|
spiwrite(lo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//digitalWrite(_cs, HIGH);
|
||||||
|
*csport |= cspinmask;
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
|
||||||
|
uint16_t Adafruit_ILI9341::color565(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
|
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MADCTL_MY 0x80
|
||||||
|
#define MADCTL_MX 0x40
|
||||||
|
#define MADCTL_MV 0x20
|
||||||
|
#define MADCTL_ML 0x10
|
||||||
|
#define MADCTL_RGB 0x00
|
||||||
|
#define MADCTL_BGR 0x08
|
||||||
|
#define MADCTL_MH 0x04
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::setRotation(uint8_t m) {
|
||||||
|
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
writecommand(ILI9341_MADCTL);
|
||||||
|
rotation = m % 4; // can't be higher than 3
|
||||||
|
switch (rotation) {
|
||||||
|
case 0:
|
||||||
|
writedata(MADCTL_MX | MADCTL_BGR);
|
||||||
|
_width = ILI9341_TFTWIDTH;
|
||||||
|
_height = ILI9341_TFTHEIGHT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
writedata(MADCTL_MV | MADCTL_BGR);
|
||||||
|
_width = ILI9341_TFTHEIGHT;
|
||||||
|
_height = ILI9341_TFTWIDTH;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
writedata(MADCTL_MY | MADCTL_BGR);
|
||||||
|
_width = ILI9341_TFTWIDTH;
|
||||||
|
_height = ILI9341_TFTHEIGHT;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
writedata(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||||
|
_width = ILI9341_TFTHEIGHT;
|
||||||
|
_height = ILI9341_TFTWIDTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Adafruit_ILI9341::invertDisplay(boolean i) {
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
writecommand(i ? ILI9341_INVON : ILI9341_INVOFF);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////// stuff not actively being used, but kept for posterity
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Adafruit_ILI9341::spiread(void) {
|
||||||
|
uint8_t r = 0;
|
||||||
|
|
||||||
|
if (hwSPI) {
|
||||||
|
#if defined (__AVR__)
|
||||||
|
uint8_t backupSPCR = SPCR;
|
||||||
|
SPCR = mySPCR;
|
||||||
|
SPDR = 0x00;
|
||||||
|
while(!(SPSR & _BV(SPIF)));
|
||||||
|
r = SPDR;
|
||||||
|
SPCR = backupSPCR;
|
||||||
|
#elif defined(TEENSYDUINO) || defined (__STM32F1__)
|
||||||
|
r = SPI.transfer(0x00);
|
||||||
|
#elif defined (__arm__)
|
||||||
|
SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
|
||||||
|
SPI.setBitOrder(MSBFIRST);
|
||||||
|
SPI.setDataMode(SPI_MODE0);
|
||||||
|
r = SPI.transfer(0x00);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<8; i++) {
|
||||||
|
digitalWrite(_sclk, LOW);
|
||||||
|
digitalWrite(_sclk, HIGH);
|
||||||
|
r <<= 1;
|
||||||
|
if (digitalRead(_miso))
|
||||||
|
r |= 0x1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Serial.print("read: 0x"); Serial.print(r, HEX);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Adafruit_ILI9341::readdata(void) {
|
||||||
|
digitalWrite(_dc, HIGH);
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
uint8_t r = spiread();
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) {
|
||||||
|
if (hwSPI) spi_begin();
|
||||||
|
digitalWrite(_dc, LOW); // command
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
spiwrite(0xD9); // woo sekret command?
|
||||||
|
digitalWrite(_dc, HIGH); // data
|
||||||
|
spiwrite(0x10 + index);
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
digitalWrite(_dc, LOW);
|
||||||
|
digitalWrite(_sclk, LOW);
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
spiwrite(c);
|
||||||
|
|
||||||
|
digitalWrite(_dc, HIGH);
|
||||||
|
uint8_t r = spiread();
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
if (hwSPI) spi_end();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
uint16_t Adafruit_ILI9341::readcommand16(uint8_t c) {
|
||||||
|
digitalWrite(_dc, LOW);
|
||||||
|
if (_cs)
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
|
||||||
|
spiwrite(c);
|
||||||
|
pinMode(_sid, INPUT); // input!
|
||||||
|
uint16_t r = spiread();
|
||||||
|
r <<= 8;
|
||||||
|
r |= spiread();
|
||||||
|
if (_cs)
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
pinMode(_sid, OUTPUT); // back to output
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Adafruit_ILI9341::readcommand32(uint8_t c) {
|
||||||
|
digitalWrite(_dc, LOW);
|
||||||
|
if (_cs)
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
spiwrite(c);
|
||||||
|
pinMode(_sid, INPUT); // input!
|
||||||
|
|
||||||
|
dummyclock();
|
||||||
|
dummyclock();
|
||||||
|
|
||||||
|
uint32_t r = spiread();
|
||||||
|
r <<= 8;
|
||||||
|
r |= spiread();
|
||||||
|
r <<= 8;
|
||||||
|
r |= spiread();
|
||||||
|
r <<= 8;
|
||||||
|
r |= spiread();
|
||||||
|
if (_cs)
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
pinMode(_sid, OUTPUT); // back to output
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,169 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our library for the Adafruit ILI9341 Breakout and Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
#ifndef _ADAFRUIT_ILI9341H_
|
||||||
|
#define _ADAFRUIT_ILI9341H_
|
||||||
|
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Print.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ILI9341_TFTWIDTH 240
|
||||||
|
#define ILI9341_TFTHEIGHT 320
|
||||||
|
|
||||||
|
#define ILI9341_NOP 0x00
|
||||||
|
#define ILI9341_SWRESET 0x01
|
||||||
|
#define ILI9341_RDDID 0x04
|
||||||
|
#define ILI9341_RDDST 0x09
|
||||||
|
|
||||||
|
#define ILI9341_SLPIN 0x10
|
||||||
|
#define ILI9341_SLPOUT 0x11
|
||||||
|
#define ILI9341_PTLON 0x12
|
||||||
|
#define ILI9341_NORON 0x13
|
||||||
|
|
||||||
|
#define ILI9341_RDMODE 0x0A
|
||||||
|
#define ILI9341_RDMADCTL 0x0B
|
||||||
|
#define ILI9341_RDPIXFMT 0x0C
|
||||||
|
#define ILI9341_RDIMGFMT 0x0A
|
||||||
|
#define ILI9341_RDSELFDIAG 0x0F
|
||||||
|
|
||||||
|
#define ILI9341_INVOFF 0x20
|
||||||
|
#define ILI9341_INVON 0x21
|
||||||
|
#define ILI9341_GAMMASET 0x26
|
||||||
|
#define ILI9341_DISPOFF 0x28
|
||||||
|
#define ILI9341_DISPON 0x29
|
||||||
|
|
||||||
|
#define ILI9341_CASET 0x2A
|
||||||
|
#define ILI9341_PASET 0x2B
|
||||||
|
#define ILI9341_RAMWR 0x2C
|
||||||
|
#define ILI9341_RAMRD 0x2E
|
||||||
|
|
||||||
|
#define ILI9341_PTLAR 0x30
|
||||||
|
#define ILI9341_MADCTL 0x36
|
||||||
|
#define ILI9341_PIXFMT 0x3A
|
||||||
|
|
||||||
|
#define ILI9341_FRMCTR1 0xB1
|
||||||
|
#define ILI9341_FRMCTR2 0xB2
|
||||||
|
#define ILI9341_FRMCTR3 0xB3
|
||||||
|
#define ILI9341_INVCTR 0xB4
|
||||||
|
#define ILI9341_DFUNCTR 0xB6
|
||||||
|
|
||||||
|
#define ILI9341_PWCTR1 0xC0
|
||||||
|
#define ILI9341_PWCTR2 0xC1
|
||||||
|
#define ILI9341_PWCTR3 0xC2
|
||||||
|
#define ILI9341_PWCTR4 0xC3
|
||||||
|
#define ILI9341_PWCTR5 0xC4
|
||||||
|
#define ILI9341_VMCTR1 0xC5
|
||||||
|
#define ILI9341_VMCTR2 0xC7
|
||||||
|
|
||||||
|
#define ILI9341_RDID1 0xDA
|
||||||
|
#define ILI9341_RDID2 0xDB
|
||||||
|
#define ILI9341_RDID3 0xDC
|
||||||
|
#define ILI9341_RDID4 0xDD
|
||||||
|
|
||||||
|
#define ILI9341_GMCTRP1 0xE0
|
||||||
|
#define ILI9341_GMCTRN1 0xE1
|
||||||
|
/*
|
||||||
|
#define ILI9341_PWCTR6 0xFC
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Color definitions
|
||||||
|
#define ILI9341_BLACK 0x0000 /* 0, 0, 0 */
|
||||||
|
#define ILI9341_NAVY 0x000F /* 0, 0, 128 */
|
||||||
|
#define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */
|
||||||
|
#define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */
|
||||||
|
#define ILI9341_MAROON 0x7800 /* 128, 0, 0 */
|
||||||
|
#define ILI9341_PURPLE 0x780F /* 128, 0, 128 */
|
||||||
|
#define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */
|
||||||
|
#define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */
|
||||||
|
#define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */
|
||||||
|
#define ILI9341_BLUE 0x001F /* 0, 0, 255 */
|
||||||
|
#define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */
|
||||||
|
#define ILI9341_CYAN 0x07FF /* 0, 255, 255 */
|
||||||
|
#define ILI9341_RED 0xF800 /* 255, 0, 0 */
|
||||||
|
#define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */
|
||||||
|
#define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */
|
||||||
|
#define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */
|
||||||
|
#define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */
|
||||||
|
#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
|
||||||
|
#define ILI9341_PINK 0xF81F
|
||||||
|
|
||||||
|
class Adafruit_ILI9341 : public Adafruit_GFX {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
|
||||||
|
int8_t _RST, int8_t _MISO);
|
||||||
|
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
|
||||||
|
|
||||||
|
void begin(void),
|
||||||
|
setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
|
||||||
|
pushColor(uint16_t color),
|
||||||
|
fillScreen(uint16_t color),
|
||||||
|
drawPixel(int16_t x, int16_t y, uint16_t color),
|
||||||
|
drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
|
||||||
|
drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
|
||||||
|
fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
|
||||||
|
uint16_t color),
|
||||||
|
setRotation(uint8_t r),
|
||||||
|
invertDisplay(boolean i);
|
||||||
|
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
/* These are not for current use, 8-bit protocol only! */
|
||||||
|
uint8_t readdata(void),
|
||||||
|
readcommand8(uint8_t reg, uint8_t index = 0);
|
||||||
|
/*
|
||||||
|
uint16_t readcommand16(uint8_t);
|
||||||
|
uint32_t readcommand32(uint8_t);
|
||||||
|
void dummyclock(void);
|
||||||
|
*/
|
||||||
|
|
||||||
|
void spiwrite(uint8_t),
|
||||||
|
writecommand(uint8_t c),
|
||||||
|
writedata(uint8_t d),
|
||||||
|
commandList(uint8_t *addr);
|
||||||
|
uint8_t spiread(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t tabcolor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean hwSPI;
|
||||||
|
#if defined (__STM32F1__)
|
||||||
|
#define RwReg uint32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__AVR__) || defined(TEENSYDUINO)
|
||||||
|
uint8_t mySPCR;
|
||||||
|
volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport;
|
||||||
|
int8_t _cs, _dc, _rst, _mosi, _miso, _sclk;
|
||||||
|
uint8_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
|
||||||
|
#elif defined (__arm__)
|
||||||
|
volatile RwReg *mosiport, *clkport, *dcport, *rsport, *csport;
|
||||||
|
uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk;
|
||||||
|
uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,21 @@
|
||||||
|
This is a library for the Adafruit ILI9341 display products
|
||||||
|
|
||||||
|
This library works with the Adafruit 2.8" Touch Shield V2 (SPI)
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams.
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required
|
||||||
|
to interface (RST is optional).
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
|
||||||
|
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_ILI9341. Check that the Adafruit_ILI9341 folder contains Adafruit_ILI9341.cpp and Adafruit_ILI9341.
|
||||||
|
|
||||||
|
Place the Adafruit_ILI9341 library folder your arduinosketchfolder/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE
|
||||||
|
|
||||||
|
Also requires the Adafruit_GFX library for Arduino.
|
|
@ -0,0 +1,145 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our touchscreen painting example for the Adafruit ILI9341 Breakout
|
||||||
|
----> http://www.adafruit.com/products/1770
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
/** NOT FOR USE WITH THE TOUCH SHIELD, ONLY FOR THE BREAKOUT! **/
|
||||||
|
|
||||||
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Adafruit_ILI9341.h>
|
||||||
|
#include "TouchScreen.h"
|
||||||
|
|
||||||
|
// These are the four touchscreen analog pins
|
||||||
|
#define YP A2 // must be an analog pin, use "An" notation!
|
||||||
|
#define XM A3 // must be an analog pin, use "An" notation!
|
||||||
|
#define YM 5 // can be a digital pin
|
||||||
|
#define XP 4 // can be a digital pin
|
||||||
|
|
||||||
|
// This is calibration data for the raw touch data to the screen coordinates
|
||||||
|
#define TS_MINX 150
|
||||||
|
#define TS_MINY 120
|
||||||
|
#define TS_MAXX 920
|
||||||
|
#define TS_MAXY 940
|
||||||
|
|
||||||
|
#define MINPRESSURE 10
|
||||||
|
#define MAXPRESSURE 1000
|
||||||
|
|
||||||
|
// The display uses hardware SPI, plus #9 & #10
|
||||||
|
#define TFT_CS 10
|
||||||
|
#define TFT_DC 9
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
|
||||||
|
// 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 300 ohms across the X plate
|
||||||
|
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
|
||||||
|
|
||||||
|
// Size of the color selection boxes and the paintbrush size
|
||||||
|
#define BOXSIZE 40
|
||||||
|
#define PENRADIUS 3
|
||||||
|
int oldcolor, currentcolor;
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
// while (!Serial); // used for leonardo debugging
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println(F("Touch Paint!"));
|
||||||
|
|
||||||
|
tft.begin();
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
// make the color selection boxes
|
||||||
|
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
|
||||||
|
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
|
||||||
|
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
|
||||||
|
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
|
||||||
|
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
|
||||||
|
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
|
||||||
|
|
||||||
|
// select the current color 'red'
|
||||||
|
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
currentcolor = ILI9341_RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Retrieve a point
|
||||||
|
TSPoint p = ts.getPoint();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("X = "); Serial.print(p.x);
|
||||||
|
Serial.print("\tY = "); Serial.print(p.y);
|
||||||
|
Serial.print("\tPressure = "); Serial.println(p.z);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we have some minimum pressure we consider 'valid'
|
||||||
|
// pressure of 0 means no pressing!
|
||||||
|
if (p.z < MINPRESSURE || p.z > MAXPRESSURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale from ~0->1000 to tft.width using the calibration #'s
|
||||||
|
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
|
||||||
|
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("("); Serial.print(p.x);
|
||||||
|
Serial.print(", "); Serial.print(p.y);
|
||||||
|
Serial.println(")");
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (p.y < BOXSIZE) {
|
||||||
|
oldcolor = currentcolor;
|
||||||
|
|
||||||
|
if (p.x < BOXSIZE) {
|
||||||
|
currentcolor = ILI9341_RED;
|
||||||
|
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*2) {
|
||||||
|
currentcolor = ILI9341_YELLOW;
|
||||||
|
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*3) {
|
||||||
|
currentcolor = ILI9341_GREEN;
|
||||||
|
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*4) {
|
||||||
|
currentcolor = ILI9341_CYAN;
|
||||||
|
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*5) {
|
||||||
|
currentcolor = ILI9341_BLUE;
|
||||||
|
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*6) {
|
||||||
|
currentcolor = ILI9341_MAGENTA;
|
||||||
|
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldcolor != currentcolor) {
|
||||||
|
if (oldcolor == ILI9341_RED)
|
||||||
|
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
|
||||||
|
if (oldcolor == ILI9341_YELLOW)
|
||||||
|
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
|
||||||
|
if (oldcolor == ILI9341_GREEN)
|
||||||
|
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
|
||||||
|
if (oldcolor == ILI9341_CYAN)
|
||||||
|
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
|
||||||
|
if (oldcolor == ILI9341_BLUE)
|
||||||
|
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
|
||||||
|
if (oldcolor == ILI9341_MAGENTA)
|
||||||
|
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
|
||||||
|
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,349 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our GFX example for the Adafruit ILI9341 Breakout and Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SPI.h"
|
||||||
|
#include "Adafruit_GFX.h"
|
||||||
|
#include "Adafruit_ILI9341.h"
|
||||||
|
|
||||||
|
// For the Adafruit shield, these are the default.
|
||||||
|
#define TFT_DC 9
|
||||||
|
#define TFT_CS 10
|
||||||
|
|
||||||
|
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
// If using the breakout, change pins as desired
|
||||||
|
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println("ILI9341 Test!");
|
||||||
|
|
||||||
|
tft.begin();
|
||||||
|
|
||||||
|
// read diagnostics (optional but can help debug problems)
|
||||||
|
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
|
||||||
|
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDMADCTL);
|
||||||
|
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDPIXFMT);
|
||||||
|
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDIMGFMT);
|
||||||
|
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDSELFDIAG);
|
||||||
|
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
|
||||||
|
|
||||||
|
Serial.println(F("Benchmark Time (microseconds)"));
|
||||||
|
|
||||||
|
Serial.print(F("Screen fill "));
|
||||||
|
Serial.println(testFillScreen());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Text "));
|
||||||
|
Serial.println(testText());
|
||||||
|
delay(3000);
|
||||||
|
|
||||||
|
Serial.print(F("Lines "));
|
||||||
|
Serial.println(testLines(ILI9341_CYAN));
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Horiz/Vert Lines "));
|
||||||
|
Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Rectangles (outline) "));
|
||||||
|
Serial.println(testRects(ILI9341_GREEN));
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Rectangles (filled) "));
|
||||||
|
Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Circles (filled) "));
|
||||||
|
Serial.println(testFilledCircles(10, ILI9341_MAGENTA));
|
||||||
|
|
||||||
|
Serial.print(F("Circles (outline) "));
|
||||||
|
Serial.println(testCircles(10, ILI9341_WHITE));
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Triangles (outline) "));
|
||||||
|
Serial.println(testTriangles());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Triangles (filled) "));
|
||||||
|
Serial.println(testFilledTriangles());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Rounded rects (outline) "));
|
||||||
|
Serial.println(testRoundRects());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.print(F("Rounded rects (filled) "));
|
||||||
|
Serial.println(testFilledRoundRects());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.println(F("Done!"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop(void) {
|
||||||
|
for(uint8_t rotation=0; rotation<4; rotation++) {
|
||||||
|
tft.setRotation(rotation);
|
||||||
|
testText();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFillScreen() {
|
||||||
|
unsigned long start = micros();
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
tft.fillScreen(ILI9341_RED);
|
||||||
|
tft.fillScreen(ILI9341_GREEN);
|
||||||
|
tft.fillScreen(ILI9341_BLUE);
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testText() {
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
unsigned long start = micros();
|
||||||
|
tft.setCursor(0, 0);
|
||||||
|
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
|
||||||
|
tft.println("Hello World!");
|
||||||
|
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
|
||||||
|
tft.println(1234.56);
|
||||||
|
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
|
||||||
|
tft.println(0xDEADBEEF, HEX);
|
||||||
|
tft.println();
|
||||||
|
tft.setTextColor(ILI9341_GREEN);
|
||||||
|
tft.setTextSize(5);
|
||||||
|
tft.println("Groop");
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("I implore thee,");
|
||||||
|
tft.setTextSize(1);
|
||||||
|
tft.println("my foonting turlingdromes.");
|
||||||
|
tft.println("And hooptiously drangle me");
|
||||||
|
tft.println("with crinkly bindlewurdles,");
|
||||||
|
tft.println("Or I will rend thee");
|
||||||
|
tft.println("in the gobberwarts");
|
||||||
|
tft.println("with my blurglecruncheon,");
|
||||||
|
tft.println("see if I don't!");
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testLines(uint16_t color) {
|
||||||
|
unsigned long start, t;
|
||||||
|
int x1, y1, x2, y2,
|
||||||
|
w = tft.width(),
|
||||||
|
h = tft.height();
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = y1 = 0;
|
||||||
|
y2 = h - 1;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = w - 1;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t = micros() - start; // fillScreen doesn't count against timing
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = w - 1;
|
||||||
|
y1 = 0;
|
||||||
|
y2 = h - 1;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = 0;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t += micros() - start;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = 0;
|
||||||
|
y1 = h - 1;
|
||||||
|
y2 = 0;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = w - 1;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t += micros() - start;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = w - 1;
|
||||||
|
y1 = h - 1;
|
||||||
|
y2 = 0;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = 0;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, w = tft.width(), h = tft.height();
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
|
||||||
|
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testRects(uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int n, i, i2,
|
||||||
|
cx = tft.width() / 2,
|
||||||
|
cy = tft.height() / 2;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(tft.width(), tft.height());
|
||||||
|
start = micros();
|
||||||
|
for(i=2; i<n; i+=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.drawRect(cx-i2, cy-i2, i, i, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
||||||
|
unsigned long start, t = 0;
|
||||||
|
int n, i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(tft.width(), tft.height());
|
||||||
|
for(i=n; i>0; i-=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
start = micros();
|
||||||
|
tft.fillRect(cx-i2, cy-i2, i, i, color1);
|
||||||
|
t += micros() - start;
|
||||||
|
// Outlines are not included in timing results
|
||||||
|
tft.drawRect(cx-i2, cy-i2, i, i, color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(x=radius; x<w; x+=r2) {
|
||||||
|
for(y=radius; y<h; y+=r2) {
|
||||||
|
tft.fillCircle(x, y, radius, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, r2 = radius * 2,
|
||||||
|
w = tft.width() + radius,
|
||||||
|
h = tft.height() + radius;
|
||||||
|
|
||||||
|
// Screen is not cleared for this one -- this is
|
||||||
|
// intentional and does not affect the reported time.
|
||||||
|
start = micros();
|
||||||
|
for(x=0; x<w; x+=r2) {
|
||||||
|
for(y=0; y<h; y+=r2) {
|
||||||
|
tft.drawCircle(x, y, radius, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testTriangles() {
|
||||||
|
unsigned long start;
|
||||||
|
int n, i, cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(cx, cy);
|
||||||
|
start = micros();
|
||||||
|
for(i=0; i<n; i+=5) {
|
||||||
|
tft.drawTriangle(
|
||||||
|
cx , cy - i, // peak
|
||||||
|
cx - i, cy + i, // bottom left
|
||||||
|
cx + i, cy + i, // bottom right
|
||||||
|
tft.color565(0, 0, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledTriangles() {
|
||||||
|
unsigned long start, t = 0;
|
||||||
|
int i, cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(i=min(cx,cy); i>10; i-=5) {
|
||||||
|
start = micros();
|
||||||
|
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||||
|
tft.color565(0, i, i));
|
||||||
|
t += micros() - start;
|
||||||
|
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||||
|
tft.color565(i, i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testRoundRects() {
|
||||||
|
unsigned long start;
|
||||||
|
int w, i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
w = min(tft.width(), tft.height());
|
||||||
|
start = micros();
|
||||||
|
for(i=0; i<w; i+=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledRoundRects() {
|
||||||
|
unsigned long start;
|
||||||
|
int i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
//This example implements a simple sliding On/Off button. The example
|
||||||
|
// demonstrates drawing and touch operations.
|
||||||
|
//
|
||||||
|
//Thanks to Adafruit forums member Asteroid for the original sketch!
|
||||||
|
//
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_ILI9341.h>
|
||||||
|
#include <Adafruit_STMPE610.h>
|
||||||
|
|
||||||
|
// This is calibration data for the raw touch data to the screen coordinates
|
||||||
|
#define TS_MINX 150
|
||||||
|
#define TS_MINY 130
|
||||||
|
#define TS_MAXX 3800
|
||||||
|
#define TS_MAXY 4000
|
||||||
|
|
||||||
|
#define STMPE_CS 8
|
||||||
|
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
|
||||||
|
#define TFT_CS 10
|
||||||
|
#define TFT_DC 9
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
|
||||||
|
boolean RecordOn = false;
|
||||||
|
|
||||||
|
#define FRAME_X 210
|
||||||
|
#define FRAME_Y 180
|
||||||
|
#define FRAME_W 100
|
||||||
|
#define FRAME_H 50
|
||||||
|
|
||||||
|
#define REDBUTTON_X FRAME_X
|
||||||
|
#define REDBUTTON_Y FRAME_Y
|
||||||
|
#define REDBUTTON_W (FRAME_W/2)
|
||||||
|
#define REDBUTTON_H FRAME_H
|
||||||
|
|
||||||
|
#define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
|
||||||
|
#define GREENBUTTON_Y FRAME_Y
|
||||||
|
#define GREENBUTTON_W (FRAME_W/2)
|
||||||
|
#define GREENBUTTON_H FRAME_H
|
||||||
|
|
||||||
|
void drawFrame()
|
||||||
|
{
|
||||||
|
tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redBtn()
|
||||||
|
{
|
||||||
|
tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_RED);
|
||||||
|
tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_BLUE);
|
||||||
|
drawFrame();
|
||||||
|
tft.setCursor(GREENBUTTON_X + 6 , GREENBUTTON_Y + (GREENBUTTON_H/2));
|
||||||
|
tft.setTextColor(ILI9341_WHITE);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("ON");
|
||||||
|
RecordOn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void greenBtn()
|
||||||
|
{
|
||||||
|
tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_GREEN);
|
||||||
|
tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_BLUE);
|
||||||
|
drawFrame();
|
||||||
|
tft.setCursor(REDBUTTON_X + 6 , REDBUTTON_Y + (REDBUTTON_H/2));
|
||||||
|
tft.setTextColor(ILI9341_WHITE);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("OFF");
|
||||||
|
RecordOn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(void)
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
tft.begin();
|
||||||
|
if (!ts.begin()) {
|
||||||
|
Serial.println("Unable to start touchscreen.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Serial.println("Touchscreen started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLUE);
|
||||||
|
// origin = left,top landscape (USB left upper)
|
||||||
|
tft.setRotation(1);
|
||||||
|
redBtn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// See if there's any touch data for us
|
||||||
|
if (!ts.bufferEmpty())
|
||||||
|
{
|
||||||
|
// Retrieve a point
|
||||||
|
TS_Point p = ts.getPoint();
|
||||||
|
// Scale using the calibration #'s
|
||||||
|
// and rotate coordinate system
|
||||||
|
p.x = map(p.x, TS_MINY, TS_MAXY, 0, tft.height());
|
||||||
|
p.y = map(p.y, TS_MINX, TS_MAXX, 0, tft.width());
|
||||||
|
int y = tft.height() - p.x;
|
||||||
|
int x = p.y;
|
||||||
|
|
||||||
|
if (RecordOn)
|
||||||
|
{
|
||||||
|
if((x > REDBUTTON_X) && (x < (REDBUTTON_X + REDBUTTON_W))) {
|
||||||
|
if ((y > REDBUTTON_Y) && (y <= (REDBUTTON_Y + REDBUTTON_H))) {
|
||||||
|
Serial.println("Red btn hit");
|
||||||
|
redBtn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //Record is off (RecordOn == false)
|
||||||
|
{
|
||||||
|
if((x > GREENBUTTON_X) && (x < (GREENBUTTON_X + GREENBUTTON_W))) {
|
||||||
|
if ((y > GREENBUTTON_Y) && (y <= (GREENBUTTON_Y + GREENBUTTON_H))) {
|
||||||
|
Serial.println("Green btn hit");
|
||||||
|
greenBtn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(RecordOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
//This example implements a simple sliding On/Off button. The example
|
||||||
|
// demonstrates drawing and touch operations.
|
||||||
|
//
|
||||||
|
//Thanks to Adafruit forums member Asteroid for the original sketch!
|
||||||
|
//
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_ILI9341.h>
|
||||||
|
#include <TouchScreen.h>
|
||||||
|
|
||||||
|
//Touchscreen X+ X- Y+ Y- pins
|
||||||
|
#define YP A3 // must be an analog pin, use "An" notation!
|
||||||
|
#define XM A2 // must be an analog pin, use "An" notation!
|
||||||
|
#define YM 5 // can be a digital pin
|
||||||
|
#define XP 4 // can be a digital pin
|
||||||
|
|
||||||
|
// This is calibration data for the raw touch data to the screen coordinates
|
||||||
|
#define TS_MINX 150
|
||||||
|
#define TS_MINY 120
|
||||||
|
#define TS_MAXX 920
|
||||||
|
#define TS_MAXY 940
|
||||||
|
|
||||||
|
#define MINPRESSURE 10
|
||||||
|
#define MAXPRESSURE 1000
|
||||||
|
|
||||||
|
// 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 300 ohms across the X plate
|
||||||
|
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
|
||||||
|
|
||||||
|
|
||||||
|
#define TFT_CS 10
|
||||||
|
#define TFT_DC 9
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
|
||||||
|
boolean RecordOn = false;
|
||||||
|
|
||||||
|
#define FRAME_X 210
|
||||||
|
#define FRAME_Y 180
|
||||||
|
#define FRAME_W 100
|
||||||
|
#define FRAME_H 50
|
||||||
|
|
||||||
|
#define REDBUTTON_X FRAME_X
|
||||||
|
#define REDBUTTON_Y FRAME_Y
|
||||||
|
#define REDBUTTON_W (FRAME_W/2)
|
||||||
|
#define REDBUTTON_H FRAME_H
|
||||||
|
|
||||||
|
#define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
|
||||||
|
#define GREENBUTTON_Y FRAME_Y
|
||||||
|
#define GREENBUTTON_W (FRAME_W/2)
|
||||||
|
#define GREENBUTTON_H FRAME_H
|
||||||
|
|
||||||
|
void drawFrame()
|
||||||
|
{
|
||||||
|
tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redBtn()
|
||||||
|
{
|
||||||
|
tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_RED);
|
||||||
|
tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_BLUE);
|
||||||
|
drawFrame();
|
||||||
|
tft.setCursor(GREENBUTTON_X + 6 , GREENBUTTON_Y + (GREENBUTTON_H/2));
|
||||||
|
tft.setTextColor(ILI9341_WHITE);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("ON");
|
||||||
|
RecordOn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void greenBtn()
|
||||||
|
{
|
||||||
|
tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_GREEN);
|
||||||
|
tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_BLUE);
|
||||||
|
drawFrame();
|
||||||
|
tft.setCursor(REDBUTTON_X + 6 , REDBUTTON_Y + (REDBUTTON_H/2));
|
||||||
|
tft.setTextColor(ILI9341_WHITE);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("OFF");
|
||||||
|
RecordOn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(void)
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
tft.begin();
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLUE);
|
||||||
|
// origin = left,top landscape (USB left upper)
|
||||||
|
tft.setRotation(1);
|
||||||
|
redBtn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Retrieve a point
|
||||||
|
TSPoint p = ts.getPoint();
|
||||||
|
|
||||||
|
// See if there's any touch data for us
|
||||||
|
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
|
||||||
|
{
|
||||||
|
// Scale using the calibration #'s
|
||||||
|
// and rotate coordinate system
|
||||||
|
p.x = map(p.x, TS_MINY, TS_MAXY, 0, tft.height());
|
||||||
|
p.y = map(p.y, TS_MINX, TS_MAXX, 0, tft.width());
|
||||||
|
int y = tft.height() - p.x;
|
||||||
|
int x = p.y;
|
||||||
|
|
||||||
|
if (RecordOn)
|
||||||
|
{
|
||||||
|
if((x > REDBUTTON_X) && (x < (REDBUTTON_X + REDBUTTON_W))) {
|
||||||
|
if ((y > REDBUTTON_Y) && (y <= (REDBUTTON_Y + REDBUTTON_H))) {
|
||||||
|
Serial.println("Red btn hit");
|
||||||
|
redBtn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //Record is off (RecordOn == false)
|
||||||
|
{
|
||||||
|
if((x > GREENBUTTON_X) && (x < (GREENBUTTON_X + GREENBUTTON_W))) {
|
||||||
|
if ((y > GREENBUTTON_Y) && (y <= (GREENBUTTON_Y + GREENBUTTON_H))) {
|
||||||
|
Serial.println("Green btn hit");
|
||||||
|
greenBtn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(RecordOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our Bitmap drawing example for the Adafruit ILI9341 Breakout and Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
|
#include "Adafruit_ILI9341.h" // Hardware-specific library
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <SD.h>
|
||||||
|
|
||||||
|
// TFT display and SD card will share the hardware SPI interface.
|
||||||
|
// Hardware SPI pins are specific to the Arduino board type and
|
||||||
|
// cannot be remapped to alternate pins. For Arduino Uno,
|
||||||
|
// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
|
||||||
|
|
||||||
|
#define TFT_DC 9
|
||||||
|
#define TFT_CS 10
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
|
||||||
|
#define SD_CS 4
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
tft.begin();
|
||||||
|
tft.fillScreen(ILI9341_BLUE);
|
||||||
|
|
||||||
|
Serial.print("Initializing SD card...");
|
||||||
|
if (!SD.begin(SD_CS)) {
|
||||||
|
Serial.println("failed!");
|
||||||
|
}
|
||||||
|
Serial.println("OK!");
|
||||||
|
|
||||||
|
bmpDraw("purple.bmp", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function opens a Windows Bitmap (BMP) file and
|
||||||
|
// displays it at the given coordinates. It's sped up
|
||||||
|
// by reading many pixels worth of data at a time
|
||||||
|
// (rather than pixel by pixel). Increasing the buffer
|
||||||
|
// size takes more of the Arduino's precious RAM but
|
||||||
|
// makes loading a little faster. 20 pixels seems a
|
||||||
|
// good balance.
|
||||||
|
|
||||||
|
#define BUFFPIXEL 20
|
||||||
|
|
||||||
|
void bmpDraw(char *filename, uint8_t x, uint16_t y) {
|
||||||
|
|
||||||
|
File bmpFile;
|
||||||
|
int bmpWidth, bmpHeight; // W+H in pixels
|
||||||
|
uint8_t bmpDepth; // Bit depth (currently must be 24)
|
||||||
|
uint32_t bmpImageoffset; // Start of image data in file
|
||||||
|
uint32_t rowSize; // Not always = bmpWidth; may have padding
|
||||||
|
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
|
||||||
|
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
||||||
|
boolean goodBmp = false; // Set to true on valid header parse
|
||||||
|
boolean flip = true; // BMP is stored bottom-to-top
|
||||||
|
int w, h, row, col;
|
||||||
|
uint8_t r, g, b;
|
||||||
|
uint32_t pos = 0, startTime = millis();
|
||||||
|
|
||||||
|
if((x >= tft.width()) || (y >= tft.height())) return;
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.print(F("Loading image '"));
|
||||||
|
Serial.print(filename);
|
||||||
|
Serial.println('\'');
|
||||||
|
|
||||||
|
// Open requested file on SD card
|
||||||
|
if ((bmpFile = SD.open(filename)) == NULL) {
|
||||||
|
Serial.print(F("File not found"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse BMP header
|
||||||
|
if(read16(bmpFile) == 0x4D42) { // BMP signature
|
||||||
|
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
|
||||||
|
(void)read32(bmpFile); // Read & ignore creator bytes
|
||||||
|
bmpImageoffset = read32(bmpFile); // Start of image data
|
||||||
|
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
||||||
|
// Read DIB header
|
||||||
|
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
||||||
|
bmpWidth = read32(bmpFile);
|
||||||
|
bmpHeight = read32(bmpFile);
|
||||||
|
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
||||||
|
bmpDepth = read16(bmpFile); // bits per pixel
|
||||||
|
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
||||||
|
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
||||||
|
|
||||||
|
goodBmp = true; // Supported BMP format -- proceed!
|
||||||
|
Serial.print(F("Image size: "));
|
||||||
|
Serial.print(bmpWidth);
|
||||||
|
Serial.print('x');
|
||||||
|
Serial.println(bmpHeight);
|
||||||
|
|
||||||
|
// BMP rows are padded (if needed) to 4-byte boundary
|
||||||
|
rowSize = (bmpWidth * 3 + 3) & ~3;
|
||||||
|
|
||||||
|
// If bmpHeight is negative, image is in top-down order.
|
||||||
|
// This is not canon but has been observed in the wild.
|
||||||
|
if(bmpHeight < 0) {
|
||||||
|
bmpHeight = -bmpHeight;
|
||||||
|
flip = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crop area to be loaded
|
||||||
|
w = bmpWidth;
|
||||||
|
h = bmpHeight;
|
||||||
|
if((x+w-1) >= tft.width()) w = tft.width() - x;
|
||||||
|
if((y+h-1) >= tft.height()) h = tft.height() - y;
|
||||||
|
|
||||||
|
// Set TFT address window to clipped image bounds
|
||||||
|
tft.setAddrWindow(x, y, x+w-1, y+h-1);
|
||||||
|
|
||||||
|
for (row=0; row<h; row++) { // For each scanline...
|
||||||
|
|
||||||
|
// Seek to start of scan line. It might seem labor-
|
||||||
|
// intensive to be doing this on every line, but this
|
||||||
|
// method covers a lot of gritty details like cropping
|
||||||
|
// and scanline padding. Also, the seek only takes
|
||||||
|
// place if the file position actually needs to change
|
||||||
|
// (avoids a lot of cluster math in SD library).
|
||||||
|
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||||
|
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
|
||||||
|
else // Bitmap is stored top-to-bottom
|
||||||
|
pos = bmpImageoffset + row * rowSize;
|
||||||
|
if(bmpFile.position() != pos) { // Need seek?
|
||||||
|
bmpFile.seek(pos);
|
||||||
|
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||||
|
}
|
||||||
|
|
||||||
|
for (col=0; col<w; col++) { // For each pixel...
|
||||||
|
// Time to read more pixel data?
|
||||||
|
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||||
|
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||||
|
buffidx = 0; // Set index to beginning
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert pixel from BMP to TFT format, push to display
|
||||||
|
b = sdbuffer[buffidx++];
|
||||||
|
g = sdbuffer[buffidx++];
|
||||||
|
r = sdbuffer[buffidx++];
|
||||||
|
tft.pushColor(tft.color565(r,g,b));
|
||||||
|
} // end pixel
|
||||||
|
} // end scanline
|
||||||
|
Serial.print(F("Loaded in "));
|
||||||
|
Serial.print(millis() - startTime);
|
||||||
|
Serial.println(" ms");
|
||||||
|
} // end goodBmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bmpFile.close();
|
||||||
|
if(!goodBmp) Serial.println(F("BMP format not recognized."));
|
||||||
|
}
|
||||||
|
|
||||||
|
// These read 16- and 32-bit types from the SD card file.
|
||||||
|
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||||
|
// May need to reverse subscript order if porting elsewhere.
|
||||||
|
|
||||||
|
uint16_t read16(File &f) {
|
||||||
|
uint16_t result;
|
||||||
|
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||||
|
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t read32(File &f) {
|
||||||
|
uint32_t result;
|
||||||
|
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||||
|
((uint8_t *)&result)[1] = f.read();
|
||||||
|
((uint8_t *)&result)[2] = f.read();
|
||||||
|
((uint8_t *)&result)[3] = f.read(); // MSB
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,348 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our GFX example for the Adafruit ILI9341 Breakout and Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SPI.h"
|
||||||
|
#include "Adafruit_GFX.h"
|
||||||
|
#include "Adafruit_ILI9341.h"
|
||||||
|
|
||||||
|
// For the Adafruit shield, these are the default.
|
||||||
|
#define TFT_CS PB4
|
||||||
|
#define TFT_DC PA15
|
||||||
|
#define TFT_RST PB3
|
||||||
|
|
||||||
|
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
|
||||||
|
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
// If using the breakout, change pins as desired
|
||||||
|
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
tft.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop(void) {
|
||||||
|
|
||||||
|
Serial.println("ILI9341 Test!");
|
||||||
|
// read diagnostics (optional but can help debug problems)
|
||||||
|
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
|
||||||
|
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDMADCTL);
|
||||||
|
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDPIXFMT);
|
||||||
|
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDIMGFMT);
|
||||||
|
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
|
||||||
|
x = tft.readcommand8(ILI9341_RDSELFDIAG);
|
||||||
|
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
|
||||||
|
|
||||||
|
Serial.println(F("Benchmark Time (microseconds)"));
|
||||||
|
|
||||||
|
Serial.print(F("Screen fill "));
|
||||||
|
Serial.println(testFillScreen());
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Text "));
|
||||||
|
Serial.println(testText());
|
||||||
|
|
||||||
|
Serial.print(F("Lines "));
|
||||||
|
Serial.println(testLines(ILI9341_CYAN));
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Horiz/Vert Lines "));
|
||||||
|
Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Rectangles (outline) "));
|
||||||
|
Serial.println(testRects(ILI9341_GREEN));
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Rectangles (filled) "));
|
||||||
|
Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Circles (filled) "));
|
||||||
|
Serial.println(testFilledCircles(10, ILI9341_MAGENTA));
|
||||||
|
|
||||||
|
Serial.print(F("Circles (outline) "));
|
||||||
|
Serial.println(testCircles(10, ILI9341_WHITE));
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Triangles (outline) "));
|
||||||
|
Serial.println(testTriangles());
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Triangles (filled) "));
|
||||||
|
Serial.println(testFilledTriangles());
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Rounded rects (outline) "));
|
||||||
|
Serial.println(testRoundRects());
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Rounded rects (filled) "));
|
||||||
|
Serial.println(testFilledRoundRects());
|
||||||
|
|
||||||
|
|
||||||
|
Serial.println(F("Done!"));
|
||||||
|
|
||||||
|
for(uint8_t rotation=0; rotation<4; rotation++) {
|
||||||
|
tft.setRotation(rotation);
|
||||||
|
testText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFillScreen() {
|
||||||
|
unsigned long start = micros();
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
tft.fillScreen(ILI9341_RED);
|
||||||
|
tft.fillScreen(ILI9341_GREEN);
|
||||||
|
tft.fillScreen(ILI9341_BLUE);
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testText() {
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
unsigned long start = micros();
|
||||||
|
tft.setCursor(0, 0);
|
||||||
|
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
|
||||||
|
tft.println("Hello World!");
|
||||||
|
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
|
||||||
|
tft.println(1234.56);
|
||||||
|
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
|
||||||
|
tft.println(0xDEADBEEF, HEX);
|
||||||
|
tft.println();
|
||||||
|
tft.setTextColor(ILI9341_GREEN);
|
||||||
|
tft.setTextSize(5);
|
||||||
|
tft.println("Groop");
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.println("I implore thee,");
|
||||||
|
tft.setTextSize(1);
|
||||||
|
tft.println("my foonting turlingdromes.");
|
||||||
|
tft.println("And hooptiously drangle me");
|
||||||
|
tft.println("with crinkly bindlewurdles,");
|
||||||
|
tft.println("Or I will rend thee");
|
||||||
|
tft.println("in the gobberwarts");
|
||||||
|
tft.println("with my blurglecruncheon,");
|
||||||
|
tft.println("see if I don't!");
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testLines(uint16_t color) {
|
||||||
|
unsigned long start, t;
|
||||||
|
int x1, y1, x2, y2,
|
||||||
|
w = tft.width(),
|
||||||
|
h = tft.height();
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = y1 = 0;
|
||||||
|
y2 = h - 1;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = w - 1;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t = micros() - start; // fillScreen doesn't count against timing
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = w - 1;
|
||||||
|
y1 = 0;
|
||||||
|
y2 = h - 1;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = 0;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t += micros() - start;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = 0;
|
||||||
|
y1 = h - 1;
|
||||||
|
y2 = 0;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = w - 1;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
t += micros() - start;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
x1 = w - 1;
|
||||||
|
y1 = h - 1;
|
||||||
|
y2 = 0;
|
||||||
|
start = micros();
|
||||||
|
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
x2 = 0;
|
||||||
|
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, w = tft.width(), h = tft.height();
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
|
||||||
|
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testRects(uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int n, i, i2,
|
||||||
|
cx = tft.width() / 2,
|
||||||
|
cy = tft.height() / 2;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(tft.width(), tft.height());
|
||||||
|
start = micros();
|
||||||
|
for(i=2; i<n; i+=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.drawRect(cx-i2, cy-i2, i, i, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
||||||
|
unsigned long start, t = 0;
|
||||||
|
int n, i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(tft.width(), tft.height());
|
||||||
|
for(i=n; i>0; i-=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
start = micros();
|
||||||
|
tft.fillRect(cx-i2, cy-i2, i, i, color1);
|
||||||
|
t += micros() - start;
|
||||||
|
// Outlines are not included in timing results
|
||||||
|
tft.drawRect(cx-i2, cy-i2, i, i, color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(x=radius; x<w; x+=r2) {
|
||||||
|
for(y=radius; y<h; y+=r2) {
|
||||||
|
tft.fillCircle(x, y, radius, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
||||||
|
unsigned long start;
|
||||||
|
int x, y, r2 = radius * 2,
|
||||||
|
w = tft.width() + radius,
|
||||||
|
h = tft.height() + radius;
|
||||||
|
|
||||||
|
// Screen is not cleared for this one -- this is
|
||||||
|
// intentional and does not affect the reported time.
|
||||||
|
start = micros();
|
||||||
|
for(x=0; x<w; x+=r2) {
|
||||||
|
for(y=0; y<h; y+=r2) {
|
||||||
|
tft.drawCircle(x, y, radius, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testTriangles() {
|
||||||
|
unsigned long start;
|
||||||
|
int n, i, cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
n = min(cx, cy);
|
||||||
|
start = micros();
|
||||||
|
for(i=0; i<n; i+=5) {
|
||||||
|
tft.drawTriangle(
|
||||||
|
cx , cy - i, // peak
|
||||||
|
cx - i, cy + i, // bottom left
|
||||||
|
cx + i, cy + i, // bottom right
|
||||||
|
tft.color565(0, 0, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledTriangles() {
|
||||||
|
unsigned long start, t = 0;
|
||||||
|
int i, cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(i=min(cx,cy); i>10; i-=5) {
|
||||||
|
start = micros();
|
||||||
|
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||||
|
tft.color565(0, i, i));
|
||||||
|
t += micros() - start;
|
||||||
|
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||||
|
tft.color565(i, i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testRoundRects() {
|
||||||
|
unsigned long start;
|
||||||
|
int w, i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
w = min(tft.width(), tft.height());
|
||||||
|
start = micros();
|
||||||
|
for(i=0; i<w; i+=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long testFilledRoundRects() {
|
||||||
|
unsigned long start;
|
||||||
|
int i, i2,
|
||||||
|
cx = tft.width() / 2 - 1,
|
||||||
|
cy = tft.height() / 2 - 1;
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
start = micros();
|
||||||
|
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
|
||||||
|
i2 = i / 2;
|
||||||
|
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return micros() - start;
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
/***************************************************
|
||||||
|
This is our touchscreen painting example for the Adafruit ILI9341 Shield
|
||||||
|
----> http://www.adafruit.com/products/1651
|
||||||
|
|
||||||
|
Check out the links above for our tutorials and wiring diagrams
|
||||||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||||
|
interface (RST is optional)
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Wire.h> // this is needed even tho we aren't using it
|
||||||
|
#include <Adafruit_ILI9341.h>
|
||||||
|
#include <Adafruit_STMPE610.h>
|
||||||
|
|
||||||
|
// This is calibration data for the raw touch data to the screen coordinates
|
||||||
|
#define TS_MINX 150
|
||||||
|
#define TS_MINY 130
|
||||||
|
#define TS_MAXX 3800
|
||||||
|
#define TS_MAXY 4000
|
||||||
|
|
||||||
|
// The STMPE610 uses hardware SPI on the shield, and #8
|
||||||
|
#define STMPE_CS 8
|
||||||
|
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
|
||||||
|
|
||||||
|
// The display also uses hardware SPI, plus #9 & #10
|
||||||
|
#define TFT_CS 10
|
||||||
|
#define TFT_DC 9
|
||||||
|
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
|
||||||
|
|
||||||
|
// Size of the color selection boxes and the paintbrush size
|
||||||
|
#define BOXSIZE 40
|
||||||
|
#define PENRADIUS 3
|
||||||
|
int oldcolor, currentcolor;
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
// while (!Serial); // used for leonardo debugging
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println(F("Touch Paint!"));
|
||||||
|
|
||||||
|
tft.begin();
|
||||||
|
|
||||||
|
if (!ts.begin()) {
|
||||||
|
Serial.println("Couldn't start touchscreen controller");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.println("Touchscreen started");
|
||||||
|
|
||||||
|
tft.fillScreen(ILI9341_BLACK);
|
||||||
|
|
||||||
|
// make the color selection boxes
|
||||||
|
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
|
||||||
|
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
|
||||||
|
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
|
||||||
|
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
|
||||||
|
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
|
||||||
|
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
|
||||||
|
|
||||||
|
// select the current color 'red'
|
||||||
|
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
currentcolor = ILI9341_RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// See if there's any touch data for us
|
||||||
|
if (ts.bufferEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// You can also wait for a touch
|
||||||
|
if (! ts.touched()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Retrieve a point
|
||||||
|
TS_Point p = ts.getPoint();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("X = "); Serial.print(p.x);
|
||||||
|
Serial.print("\tY = "); Serial.print(p.y);
|
||||||
|
Serial.print("\tPressure = "); Serial.println(p.z);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Scale from ~0->4000 to tft.width using the calibration #'s
|
||||||
|
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
|
||||||
|
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("("); Serial.print(p.x);
|
||||||
|
Serial.print(", "); Serial.print(p.y);
|
||||||
|
Serial.println(")");
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (p.y < BOXSIZE) {
|
||||||
|
oldcolor = currentcolor;
|
||||||
|
|
||||||
|
if (p.x < BOXSIZE) {
|
||||||
|
currentcolor = ILI9341_RED;
|
||||||
|
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*2) {
|
||||||
|
currentcolor = ILI9341_YELLOW;
|
||||||
|
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*3) {
|
||||||
|
currentcolor = ILI9341_GREEN;
|
||||||
|
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*4) {
|
||||||
|
currentcolor = ILI9341_CYAN;
|
||||||
|
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*5) {
|
||||||
|
currentcolor = ILI9341_BLUE;
|
||||||
|
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
} else if (p.x < BOXSIZE*6) {
|
||||||
|
currentcolor = ILI9341_MAGENTA;
|
||||||
|
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldcolor != currentcolor) {
|
||||||
|
if (oldcolor == ILI9341_RED)
|
||||||
|
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
|
||||||
|
if (oldcolor == ILI9341_YELLOW)
|
||||||
|
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
|
||||||
|
if (oldcolor == ILI9341_GREEN)
|
||||||
|
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
|
||||||
|
if (oldcolor == ILI9341_CYAN)
|
||||||
|
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
|
||||||
|
if (oldcolor == ILI9341_BLUE)
|
||||||
|
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
|
||||||
|
if (oldcolor == ILI9341_MAGENTA)
|
||||||
|
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
|
||||||
|
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue