├── Adafruit_QDTech.cpp ├── Adafruit_QDTech.h ├── README.txt └── examples ├── TFT_Clock └── TFT_Clock.ino └── graphicstest_QDTech └── graphicstest_QDTech.ino /Adafruit_QDTech.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is a modification of the Adafruit SPI LCD library, 3 | customised for hardware SPI and the QDTech board 4 | using a Samsung S6D02A1 chip. 5 | 6 | Most changes are made to the initialisation routine but 7 | non-Arduino code has been removed too. 8 | 9 | The initialisation sequence comes from Henning Karlsen's 10 | UTFT library: http://henningkarlsen.com 11 | 12 | Using the hardware SPI pins is highly recommeneded. 13 | 14 | You will also need the stock "Adafruit_GFX" library. 15 | https://github.com/adafruit/Adafruit-GFX-Library 16 | 17 | Gilchrist 30/1/2014 18 | 6/2/14 1.1 Fixed RGB colour order error 19 | 20 | 21 | /*************************************************** 22 | This is a library for the Adafruit 1.8" SPI display. 23 | This library works with the Adafruit 1.8" TFT Breakout w/SD card 24 | ----> http://www.adafruit.com/products/358 25 | as well as Adafruit raw 1.8" TFT display 26 | ----> http://www.adafruit.com/products/618 27 | 28 | Check out the links above for our tutorials and wiring diagrams 29 | These displays use SPI to communicate, 4 or 5 pins are required to 30 | interface (RST is optional) 31 | Adafruit invests time and resources providing this open source code, 32 | please support Adafruit and open-source hardware by purchasing 33 | products from Adafruit! 34 | 35 | Written by Limor Fried/Ladyada for Adafruit Industries. 36 | MIT license, all text above must be included in any redistribution 37 | ****************************************************/ 38 | 39 | #include "Adafruit_QDTech.h" 40 | #include 41 | #include "pins_arduino.h" 42 | #include "wiring_private.h" 43 | #include 44 | 45 | inline uint16_t swapcolor(uint16_t x) { 46 | return (x << 11) | (x & 0x07E0) | (x >> 11); 47 | } 48 | 49 | 50 | // Constructor when using software SPI. All output pins are configurable. 51 | Adafruit_QDTech::Adafruit_QDTech(uint8_t cs, uint8_t rs, uint8_t sid, 52 | uint8_t sclk, uint8_t rst) : Adafruit_GFX(QDTech_TFTWIDTH, QDTech_TFTHEIGHT) 53 | { 54 | _cs = cs; 55 | _rs = rs; 56 | _sid = sid; 57 | _sclk = sclk; 58 | _rst = rst; 59 | hwSPI = false; 60 | } 61 | 62 | 63 | // Constructor when using hardware SPI. Faster, but must use SPI pins 64 | // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) 65 | Adafruit_QDTech::Adafruit_QDTech(uint8_t cs, uint8_t rs, uint8_t rst) : 66 | Adafruit_GFX(QDTech_TFTWIDTH, QDTech_TFTHEIGHT) { 67 | _cs = cs; 68 | _rs = rs; 69 | _rst = rst; 70 | hwSPI = true; 71 | _sid = _sclk = 0; 72 | } 73 | 74 | inline void Adafruit_QDTech::spiwrite(uint8_t c) { 75 | 76 | if (hwSPI) { 77 | SPDR = c; 78 | while(!(SPSR & _BV(SPIF))); 79 | } else { 80 | // Fast SPI bitbang swiped from LPD8806 library 81 | for(uint8_t bit = 0x80; bit; bit >>= 1) { 82 | if(c & bit) *dataport |= datapinmask; 83 | else *dataport &= ~datapinmask; 84 | *clkport |= clkpinmask; 85 | *clkport &= ~clkpinmask; 86 | } 87 | } 88 | } 89 | 90 | 91 | void Adafruit_QDTech::writecommand(uint8_t c) { 92 | *rsport &= ~rspinmask; 93 | *csport &= ~cspinmask; 94 | spiwrite(c); 95 | *csport |= cspinmask; 96 | } 97 | 98 | 99 | void Adafruit_QDTech::writedata(uint8_t c) { 100 | *rsport |= rspinmask; 101 | *csport &= ~cspinmask; 102 | spiwrite(c); 103 | *csport |= cspinmask; 104 | } 105 | 106 | 107 | // Rather than a bazillion writecommand() and writedata() calls, screen 108 | // initialization commands and arguments are organized in these tables 109 | // stored in PROGMEM. The table may look bulky, but that's mostly the 110 | // formatting -- storage-wise this is hundreds of bytes more compact 111 | // than the equivalent code. Companion function follows. 112 | #define DELAY 0x80 113 | 114 | 115 | static const uint8_t PROGMEM // Multiple LCD init commands removed 116 | QDTech[] = { // QDTech support only now 117 | 29, 118 | 0xf0, 2, 0x5a, 0x5a, // Excommand2 119 | 0xfc, 2, 0x5a, 0x5a, // Excommand3 120 | 0x26, 1, 0x01, // Gamma set 121 | 0xfa, 15, 0x02, 0x1f, 0x00, 0x10, 0x22, 0x30, 0x38, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3d, 0x02, 0x01, // Positive gamma control 122 | 0xfb, 15, 0x21, 0x00, 0x02, 0x04, 0x07, 0x0a, 0x0b, 0x0c, 0x0c, 0x16, 0x1e, 0x30, 0x3f, 0x01, 0x02, // Negative gamma control 123 | 0xfd, 11, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x01, 0x00, 0x1f, 0x1f, // Analog parameter control 124 | 0xf4, 15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00, // Power control 125 | 0xf5, 13, 0x00, 0x70, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x66, 0x06, // VCOM control 126 | 0xf6, 11, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x01, 0x00, // Source control 127 | 0xf2, 17, 0x00, 0x01, 0x03, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x08, 0x08, //Display control 128 | 0xf8, 1, 0x11, // Gate control 129 | 0xf7, 4, 0xc8, 0x20, 0x00, 0x00, // Interface control 130 | 0xf3, 2, 0x00, 0x00, // Power sequence control 131 | 0x11, DELAY, 50, // Wake 132 | 0xf3, 2+DELAY, 0x00, 0x01, 50, // Power sequence control 133 | 0xf3, 2+DELAY, 0x00, 0x03, 50, // Power sequence control 134 | 0xf3, 2+DELAY, 0x00, 0x07, 50, // Power sequence control 135 | 0xf3, 2+DELAY, 0x00, 0x0f, 50, // Power sequence control 136 | 0xf4, 15+DELAY, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00, 50, // Power control 137 | 0xf3, 2+DELAY, 0x00, 0x1f, 50, // Power sequence control 138 | 0xf3, 2+DELAY, 0x00, 0x7f, 50, // Power sequence control 139 | 0xf3, 2+DELAY, 0x00, 0xff, 50, // Power sequence control 140 | 0xfd, 11, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x01, 0x00, 0x16, 0x16, // Analog parameter control 141 | 0xf4, 15, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00, // Power control 142 | 0x36, 1, 0x08, // Memory access data control 143 | 0x35, 1, 0x00, // Tearing effect line on 144 | 0x3a, 1+DELAY, 0x05, 150, // Interface pixel control 145 | 0x29, 0, // Display on 146 | 0x2c, 0 // Memory write 147 | }; 148 | 149 | 150 | // Companion code to the above tables. Reads and issues 151 | // a series of LCD commands stored in PROGMEM byte array. 152 | void Adafruit_QDTech::commandList(const uint8_t *addr) { 153 | 154 | uint8_t numCommands, numArgs; 155 | uint16_t ms; 156 | 157 | numCommands = pgm_read_byte(addr++); // Number of commands to follow 158 | 159 | while(numCommands--) { // For each command... 160 | writecommand(pgm_read_byte(addr++)); // Read, issue command 161 | numArgs = pgm_read_byte(addr++); // Number of args to follow 162 | ms = numArgs & DELAY; // If hibit set, delay follows args 163 | numArgs &= ~DELAY; // Mask out delay bit 164 | while(numArgs--) { // For each argument... 165 | writedata(pgm_read_byte(addr++)); // Read, issue argument 166 | } 167 | if(ms) { 168 | ms = pgm_read_byte(addr++); // Read post-command delay time (ms) 169 | if(ms == 255) ms = 500; // If 255, delay for 500 ms 170 | delay(ms); 171 | } 172 | } 173 | } 174 | 175 | 176 | // Initialization code for QDTech displays 177 | void Adafruit_QDTech::commonInit(const uint8_t *cmdList) { 178 | colstart = rowstart = 0; // May be overridden in init func 179 | 180 | pinMode(_rs, OUTPUT); 181 | pinMode(_cs, OUTPUT); 182 | csport = portOutputRegister(digitalPinToPort(_cs)); 183 | rsport = portOutputRegister(digitalPinToPort(_rs)); 184 | cspinmask = digitalPinToBitMask(_cs); 185 | rspinmask = digitalPinToBitMask(_rs); 186 | 187 | if(hwSPI) { // Using hardware SPI 188 | SPI.begin(); 189 | SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz (half speed) 190 | //Due defaults to 4mHz (clock divider setting of 21) 191 | SPI.setBitOrder(MSBFIRST); 192 | SPI.setDataMode(SPI_MODE0); 193 | } else { 194 | pinMode(_sclk, OUTPUT); 195 | pinMode(_sid , OUTPUT); 196 | clkport = portOutputRegister(digitalPinToPort(_sclk)); 197 | dataport = portOutputRegister(digitalPinToPort(_sid)); 198 | clkpinmask = digitalPinToBitMask(_sclk); 199 | datapinmask = digitalPinToBitMask(_sid); 200 | *clkport &= ~clkpinmask; 201 | *dataport &= ~datapinmask; 202 | } 203 | 204 | // toggle RST low to reset; CS low so it'll listen to us 205 | *csport &= ~cspinmask; 206 | if (_rst) { 207 | pinMode(_rst, OUTPUT); 208 | digitalWrite(_rst, HIGH); 209 | delay(500); 210 | digitalWrite(_rst, LOW); 211 | delay(500); 212 | digitalWrite(_rst, HIGH); 213 | delay(500); 214 | } 215 | 216 | if(cmdList) commandList(cmdList); 217 | } 218 | 219 | 220 | // Initialization for QDTech LCD only 221 | void Adafruit_QDTech::init() { 222 | commonInit(0); 223 | commandList(QDTech); 224 | } 225 | 226 | 227 | void Adafruit_QDTech::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, 228 | uint8_t y1) { 229 | 230 | writecommand(QDTech_CASET); // Column addr set 231 | writedata(0x00); 232 | writedata(x0+colstart); // XSTART 233 | writedata(0x00); 234 | writedata(x1+colstart); // XEND 235 | 236 | writecommand(QDTech_RASET); // Row addr set 237 | writedata(0x00); 238 | writedata(y0+rowstart); // YSTART 239 | writedata(0x00); 240 | writedata(y1+rowstart); // YEND 241 | 242 | writecommand(QDTech_RAMWR); // write to RAM 243 | } 244 | 245 | 246 | void Adafruit_QDTech::pushColor(uint16_t color) { 247 | *rsport |= rspinmask; 248 | *csport &= ~cspinmask; 249 | 250 | spiwrite(color >> 8); 251 | spiwrite(color); 252 | 253 | *csport |= cspinmask; 254 | } 255 | 256 | void Adafruit_QDTech::drawPixel(int16_t x, int16_t y, uint16_t color) { 257 | 258 | if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 259 | 260 | setAddrWindow(x,y,x+1,y+1); 261 | 262 | *rsport |= rspinmask; 263 | *csport &= ~cspinmask; 264 | 265 | spiwrite(color >> 8); 266 | spiwrite(color); 267 | 268 | *csport |= cspinmask; 269 | } 270 | 271 | void Adafruit_QDTech::drawFastVLine(int16_t x, int16_t y, int16_t h, 272 | uint16_t color) { 273 | 274 | // Rudimentary clipping 275 | if((x >= _width) || (y >= _height)) return; 276 | if((y+h-1) >= _height) h = _height-y; 277 | setAddrWindow(x, y, x, y+h-1); 278 | 279 | uint8_t hi = color >> 8, lo = color; 280 | *rsport |= rspinmask; 281 | *csport &= ~cspinmask; 282 | while (h--) { 283 | spiwrite(hi); 284 | spiwrite(lo); 285 | } 286 | *csport |= cspinmask; 287 | } 288 | 289 | 290 | void Adafruit_QDTech::drawFastHLine(int16_t x, int16_t y, int16_t w, 291 | uint16_t color) { 292 | 293 | // Rudimentary clipping 294 | if((x >= _width) || (y >= _height)) return; 295 | if((x+w-1) >= _width) w = _width-x; 296 | setAddrWindow(x, y, x+w-1, y); 297 | 298 | uint8_t hi = color >> 8, lo = color; 299 | *rsport |= rspinmask; 300 | *csport &= ~cspinmask; 301 | while (w--) { 302 | spiwrite(hi); 303 | spiwrite(lo); 304 | } 305 | *csport |= cspinmask; 306 | } 307 | 308 | 309 | void Adafruit_QDTech::fillScreen(uint16_t color) { 310 | fillRect(0, 0, _width, _height, color); 311 | } 312 | 313 | 314 | 315 | // fill a rectangle 316 | void Adafruit_QDTech::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 317 | uint16_t color) { 318 | 319 | // rudimentary clipping (drawChar w/big text requires this) 320 | if((x >= _width) || (y >= _height)) return; 321 | if((x + w - 1) >= _width) w = _width - x; 322 | if((y + h - 1) >= _height) h = _height - y; 323 | 324 | setAddrWindow(x, y, x+w-1, y+h-1); 325 | 326 | uint8_t hi = color >> 8, lo = color; 327 | *rsport |= rspinmask; 328 | *csport &= ~cspinmask; 329 | for(y=h; y>0; y--) { 330 | for(x=w; x>0; x--) { 331 | spiwrite(hi); 332 | spiwrite(lo); 333 | } 334 | } 335 | *csport |= cspinmask; 336 | } 337 | 338 | // Pass 8-bit (each) R,G,B, get back 16-bit packed color 339 | uint16_t Adafruit_QDTech::Color565(uint8_t r, uint8_t g, uint8_t b) { 340 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 341 | } 342 | 343 | 344 | #define MADCTL_MY 0x80 345 | #define MADCTL_MX 0x40 346 | #define MADCTL_MV 0x20 347 | #define MADCTL_ML 0x10 348 | #define MADCTL_RGB 0x00 349 | #define MADCTL_BGR 0x08 350 | #define MADCTL_MH 0x04 351 | 352 | void Adafruit_QDTech::setRotation(uint8_t m) { 353 | // Generally 0 - Portrait 1 - Landscape 354 | 355 | writecommand(QDTech_MADCTL); 356 | rotation = m % 4; // can't be higher than 3 357 | switch (rotation) { 358 | case 0: 359 | writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR); 360 | _width = QDTech_TFTWIDTH; 361 | _height = QDTech_TFTHEIGHT; 362 | break; 363 | case 1: 364 | writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR); 365 | _width = QDTech_TFTHEIGHT; 366 | _height = QDTech_TFTWIDTH; 367 | break; 368 | case 2: 369 | writedata(MADCTL_BGR); 370 | _width = QDTech_TFTWIDTH; 371 | _height = QDTech_TFTHEIGHT; 372 | break; 373 | case 3: 374 | // writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB); 375 | writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR); 376 | _width = QDTech_TFTHEIGHT; 377 | _height = QDTech_TFTWIDTH; 378 | break; 379 | } 380 | } 381 | 382 | 383 | void Adafruit_QDTech::invertDisplay(boolean i) { 384 | writecommand(i ? QDTech_INVON : QDTech_INVOFF); 385 | } 386 | -------------------------------------------------------------------------------- /Adafruit_QDTech.h: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is a modification of the Adafruit SPI LCD library, 3 | customised for hardware SPI and the QDTech board 4 | using a Samsung S6D02A1 chip. 5 | 6 | Most changes are made to the initialisation routine but 7 | non-Arduino code has been removed too. 8 | 9 | The initialisation sequence comes from Henning Karlsen's 10 | UTFT library: http://henningkarlsen.com 11 | 12 | Using the hardware SPI pins is highly recommeneded. 13 | 14 | You will also need the stock "Adafruit_GFX" library. 15 | https://github.com/adafruit/Adafruit-GFX-Library 16 | 17 | Gilchrist 30/1/2014 18 | 6/2/14 1.1 Fixed RGB colour order error 19 | 20 | /*************************************************** 21 | This is a library for the Adafruit 1.8" SPI display. 22 | This library works with the Adafruit 1.8" TFT Breakout w/SD card 23 | ----> http://www.adafruit.com/products/358 24 | as well as Adafruit raw 1.8" TFT display 25 | ----> http://www.adafruit.com/products/618 26 | 27 | Check out the links above for our tutorials and wiring diagrams 28 | These displays use SPI to communicate, 4 or 5 pins are required to 29 | interface (RST is optional) 30 | Adafruit invests time and resources providing this open source code, 31 | please support Adafruit and open-source hardware by purchasing 32 | products from Adafruit! 33 | 34 | Written by Limor Fried/Ladyada for Adafruit Industries. 35 | MIT license, all text above must be included in any redistribution 36 | ****************************************************/ 37 | 38 | #ifndef Adafruit_QDTech_h 39 | #define Adafruit_QDTech_h 40 | 41 | #if ARDUINO >= 100 42 | #include "Arduino.h" 43 | #include "Print.h" 44 | #else 45 | #include "WProgram.h" 46 | #endif 47 | 48 | #include 49 | #include 50 | 51 | #define QDTech_TFTWIDTH 128 52 | #define QDTech_TFTHEIGHT 160 53 | 54 | // Some used command definitions kept from original 55 | #define QDTech_INVOFF 0x20 56 | #define QDTech_INVON 0x21 57 | #define QDTech_DISPOFF 0x28 58 | #define QDTech_DISPON 0x29 59 | #define QDTech_CASET 0x2A 60 | #define QDTech_RASET 0x2B 61 | #define QDTech_RAMWR 0x2C 62 | #define QDTech_RAMRD 0x2E 63 | 64 | #define QDTech_PTLAR 0x30 65 | #define QDTech_COLMOD 0x3A 66 | #define QDTech_MADCTL 0x36 67 | 68 | // Basic colour definitions 69 | #define QDTech_BLACK 0x0000 70 | #define QDTech_RED 0xF800 71 | #define QDTech_GREEN 0x07E0 72 | #define QDTech_BLUE 0x001F 73 | #define QDTech_YELLOW 0xFFE0 74 | #define QDTech_MAGENTA 0xF81F 75 | #define QDTech_CYAN 0x07FF 76 | #define QDTech_WHITE 0xFFFF 77 | #define QDTech_GREY 0x632C 78 | 79 | 80 | class Adafruit_QDTech : public Adafruit_GFX { 81 | 82 | public: 83 | 84 | Adafruit_QDTech(uint8_t CS, uint8_t RS, uint8_t SID, uint8_t SCLK, uint8_t RST); 85 | Adafruit_QDTech(uint8_t CS, uint8_t RS, uint8_t RST); 86 | 87 | void init(), 88 | setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1), 89 | pushColor(uint16_t color), 90 | fillScreen(uint16_t color), 91 | drawPixel(int16_t x, int16_t y, uint16_t color), 92 | drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), 93 | drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), 94 | fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), 95 | setRotation(uint8_t r), 96 | invertDisplay(boolean i); 97 | 98 | uint16_t Color565(uint8_t r, uint8_t g, uint8_t b); 99 | 100 | private: 101 | uint8_t tabcolor; 102 | 103 | void spiwrite(uint8_t), 104 | writecommand(uint8_t c), 105 | writedata(uint8_t d), 106 | commandList(const uint8_t *addr), 107 | commonInit(const uint8_t *cmdList); 108 | 109 | boolean hwSPI; 110 | 111 | volatile uint8_t *dataport, *clkport, *csport, *rsport; 112 | uint8_t _cs, _rs, _rst, _sid, _sclk, 113 | datapinmask, clkpinmask, cspinmask, rspinmask, 114 | colstart, rowstart; // some displays need this changed 115 | 116 | }; 117 | #endif 118 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | *************************************************** 2 | This is a modification of the Adafruit SPI TFT LCD Arduino 3 | library, customised for hardware SPI and the QDTech 1.8" 4 | 128x160 pixel LCD board using a Samsung S6D02A1 chip. 5 | 6 | Most changes are made to the initialisation routine but 7 | non-Arduino code has been removed too. 8 | 9 | The initialisation sequence comes from Henning Karlsen's 10 | UTFT library: http://henningkarlsen.com 11 | 12 | Using the hardware SPI pins is highly recommeneded. 13 | 14 | Unzip and change the folder name to "Adafruit_QDTech". 15 | Copy the folder into your 16 | /libraries/ folder. 17 | 18 | You will also need the stock "Adafruit_GFX" library. 19 | https://github.com/adafruit/Adafruit-GFX-Library 20 | 21 | Gilchrist 30/1/2014 22 | 6/2/14 1.1 Fixed RGB colour order error 23 | 24 | *************************************************** 25 | 26 | This is a library for the Adafruit 1.8" SPI display. 27 | This library works with the Adafruit 1.8" TFT Breakout w/SD card 28 | ----> http://www.adafruit.com/products/358 29 | as well as Adafruit raw 1.8" TFT display 30 | ----> http://www.adafruit.com/products/618 31 | 32 | Check out the links above for our tutorials and wiring diagrams. 33 | These displays use SPI to communicate, 4 or 5 pins are required 34 | to interface (RST is optional). 35 | Adafruit invests time and resources providing this open source code, 36 | please support Adafruit and open-source hardware by purchasing 37 | products from Adafruit! 38 | 39 | Written by Limor Fried/Ladyada for Adafruit Industries. 40 | MIT license, all text above must be included in any redistribution 41 | 42 | To download. click the DOWNLOADS button in the top right corner, 43 | rename the uncompressed folder Adafruit_ST7735. Check that the 44 | Adafruit_ST7735 folder contains Adafruit_ST7735.cpp and Adafruit_ST7735. 45 | 46 | Place the Adafruit_ST7735 library folder your 47 | /libraries/ folder. You may need to create the 48 | libraries subfolder if its your first library. Restart the IDE 49 | 50 | Also requires the Adafruit_GFX library for Arduino. 51 | -------------------------------------------------------------------------------- /examples/TFT_Clock/TFT_Clock.ino: -------------------------------------------------------------------------------- 1 | /* 2 | An example analogue/digital clock using a TFT LCD screen to show the 3 | use of some of the drawing commands with the Adafruit_QDTech library. 4 | For a more accurate clock, it would be better to use the RTClib library. 5 | But this is just a demo. 6 | 7 | This examples uses the hardware SPI only. Non-hardware SPI 8 | is just too slow (~8 times slower!) 9 | 10 | Gilchrist 6/2/2014 1.0 11 | */ 12 | 13 | #define sclk 13 // Don't change 14 | #define mosi 11 // Don't change 15 | #define cs 9 16 | #define dc 8 17 | #define rst 7 // you can also connect this to the Arduino reset 18 | #include // Core graphics library 19 | #include // Hardware-specific library 20 | #include 21 | 22 | Adafruit_QDTech tft = Adafruit_QDTech(cs, dc, rst); // Invoke custom library 23 | 24 | float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers 25 | float sdeg=0, mdeg=0, hdeg=0; 26 | uint16_t osx=64, osy=64, omx=64, omy=64, ohx=64, ohy=64; // Saved H, M, S x & y coords 27 | uint16_t x0=0, x1=0, y0=0, y1=0; 28 | uint32_t targetTime = 0; // for next 1 second timeout 29 | uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6); // Get H, M, S from compile time 30 | 31 | void setup(void) { 32 | tft.init(); 33 | 34 | tft.setRotation(0); 35 | tft.fillScreen(QDTech_BLACK); 36 | tft.setTextColor(QDTech_WHITE, QDTech_BLACK); // Adding a black background colour erases previous text automatically 37 | 38 | // Draw clock face 39 | tft.fillCircle(64, 64, 61, QDTech_BLUE); 40 | tft.fillCircle(64, 64, 57, QDTech_BLACK); 41 | 42 | // Draw 12 lines 43 | for(int i = 0; i<360; i+= 30) { 44 | sx = cos((i-90)*0.0174532925); 45 | sy = sin((i-90)*0.0174532925); 46 | x0 = sx*57+64; 47 | y0 = sy*57+64; 48 | x1 = sx*50+64; 49 | y1 = sy*50+64; 50 | 51 | tft.drawLine(x0, y0, x1, y1, QDTech_BLUE); 52 | } 53 | tft.fillCircle(65, 65, 3, QDTech_RED); 54 | tft.setCursor (34, 151); 55 | tft.print(__DATE__); 56 | targetTime = millis() + 1000; 57 | } 58 | 59 | void loop() { 60 | if (targetTime < millis()) { 61 | targetTime = millis()+1000; 62 | ss++; // Advance second 63 | if (ss==60) { 64 | ss=0; 65 | mm++; // Advance minute 66 | if(mm>59) { 67 | mm=0; 68 | hh++; // Advance hour 69 | if (hh>23) { 70 | hh=0; 71 | } 72 | } 73 | } 74 | 75 | // Pre-compute hand degrees, x & y coords for a fast screen update 76 | sdeg = ss*6; // 0-59 -> 0-354 77 | mdeg = mm*6+sdeg*0.01666667; // 0-59 -> 0-360 - includes seconds 78 | hdeg = hh*30+mdeg*0.0833333; // 0-11 -> 0-360 - includes minutes and seconds 79 | hx = cos((hdeg-90)*0.0174532925); hy = sin((hdeg-90)*0.0174532925); 80 | mx = cos((mdeg-90)*0.0174532925); my = sin((mdeg-90)*0.0174532925); 81 | sx = cos((sdeg-90)*0.0174532925); sy = sin((sdeg-90)*0.0174532925); 82 | 83 | // Erase just old hand positions 84 | tft.drawLine(ohx, ohy, 65, 65, QDTech_BLACK); 85 | tft.drawLine(omx, omy, 65, 65, QDTech_BLACK); 86 | tft.drawLine(osx, osy, 65, 65, QDTech_BLACK); 87 | // Draw new hand positions 88 | tft.drawLine(hx*33+65, hy*33+65, 65, 65, QDTech_WHITE); 89 | tft.drawLine(mx*44+65, my*44+65, 65, 65, QDTech_WHITE); 90 | tft.drawLine(sx*47+65, sy*47+65, 65, 65, QDTech_RED); 91 | tft.fillCircle(65, 65, 3, QDTech_RED); 92 | 93 | // Update old x&y coords 94 | osx = sx*47+65; osy = sy*47+65; 95 | omx = mx*44+65; omy = my*44+65; 96 | ohx = hx*33+65; ohy = hy*33+65; 97 | 98 | // Update digital time 99 | tft.setCursor (34, 140); 100 | 101 | if(hh>12) { 102 | if (hh<22) tft.print('0'); 103 | tft.print (hh-12); 104 | } else { 105 | if (hh<10) tft.print('0'); 106 | tft.print (hh); 107 | } 108 | tft.print (':'); 109 | if (mm<10) tft.print('0'); 110 | tft.print (mm); 111 | tft.print (':'); 112 | if (ss<10) tft.print('0'); 113 | tft.print (ss); 114 | if (hh>12) tft.print(" pm"); else tft.print (" am"); 115 | } 116 | } 117 | 118 | static uint8_t conv2d(const char* p) { 119 | uint8_t v = 0; 120 | if ('0' <= *p && *p <= '9') 121 | v = *p - '0'; 122 | return 10 * v + *++p - '0'; 123 | } 124 | -------------------------------------------------------------------------------- /examples/graphicstest_QDTech/graphicstest_QDTech.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is a modification of the Adafruit SPI LCD library example, 3 | customised for just hardware SPI and the QDTech board 4 | using a Samsung S6D02A1 chip. 5 | Most changes are made to the initialisation routines. 6 | CSA 30/1/2014 7 | 8 | /*************************************************** 9 | This is an example sketch for the Adafruit 1.8" SPI display. 10 | This library works with the Adafruit 1.8" TFT Breakout w/SD card 11 | ----> http://www.adafruit.com/products/358 12 | as well as Adafruit raw 1.8" TFT display 13 | ----> http://www.adafruit.com/products/618 14 | 15 | Check out the links above for our tutorials and wiring diagrams 16 | These displays use SPI to communicate, 4 or 5 pins are required to 17 | interface (RST is optional) 18 | Adafruit invests time and resources providing this open source code, 19 | please support Adafruit and open-source hardware by purchasing 20 | products from Adafruit! 21 | 22 | Written by Limor Fried/Ladyada for Adafruit Industries. 23 | MIT license, all text above must be included in any redistribution 24 | ****************************************************/ 25 | 26 | // This examples uses the hardware SPI only. Non-hardware SPI 27 | // is just too slow (~8 times slower!) 28 | 29 | #define sclk 13 // Don't change 30 | #define mosi 11 // Don't change 31 | #define cs 9 32 | #define dc 8 33 | #define rst 7 // you can also connect this to the Arduino reset 34 | #include // Core graphics library 35 | #include // Hardware-specific library 36 | #include 37 | 38 | Adafruit_QDTech tft = Adafruit_QDTech(cs, dc, rst); // Invoke custom library 39 | float p = 3.1415926; 40 | 41 | void setup(void) { 42 | tft.init(); 43 | 44 | uint16_t time = millis(); 45 | tft.setRotation(0); // 0 - Portrait, 1 - Lanscape 46 | tft.fillScreen(QDTech_BLACK); 47 | tft.setTextWrap(true); 48 | 49 | delay(500); 50 | 51 | // large block of text 52 | tft.fillScreen (QDTech_BLACK); 53 | tft.fillRect (0, 0, 128, 16, QDTech_GREY); 54 | tft.fillRect (0, 24, 128, 16 ,QDTech_BLUE); 55 | testdrawtext (" 111111111222123456789012345678901\nScreen is 21 x 20\ncharacters in size.\n", QDTech_WHITE); 56 | 57 | tft.setCursor (1, 48); 58 | tft.println ("\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz~ right up to ASCII 255\n\nThe quick brown fox jumped over the lazy dog.\n\n"); 59 | 60 | tft.setTextColor(QDTech_RED); 61 | tft.setCursor (1, 134); 62 | tft.println ("Countdown:"); 63 | 64 | tft.setTextColor (QDTech_BLACK); 65 | tft.setTextSize (2); 66 | for (int i=6; i>=0; i--) { 67 | tft.setCursor (2, 144); 68 | tft.fillRect (0, 142, 128, 18, QDTech_RED); 69 | tft.print (i); 70 | tft.print (" seconds"); 71 | delay(1000); 72 | } 73 | 74 | tft.setTextSize(1); 75 | 76 | // tft print function! 77 | tftPrintTest(); 78 | delay(3000); 79 | 80 | // a single pixel 81 | tft.drawPixel(tft.width()/2, tft.height()/2, QDTech_GREEN); 82 | delay(500); 83 | 84 | // line draw test 85 | testlines(QDTech_YELLOW); 86 | delay(500); 87 | 88 | // optimized lines 89 | testfastlines(QDTech_RED, QDTech_BLUE); 90 | delay(500); 91 | 92 | testdrawrects(QDTech_GREEN); 93 | delay(500); 94 | 95 | testfillrects(QDTech_YELLOW, QDTech_MAGENTA); 96 | delay(500); 97 | 98 | tft.fillScreen(QDTech_BLACK); 99 | testfillcircles(10, QDTech_BLUE); 100 | testdrawcircles(10, QDTech_WHITE); 101 | delay(500); 102 | 103 | testroundrects(); 104 | delay(500); 105 | 106 | testmultifillcircles(60); 107 | delay(500); 108 | 109 | testtriangles(); 110 | delay(500); 111 | 112 | mediabuttons(); 113 | delay(500); 114 | } 115 | 116 | void loop() { 117 | tft.invertDisplay(true); 118 | delay(500); 119 | tft.invertDisplay(false); 120 | delay(500); 121 | 122 | } 123 | 124 | void testlines(uint16_t color) { 125 | tft.fillScreen(QDTech_BLACK); 126 | for (int16_t x=0; x < tft.width(); x+=6) { 127 | tft.drawLine(0, 0, x, tft.height()-1, color); 128 | } 129 | for (int16_t y=0; y < tft.height(); y+=6) { 130 | tft.drawLine(0, 0, tft.width()-1, y, color); 131 | } 132 | 133 | tft.fillScreen(QDTech_BLACK); 134 | for (int16_t x=0; x < tft.width(); x+=6) { 135 | tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color); 136 | } 137 | for (int16_t y=0; y < tft.height(); y+=6) { 138 | tft.drawLine(tft.width()-1, 0, 0, y, color); 139 | } 140 | 141 | tft.fillScreen(QDTech_BLACK); 142 | for (int16_t x=0; x < tft.width(); x+=6) { 143 | tft.drawLine(0, tft.height()-1, x, 0, color); 144 | } 145 | for (int16_t y=0; y < tft.height(); y+=6) { 146 | tft.drawLine(0, tft.height()-1, tft.width()-1, y, color); 147 | } 148 | 149 | tft.fillScreen(QDTech_BLACK); 150 | for (int16_t x=0; x < tft.width(); x+=6) { 151 | tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color); 152 | } 153 | for (int16_t y=0; y < tft.height(); y+=6) { 154 | tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color); 155 | } 156 | } 157 | 158 | void testdrawtext(char *text, uint16_t color) { 159 | tft.setCursor(0, 0); 160 | tft.setTextColor(color); 161 | tft.setTextWrap(true); 162 | tft.print(text); 163 | } 164 | 165 | void testfastlines(uint16_t color1, uint16_t color2) { 166 | tft.fillScreen(QDTech_BLACK); 167 | for (int16_t y=0; y < tft.height(); y+=5) { 168 | tft.drawFastHLine(0, y, tft.width(), color1); 169 | } 170 | for (int16_t x=0; x < tft.width(); x+=5) { 171 | tft.drawFastVLine(x, 0, tft.height(), color2); 172 | } 173 | } 174 | 175 | void testdrawrects(uint16_t color) { 176 | tft.fillScreen(QDTech_BLACK); 177 | for (int16_t x=0; x < tft.width(); x+=6) { 178 | tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color); 179 | } 180 | } 181 | 182 | void testfillrects(uint16_t color1, uint16_t color2) { 183 | tft.fillScreen(QDTech_BLACK); 184 | for (int16_t x=tft.width()-1; x > 6; x-=6) { 185 | tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1); 186 | tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2); 187 | } 188 | } 189 | 190 | void testfillcircles(uint8_t radius, uint16_t color) { 191 | for (int16_t x=radius; x < tft.width(); x+=radius*2) { 192 | for (int16_t y=radius; y < tft.height(); y+=radius*2) { 193 | tft.fillCircle(x, y, radius, color); 194 | } 195 | } 196 | } 197 | 198 | void testmultifillcircles(uint8_t radius) { 199 | uint8_t x = tft.width() / 2; 200 | uint8_t y = tft.height() / 2; 201 | for (uint8_t i=radius; i>1; i-=1) { 202 | tft.fillCircle(x, y, i, tft.Color565 (i, 255-(i*2), 0)); 203 | } 204 | } 205 | 206 | void testdrawcircles(uint8_t radius, uint16_t color) { 207 | for (int16_t x=0; x < tft.width()+radius; x+=radius*2) { 208 | for (int16_t y=0; y < tft.height()+radius; y+=radius*2) { 209 | tft.drawCircle(x, y, radius, color); 210 | } 211 | } 212 | } 213 | 214 | void testtriangles() { 215 | tft.fillScreen(QDTech_BLACK); 216 | int color = 0xF800; 217 | int t; 218 | int w = 63; 219 | int x = 159; 220 | int y = 0; 221 | int z = 127; 222 | for(t = 0 ; t <= 15; t+=1) { 223 | tft.drawTriangle(w, y, y, x, z, x, color); 224 | x-=4; 225 | y+=4; 226 | z-=4; 227 | color+=100; 228 | } 229 | } 230 | 231 | void testroundrects() { 232 | tft.fillScreen(QDTech_BLACK); 233 | int color = 100; 234 | int i; 235 | int t; 236 | for(t = 0 ; t <= 4; t+=1) { 237 | int x = 0; 238 | int y = 0; 239 | int w = 127; 240 | int h = 159; 241 | for(i = 0 ; i <= 24; i+=1) { 242 | tft.drawRoundRect(x, y, w, h, 5, color); 243 | x+=2; 244 | y+=3; 245 | w-=4; 246 | h-=6; 247 | color+=1100; 248 | } 249 | color+=100; 250 | } 251 | } 252 | 253 | void tftPrintTest() { 254 | tft.setTextWrap(false); 255 | tft.fillScreen(QDTech_BLACK); 256 | tft.setCursor(0, 30); 257 | tft.setTextColor(QDTech_RED); 258 | tft.setTextSize(1); 259 | tft.println("Hello World!"); 260 | tft.setTextColor(QDTech_YELLOW); 261 | tft.setTextSize(2); 262 | tft.println("Hello World!"); 263 | tft.setTextColor(QDTech_GREEN); 264 | tft.setTextSize(3); 265 | tft.println("Hello World!"); 266 | tft.setTextColor(QDTech_BLUE); 267 | tft.setTextSize(4); 268 | tft.print(1234.567); 269 | delay(1500); 270 | tft.setCursor(0, 0); 271 | tft.fillScreen(QDTech_BLACK); 272 | tft.setTextColor(QDTech_WHITE); 273 | tft.setTextSize(0); 274 | tft.println("Hello World!"); 275 | tft.setTextSize(1); 276 | tft.setTextColor(QDTech_GREEN); 277 | tft.print(p, 6); 278 | tft.println(" Want pi?"); 279 | tft.println(" "); 280 | tft.print(8675309, HEX); // print 8,675,309 out in HEX! 281 | tft.println(" Print HEX!"); 282 | tft.println(" "); 283 | tft.setTextColor(QDTech_WHITE); 284 | tft.println("Sketch has been"); 285 | tft.println("running for: "); 286 | tft.setTextColor(QDTech_MAGENTA); 287 | tft.print(millis() / 1000); 288 | tft.setTextColor(QDTech_WHITE); 289 | tft.print(" seconds."); 290 | } 291 | 292 | void mediabuttons() { 293 | // play 294 | tft.fillScreen(QDTech_BLACK); 295 | tft.fillRoundRect(25, 10, 78, 60, 8, QDTech_WHITE); 296 | tft.fillTriangle(42, 20, 42, 60, 90, 40, QDTech_RED); 297 | delay(500); 298 | // pause 299 | tft.fillRoundRect(25, 90, 78, 60, 8, QDTech_WHITE); 300 | tft.fillRoundRect(39, 98, 20, 45, 5, QDTech_GREEN); 301 | tft.fillRoundRect(69, 98, 20, 45, 5, QDTech_GREEN); 302 | delay(500); 303 | // play color 304 | tft.fillTriangle(42, 20, 42, 60, 90, 40, QDTech_BLUE); 305 | delay(50); 306 | // pause color 307 | tft.fillRoundRect(39, 98, 20, 45, 5, QDTech_RED); 308 | tft.fillRoundRect(69, 98, 20, 45, 5, QDTech_RED); 309 | // play color 310 | tft.fillTriangle(42, 20, 42, 60, 90, 40, QDTech_GREEN); 311 | } 312 | --------------------------------------------------------------------------------