// * Project Name: // TouchPanel (Demo for working with TouchPanel Controller) // * Target Platform: // PIC // * Copyright: // (c) mikroElektronika, 2007. // * Revision History: // 20071225: // - Initial release. // * Description: // this code in intended to work with TouchPanel and GLCD // Target devices are PIC16 and PIC18 family MCU's, any speed. // * Test configuration: // MCU: PIC16F887 // Dev.Board: EasyPic5 // Oscillator: HS, 8.000MHz // Ext. Modules: TouchPanel, GLCD // SW: mikroC v8.0 // * NOTES: // - Turn off PORTA LEDs, 7Seg Display Switches, ADC jumpers and PORTA pull-up/down resistors. // - Turn on GLCD backlight and TouchPanel Contoller switches on EasyPIC5 board. char write_erase, pen_size; unsigned int x_coord, y_coord; long x_coord128, y_coord64; // scaled x-y position int cal_x_min, cal_y_min, cal_x_max, cal_y_max; // calibration constants char write_msg[] = "WRITE"; // GLCD menu messages char clear_msg[] = "CLEAR"; char erase_msg[] = "ERASE"; const unsigned int ADC_THRESHOLD = 900; // Threshold value for press detecting // returns 1 if TouchPanel is pressed, 0 otherwise char PressDetect() { unsigned adc_rd; char result; // PRESS detecting PORTC.F0 = 0; // DRIVEA = 0 (LEFT drive off, RIGHT drive off, TOP drive on) PORTC.F1 = 0; // DRIVEB = 0 (BOTTOM drive off) Delay_us(3500); adc_rd = ADC_read(1); // Read RA1 (READ-Y) result = (adc_rd > ADC_THRESHOLD); // if logical one is detectet //debouncing, repeat detecting after 2ms Delay_ms(2); adc_rd = ADC_read(1); result = result & (adc_rd > ADC_THRESHOLD); return result; } unsigned int GetX() { unsigned int result; //reading X PORTC.F0 = 1; // DRIVEA = 1 (LEFT drive on, RIGHT drive on, TOP drive off) PORTC.F1 = 0; // DRIVEB = 0 (BOTTOM drive off) Delay_ms(5); result = ADC_read(0); // reading X value from RA0 (BOTTOM) return result; } unsigned int GetY() { unsigned int result; //reading Y PORTC.F0 = 0; // DRIVEA = 0 (LEFT drive off, RIGHT drive off, TOP drive on) PORTC.F1 = 1; // DRIVEB = 1 (BOTTOM drive on) Delay_ms(5); result = ADC_read(1); // reading Y value from RA1 (from LEFT) return result; } void Calibrate() { Glcd_Dot(0,63,1); Glcd_Write_Text("TOUCH BOTTOM LEFT",10,3,1); while (!PressDetect()); // get calibration constants (reading and compensating TouchPanel nonlinearity) cal_x_min = GetX() - 10; cal_y_min = GetY() - 10; Delay_ms(1000); Glcd_Fill(0); Glcd_Dot(127,0,1); Glcd_Write_Text("TOUCH UPPER RIGHT",10,4,1); while (!PressDetect()) ; // get calibration constants (reading and compensating TouchPanel nonlinearity) cal_x_max = GetX() + 5; cal_y_max = GetY() + 5; Delay_ms(1000); } void main() { PORTA = 0x00; TRISA = 0x03; // RA0 i RA1 are analog inputs ANSEL = 0x03; ANSELH = 0; // Configure other AN pins as digital I/O PORTC = 0 ; TRISC = 0 ; // PORTC is output Glcd_Init(&PORTB, 0, 1, 2, 3, 5, 4, &PORTD); // Glcd_Init_EP5, see Autocomplete Glcd_Fill(0); Glcd_Set_Font(FontSystem5x8, 5, 8, 32); Glcd_Write_Text("CALIBRATION", 24, 3, 1); Delay_ms(1500); Glcd_Fill(0); Calibrate(); Glcd_Fill(0); Glcd_Write_Text("WRITE ON SCREEN", 24, 4, 1) ; Delay_ms(1000); Glcd_Fill(0); Glcd_Fill(0); Glcd_V_Line(0,7,0,1); Glcd_Write_Text(clear_msg,1,0,0); Glcd_V_Line(0,7,97,1); Glcd_Write_Text(erase_msg,98,0,0); //Pen Menu: Glcd_Rectangle(41,0,52,9,1); Glcd_Box(45,3,48,6,1); Glcd_Rectangle(63,0,70,7,1); Glcd_Box(66,3,67,4,1); Glcd_Rectangle(80,0,86,6,1); Glcd_Dot(83,3,1); write_erase = 1; pen_size = 1; while (1) { if (PressDetect()) { // after a PRESS is detected read X-Y and convert it to 128x64 space x_coord = GetX() - cal_x_min; y_coord = GetY() - cal_y_min; x_coord128 = (x_coord * 128l) / (cal_x_max - cal_x_min); y_coord64 = (64 -(y_coord *64) / (cal_y_max - cal_y_min)); if ((x_coord128 < 0) || (x_coord128 > 127)) continue; if ((y_coord64 < 0) || (y_coord64 > 63)) continue; //if clear is pressed if ((x_coord128 < 31) && (y_coord64 < 8)) { Glcd_Fill(0); //Pen Menu: Glcd_Rectangle(41,0,52,9,1); Glcd_Box(45,3,48,6,1); Glcd_Rectangle(63,0,70,7,1); Glcd_Box(66,3,67,4,1); Glcd_Rectangle(80,0,86,6,1); Glcd_Dot(83,3,1); Glcd_V_Line(0,7,0,1); Glcd_Write_Text(clear_msg,1,0,0); Glcd_V_Line(0,7,97,1); if (write_erase) Glcd_Write_Text(erase_msg,98,0,0); else Glcd_Write_Text(write_msg,98,0,0); } //if write/erase is pressed if ((x_coord128 > 96) && (y_coord64 < 8)) { if (write_erase) { write_erase = 0; Glcd_Write_Text(write_msg,98,0,0); Delay_ms(500); } else { write_erase = 1; Glcd_Write_Text(erase_msg,98,0,0); Delay_ms(500); } } //if pen size is selected if ((x_coord128 >= 41) && (x_coord128 <= 52) && (y_coord64 <= 9)) pen_size = 3; if ((x_coord128 >= 63) && (x_coord128 <= 70) && (y_coord64 <= 7)) pen_size = 2; if ((x_coord128 >= 80) && (x_coord128 <= 86) && (y_coord64 <= 6)) pen_size = 1; if (y_coord64 < 11) continue; switch (pen_size) { case 1 : Glcd_Dot(x_coord128, y_coord64, write_erase); break; case 2 : Glcd_Box(x_coord128, y_coord64, x_coord128 + 1, y_coord64 + 1, write_erase); break; case 3 : Glcd_Box(x_coord128-1, y_coord64-1, x_coord128 + 2, y_coord64 + 2, write_erase); break; } } } }