Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SPI.h>
- #include "Adafruit_GFX.h"
- #include "Adafruit_RA8875.h"
- #include <MemoryFree.h>
- #define RA8875_INT 3
- #define RA8875_CS 10
- #define RA8875_RESET 9
- unsigned short boardType = 0; // 0 = keyboard, 1 = numpad
- const char alphaKeys[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
- Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);
- tsPoint_t _tsLCDPoints[3];
- tsPoint_t _tsTSPoints[3];
- tsMatrix_t _tsMatrix;
- /**************************************************************************/
- /*!
- @brief Calculates the difference between the touch screen and the
- actual screen co-ordinates, taking into account misalignment
- and any physical offset of the touch screen.
- @note This is based on the public domain touch screen calibration code
- written by Carlos E. Vidales (copyright (c) 2001).
- For more information, see the following app notes:
- - AN2173 - Touch Screen Control and Calibration
- Svyatoslav Paliy, Cypress Microsystems
- - Calibration in touch-screen systems
- Wendy Fang and Tony Chang,
- Analog Applications Journal, 3Q 2007 (Texas Instruments)
- */
- /**************************************************************************/
- int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr)
- {
- int retValue = 0;
- 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 )
- {
- retValue = -1 ;
- }
- else
- {
- 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 ;
- // Persist data to EEPROM
- /*eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN, matrixPtr->An);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN, matrixPtr->Bn);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN, matrixPtr->Cn);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN, matrixPtr->Dn);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN, matrixPtr->En);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn);
- eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER, matrixPtr->Divider);
- eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1);*/
- }
- return( retValue ) ;
- }
- /**************************************************************************/
- /*!
- @brief Converts raw touch screen locations (screenPtr) into actual
- pixel locations on the display (displayPtr) using the
- supplied matrix.
- @param[out] displayPtr Pointer to the tsPoint_t object that will hold
- the compensated pixel location on the display
- @param[in] screenPtr Pointer to the tsPoint_t object that contains the
- raw touch screen co-ordinates (before the
- calibration calculations are made)
- @param[in] matrixPtr Pointer to the calibration matrix coefficients
- used during the calibration process (calculated
- via the tsCalibrate() helper function)
- @note This is based on the public domain touch screen calibration code
- written by Carlos E. Vidales (copyright (c) 2001).
- */
- /**************************************************************************/
- int calibrateTSPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr )
- {
- int retValue = 0 ;
- if( matrixPtr->Divider != 0 )
- {
- 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 ;
- }
- else
- {
- return -1;
- }
- return( retValue );
- }
- /**************************************************************************/
- /*!
- @brief Waits for a touch event
- */
- /**************************************************************************/
- void waitForTouchEvent(tsPoint_t * point)
- {
- /* Clear the touch data object and placeholder variables */
- memset(point, 0, sizeof(tsPoint_t));
- /* Clear any previous interrupts to avoid false buffered reads */
- uint16_t x, y;
- tft.touchRead(&x, &y);
- delay(1);
- /* Wait around for a new touch event (INT pin goes low) */ // MODIFIED ARG: From arg "digitalRead(RA8875_INT)" to "!tft.touched()"
- while (!tft.touched()){
- }
- /* Make sure this is really a touch event */
- if (tft.touched())
- {
- tft.touchRead(&x, &y);
- point->x = x;
- point->y = y;
- //Serial.print("Touch: ");
- //Serial.print(point->x); Serial.print(", "); Serial.println(point->y);
- }
- else
- {
- point->x = 0;
- point->y = 0;
- }
- }
- /**************************************************************************/
- /*!
- @brief Renders the calibration screen with an appropriately
- placed test point and waits for a touch event
- */
- /**************************************************************************/
- tsPoint_t renderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius)
- {
- tft.fillScreen(RA8875_WHITE);
- tft.drawCircle(x, y, radius, RA8875_RED);
- tft.drawCircle(x, y, radius + 2, 0x8410); /* 50% Gray */
- // Wait for a valid touch events
- tsPoint_t point = { 0, 0 };
- /* Keep polling until the TS event flag is valid */
- bool valid = false;
- while (!valid)
- {
- waitForTouchEvent(&point);
- if (point.x || point.y)
- {
- valid = true;
- }
- }
- return point;
- }
- /**************************************************************************/
- /*!
- @brief Starts the screen calibration process. Each corner will be
- tested, meaning that each boundary (top, left, right and
- bottom) will be tested twice and the readings averaged.
- */
- /**************************************************************************/
- void tsCalibrate(void)
- {
- tsPoint_t data;
- /* --------------- Welcome Screen --------------- */
- Serial.println("Starting the calibration process");
- data = renderCalibrationScreen(tft.width() / 2, tft.height() / 2, 5);
- delay(250);
- /* ----------------- First Dot ------------------ */
- // 10% over and 10% down
- data = renderCalibrationScreen(tft.width() / 10, tft.height() / 10, 5);
- _tsLCDPoints[0].x = tft.width() / 10;
- _tsLCDPoints[0].y = tft.height() / 10;
- _tsTSPoints[0].x = data.x;
- _tsTSPoints[0].y = data.y;
- Serial.print("Point 1 - LCD");
- Serial.print(" X: ");
- Serial.print(_tsLCDPoints[0].x);
- Serial.print(" Y: ");
- Serial.print(_tsLCDPoints[0].y);
- Serial.print(" TS X: ");
- Serial.print(_tsTSPoints[0].x);
- Serial.print(" Y: ");
- Serial.println(_tsTSPoints[0].y);
- delay(250);
- /* ---------------- Second Dot ------------------ */
- // 50% over and 90% down
- data = renderCalibrationScreen(tft.width() / 2, tft.height() - tft.height() / 10, 5);
- _tsLCDPoints[1].x = tft.width() / 2;
- _tsLCDPoints[1].y = tft.height() - tft.height() / 10;
- _tsTSPoints[1].x = data.x;
- _tsTSPoints[1].y = data.y;
- Serial.print("Point 2 - LCD");
- Serial.print(" X: ");
- Serial.print(_tsLCDPoints[1].x);
- Serial.print(" Y: ");
- Serial.print(_tsLCDPoints[1].y);
- Serial.print(" TS X: ");
- Serial.print(_tsTSPoints[1].x);
- Serial.print(" Y: ");
- Serial.println(_tsTSPoints[1].y);
- delay(250);
- /* ---------------- Third Dot ------------------- */
- // 90% over and 50% down
- data = renderCalibrationScreen(tft.width() - tft.width() / 10, tft.height() / 2, 5);
- _tsLCDPoints[2].x = tft.width() - tft.width() / 10;
- _tsLCDPoints[2].y = tft.height() / 2;
- _tsTSPoints[2].x = data.x;
- _tsTSPoints[2].y = data.y;
- Serial.print("Point 3 - LCD");
- Serial.print(" X: ");
- Serial.print(_tsLCDPoints[2].x);
- Serial.print(" Y: ");
- Serial.print(_tsLCDPoints[2].y);
- Serial.print(" TS X: ");
- Serial.print(_tsTSPoints[2].x);
- Serial.print(" Y: ");
- Serial.println(_tsTSPoints[2].y);
- delay(250);
- /* Clear the screen */
- tft.fillScreen(RA8875_WHITE);
- // Do matrix calculations for calibration and store to EEPROM
- setCalibrationMatrix(&_tsLCDPoints[0], &_tsTSPoints[0], &_tsMatrix);
- }
- void setup(){
- tft.begin(RA8875_800x480);
- Serial.begin(9600);
- delay(100);
- tft.displayOn(true);
- tft.GPIOX(true);
- tft.PWM1config(true, RA8875_PWM_CLK_DIV1024);
- tft.PWM1out(255);
- pinMode(RA8875_INT, INPUT);
- digitalWrite(RA8875_INT, HIGH);
- tft.touchEnable(true);
- tsCalibrate();
- tft.fillScreen(RA8875_WHITE);
- tft.fillRoundRect(10,200,780,80,15,0xAD35);
- tft.textMode();
- tft.textSetCursor(27,220);
- tft.textTransparent(RA8875_BLACK);
- tft.textEnlarge(1);
- tft.textWrite(" Digital Air Brake Pressure Monitoring System");
- tft.textSetCursor(70,290);
- tft.textEnlarge(3);
- tft.textWrite("(c) Chris Kuhn, 2018");
- delay(500);
- tft.graphicsMode();
- tft.fillScreen(0xCE39); // HEX RGB565 Control Panel Gray
- tft.drawFastHLine(0,80,800,RA8875_BLACK);
- tft.fillRect(0,0,800,79,0xAD36);
- tft.textMode();
- tft.textSetCursor(10,10);
- tft.textEnlarge(3);
- tft.textTransparent(RA8875_BLACK);
- tft.textWrite("Enter Channel ID below:");
- tft.textSetCursor(220,120);
- tft.textEnlarge(3);
- tft.textTransparent(0xAD35);
- tft.textWrite("A B C D 1 2");
- tft.textSetCursor(218,140);
- tft.textTransparent(RA8875_BLACK);
- tft.textWrite("_ _ _ _ _ _");
- char targetChannel[12] = " ";
- channelEntryHandler(targetChannel);
- Serial.print("CHANNEL ID: ");
- Serial.println(targetChannel);
- }
- void loop() {
- }
- void drawKeyboard(){
- short xRow2[] = {31, 121, 211, 301, 389, 477, 566, 655, 744};
- short xRow3[] = {46, 160, 274, 387, 504, 617, 731};
- tft.graphicsMode();
- tft.drawFastHLine(0,255,800,RA8875_BLACK); // Row 1
- tft.drawFastHLine(0,330,800,RA8875_BLACK); // Row 2
- tft.drawFastHLine(0,405,800,RA8875_BLACK); // Row 3
- tft.drawFastVLine(160,80,175,RA8875_BLACK); // Action 1
- tft.drawFastVLine(640,80,175,RA8875_BLACK); // Action 2
- for(short i = 1; i < 10; i++){ // Row 1 columns
- tft.drawFastVLine(80*i,255,75,RA8875_BLACK);
- }
- for(short i = 1; i < 9; i++){ // Row 2 columns
- tft.drawFastVLine(88.888*i,330,75,RA8875_BLACK);
- }
- for(short i = 1; i < 7; i++){ // Row 3 columns
- tft.drawFastVLine(114.285714*i,405,75,RA8875_BLACK);
- }
- tft.textMode();
- tft.textEnlarge(2);
- for(short i = 0; i < 10; i++){
- tft.textSetCursor(29+(80*i),265);
- tft.textWrite(&alphaKeys[i], 1);
- }
- for(short i = 0; i < 9; i++){
- tft.textSetCursor(xRow2[i],340);
- tft.textWrite(&alphaKeys[i+10], 1);
- }
- for(short i = 0; i < 7; i++){
- tft.textSetCursor(xRow3[i],415);
- tft.textWrite(&alphaKeys[i+19], 1);
- }
- }
- void drawNumpad(){
- tft.graphicsMode();
- tft.drawFastHLine(0,255,800
- }
- void drawClear(){
- tft.graphicsMode();
- tft.fillRect(641,81,159,173,0xCE39);
- tft.fillRect(660,100,120,100,RA8875_RED);
- tft.fillTriangle(665,100,720,145,775,100,0xCE39);
- tft.fillTriangle(660,105,715,150,660,195,0xCE39);
- tft.fillTriangle(665,200,720,155,775,200,0xCE39);
- tft.fillTriangle(780,195,725,150,780,105,0xCE39);
- tft.textMode();
- tft.textEnlarge(1);
- tft.textTransparent(RA8875_BLACK);
- tft.textSetCursor(683,220);
- tft.textWrite("Clear");
- return;
- }
- void drawBackspace(){
- tft.graphicsMode();
- tft.fillRect(0,81,159,173,0xCE39);
- tft.fillTriangle(20,150,80,200,80,100,RA8875_RED);
- tft.fillTriangle(30,150,90,200,90,100,0xCE39);
- tft.fillRect(30,147,107,7,RA8875_RED);
- tft.textMode();
- tft.textSetCursor(8,220);
- tft.textEnlarge(1);
- tft.textTransparent(RA8875_BLACK);
- tft.textWrite("Backspace");
- return;
- }
- void drawEnter(){
- tft.graphicsMode();
- tft.fillRect(641,81,159,173,0xCE39);
- tft.fillTriangle(780,150,720,200,720,100,RA8875_GREEN);
- tft.fillTriangle(770,150,710,200,710,100,0xCE39);
- tft.fillRect(663,147,107,7,RA8875_GREEN);
- tft.textMode();
- tft.textEnlarge(1);
- tft.textTransparent(RA8875_BLACK);
- tft.textSetCursor(683,220);
- tft.textWrite("Enter");
- return;
- }
- void channelEntryHandler(char* outPtr){
- drawKeyboard();
- drawBackspace();
- drawClear();
- tft.textSetCursor(223,120);
- tft.textEnlarge(3);
- tft.textTransparent(0xAD35);
- tft.textWrite("A B C D 1 2");
- tft.textSetCursor(221,140);
- tft.textTransparent(RA8875_BLACK);
- tft.textWrite("_ _ _ _ _ _");
- short cursorPtr = 0;
- boolean alphaInputMode = true;
- boolean firstEntry = true;
- while(true){
- while(cursorPtr < 8){
- Serial.print("Channel Entry to Date: ");
- for(short i = 0; i < 10; i++){
- Serial.print(outPtr[i]);
- }
- Serial.println(". ");
- if(alphaInputMode == false){
- drawKeyboard();
- alphaInputMode = true;
- }
- char nextInput = handleAlphaEntry();
- if(nextInput == ('!')){
- cursorPtr = 0;
- drawEntry(outPtr, cursorPtr);
- }else if(nextInput == ('`')){
- cursorPtr -= 2;
- if(cursorPtr < 0){
- cursorPtr = 0;
- }
- drawEntry(outPtr, cursorPtr);
- }else{
- if(firstEntry == true){
- firstEntry = false;
- tft.graphicsMode();
- tft.fillRect(223,120,400,19,0xCE39);
- }
- if(nextInput != ('*')){
- outPtr[cursorPtr] = nextInput;
- cursorPtr += 2;
- drawEntry(outPtr, cursorPtr);
- }
- }
- }
- while(cursorPtr >= 8 && cursorPtr < 11){
- Serial.print("Channel Entry to Date: ");
- for(short i = 0; i < 10; i+=2){
- Serial.print(outPtr[i]);
- }
- Serial.println(". ");
- if(alphaInputMode == true){
- drawKeyboard();
- alphaInputMode = false;
- }
- char nextInput = handleNumEntry();
- if(nextInput == ('!')){
- cursorPtr = 0;
- drawEntry(outPtr, cursorPtr);
- }else if(nextInput == ('`')){
- cursorPtr -= 2;
- drawEntry(outPtr, cursorPtr);
- }else{
- if(nextInput != ('*')){
- outPtr[cursorPtr] = nextInput;
- cursorPtr += 2;
- drawEntry(outPtr, cursorPtr);
- }
- }
- }
- while(cursorPtr == 11){
- Serial.print("Channel Entry to Date: ");
- for(short i = 0; i < 10; i+=2){
- Serial.print(outPtr[i]);
- }
- Serial.println(". ");
- boolean enter = handleEntryConfirmation();
- if(enter == true){
- return;
- }else{
- cursorPtr = 10;
- drawEntry(outPtr, cursorPtr);
- }
- }
- }
- return;
- }
- void drawEntry(char *entryToDate, short cursorPtr){
- tft.fillRect(220,120,400,60,0xCE39);
- tft.textMode();
- tft.textEnlarge(3);
- tft.textTransparent(RA8875_BLACK);
- tft.textSetCursor(220,120);
- if(cursorPtr == 0){
- return;
- }
- tft.textWrite(entryToDate, cursorPtr);
- }
- char handleAlphaEntry(){
- if(boardType != 0){
- drawKeyboard();
- }
- Serial.println("handleAlphaEntry start success, init if pass");
- tsPoint_t raw;
- tsPoint_t cal;
- waitForTouchEvent(&raw);
- Serial.println("Point accepted");
- calibrateTSPoint(&cal, &raw, &_tsMatrix);
- Serial.println("Point accepted and calibrated");
- delay(250);
- if(cal.y > 80){
- if(cal.y < 255){
- if(cal.x < 160){
- Serial.println("Backspace returned");
- return '`';
- }else if(cal.x > 640){
- Serial.println("Clear returned");
- return '!';
- }
- }else if(cal.y < 330 && cal.x >= 0 && cal.x <= 800){
- return alphaKeys[((short)(cal.x/80))];
- }else if(cal.y < 405){
- return alphaKeys[(((short)(cal.x/88.888))+10)];
- }else if(cal.y < 801){
- return alphaKeys[(((short)(cal.x/114.285714))+19)];
- }
- }
- return '*';
- }
- char handleNumEntry(){
- if(boardType != 1){
- drawNumpad();
- }
- tsPoint_t raw;
- tsPoint_t cal;
- waitForTouchEvent(&raw);
- calibrateTSPoint(&cal, &raw, &_tsMatrix);
- return '*';
- }
- boolean handleEntryConfirmation(){
- drawEnter();
- while(true){
- tsPoint_t raw;
- tsPoint_t cal;
- waitForTouchEvent(&raw);
- calibrateTSPoint(&cal, &raw, &_tsMatrix);
- if(cal.y > 80){ // Below header
- if(cal.y < 255){ // Action buttons
- if(cal.x < 160){ // Backspace
- drawClear();
- return false;
- }else if(cal.x > 640){ // Enter
- return true;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement