From 1bab2aa1070dbaf65dfe06be49d231d63531a8f7 Mon Sep 17 00:00:00 2001 From: Mike C Date: Sun, 10 Mar 2013 22:05:44 -0400 Subject: [PATCH] Added SparkFun ColorLCDLibrary which this project depends upon --- Libraries/ColorLCDShield/ColorLCDShield.cpp | 623 ++++++++++++++++++ Libraries/ColorLCDShield/ColorLCDShield.h | 384 +++++++++++ .../ChronoLCD_Color/ChronoLCD_Color.ino | 247 +++++++ .../LCD_with_Arc_Function.ino | 41 ++ .../Examples/TestPattern/TestPattern.ino | 79 +++ .../Examples/ZanyCircles/ZanyCircles.ino | 87 +++ Libraries/ColorLCDShield/keywords.txt | 28 + 7 files changed, 1489 insertions(+) create mode 100644 Libraries/ColorLCDShield/ColorLCDShield.cpp create mode 100644 Libraries/ColorLCDShield/ColorLCDShield.h create mode 100644 Libraries/ColorLCDShield/Examples/ChronoLCD_Color/ChronoLCD_Color.ino create mode 100644 Libraries/ColorLCDShield/Examples/LCD_with_Arc_Function/LCD_with_Arc_Function.ino create mode 100644 Libraries/ColorLCDShield/Examples/TestPattern/TestPattern.ino create mode 100644 Libraries/ColorLCDShield/Examples/ZanyCircles/ZanyCircles.ino create mode 100644 Libraries/ColorLCDShield/keywords.txt diff --git a/Libraries/ColorLCDShield/ColorLCDShield.cpp b/Libraries/ColorLCDShield/ColorLCDShield.cpp new file mode 100644 index 0000000..96ceaab --- /dev/null +++ b/Libraries/ColorLCDShield/ColorLCDShield.cpp @@ -0,0 +1,623 @@ +/* + LCDShield.cpp - Arduino Library to control a Nokia 6100 LCD, + specifically that found on SparkFun's Color LCD Shield. + This code should work for both Epson and Phillips display drivers + normally found on the Color LCD Shield. + + License: CC BY-SA 3.0: Creative Commons Share-alike 3.0. Feel free + to use and abuse this code however you'd like. If you find it useful + please attribute, and SHARE-ALIKE! + + This is based on code by Mark Sproul, and Peter Davenport. + Thanks to Coleman Sellers and Harold Timmis for help getting it to work with the Phillips Driver 7-31-2011 +*/ + +#include "ColorLCDShield.h" + +/*extern "C" { + #include "wiring.h" +}*/ + +#include "Arduino.h" + +static char x_offset = 0; +static char y_offset = 0; + +LCDShield::LCDShield() +{ + +#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) + DDRB = ((1<68, 132<-69 scan direction + + LCDCommand(OSCON); // internal oscialltor ON (0xD1) + LCDCommand(SLPOUT); // sleep out (0x94) + + LCDCommand(PWRCTR); // power ctrl (0x20) + LCDData(0x0F); // everything on, no external reference resistors + + LCDCommand(DISINV); // invert display mode (0xA7) + + LCDCommand(DATCTL); // data control (0xBC) + LCDData(0x03); // Inverse page address, reverse rotation column address, column scan-direction !!! try 0x01 + LCDData(0x00); // normal RGB arrangement + LCDData(0x02); // 16-bit Grayscale Type A (12-bit color) + + LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness (0x81) + LCDData(32); // volume (contrast) setting - fine tuning, original (0-63) + LCDData(3); // internal resistor ratio - coarse adjustment (0-7) + + LCDCommand(NOP); // nop (0x25) + + delay(100); + + LCDCommand(DISON); // display on (0xAF) + } + else if (driver == PHILIPS) + { + LCDCommand(SLEEPOUT); // Sleep Out (0x11) + LCDCommand(BSTRON); // Booster voltage on (0x03) + LCDCommand(DISPON); // Display on (0x29) + + //LCDCommand(INVON); // Inversion on (0x20) + + // 12-bit color pixel format: + LCDCommand(COLMOD); // Color interface format (0x3A) + LCDData(0x03); // 0b011 is 12-bit/pixel mode + + LCDCommand(MADCTL); // Memory Access Control(PHILLIPS) + if (colorSwap) + LCDData(0x08); + else + LCDData(0x00); + + LCDCommand(SETCON); // Set Contrast(PHILLIPS) + LCDData(0x30); + + LCDCommand(NOPP); // nop(PHILLIPS) + } +} + +void LCDShield::clear(int color) +{ + if (driver) // if it's an Epson + { + LCDCommand(PASET); + LCDData(0); + LCDData(131); + + LCDCommand(CASET); + LCDData(0); + LCDData(131); + + LCDCommand(RAMWR); + } + else // otherwise it's a phillips + { + LCDCommand(PASETP); + LCDData(0); + LCDData(131); + + LCDCommand(CASETP); + LCDData(0); + LCDData(131); + + LCDCommand(RAMWRP); + } + + for(unsigned int i=0; i < (131*131)/2; i++) + { + LCDData((color>>4)&0x00FF); + LCDData(((color&0x0F)<<4)|(color>>8)); + LCDData(color&0x0FF); + } + + x_offset = 0; + y_offset = 0; +} + +void LCDShield::contrast(char setting) +{ + if (driver == EPSON) + { + setting &= 0x3F; // 2 msb's not used, mask out + LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON) + LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24 + LCDData(3); // TODO: Make this coarse adjustment variable, 3's a good place to stay + } + else if (driver == PHILIPS) + { + setting &= 0x7F; // msb is not used, mask it out + LCDCommand(SETCON); // contrast command (PHILLIPS) + LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24 + } +} + +// Added by Steve Sparks @ Big Nerd Ranch. +// This swaps the Epson RGB order into the Philips RGB order. (Or, vice versa, I suppose.) +uint16_t LCDShield::swapColors(uint16_t in) { + return ((in & 0x000F)<<8)|(in & 0x00F0)|((in & 0x0F00)>>8); +} + +void LCDShield::setPixel(int color, unsigned char x, unsigned char y) +{ + y = (COL_HEIGHT - 1) - y; + x = (ROW_LENGTH - 1) - x; + + if (driver == EPSON) // if it's an epson + { + LCDCommand(PASET); // page start/end ram + LCDData(x); + LCDData(ENDPAGE); + + LCDCommand(CASET); // column start/end ram + LCDData(y); + LCDData(ENDCOL); + + LCDCommand(RAMWR); // write + LCDData((color>>4)&0x00FF); + LCDData(((color&0x0F)<<4)|(color>>8)); + LCDData(color&0x0FF); + } + else if (driver == PHILIPS) // otherwise it's a phillips + { + LCDCommand(PASETP); // page start/end ram + LCDData(x); + LCDData(x); + + LCDCommand(CASETP); // column start/end ram + LCDData(y); + LCDData(y); + + LCDCommand(RAMWRP); // write + + LCDData((unsigned char)((color>>4)&0x00FF)); + LCDData((unsigned char)(((color&0x0F)<<4)|0x00)); + } +} +// 2/18/2013 This Methos added by Tony Contrada in order to create arc segments in varied line thickness, or Filled +void LCDShield::setArc(int x0, int y0, int radius, int arcSegments[], int numSegments, int lineThickness, int color) +{ + //Line Thickness (Num Pixels) + if(lineThickness == FILL) lineThickness = radius; + for(int i = 0; i < lineThickness; i++) + { + int f = 1 - radius; + int ddF_x = 0; + int ddF_y = -2 * radius; + int x = 0; + int y = radius; + while(x < y) + { + if(f >= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x + 1; + + for(int i = 0; i < numSegments; i++) + { + if(arcSegments[i] == NNE) setPixel(color, x0 - y, y0 + x); //SHOW NNE + if(arcSegments[i] == ENE) setPixel(color, x0 - x, y0 + y); //SHOW ENE + if(arcSegments[i] == ESE) setPixel(color, x0 + x, y0 + y); //SHOW ESE + if(arcSegments[i] == SSE) setPixel(color, x0 + y, y0 + x); //SHOW SSE + if(arcSegments[i] == SSW) setPixel(color, x0 + y, y0 - x); //SHOW SSW + if(arcSegments[i] == WSW) setPixel(color, x0 + x, y0 - y); //SHOW WSW + if(arcSegments[i] == WNW) setPixel(color, x0 - x, y0 - y); //SHOW WNW + if(arcSegments[i] == NNW) setPixel(color, x0 - y, y0 - x); //SHOW NNW + } + + } + radius--; + } + +} + +// 2/22/2013 - Modified by Tony Contrada to include Line Thickness (in pixels) or a Filled Circle +void LCDShield::setCircle (int x0, int y0, int radius, int color, int lineThickness) +{ + if(lineThickness == FILL) lineThickness = radius; + + for(int r = 0; r < lineThickness; r++) + { + int f = 1 - radius; + int ddF_x = 0; + int ddF_y = -2 * radius; + int x = 0; + int y = radius; + + setPixel(color, x0, y0 + radius); + setPixel(color, x0, y0 - radius); + setPixel(color, x0 + radius, y0); + setPixel(color, x0 - radius, y0); + + while(x < y) + { + if(f >= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x + 1; + + setPixel(color, x0 + x, y0 + y); + setPixel(color, x0 - x, y0 + y); + setPixel(color, x0 + x, y0 - y); + setPixel(color, x0 - x, y0 - y); + setPixel(color, x0 + y, y0 + x); + setPixel(color, x0 - y, y0 + x); + setPixel(color, x0 + y, y0 - x); + setPixel(color, x0 - y, y0 - x); + } + radius--; + } + +} + +void LCDShield::setChar(char c, int x, int y, int fColor, int bColor) +{ + y = (COL_HEIGHT - 1) - y; // make display "right" side up + x = (ROW_LENGTH - 2) - x; + + int i,j; + unsigned int nCols; + unsigned int nRows; + unsigned int nBytes; + unsigned char PixelRow; + unsigned char Mask; + unsigned int Word0; + unsigned int Word1; + unsigned char *pFont; + unsigned char *pChar; + + // get pointer to the beginning of the selected font table + pFont = (unsigned char *)FONT8x16; + // get the nColumns, nRows and nBytes + nCols = *pFont; + nRows = *(pFont + 1); + nBytes = *(pFont + 2); + // get pointer to the last byte of the desired character + pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1; + + if (driver) // if it's an epson + { + // Row address set (command 0x2B) + LCDCommand(PASET); + LCDData(x); + LCDData(x + nRows - 1); + // Column address set (command 0x2A) + LCDCommand(CASET); + LCDData(y); + LCDData(y + nCols - 1); + + // WRITE MEMORY + LCDCommand(RAMWR); + // loop on each row, working backwards from the bottom to the top + for (i = nRows - 1; i >= 0; i--) { + // copy pixel row from font table and then decrement row + PixelRow = *pChar++; + // loop on each pixel in the row (left to right) + // Note: we do two pixels each loop + Mask = 0x80; + for (j = 0; j < nCols; j += 2) + { + // if pixel bit set, use foreground color; else use the background color + // now get the pixel color for two successive pixels + if ((PixelRow & Mask) == 0) + Word0 = bColor; + else + Word0 = fColor; + Mask = Mask >> 1; + if ((PixelRow & Mask) == 0) + Word1 = bColor; + else + Word1 = fColor; + Mask = Mask >> 1; + // use this information to output three data bytes + LCDData((Word0 >> 4) & 0xFF); + LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF)); + LCDData(Word1 & 0xFF); + } + } + } + else + { + fColor = swapColors(fColor); + bColor = swapColors(bColor); + + // Row address set (command 0x2B) + LCDCommand(PASETP); + LCDData(x); + LCDData(x + nRows - 1); + // Column address set (command 0x2A) + LCDCommand(CASETP); + LCDData(y); + LCDData(y + nCols - 1); + + // WRITE MEMORY + LCDCommand(RAMWRP); + // loop on each row, working backwards from the bottom to the top + pChar+=nBytes-1; // stick pChar at the end of the row - gonna reverse print on phillips + for (i = nRows - 1; i >= 0; i--) { + // copy pixel row from font table and then decrement row + PixelRow = *pChar--; + // loop on each pixel in the row (left to right) + // Note: we do two pixels each loop + Mask = 0x01; // <- opposite of epson + for (j = 0; j < nCols; j += 2) + { + // if pixel bit set, use foreground color; else use the background color + // now get the pixel color for two successive pixels + if ((PixelRow & Mask) == 0) + Word0 = bColor; + else + Word0 = fColor; + Mask = Mask << 1; // <- opposite of epson + if ((PixelRow & Mask) == 0) + Word1 = bColor; + else + Word1 = fColor; + Mask = Mask << 1; // <- opposite of epson + // use this information to output three data bytes + LCDData((Word0 >> 4) & 0xFF); + LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF)); + LCDData(Word1 & 0xFF); + } + } + } +} + + +void LCDShield::setStr(char *pString, int x, int y, int fColor, int bColor) +{ + x = x + 16; + y = y + 8; + int originalY = y; + + // loop until null-terminator is seen + while (*pString != 0x00) { + // draw the character + setChar(*pString++, x, y, fColor, bColor); + // advance the y position + y = y + 8; + // bail out if y exceeds 131 + if (y > 131) { + x = x + 16; + y = originalY; + } + if (x > 123) break; + } +} + +void LCDShield::setLine(int x0, int y0, int x1, int y1, int color) +{ + int dy = y1 - y0; // Difference between y0 and y1 + int dx = x1 - x0; // Difference between x0 and x1 + int stepx, stepy; + + if (dy < 0) + { + dy = -dy; + stepy = -1; + } + else + stepy = 1; + + if (dx < 0) + { + dx = -dx; + stepx = -1; + } + else + stepx = 1; + + dy <<= 1; // dy is now 2*dy + dx <<= 1; // dx is now 2*dx + setPixel(color, x0, y0); + + if (dx > dy) + { + int fraction = dy - (dx >> 1); + while (x0 != x1) + { + if (fraction >= 0) + { + y0 += stepy; + fraction -= dx; + } + x0 += stepx; + fraction += dy; + setPixel(color, x0, y0); + } + } + else + { + int fraction = dx - (dy >> 1); + while (y0 != y1) + { + if (fraction >= 0) + { + x0 += stepx; + fraction -= dy; + } + y0 += stepy; + fraction += dx; + setPixel(color, x0, y0); + } + } +} + +void LCDShield::setRect(int x0, int y0, int x1, int y1, unsigned char fill, int color) +{ + // check if the rectangle is to be filled + if (fill == 1) + { + int xDiff; + + if(x0 > x1) + xDiff = x0 - x1; //Find the difference between the x vars + else + xDiff = x1 - x0; + + while(xDiff > 0) + { + setLine(x0, y0, x0, y1, color); + + if(x0 > x1) + x0--; + else + x0++; + + xDiff--; + } + + } + else + { + // best way to draw an unfilled rectangle is to draw four lines + setLine(x0, y0, x1, y0, color); + setLine(x0, y1, x1, y1, color); + setLine(x0, y0, x0, y1, color); + setLine(x1, y0, x1, y1, color); + } +} + +void LCDShield::printLogo(void) +{ + int x = 4, y = 25, logo_ix = 0, z; + char logo; + + for (logo_ix = 0; logo_ix < 1120; logo_ix++) + { + logo = logo_spark[logo_ix]; + for (z = 0; z < 8; z++) + { + if ((logo & 0x80) == 0x80) setPixel(RED, y, x); + x++; + if (x == 132) + { + x = 4; + y++; + } + logo <<= 1; + } + } +} + +void LCDShield::off(void) +{ + if (driver) // If it's an epson + LCDCommand(DISOFF); + else // otherwise it's a phillips + LCDCommand(DISPOFF); +} + +void LCDShield::on(void) +{ + if (driver) // If it's an epson + LCDCommand(DISON); + else // otherwise it's a phillips + LCDCommand(DISPON); +} + diff --git a/Libraries/ColorLCDShield/ColorLCDShield.h b/Libraries/ColorLCDShield/ColorLCDShield.h new file mode 100644 index 0000000..8af59ef --- /dev/null +++ b/Libraries/ColorLCDShield/ColorLCDShield.h @@ -0,0 +1,384 @@ +/* + ColorLCDShield.h - Arduino Library to control a Nokia 6100 LCD, + specifically that found on SparkFun's Color LCD Shield. + This code should work for both Epson and Phillips display drivers + normally found on the Color LCD Shield. + + License: CC BY-SA 3.0: Creative Commons Share-alike 3.0. Feel free + to use and abuse this code however you'd like. If you find it useful + please attribute, and SHARE-ALIKE! + + This is based on code by Mark Sproul, and Peter Davenport. +*/ + +#ifndef ColorLCDShield_H +#define ColorLCDShield_H + +#define PHILLIPS 0 +#define PHILIPS 0 +#define EPSON 1 + +//#include + +#include + +//******************************************************* +// Macros +//******************************************************* +#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask)) +#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask)) + +//******************************************************************** +// +// LCD Dimension Definitions +// +//******************************************************************** +#define ROW_LENGTH 132 +#define COL_HEIGHT 132 +#define ENDPAGE 132 +#define ENDCOL 130 + +//******************************************************************** +// +// EPSON Controller Definitions +// +//******************************************************************** +#define DISON 0xAF // Display on +#define DISOFF 0xAE // Display off +#define DISNOR 0xA6 // Normal display +#define DISINV 0xA7 // Inverse display +#define SLPIN 0x95 // Sleep in +#define SLPOUT 0x94 // Sleep out +#define COMSCN 0xBB // Common scan direction +#define DISCTL 0xCA // Display control +#define PASET 0x75 // Page address set +#define CASET 0x15 // Column address set +#define DATCTL 0xBC // Data scan direction, etc. +#define RGBSET8 0xCE // 256-color position set +#define RAMWR 0x5C // Writing to memory +#define RAMRD 0x5D // Reading from memory +#define PTLIN 0xA8 // Partial display in +#define PTLOUT 0xA9 // Partial display out +#define RMWIN 0xE0 // Read and modify write +#define RMWOUT 0xEE // End +#define ASCSET 0xAA // Area scroll set +#define SCSTART 0xAB // Scroll start set +#define OSCON 0xD1 // Internal oscillation on +#define OSCOFF 0xD2 // Internal osciallation off +#define PWRCTR 0x20 // Power control +#define VOLCTR 0x81 // Electronic volume control +#define VOLUP 0xD6 // Increment electronic control by 1 +#define VOLDOWN 0xD7 // Decrement electronic control by 1 +#define TMPGRD 0x82 // Temperature gradient set +#define EPCTIN 0xCD // Control EEPROM +#define EPCOUT 0xCC // Cancel EEPROM control +#define EPMWR 0xFC // Write into EEPROM +#define EPMRD 0xFD // Read from EEPROM +#define EPSRRD1 0x7C // Read register 1 +#define EPSRRD2 0x7D // Read register 2 +#define NOP 0x25 // No op + +//******************************************************************** +// +// PHILLIPS Controller Definitions +// +//******************************************************************** +//LCD Commands +#define NOPP 0x00 // No operation +#define BSTRON 0x03 // Booster voltage on +#define SLEEPIN 0x10 // Sleep in +#define SLEEPOUT 0x11 // Sleep out +#define NORON 0x13 // Normal display mode on +#define INVOFF 0x20 // Display inversion off +#define INVON 0x21 // Display inversion on +#define SETCON 0x25 // Set contrast +#define DISPOFF 0x28 // Display off +#define DISPON 0x29 // Display on +#define CASETP 0x2A // Column address set +#define PASETP 0x2B // Page address set +#define RAMWRP 0x2C // Memory write +#define RGBSET 0x2D // Color set +#define MADCTL 0x36 // Memory data access control +#define COLMOD 0x3A // Interface pixel format +#define DISCTR 0xB9 // Super frame inversion +#define EC 0xC0 // Internal or external oscillator + +//******************************************************* +// 12-Bit Color Definitions +//******************************************************* +#define BLACK 0x000 +#define NAVY 0x008 +#define BLUE 0x00F +#define TEAL 0x088 +#define EMERALD 0x0C5 +#define GREEN 0x0F0 +#define CYAN 0x0FF +#define SLATE 0x244 +#define INDIGO 0x408 +#define TURQUOISE 0x4ED +#define OLIVE 0x682 +#define MAROON 0x800 +#define PURPLE 0x808 +#define GRAY 0x888 +#define SKYBLUE 0x8CE +#define BROWN 0xB22 +#define CRIMSON 0xD13 +#define ORCHID 0xD7D +#define RED 0xF00 +#define MAGENTA 0xF0F +#define ORANGE 0xF40 +#define PINK 0xF6A +#define CORAL 0xF75 +#define SALMON 0xF87 +#define GOLD 0xFD0 +#define YELLOW 0xFF0 +#define WHITE 0xFFF + +//******************************************************* +// Circle Definitions +//******************************************************* +#define FILL 0 + +//****************************************************** +// Arc Definitions +//****************************************************** +#define ESE 1 +#define ENE 2 +#define WSW 3 +#define WNW 4 +#define SSE 5 +#define NNE 6 +#define SSW 7 +#define NNW 8 + +#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) + //* Arduino Mega 2560 bit numbers + #define LCD_RES 5 // D8 + #define CS 6 // D9 + #define DIO 5 // D11 + #define SCK_PIN 7 // D13 + + //* Arduino Mega ports + //* NOTE: See LCDShield::LCDShield() if making changes here + #define LCD_PORT_CS PORTH + #define LCD_PORT_SCK PORTB + #define LCD_PORT_RES PORTH + #define LCD_PORT_DIO PORTB +#elif defined (__AVR_ATmega32U4__) + //* Standard Arduino Leonardo port bits + #define LCD_RES 4 // D8 + #define CS 5 // D9 + #define DIO 7 // D11 + #define SCK_PIN 7 // D13 + + //* Arduino Leonardo ports: + #define LCD_PORT_RES PORTB + #define LCD_PORT_CS PORTB + #define LCD_PORT_DIO PORTB + #define LCD_PORT_SCK PORTC +#else + //* Arduino Duemilanove bit numbers + #define LCD_RES 0 // D8 + #define CS 1 // D9 + #define DIO 3 // D11 + #define SCK_PIN 5 // D13 + //#define LCD_PORT PORTB + + //* Arduino Duemilanove ports + #define LCD_PORT_CS PORTB + #define LCD_PORT_SCK PORTB + #define LCD_PORT_RES PORTB + #define LCD_PORT_DIO PORTB +#endif + +const unsigned char FONT8x16[97][16] = { +{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes, ... +{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes, ... +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ' ' +{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // '!' +{0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // '"' +{0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // '#' +{0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00}, // '$' +{0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00}, // '%' +{0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, +{0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // '0' +{0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00}, // '5' +{0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // ':' +{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, +{0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // 'A' +{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00}, // 'C' +{0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // 'H' +{0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00}, +{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, +{0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, +{0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // 'Z' +{0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00}, // '\' +{0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, +{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // '^' +{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // '_' +{0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00}, // '`' +{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // 'a' +{0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00}, +{0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00}, +{0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00}, // 't' +{0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00}, +{0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00}, // 'z' +{0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}, // '{' +{0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00}, // '|' +{0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00}, // '}' +{0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // '~' +}; + +static char logo_spark[1120] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x20,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0f,0xe0,0x9f,0x01,0xfc,0x09,0x9e,0x1e,0x7f,0x70,0x73,0x9f,0x00,0x00,0x00,0x00, +0x3f,0xf1,0xff,0x87,0xfe,0x3f,0xde,0x3d,0xff,0x78,0xf3,0xff,0x80,0x00,0x00,0x00, +0x3c,0xf9,0xff,0xc7,0xdf,0x3f,0xde,0x79,0xff,0x78,0xf3,0xff,0xc0,0x00,0x00,0x00, +0x78,0x79,0xc3,0xcf,0x0f,0x3f,0x1c,0xf0,0x3c,0x78,0xf3,0xe3,0xc0,0x00,0x00,0x00, +0x7c,0x01,0xc1,0xe0,0x0f,0x3e,0x1f,0xe0,0x3c,0x78,0xf3,0xc3,0xc0,0x00,0x00,0x00, +0x3f,0xc1,0x81,0xe0,0x3f,0x3c,0x1f,0xe0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x1f,0xf1,0x81,0xe3,0xff,0x3c,0x1f,0xe0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x07,0xf9,0x81,0xe7,0xef,0x3c,0x1f,0xf0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x00,0xf9,0x81,0xef,0x07,0x3c,0x1e,0xf8,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x78,0x79,0xc1,0xef,0x0f,0x3c,0x1e,0x78,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x78,0x79,0xe3,0xcf,0x0f,0x3c,0x1e,0x3c,0x3c,0x7c,0xf3,0xc1,0xc0,0x00,0x00,0x00, +0x3f,0xf9,0xff,0xcf,0xff,0x3c,0x1e,0x3e,0x3c,0x7f,0xf3,0xc1,0xcf,0x00,0x00,0x00, +0x1f,0xf1,0xff,0x87,0xff,0x3c,0x1e,0x1e,0x3c,0x3f,0xf3,0xc1,0xc7,0x00,0x00,0x00, +0x07,0xc1,0x9e,0x03,0xe0,0x00,0x00,0x02,0x00,0x0e,0x20,0x00,0x00,0x00,0x00,0x00, +0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x03,0x80,0x00,0x00,0x00,0xc0,0x00,0x00,0x18,0x00,0x00,0x08,0x08,0x00,0x00, +0x00,0x01,0x87,0xc3,0x03,0xe0,0xe1,0xf0,0xf8,0x3e,0x33,0x08,0x3e,0x1e,0x00,0x00, +0x00,0x01,0x86,0x03,0x03,0x01,0xb0,0xe0,0xdc,0x66,0x3b,0x08,0x66,0x32,0x00,0x00, +0x00,0x00,0x87,0xc3,0x03,0xe1,0x80,0x40,0xd8,0x63,0x3b,0x08,0x60,0x3c,0x00,0x00, +0x00,0x00,0x87,0x83,0x03,0xc1,0x80,0x40,0xf8,0x63,0x3f,0x08,0x60,0x0e,0x00,0x00, +0x00,0x00,0x06,0x03,0x03,0x01,0xb0,0x40,0xd8,0x66,0x37,0x08,0x66,0x32,0x00,0x00, +0x00,0x00,0x07,0xc3,0xe3,0xe0,0xe0,0x40,0xc8,0x3e,0x33,0x08,0x3e,0x3e,0x00,0x00, +0x00,0x00,0x07,0xc3,0xe3,0xe0,0xe0,0x40,0x88,0x3c,0x33,0x08,0x3c,0x1e,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + +class LCDShield +{ +private: + void LCDCommand(unsigned char data); + void LCDData(unsigned char data); + uint8_t driver; + uint16_t swapColors(uint16_t in); +public: + LCDShield(); + + void init(int type, bool colorSwap = 0); + void clear(int color); + void contrast(char setting); + + void setPixel(int color, unsigned char x, unsigned char y); + void setCircle (int x0, int y0, int radius, int color, int lineThickness = 1); + void setArc(int x0, int y0, int radius, int segments[], int numSegments, int lineThickness, int color); + + void setChar(char c, int x, int y, int fColor, int bColor); + void setStr(char *pString, int x, int y, int fColor, int bColor); + + + void setLine(int x0, int y0, int x1, int y1, int color); + void setRect(int x0, int y0, int x1, int y1, unsigned char fill, int color); + + void printLogo(void); + + void on(void); + void off(void); +}; + +#endif // ColorLCDShield_H diff --git a/Libraries/ColorLCDShield/Examples/ChronoLCD_Color/ChronoLCD_Color.ino b/Libraries/ColorLCDShield/Examples/ChronoLCD_Color/ChronoLCD_Color.ino new file mode 100644 index 0000000..4aa270d --- /dev/null +++ b/Libraries/ColorLCDShield/Examples/ChronoLCD_Color/ChronoLCD_Color.ino @@ -0,0 +1,247 @@ +/* + ChronoLCD Color - An example sketch for the Color LCD Shield Library + by: Jim Lindblom + SparkFun Electronics + date: 6/23/11 + license: CC-BY SA 3.0 - Creative commons share-alike 3.0 + use this code however you'd like, just keep this license and + attribute. Let me know if you make hugely, awesome, great changes. + + This sketch draws an analog and digital clock on the Color LCD + Shield. You can also use the on-board buttons to set the hours + and minutes. + + Use the defines at the top of the code to set the initial time. + You can also adjust the size and color of the clock. + + To set the time, first hit S3. Then use S1 and S2 to adjust the + hours and minutes respsectively. Hit S3 to start the clock + back up. + + This example code should give you a good idea of how to use + the setCircle, setLine, and setStr functions of the Color LCD + Shield Library. +*/ +#include + +// Enter the time below in 12-hr format +#define HOURS 10 +#define MINUTES 21 +#define SECONDS 00 +#define AMPM 0 // enter 0 for AM, 1 for PM + +#define CLOCK_RADIUS 45 // radius of clock face +#define CLOCK_CENTER 50 // If you adjust the radius, you'll probably want to adjust this +#define H_LENGTH 25 // length of hour hand +#define M_LENGTH 35 // length of minute hand +#define S_LENGTH 43 // length of second hand + +#define BACKGROUND BLACK // room for growth, adjust the background color according to daylight +#define C_COLOR RED // This is the color of the clock face, and digital clock +#define H_COLOR BLUE // hour hand color +#define M_COLOR GREEN // minute hand color +#define S_COLOR YELLOW // second hand color + +LCDShield lcd; + +int hours, minutes, seconds, ampm; +int buttonPins[3] = {3, 4, 5}; + +void setup() +{ + /* Set up the button pins as inputs, set pull-up resistor */ + for (int i=0; i<3; i++) + { + pinMode(buttonPins[i], INPUT); + digitalWrite(buttonPins[i], HIGH); + } + + hours = HOURS; + minutes = MINUTES; + seconds = SECONDS; + ampm = AMPM; + + /* Initialize the LCD, set the contrast, clear the screen */ + lcd.init(PHILIPS); + lcd.contrast(-63); + lcd.clear(BACKGROUND); + + drawClock(); // Draw the clock face, this includes 12, 3, 6, 9 + displayAnalogTime(hours, minutes, seconds); // Draw the clock hands + displayDigitalTime(hours, minutes, seconds, ampm); // Draw the digital clock text +} + +void loop() +{ + /* We'll run around checking for button presses, + until it's been a second */ + while(millis() % 1000) + { + if (!digitalRead(buttonPins[2])) + setTime(); // If S3 was pressed, go set the time + } + + /* We'll get here if it's been a second. We need to increase + seconds by 1 and then go from there */ + seconds++; + if (seconds >= 60) + { + seconds = 0; // If seconds is 60, set it back to 0 + minutes++; // and increase minutes by 1 + if (minutes >= 60) + { + minutes = 0; // If minutes is 60, set it back to 0 + hours++; // and increase hours by 1 + if (hours == 12) + ampm ^= 1; // If it's 12 o'clock, flip ampm + if (hours >= 13) + hours = 1; // If hours is 13, set it to 1. 12-hr clock. + } + } + /* Once each second, we'll redraw the clock with new values */ + drawClock(); + displayAnalogTime(hours, minutes, seconds); + displayDigitalTime(hours, minutes, seconds, ampm); +} +/* + setTime uses on-shield switches S1, S2, and S3 to set the time + pressing S3 will exit the function. S1 increases hours, S2 + increases seconds. + */ +void setTime() +{ + /* Reset the clock to midnight */ + seconds = 0; + minutes = 0; + hours = 12; + ampm = 0; + + /* Draw the clock, so we can see the new time */ + drawClock(); + displayAnalogTime(hours, minutes, seconds); + displayDigitalTime(hours, minutes, seconds, ampm); + + while (!digitalRead(buttonPins[2])) + ; // wait till they let go of S1 + + /* We'll run around this loop until S3 is pressed again */ + while(digitalRead(buttonPins[2])) + { + /* If S1 is pressed, we'll update the hours */ + if (!digitalRead(buttonPins[0])) + { + hours++; // Increase hours by 1 + if (hours == 12) + ampm ^= 1; // Flip am/pm if it's 12 o'clock + if (hours >= 13) + hours = 1; // Set hours to 1 if it's 13. 12-hour clock. + + /* and update the clock, so we can see it */ + drawClock(); + displayAnalogTime(hours, minutes, seconds); + displayDigitalTime(hours, minutes, seconds, ampm); + } + if (!digitalRead(buttonPins[1])) + { + minutes++; // Increase minutes by 1 + if (minutes >= 60) + minutes = 0; // If minutes is 60, set it back to 0 + + /* and update the clock, so we can see it */ + drawClock(); + displayAnalogTime(hours, minutes, seconds); + displayDigitalTime(hours, minutes, seconds, ampm); + } + } + /* Once S3 is pressed, we'll exit, but not until it's released */ + while(!digitalRead(buttonPins[2])) + ; +} + +/* + displayDigitalTime() takes in values for hours, minutes, seconds + and am/pm. It'll print the time, in digital format, on the + bottom of the screen. +*/ +void displayDigitalTime(int h, int m, int s, int ap) +{ + char timeChar[12]; + + if (!ap) + { + sprintf(timeChar, "%.2d:%.2d:%.2d AM", h, m, s); + } + else + { + sprintf(timeChar, "%.2d:%.2d:%.2d PM", h, m, s); + } + /* Print the time on the clock */ + lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, + C_COLOR, BACKGROUND); +} + +/* + drawClock() simply draws the outer circle of the clock, and '12', + '3', '6', and '9'. Room for growth here, if you want to customize + your clock. Maybe add dashe marks, or even all 12 digits. +*/ +void drawClock() +{ + /* Draw the circle */ + lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR); + + /* Print 12, 3, 6, 9, a lot of arbitrary values are used here + for the coordinates. Just used trial and error to get them + into a nice position. */ + lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND); + lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND); + lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND); + lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND); +} + +/* + displayAnalogTime() draws the three clock hands in their proper + position. Room for growth here, I'd like to make the clock hands + arrow shaped, or at least thicker and more visible. +*/ +void displayAnalogTime(int h, int m, int s) +{ + double midHours; // this will be used to slightly adjust the hour hand + static int hx, hy, mx, my, sx, sy; + + /* Adjust time to shift display 90 degrees ccw + this will turn the clock the same direction as text */ + h -= 3; + m -= 15; + s -= 15; + if (h <= 0) + h += 12; + if (m < 0) + m += 60; + if (s < 0) + s += 60; + + /* Delete old lines: */ + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND); // delete second hand + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND); // delete minute hand + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND); // delete hour hand + + /* Calculate and draw new lines: */ + s = map(s, 0, 60, 0, 360); // map the 0-60, to "360 degrees" + sx = S_LENGTH * sin(3.14 * ((double) s)/180); // woo trig! + sy = S_LENGTH * cos(3.14 * ((double) s)/180); // woo trig! + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR); // print second hand + + m = map(m, 0, 60, 0, 360); // map the 0-60, to "360 degrees" + mx = M_LENGTH * sin(3.14 * ((double) m)/180); // woo trig! + my = M_LENGTH * cos(3.14 * ((double) m)/180); // woo trig! + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR); // print minute hand + + midHours = minutes/12; // midHours is used to set the hours hand to middling levels between whole hours + h *= 5; // Get hours and midhours to the same scale + h += midHours; // add hours and midhours + h = map(h, 0, 60, 0, 360); // map the 0-60, to "360 degrees" + hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig! + hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig! + lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand +} \ No newline at end of file diff --git a/Libraries/ColorLCDShield/Examples/LCD_with_Arc_Function/LCD_with_Arc_Function.ino b/Libraries/ColorLCDShield/Examples/LCD_with_Arc_Function/LCD_with_Arc_Function.ino new file mode 100644 index 0000000..41f5962 --- /dev/null +++ b/Libraries/ColorLCDShield/Examples/LCD_with_Arc_Function/LCD_with_Arc_Function.ino @@ -0,0 +1,41 @@ +// This Sample Created by Tony Contrada (2/22/2013) for use with the Sparkfun Color LCD Shield +// with the updated Arduino Color LCD Library. +// This sample sketch illustrates the new setArf method and an updated setCircle method +// which includes setting a Line Thickness in Pixels and the ability to Fill-In the circle. + +#include + +LCDShield lcd; // Creates an LCDShield, named lcd + +void setup() +{ + lcd.init(PHILIPS); // Initializes lcd, using an PHILIPSdriver + lcd.contrast(-64); // -51's usually a good contrast value + lcd.clear(BLACK); // clear the screen + + //Creates RED Arc in the ENE Quadrant with a Line Thickness of 5 Pixels + int segmentsRed[1] = {ENE}; + lcd.setArc(60,50,40,segmentsRed,sizeof(segmentsRed),5,RED); + + //Creates YELLOW Arc in the NNE Quadrant with a Line Thickness of 10 Pixels + int segmentsYellow[1] = {NNE}; + lcd.setArc(60,50,40,segmentsYellow,sizeof(segmentsYellow),10,YELLOW); + + //Creates GREEN Arc in the WNW and NNW Quadrants with a FILL + int segments[2] = {WNW,NNW}; + lcd.setArc(60,50,40,segments,sizeof(segments),FILL,GREEN); + + //Creates PINK Circle with a FILL + lcd.setCircle(90,100,20,PINK,FILL); + + //Creates CYAN Circle with a Line Thickness of 3 Pixels + lcd.setCircle(90,35,25,CYAN,3); + +} + +void loop() +{ + +} + + diff --git a/Libraries/ColorLCDShield/Examples/TestPattern/TestPattern.ino b/Libraries/ColorLCDShield/Examples/TestPattern/TestPattern.ino new file mode 100644 index 0000000..ffbd9f3 --- /dev/null +++ b/Libraries/ColorLCDShield/Examples/TestPattern/TestPattern.ino @@ -0,0 +1,79 @@ +/* + TestPattern - An example sketch for the Color LCD Shield Library + by: Jim Lindblom + SparkFun Electronics + date: 6/23/11 + license: CC-BY SA 3.0 - Creative commons share-alike 3.0 + use this code however you'd like, just keep this license and + attribute. Let me know if you make hugely, awesome, great changes. + + This sketch has example usage of the Color LCD Shield's three + buttons. It also shows how to use the setRect and contrast + functions. + + Hit S1 to increase the contrast, S2 decreases the contrast, and + S3 sets the contrast back to the middle. +*/ +#include + +LCDShield lcd; + +int buttons[3] = {3, 4, 5}; // S1 = 3, S2 = 4, S3 = 5 +signed char cont = -51; // Philips medium contrast +//signed char cont = 40; // Epson medium contrast + +void setup() +{ + Serial.begin(9600); + for (int i=0; i<3; i++) + { + pinMode(buttons[i], INPUT); // Set buttons as inputs + digitalWrite(buttons[i], HIGH); // Activate internal pull-up + } + + // Initialize the LCD, try using EPSON if it's not working + lcd.init(PHILIPS); + // lcd.init(PHILIPS, 1); // Philips init with colors swapped. (Try this if red makes blue, etc). + lcd.contrast(cont); // Initialize contrast + lcd.clear(WHITE); // Set background to white + lcd.printLogo(); // Print SparkFun test logo + testPattern(); // Print color bars on bottom of screen +} + +void loop() +{ + while(digitalRead(buttons[0])&&digitalRead(buttons[1])&&digitalRead(buttons[2])) + ; // Wait, do nothing, until a button is pressed + if (!digitalRead(buttons[0])) // If S1 is hit, increase contrast + { + cont++; + if (cont > 63) // Philips contrast goes from 63 to -64 + cont = -64; + } + else if (!digitalRead(buttons[1])) // If s2 is hit, decrease contrast + { + cont--; + if (cont < -64) + cont = 63; + } + else if (!digitalRead(buttons[2])) // If S3 is hit, reset contrast + { + cont = 0; + } + lcd.contrast(cont); // give LCD contrast command + Serial.println(cont); + + delay(100); // Delay to give each button press a little more meaning +} + +void testPattern() +{ + lcd.setRect(80, 2, 131, 19, 1, WHITE); + lcd.setRect(80, 19, 131, 35, 1, YELLOW); + lcd.setRect(80, 35, 131, 51, 1, CYAN); + lcd.setRect(80, 51, 131, 67, 1, GREEN); + lcd.setRect(80, 67, 131, 83, 1, MAGENTA); + lcd.setRect(80, 83, 131, 99, 1, RED); + lcd.setRect(80, 99, 131, 115, 1, BLUE); + lcd.setRect(80, 115, 131, 131, 1, BLACK); +} \ No newline at end of file diff --git a/Libraries/ColorLCDShield/Examples/ZanyCircles/ZanyCircles.ino b/Libraries/ColorLCDShield/Examples/ZanyCircles/ZanyCircles.ino new file mode 100644 index 0000000..afe312d --- /dev/null +++ b/Libraries/ColorLCDShield/Examples/ZanyCircles/ZanyCircles.ino @@ -0,0 +1,87 @@ +/* + ZanyCircles - An example sketch for the Color LCD Shield Library + by: Jim Lindblom + SparkFun Electronics + date: 6/23/11 + license: CC-BY SA 3.0 - Creative commons share-alike 3.0 + use this code however you'd like, just keep this license and + attribute. Let me know if you make hugely, awesome, great changes. + + This simple sketch shows how you can use setCircle and setPixel + with the Color LCD Shield library. +*/ +#include + +#define CIRCLES 10 // Number of zany circles in display +#define BACKGROUND ORANGE // Color of background +#define FOREGROUND BLUE // color of circles + +int radius = 1; // size of circles +int jump = 5; // +/- of possible jump +int xCir[CIRCLES]; // center points of circles +int yCir[CIRCLES]; // cetner points of circles + +LCDShield lcd; + +void setup() +{ + lcd.init(PHILIPS); // Try EPSON if this doesn't work. If colors are swapped try init(PHILIPS, 1) + lcd.contrast(-51); // Feel free to change this for visibility, values between 0 and 60 + lcd.clear(BACKGROUND); + + // Initilize all circles' center points + for (int i=0; i= 131-radius) + xCir[i] = 131-radius; + if (xCir[i] <= radius) + xCir[i] = radius; + if (yCir[i] >= 131-radius) + yCir[i] = 131-radius; + if (yCir[i] <= radius) + yCir[i] = radius; + } +} + +void loop() +{ + for (int i=0; i= 131-radius) + xCir[i] = 131-radius; + if (xCir[i] <= radius) + xCir[i] = radius; + if (yCir[i] >= 131-radius) + yCir[i] = 131-radius; + if (yCir[i] <= radius) + yCir[i] = radius; + } + for (int i=0; i