Created
September 5, 2015 16:12
-
-
Save gabonator/c32c29cbbcdfae63a456 to your computer and use it in GitHub Desktop.
Itead studio 2.4 TFT Touch shield for arduino (Arduino Uno)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <arduino.h> | |
| // Itead studio 2.4 TFT Touch shield for arduino (Arduino Uno) | |
| // http://wiki.iteadstudio.com/2.4_TFT_LCD_Touch_shield | |
| class CCalibration | |
| { | |
| // Carlos E. Vidales | |
| // http://www.embedded.com/design/system-integration/4023968/How-To-Calibrate-Touch-Screens | |
| // input range 0..1024 | |
| public: | |
| typedef long INT32; | |
| struct Point | |
| { | |
| Point() {} | |
| Point(INT32 _x, INT32 _y) : x(_x), y(_y) {} | |
| INT32 x, y; | |
| }; | |
| struct Matrix | |
| { | |
| INT32 An, Bn, Cn, Dn, En, Fn, Divider; | |
| }; | |
| static bool setCalibrationMatrix( Point * displayPtr, Point * screenPtr, Matrix * matrixPtr) | |
| { | |
| matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - | |
| ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; | |
| if( matrixPtr->Divider == 0 ) | |
| return false; | |
| matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - | |
| ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; | |
| matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - | |
| ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; | |
| matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + | |
| (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + | |
| (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; | |
| matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - | |
| ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; | |
| matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - | |
| ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; | |
| matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + | |
| (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + | |
| (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; | |
| return true; | |
| } | |
| static bool getDisplayPoint( Point * displayPtr, Point * screenPtr, Matrix * matrixPtr ) | |
| { | |
| if( matrixPtr->Divider == 0 ) | |
| return false; | |
| displayPtr->x = ( (matrixPtr->An * screenPtr->x) + | |
| (matrixPtr->Bn * screenPtr->y) + | |
| matrixPtr->Cn | |
| ) / matrixPtr->Divider ; | |
| displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) + | |
| (matrixPtr->En * screenPtr->y) + | |
| matrixPtr->Fn | |
| ) / matrixPtr->Divider ; | |
| return true; | |
| } | |
| }; | |
| class CTouch | |
| { | |
| const int pinCLK = 15; | |
| const int pinCS = 20; | |
| const int pinDIN = 14; | |
| const int pinDOUT = 8; | |
| const int pinIRQ = 9; | |
| const int PRECISION = 4; | |
| private: | |
| unsigned long m_ulRawX; | |
| unsigned long m_ulRawY; | |
| CCalibration::Matrix m_mCalibration; | |
| public: | |
| CTouch() | |
| { | |
| m_mCalibration.An = 1; m_mCalibration.Bn = 0; m_mCalibration.Cn = 0; | |
| m_mCalibration.Dn = 0; m_mCalibration.En = 1; m_mCalibration.Fn = 0; | |
| m_mCalibration.Divider = 100; | |
| m_mCalibration.An = 127800; m_mCalibration.Bn = 450; m_mCalibration.Cn = -125675850; | |
| m_mCalibration.Dn = -3640; m_mCalibration.En = 178100; m_mCalibration.Fn = -173510310; | |
| m_mCalibration.Divider = -486385; | |
| } | |
| void Init() | |
| { | |
| pinMode(pinCLK, OUTPUT); | |
| pinMode(pinCS, OUTPUT); | |
| pinMode(pinDIN, OUTPUT); | |
| pinMode(pinDOUT, INPUT); | |
| pinMode(pinIRQ, INPUT); | |
| digitalWrite(pinCS, HIGH); | |
| digitalWrite(pinCLK, HIGH); | |
| digitalWrite(pinDIN, HIGH); | |
| digitalWrite(pinCLK, HIGH); | |
| } | |
| void Flush() | |
| { | |
| while (Available()) | |
| { | |
| _Read(); | |
| } | |
| } | |
| bool Available() | |
| { | |
| return !digitalRead(pinIRQ); | |
| } | |
| void GetRaw(unsigned long* x, unsigned long* y) | |
| { | |
| _Read(); | |
| *x = m_ulRawX; | |
| *y = m_ulRawY; | |
| } | |
| bool Get(int& x, int& y) | |
| { | |
| if ( !_Read() ) | |
| return false; | |
| CCalibration::Point ptTouch(m_ulRawX, m_ulRawY); | |
| CCalibration::Point ptScreen; | |
| CCalibration::getDisplayPoint(&ptScreen, &ptTouch, &m_mCalibration); | |
| x = ptScreen.x; | |
| y = ptScreen.y; | |
| return true; | |
| } | |
| private: | |
| void _WriteData(unsigned char data) | |
| { | |
| digitalWrite(pinCLK, LOW); | |
| for(unsigned char i = 0; i < 8; i++) | |
| { | |
| digitalWrite(pinDIN, (data & 0x80) ? HIGH : LOW); | |
| data <<= 1; | |
| digitalWrite(pinCLK, LOW); | |
| i++; // nop | |
| digitalWrite(pinCLK, HIGH); | |
| i--; // nop | |
| } | |
| } | |
| unsigned int _ReadData() | |
| { | |
| unsigned char nop; | |
| unsigned int data = 0; | |
| for (unsigned char i = 0; i < 12; i++) | |
| { | |
| digitalWrite(pinCLK, HIGH); | |
| i++; // nop | |
| digitalWrite(pinCLK, LOW); | |
| i--; // nop | |
| data <<= 1; | |
| if (digitalRead(pinDOUT)) | |
| data++; | |
| } | |
| return data; | |
| } | |
| bool _Read() | |
| { | |
| m_ulRawX = 0; | |
| m_ulRawY = 0; | |
| digitalWrite(pinCS, LOW); | |
| for (unsigned int i=0; i<(1<<PRECISION); i++) | |
| { | |
| _WriteData(0x90); | |
| digitalWrite(pinCLK,HIGH); | |
| digitalWrite(pinCLK,LOW); | |
| m_ulRawY += _ReadData(); | |
| _WriteData(0xD0); | |
| digitalWrite(pinCLK,HIGH); | |
| digitalWrite(pinCLK,LOW); | |
| m_ulRawX += _ReadData(); | |
| if (!Available()) | |
| return false; | |
| } | |
| m_ulRawX >>= PRECISION+2; | |
| m_ulRawY >>= PRECISION+2; | |
| digitalWrite(pinCS, HIGH); | |
| return true; | |
| } | |
| }; | |
| class CLcd | |
| { | |
| const int pinRS = 19; | |
| const int pinWR = 18; | |
| const int pinCS = 17; | |
| const int pinRST = 16; | |
| public: | |
| static const int Width = 240; | |
| static const int Height = 320; | |
| public: | |
| void Init() | |
| { | |
| pinMode(pinRS, OUTPUT); | |
| pinMode(pinWR, OUTPUT); | |
| pinMode(pinCS, OUTPUT); | |
| pinMode(pinRST, OUTPUT); | |
| DDRD = 0xFF; | |
| digitalWrite(pinRST, HIGH); | |
| delay(3); | |
| digitalWrite(pinRST, LOW); | |
| delay(3); | |
| digitalWrite(pinRST, HIGH); | |
| digitalWrite(pinCS, HIGH); | |
| digitalWrite(pinWR, HIGH); | |
| delay(30); | |
| // http://asf.atmel.com/docs/3.7.2/sam.components.display.ili9325.unit_tests.sam3s_ek/html/ili9325_8c_source.html#l00696 | |
| unsigned short configuration[] = { | |
| 0x0011,0x2004, 0x0013,0xCC00, 0x0015,0x2600, 0x0014,0x252A, | |
| 0x0012,0x0033, 0x0013,0xCC04, 0x0013,0xCC06, 0x0013,0xCC4F, | |
| 0x0013,0x674F, 0x0011,0x2003, 0x0030,0x2609, 0x0031,0x242C, | |
| 0x0032,0x1F23, 0x0033,0x2425, 0x0034,0x2226, 0x0035,0x2523, | |
| 0x0036,0x1C1A, 0x0037,0x131D, 0x0038,0x0B11, 0x0039,0x1210, | |
| 0x003A,0x1315, 0x003B,0x3619, 0x003C,0x0D00, 0x003D,0x000D, | |
| 0x0016,0x0007, 0x0002,0x0013, 0x0003,0x0003, 0x0001,0x0127, | |
| 0x0008,0x0303, 0x000A,0x000B, 0x000B,0x0003, 0x000C,0x0000, | |
| 0x0041,0x0000, 0x0050,0x0000, 0x0060,0x0005, 0x0070,0x000B, | |
| 0x0071,0x0000, 0x0078,0x0000, 0x007A,0x0000, 0x0079,0x0007, | |
| 0x0007,0x0051, 0x0007,0x0053, 0x0079,0x0000, | |
| 0x0061, 1|2, | |
| 0x006a, 153}; | |
| for (int i = 0; i < sizeof(configuration)/sizeof(configuration[0]); i += 2) | |
| { | |
| _WriteCmd(configuration[i]); | |
| _WriteData(configuration[i+1]); | |
| } | |
| // Write RAM | |
| _WriteCmd(0x0022); | |
| } | |
| void Attach() | |
| { | |
| DDRD = 0xFF; | |
| } | |
| void SetRegion(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1) | |
| { | |
| x1--; | |
| y1--; | |
| _Write(0x0046, (x1 << 8)| x0); | |
| _Write(0x0047, y1); | |
| _Write(0x0048, y0); | |
| _Write(0x0020, x0); | |
| _Write(0x0021, y0); | |
| _WriteCmd(0x0022); | |
| } | |
| void Bar(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int c) | |
| { | |
| SetRegion(x0, y0, x1, y1); | |
| unsigned int nPixels = (x1-x0)*(y1-y0); | |
| while (nPixels--) | |
| PutPixel(c); | |
| } | |
| void PutPixel(unsigned int x, unsigned int y, unsigned int c) | |
| { | |
| SetRegion(x, y, x+1, y+1); | |
| _WriteData(c); | |
| } | |
| void PutPixel(unsigned int c) | |
| { | |
| _WriteData(c); | |
| } | |
| void Clear(unsigned int c) | |
| { | |
| SetRegion(0, 0, Width, Height); | |
| for (int y=0; y<Height; y++) | |
| for (int x=0; x<Width; x++) | |
| PutPixel(c); | |
| } | |
| unsigned int GetColor(unsigned long lRRGGBB) | |
| { | |
| unsigned char b = (unsigned char)lRRGGBB; | |
| lRRGGBB >>= 8; | |
| unsigned char g = (unsigned char)lRRGGBB; | |
| lRRGGBB >>= 8; | |
| unsigned char r = (unsigned char)lRRGGBB; | |
| r >>= 3; | |
| g >>= 2; | |
| b >>= 3; | |
| unsigned int aux = (unsigned int)b | ((unsigned int)g << 5) | ((unsigned int)r << 11); | |
| return aux; | |
| } | |
| unsigned long Interpolate(unsigned long c0, unsigned long c1, short level) | |
| { | |
| if ( level <= 0 ) | |
| return c0; | |
| if ( level >= 255 ) | |
| return c1; | |
| unsigned int b0 = c0 & 0xff; | |
| c0 >>= 8; | |
| unsigned int g0 = c0 & 0xff; | |
| c0 >>= 8; | |
| unsigned int r0 = c0 & 0xff; | |
| unsigned int b1 = c1 & 0xff; | |
| c1 >>= 8; | |
| unsigned int g1 = c1 & 0xff; | |
| c1 >>= 8; | |
| unsigned int r1 = c1 & 0xff; | |
| r0 += ((r1 - r0) * level) >> 8; | |
| g0 += ((g1 - g0) * level) >> 8; | |
| b0 += ((b1 - b0) * level) >> 8; | |
| return (unsigned long)b0 | ((unsigned long)g0 << 8) | ((unsigned long)r0 << 16); | |
| } | |
| private: | |
| void _WriteCmd(unsigned int c) | |
| { | |
| digitalWrite(pinRS, LOW); | |
| digitalWrite(pinCS, LOW); | |
| PORTD = c>>8; | |
| digitalWrite(pinWR, LOW); | |
| digitalWrite(pinWR, HIGH); | |
| PORTD = c; | |
| digitalWrite(pinWR, LOW); | |
| digitalWrite(pinWR, HIGH); | |
| digitalWrite(pinCS, HIGH); | |
| } | |
| void _WriteData(unsigned int c) | |
| { | |
| digitalWrite(pinRS, HIGH); | |
| digitalWrite(pinCS, LOW); | |
| PORTD = c>>8; | |
| digitalWrite(pinWR, LOW); | |
| digitalWrite(pinWR, HIGH); | |
| PORTD = c; | |
| digitalWrite(pinWR, LOW); | |
| digitalWrite(pinWR, HIGH); | |
| digitalWrite(pinCS, HIGH); | |
| } | |
| void _Write(unsigned int cmd, unsigned int data) | |
| { | |
| _WriteCmd(cmd); | |
| _WriteData(data); | |
| } | |
| }; | |
| class CCalibrationProcess | |
| { | |
| public: | |
| CLcd m_Lcd; | |
| CTouch m_Touch; | |
| CCalibration::Matrix m_Matrix; | |
| void Init() | |
| { | |
| m_Lcd.Init(); | |
| m_Touch.Init(); | |
| } | |
| void Test() | |
| { | |
| m_Touch.Init(); | |
| Serial.begin(9600); | |
| while (1) | |
| { | |
| if ( !m_Touch.Available() ) | |
| continue; | |
| unsigned long lX, lY; | |
| m_Touch.GetRaw(&lX, &lY); | |
| Serial.print((" x0=")); Serial.print(lX); | |
| Serial.print((" y0=")); Serial.print(lY); | |
| Serial.print(("\n")); | |
| delay(100); | |
| } | |
| } | |
| void Do() | |
| { | |
| CCalibration::Point arrScreen[3] = {{30, 30}, {m_Lcd.Width/2, m_Lcd.Height - 30}, {m_Lcd.Width-30, 30}}; | |
| CCalibration::Point arrTouch[3]; | |
| for ( int i = 0; i < 3; i++ ) | |
| { | |
| DrawCrosshair(arrScreen[i].x, arrScreen[i].y, 15); | |
| while (m_Touch.Available()) | |
| delay(100); | |
| while (!m_Touch.Available()) | |
| delay(100); | |
| ClearCrosshair(arrScreen[i].x, arrScreen[i].y, 15); | |
| unsigned long lX, lY; | |
| m_Touch.GetRaw(&lX, &lY); | |
| arrTouch[i].x = lX; | |
| arrTouch[i].y = lY; | |
| } | |
| CCalibration::setCalibrationMatrix(arrScreen, arrTouch, &m_Matrix); | |
| Serial.begin(9600); | |
| delay(100); | |
| Serial.print(("Points:\n")); | |
| Serial.print(("x0=")); Serial.print(arrTouch[0].x); | |
| Serial.print(("y0=")); Serial.print(arrTouch[0].y); | |
| Serial.print(("\nx1=")); Serial.print(arrTouch[1].x); | |
| Serial.print(("y1=")); Serial.print(arrTouch[1].y); | |
| Serial.print(("\nx2=")); Serial.print(arrTouch[2].x); | |
| Serial.print(("y2=")); Serial.print(arrTouch[2].y); | |
| Serial.print(("\n\n")); | |
| Serial.print(("Calibration matrix:\n")); | |
| Serial.print(("A=")); Serial.print(m_Matrix.An); | |
| Serial.print((", B=")); Serial.print(m_Matrix.Bn); | |
| Serial.print((", C=")); Serial.print(m_Matrix.Cn); | |
| Serial.print(("\nD=")); Serial.print(m_Matrix.Dn); | |
| Serial.print((", E=")); Serial.print(m_Matrix.En); | |
| Serial.print((", F=")); Serial.print(m_Matrix.Fn); | |
| Serial.print(("\nDivider=")); Serial.print(m_Matrix.Divider); | |
| Serial.print(("\n\n")); | |
| Serial.end(); | |
| delay(200); | |
| m_Lcd.Attach(); | |
| m_Lcd.Init(); | |
| } | |
| private: | |
| void DrawCrosshair(int x, int y, int l) | |
| { | |
| m_Lcd.Bar(x-l, y-1, x+l, y+1, 0xffff); | |
| m_Lcd.Bar(x-1, y-l, x+1, y+l, 0xffff); | |
| } | |
| void ClearCrosshair(int x, int y, int l) | |
| { | |
| m_Lcd.Bar(x-l, y-l, x+l, y+l, 0x0000); | |
| } | |
| }; | |
| class CDraw | |
| { | |
| CLcd m_lcd; | |
| public: | |
| int m_nWidth; | |
| unsigned long m_rgbBack; | |
| unsigned long m_rgbFront; | |
| unsigned short m_clrBack; | |
| unsigned short m_clrFront; | |
| CDraw() | |
| { | |
| m_nWidth = 3; | |
| SetBkgColor(0x000000); | |
| SetColor(0xffffff); | |
| } | |
| void SetBkgColor(unsigned long lRgb) | |
| { | |
| m_rgbBack = lRgb; | |
| m_clrBack = m_lcd.GetColor(lRgb); | |
| } | |
| void SetColor(unsigned long lRgb) | |
| { | |
| m_rgbFront = lRgb; | |
| m_clrFront = m_lcd.GetColor(lRgb); | |
| } | |
| void line(int x0, int y0, int x1, int y1) | |
| { | |
| int dx = abs(x1-x0); | |
| int sx = x0 < x1 ? 1 : -1; | |
| int dy = abs(y1-y0); | |
| int sy = y0 < y1 ? 1 : -1; | |
| int err = dx-dy, e2, x2, y2; /* error value e_xy */ | |
| int ed = (dx+dy == 0) ? 1 : sqrt((float)dx*dx+(float)dy*dy); | |
| unsigned short c = m_lcd.GetColor(m_rgbFront); | |
| for (int wd = (m_nWidth+1)/2; ; ) { /* pixel loop */ | |
| m_lcd.PutPixel(x0, y0, c); | |
| e2 = err; x2 = x0; | |
| if (2*e2 >= -dx) { /* x step */ | |
| for (e2 += dy, y2 = y0; e2 < ed*wd && (y1 != y2 || dx > dy); e2 += dx) | |
| m_lcd.PutPixel(x0, y2 += sy, c); | |
| if (x0 == x1) break; | |
| e2 = err; err -= dy; x0 += sx; | |
| } | |
| if (2*e2 <= dy) { /* y step */ | |
| for (e2 = dx-e2; e2 < ed*wd && (x1 != x2 || dx < dy); e2 += dy) | |
| m_lcd.PutPixel(x2 += sx, y0, c); | |
| if (y0 == y1) break; | |
| err += dx; y0 += sy; | |
| } | |
| } | |
| } | |
| void DrawText(int x, int y, char* strText, bool bDouble = false) | |
| { | |
| while (*strText) | |
| { | |
| bDouble ? DrawDoubleChar(x, y, *strText++) : DrawChar(x, y, *strText++); | |
| y += bDouble ? 16 : 8; | |
| } | |
| } | |
| void DrawChar(int x, int y, char c) | |
| { | |
| const unsigned char* PROGMEM data = GetSymbol(c); | |
| if ( !c ) | |
| return; | |
| m_lcd.SetRegion(x, y, x+12, y+8); | |
| for (unsigned char _x=0; _x<8; _x++) | |
| for (unsigned char _y=0; _y<12; _y++) | |
| { | |
| unsigned char r = pgm_read_byte_near(data + 11-_y); | |
| m_lcd.PutPixel((r & (1<<(7-_x))) ? m_clrFront : m_clrBack); | |
| } | |
| } | |
| void DrawDoubleChar(int x, int y, char c) | |
| { | |
| const unsigned char* PROGMEM data = GetSymbol(c); | |
| if ( !c ) | |
| return; | |
| m_lcd.SetRegion(x, y, x+12*2, y+8*2); | |
| for (unsigned char _x=0; _x<16; _x++) | |
| for (unsigned char _y=0; _y<24; _y++) | |
| { | |
| unsigned char r = pgm_read_byte_near(data + 11-_y/2); | |
| m_lcd.PutPixel((r & (1<<(7-_x/2))) ? m_clrFront : m_clrBack); | |
| } | |
| } | |
| const unsigned char* PROGMEM GetSymbol(char ch) | |
| { | |
| // UTFT library | |
| static const unsigned char SmallFont[1144] PROGMEM={ | |
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space> | |
| 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, // ! | |
| 0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // " | |
| 0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00, // # | |
| 0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00, // $ | |
| 0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00, // % | |
| 0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00, // & | |
| 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' | |
| 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00, // ( | |
| 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00, // ) | |
| 0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00, // * | |
| 0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00, // + | |
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, // , | |
| 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // - | |
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, // . | |
| 0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, // / | |
| 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // 0 | |
| 0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // 1 | |
| 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, // 2 | |
| 0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00, // 3 | |
| 0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00, // 4 | |
| 0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00, // 5 | |
| 0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, // 6 | |
| 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00, // 7 | |
| 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, // 8 | |
| 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00, // 9 | |
| 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00, // : | |
| 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00, // ; | |
| 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // < | |
| 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, // = | |
| 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // > | |
| 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, // ? | |
| 0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00, // @ | |
| 0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00, // A | |
| 0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, // B | |
| 0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, // C | |
| 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, // D | |
| 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00, // E | |
| 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00, // F | |
| 0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00, // G | |
| 0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00, // H | |
| 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // I | |
| 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00, // J | |
| 0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00, // K | |
| 0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00, // L | |
| 0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // M | |
| 0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00, // N | |
| 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // O | |
| 0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00, // P | |
| 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00, // Q | |
| 0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00, // R | |
| 0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00, // S | |
| 0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // T | |
| 0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00, // U | |
| 0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00, // V | |
| 0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00, // W | |
| 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00, // X | |
| 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // Y | |
| 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00, // Z | |
| 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, // [ | |
| 0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00, // <Backslash> | |
| 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, // ] | |
| 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^ | |
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, // _ | |
| 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' | |
| 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00, // a | |
| 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, // b | |
| 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00, // c | |
| 0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00, // d | |
| 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, // e | |
| 0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00, // f | |
| 0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38, // g | |
| 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00, // h | |
| 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00, // i | |
| 0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0, // j | |
| 0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00, // k | |
| 0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // l | |
| 0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // m | |
| 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00, // n | |
| 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, // o | |
| 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0, // p | |
| 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C, // q | |
| 0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00, // r | |
| 0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00, // s | |
| 0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00, // t | |
| 0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00, // u | |
| 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00, // v | |
| 0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00, // w | |
| 0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00, // x | |
| 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0, // y | |
| 0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00, // z | |
| 0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00, // { | |
| 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, // | | |
| 0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00, // } | |
| 0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~ | |
| }; | |
| unsigned int nOfs = (ch-' ')*12; | |
| if ( nOfs >= sizeof(SmallFont) ) | |
| return NULL; | |
| return SmallFont + nOfs; | |
| } | |
| }; | |
| CLcd lcd; | |
| CTouch touch; | |
| CDraw draw; | |
| void chess() | |
| { | |
| unsigned short clr1 = lcd.GetColor(0x0060b0); | |
| unsigned short clr2 = lcd.GetColor(0x808080); | |
| lcd.SetRegion(0, 0, lcd.Width, lcd.Height); | |
| for (int y=0; y<lcd.Height; y++) | |
| for (int x=0; x<lcd.Width; x++) | |
| { | |
| if ( ((x >> 4) + (y>>4))&1) | |
| lcd.PutPixel(clr1); | |
| else | |
| lcd.PutPixel(clr2); | |
| } | |
| } | |
| void spheres() | |
| { | |
| static int nOffset = 0; | |
| lcd.SetRegion(0, 0, lcd.Width, lcd.Height); | |
| for (int y=0; y<lcd.Height; y++) | |
| for (int x=0; x<lcd.Width; x++) | |
| { | |
| int nDistX = (x-lcd.Width/2); | |
| int nDistY = (y-lcd.Height/2); | |
| int nDist = nDistX*nDistX + nDistY*nDistY; | |
| nDist >>= 2; | |
| nDist += nOffset; | |
| lcd.PutPixel(nDist); | |
| } | |
| nOffset += 200; | |
| } | |
| unsigned short rainbow() | |
| { | |
| static const unsigned long arrColors[] = | |
| {0xff0000, 0xffff00, 0xffffff, 0x00ffff, 0x0000ff, 0x000000}; | |
| const int nColors = (sizeof(arrColors)/sizeof(arrColors[0])); | |
| unsigned long lPhase = millis() >> 2; | |
| unsigned int nColor = (lPhase >> 8) % nColors; | |
| unsigned int nMid = lPhase & 0xff; | |
| unsigned long lRGB = lcd.Interpolate(arrColors[nColor], arrColors[(nColor+1)%nColors], nMid); | |
| return lcd.GetColor(lRGB); | |
| } | |
| void worm() | |
| { | |
| float omega = millis() * 2.0f * PI * 0.001f; | |
| const float fFreqX = 1.5f; | |
| const float fFreqY = 1.0f; | |
| const int nDimension = min(lcd.Width, lcd.Height) / 3; | |
| int nX = lcd.Width/2 + cos(omega * fFreqX) * nDimension; | |
| int nY = lcd.Height/2 + sin(omega * fFreqY) * nDimension; | |
| unsigned long nColor = millis(); | |
| nColor &= 511; | |
| if (nColor >= 256) | |
| nColor = 256 - (nColor - 256); | |
| nColor = nColor & 0xff; | |
| nColor = nColor | (nColor<<8) | (nColor<<16); | |
| lcd.Bar(nX-5, nY-5, nX+5, nY+5, lcd.GetColor(nColor)); | |
| } | |
| void gradient() // nic moc | |
| { | |
| lcd.SetRegion(0, 0, lcd.Width, lcd.Height); | |
| unsigned long lTopLeft = 0xff0000; | |
| unsigned long lTopRight = 0x00ff00; | |
| unsigned long lBottomLeft = 0x0000ff; | |
| unsigned long lBottomRight = 0xb0b0b0; | |
| for (int y=0; y<lcd.Height; y++) | |
| for (int x=0; x<lcd.Width; x++) | |
| { | |
| unsigned long nLeft = (unsigned long)x*256/lcd.Width; | |
| unsigned long nTop = (unsigned long)y*256/lcd.Height; | |
| unsigned long nInterpolateTop = lcd.Interpolate(lTopLeft, lTopRight, nLeft); | |
| unsigned long nInterpolateBottom = lcd.Interpolate(lBottomLeft, lBottomRight, nLeft); | |
| unsigned long nInterpolate = lcd.Interpolate(nInterpolateTop, nInterpolateBottom, nTop); | |
| lcd.PutPixel(lcd.GetColor(nInterpolate)); | |
| } | |
| } | |
| void sierpinski() | |
| { | |
| static const int arrX[3] = {20, lcd.Width-20, 20}; | |
| static const int arrY[3] = {20, lcd.Height/2, lcd.Height-20}; | |
| static int x = arrX[0]; | |
| static int y = arrY[0]; | |
| int nRandom = rand() % 3; | |
| int nNewX = arrX[nRandom]; | |
| int nNewY = arrY[nRandom]; | |
| x = (x + nNewX) / 2; | |
| y = (y + nNewY) / 2; | |
| lcd.Bar(x, y, x+1, y+1, rainbow()); | |
| } | |
| bool Paint() | |
| { | |
| static int nLastX = -1, nLastY = -1; | |
| static int nNewX = -1, nNewY = -1; | |
| static long nPressed = 0; | |
| if ( touch.Available() ) | |
| { | |
| if ( nNewX == -1 ) | |
| nPressed = millis(); | |
| else | |
| { | |
| long lPassed = millis() - nPressed; | |
| if ( lPassed > 5000 ) | |
| { | |
| nPressed = millis(); | |
| return true; | |
| } | |
| } | |
| } else | |
| { | |
| nLastX = -1; | |
| nNewX = -1; | |
| return false; | |
| } | |
| if ( nLastX != -1 && nNewX != -1 ) | |
| { | |
| draw.line(nLastX, nLastY, nNewX, nNewY); | |
| } | |
| nLastX = nNewX; | |
| nLastY = nNewY; | |
| if (!touch.Get(nNewX, nNewY)) | |
| { | |
| nNewX = -1; | |
| nLastX = -1; | |
| } | |
| return false; | |
| } | |
| void Ball(int x0, int y0, int x1, int y1) | |
| { | |
| unsigned long lBack = 0x0060b0; | |
| const int r = 20; | |
| const int g = 150; | |
| const int b = 10; | |
| const int w = x1-x0; | |
| const int h = y1-y0; | |
| const int cx = (w*128)>>8; // center | |
| const int cy = (w*128)>>8; | |
| const int gx = (w*133)>>8; // glow | |
| const int gy = (h*159)>>8; | |
| const int sx = (w*179)>>8; // shadow | |
| const int sy = (h*205)>>8; | |
| const int lc = (60*w)>>7; | |
| const int lg = (70*w)>>7; | |
| const int ls = (50*w)>>7; | |
| const long aMat[9] = | |
| {r, 240-r, -60, | |
| g, 240-g, -60, | |
| b, 240-b, -60}; | |
| lcd.SetRegion(x0, y0, x1, y1); | |
| for (long y=0; y<h; y++) | |
| for (long x=0; x<w; x++) | |
| { | |
| unsigned long a = (x-cx)*(x-cx) + (y-cy)*(y-cy); | |
| a = sqrt( a *256*256/lc/lc ); | |
| a = min(max(0, a), 255); | |
| a = (255-a)*5; | |
| a = min(max(0, a), 255); | |
| long c = (x-gx)*(x-gx) + (y-gy)*(y-gy); | |
| c = sqrt( c *256*256/lg/lg ); | |
| c = c*c/256; | |
| c = min(c, 255); | |
| long s = (x-sx)*(x-sx) + (y-sy)*(y-sy); | |
| s = 255-sqrt( s *256*156/ls/ls); | |
| s = min(max(0, s), 255); | |
| long r = aMat[0*3+0] + ((aMat[0*3+1]*c)>>8) + ((aMat[0*3+2]*s)>>8); | |
| long g = aMat[1*3+0] + ((aMat[1*3+1]*c)>>8) + ((aMat[1*3+2]*s)>>8); | |
| long b = aMat[2*3+0] + ((aMat[2*3+1]*c)>>8) + ((aMat[2*3+2]*s)>>8); | |
| r = min(max(0, r), 255); | |
| g = min(max(0, g), 255); | |
| b = min(max(0, b), 255); | |
| //a = 255; | |
| unsigned long rgb = (unsigned long)b | ((unsigned long)g << 8) | ((unsigned long)r << 16); | |
| lcd.PutPixel(lcd.GetColor(lcd.Interpolate(lBack, rgb, a))); | |
| } | |
| } | |
| void setup() | |
| { | |
| lcd.Init(); | |
| touch.Init(); | |
| draw.DrawText(20, 60, "ILI9325D test!", true); | |
| draw.SetBkgColor(0x0060b0); | |
| draw.DrawText(225, 80, " Gradient! ", false); | |
| gradient(); | |
| draw.DrawText(225, 80, " Chess board ", false); | |
| chess(); | |
| draw.DrawText(225, 80, "Nice smooth 3d ball", false); | |
| Ball(40, 80, 200, 240); | |
| draw.DrawText(0, 0, "touch the screen for drawing, or hold...", false); | |
| } | |
| void loop() | |
| { | |
| /* | |
| CCalibrationProcess proc; | |
| proc.Init(); | |
| proc.Do(); | |
| */ | |
| static unsigned int nCurrentApp = -1; | |
| bool bSwapApp = Paint(); | |
| if ( bSwapApp || nCurrentApp == -1 ) | |
| { | |
| if (++nCurrentApp > 4) | |
| nCurrentApp = 0; | |
| if ( nCurrentApp == 0 ) | |
| draw.DrawText(225, 80, "Sierpinski triangle", false); | |
| if ( nCurrentApp == 1 ) | |
| draw.DrawText(225, 80, " Worm ", false); | |
| if ( nCurrentApp == 2 ) | |
| { | |
| chess(); | |
| draw.DrawText(225, 80, " Drawing ", false); | |
| } | |
| if ( nCurrentApp == 3 ) | |
| { | |
| gradient(); | |
| draw.DrawText(225, 80, " Drawing ", false); | |
| } | |
| if ( nCurrentApp == 4 ) | |
| { | |
| spheres(); | |
| draw.DrawText(225, 80, " Drawing ", false); | |
| } | |
| } | |
| if ( nCurrentApp == 0 ) | |
| sierpinski(); | |
| if ( nCurrentApp == 1 ) | |
| worm(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment