Problem with touch panel

Thread Starter

mamech

Joined Nov 3, 2010
27
I have easypic6 development board and I want to develop touch panel and GLCD applications on pic18f452.

But when I tried the touch panel example (in mikroC compiler examples) after making some modifications to suit pic18F452(as it is originally designed to suit pic16F887), I got the writings clear on the screen, but the touch screen does not work.

I suppose that the configuration of ADCON1 is the source of the problem now.

As I understand, it needs to change A0 and A1 to analog inputs, while all other port A pins are digital output.

Rich (BB code):
/*
 * Project name:
     TouchPanelWrite (Demo for working with TouchPanel Controller)
 * Copyright:
     (c) Mikroelektronika, 2010.
 * Revision History:
     20100203:
       - initial release;
 * Description:
     This code works with TouchPanel and GLCD. Two digital output and
     two analog input signals are used for communication with TouchPanel. 
     This example is for writing on the screen, calibration constants for touch
     panel are set via library function.
 * Test configuration:
     MCU:             PIC16F887
                      http://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf
     Dev.Board:       EasyPIC6 - ac:Touch_Panel
                      http://www.mikroe.com/eng/products/view/297/easypic6-development-system/
     Oscillator:      HS, 08.0000 MHz
     Ext. Modules:    GLCD 128x64, Touch Panel
                      http://www.mikroe.com/eng/categories/view/43/components/
     SW:              mikroC PRO for PIC
                      http://www.mikroe.com/eng/products/view/7/mikroc-pro-for-pic/
 * Notes:
     - Turn on GLCD backlight switch SW8.8.
     - Turn on TouchPanel Controller switches SW9.5, SW9.6, SW9.7 and SW9.8.
     - Turn off PORTA LEDs SW9.1.
*/

// Glcd module connections
char GLCD_DataPort at PORTD;

sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN  at RB4_bit;
sbit GLCD_RST at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction  at TRISB2_bit;
sbit GLCD_RW_Direction  at TRISB3_bit;
sbit GLCD_EN_Direction  at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
// End Glcd module connections

// Touch Panel module connections
sbit DriveA at RC0_bit;
sbit DriveB at RC1_bit;
sbit DriveA_Direction at TRISC0_bit;
sbit DriveB_Direction at TRISC1_bit;
// End Touch Panel module connections

bit          write_erase;
char         pen_size;
char write_msg[] = "WRITE";                                // GLCD menu messages
char clear_msg[] = "CLEAR";
char erase_msg[] = "ERASE";
unsigned int x_coord, y_coord;

void Initialize() {
  /*ANSEL  = 3;                                              // Configure AN0 and AN1 pins as analog inputs
  ANSELH = 0;                                              // and other AN pins as digital I/O
  TRISA  = 3;

  C1ON_bit = 0;                                            // Disable comparators
  C2ON_bit = 0; */
  
  ADCON1 = 4;   //This is the closest configuration to ANSEL =3
               //but here AN3 also will be analog
 
CCP1CON = 0;
CCP2CON = 0;
TRISA = 0b00000011;

  Glcd_Init();                                             // Initialize GLCD
  Glcd_Fill(0);                                            // Clear GLCD

  ADC_Init();                                              // Initialize ADC
  TP_Init(128, 64, 0, 1);                                  // Initialize touch panel
  TP_Set_ADC_Threshold(900);                               // Set touch panel ADC threshold
}

void main() {

  Initialize();
  
  // You can get calibration constants using touch panel calibration example
  TP_Set_Calibration_Consts(76, 917, 108, 906);           // Set calibration constants

  Glcd_Write_Text("WRITE ON SCREEN", 20, 5, 1) ;
  Delay_ms(1000);

  Glcd_Fill(0);                                            // Clear GLCD
  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 (TP_Press_Detect()) {
      // After a PRESS is detected read X-Y and convert it to 128x64 space
      if (TP_Get_Coordinates(&x_coord, &y_coord) == 0) {

        if ((x_coord < 31) && (y_coord < 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_coord > 96) && (y_coord < 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_coord >= 41) && (x_coord <= 52) && (y_coord <= 9))
          pen_size = 3;

        if ((x_coord >= 63) && (x_coord <= 70) && (y_coord <= 7))
          pen_size = 2;

        if ((x_coord >= 80) && (x_coord <= 86) && (y_coord <= 6))
          pen_size = 1;

        if (y_coord < 11)
          continue;

        switch (pen_size) {
          case 1 : {
                      if ( (x_coord >= 0) && (y_coord >= 0)  && (x_coord <= 127) && (y_coord <= 63) )
                       Glcd_Dot(x_coord, y_coord, write_erase);
                     break;
                   }
          case 2 : {
                      if ( (x_coord >= 0) && (y_coord >= 0)  && (x_coord <= 127-1) && (y_coord <= 63-1) )
                       Glcd_Box(x_coord, y_coord, x_coord + 1, y_coord + 1, write_erase);
                     break;
                   }
          case 3 : {
                      if ( (x_coord >= 1) && (y_coord >= 1)  && (x_coord <= 127-2) && (y_coord <= 63-2) )
                       Glcd_Box(x_coord-1, y_coord-1, x_coord + 2, y_coord + 2, write_erase);
                     break;
                   }
        }
      }
    }
  }
}

Can anyone here help me in this problem ?


Thanks
 

ErnieM

Joined Apr 24, 2011
8,053
The touchscreen needs a bit more handling then just reading the A2D: you also need to drive the other sides. What I mean is if you're reading Y then you need to set X+ and X- to a high and low voltage.

Can you post the schematic of this area? I've used Mikroe's touch screens in the past but I made my own interface. Just need which touchscreen pins go to which A2D inputs, and the transistors in the drive too.

Also gonna need the code behind TP_Get_Coordinates() too.
 

Thread Starter

mamech

Joined Nov 3, 2010
27
The touchscreen needs a bit more handling then just reading the A2D: you also need to drive the other sides. What I mean is if you're reading Y then you need to set X+ and X- to a high and low voltage.

Can you post the schematic of this area? I've used Mikroe's touch screens in the past but I made my own interface. Just need which touchscreen pins go to which A2D inputs, and the transistors in the drive too.

Also gonna need the code behind TP_Get_Coordinates() too.
Actually, the code works perfectly with pic16F887. The only difference is how should I initialize analog port I think and other necessary initializations.

The schematic is from Visual GLCD tutorial :
s1.jpg


Actually, I do not know code behind TP_Get_Coordinates() , here is some kind of illustration in MikroC help:
s2.jpg


Datasheet of pic18F452:

ww1.microchip.com/downloads/en/devicedoc/39564c.pdf


Thanks for your time
 

ErnieM

Joined Apr 24, 2011
8,053
Wow, you linked to everything beautifully, even the PIC part spec. Thanks, that makes checking this so much faster for me.

OK, with the schematic and the code looks like you have the driver pins nailed down correctly. (Aside: I always wondered why Mikroe used 5 transistors to do that, I only needed 4.) It works like this:

Drive A low: Right & Left both float
Drive A high: Vcc->Right GND->Left
Drive B low: Top & Bottom both float
Drive B high: Vcc->Top GND->Bottom

To read Top to Bottom you make A low & B high and read what Left is.
To read Top to Bottom you make A high & B low and read what Bottom is.

That may seen backwards but it's how these silly things work.

So the code to do that looks OK, you are telling the code in "Touch Panel module connections" that A & B are on RC0 and 1. Leads me to think the problem is in the A2D.

For the A2D to work you need to set both ADCON0 and ADCON1. With an 8 MHz clock (see Table 17-1 to select ADCS2:ADCS0) I get these to be:

ADCON0 = b01000001 // to read Right
ADCON0 = b01001001 // to read Left
ADCON1 = b11000100 // for both inputs

In the same way you set the DriveA and DriveB symbols in "Touch Panel module connections" you need a way to define these config bits. Somewhere in the manual for library that supplies TP_Get_Coordinates these should be called out.

Sorry I don't have that manual to look that up, but congrats in getting that display to work!
 

Thread Starter

mamech

Joined Nov 3, 2010
27
Wow, you linked to everything beautifully, even the PIC part spec. Thanks, that makes checking this so much faster for me.
Haha, this is logic. I should make you feel comfortable while helping me, so you can help me



For the A2D to work you need to set both ADCON0 and ADCON1. With an 8 MHz clock (see Table 17-1 to select ADCS2:ADCS0) I get these to be:

ADCON0 = b01000001 // to read Right
ADCON0 = b01001001 // to read Left
ADCON1 = b11000100 // for both inputs

In the same way you set the DriveA and DriveB symbols in "Touch Panel module connections" you need a way to define these config bits. Somewhere in the manual for library that supplies TP_Get_Coordinates these should be called out.

Sorry I don't have that manual to look that up, but congrats in getting that display to work!
But I do not think so. I do not need to make anything to be called. I think that all what I have to do is to set A2d correctly -which I could not till now :(

The original code for pic16f887 has Ansel =3 and Anselh=0, C1ON_bit = 0 ,C2ON_bit = 0, and then everything works well. The name of the game here is how to make the PIC18f452 with its different register names and funtionalities to do the same as Ansel=3 and Anselh =0

There is a new remark that I want to say, may be you can conclude something from it:

There is an example in help of MikroC, this example do the same as the above mentioned code (i.e writes on the screen), but it has an additional part in the beginning that makes calibration before writing on the screen.
So it asks the user to click the left bottom of the screen then to click the upper right of the screen. When I used the example, I noticed that after calibration, when I try to write on the screen , the writing in permitted only in 2 vertical lines in the right side of the screen, so if I moved my finger right and left nothing written, but when I move it up and down any where on the screen, the filling happens only vertically in those two fixed places.

I conclude from this that there is something works, but works wrongly.

*This is MikroC compiler, with its help section :
http://www.mikroe.com/eng/downloads/get/29/mikroc_pro_pic_2011_v501.zip


*this is the data sheet of pic16f887:
http://ww1.microchip.com/downloads/en/DeviceDoc/41291D.pdf



Need to hear your opinion.


Thanks for your time
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
I don't think it is related to MikroC, it sounds like the fault might be your ADC right/left justification setting.

If your ADC is set to the wrong justifiy your ADC reading might be taken as 4 times higher than what it is, (ie; 10bit not 8bit) so the X coordinates appear on the far right quarter of the screen as the X coords are 4 times too big.
 

ErnieM

Joined Apr 24, 2011
8,053
mamech: Sorry I disappeared but yesterday morning I had a hurricane pass about 25 miles from my house and have not had power or interwebs since 8AM. (Just some downed tree limbs for me.) I have to say the best time I have responding to posts is when the person on the other end actually has a fully functional brain, not just someone looking for help thru "post me some code to do X."

Now at work I discover I have that compiler installed here, not that I have ever used it much. I can't get your code to compile clean, looks like its too big for the demo version.

Anyway, what I did notice is you don't seem to call TP_Init. This function is the place where you tell the lib where the A2D channels are, that's the "char readX_ChNo" and "char readY_ChNo" numbers you send it. You also let it know how big your screen is.

I don't get what TP_Set_ADC_Threshold() is doing but that looks important too.

Unfortunately, looks like Mikroe sells you per-compiled libraries without the source code so you can't peek at how it does what it does (nor tweak then if need be). I looked for the source but only found ".mcl" files that are not source code.
 
Top