CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

reading a 4 wire touch panel
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

reading a 4 wire touch panel
PostPosted: Mon Jun 22, 2009 10:15 am     Reply with quote

hi,

i want to read a 4 wire panel, and for that i need to put some input in high impedancy mode on my 16F876A

cans CCS do this? i can't find anything in the help file.

i planned to use RA0-RA3

thanks
_________________
yup, i know, i don't speak english very well

CCS V4.057
Steve H.
Guest







PostPosted: Mon Jun 22, 2009 10:27 am     Reply with quote

You can get a good idea of how this has to work by reading the MXB7846 data sheet from Maxim. Or you can easily use this IC and use CCS to control it in your project.

HTH - Steve H.
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Mon Jun 22, 2009 10:31 am     Reply with quote

I know how it worked (I guess^^) but i don't know how to put a input in high impedance mode (HZ).

I don't want to use an external chip to read it cause I don't have any and transport always last more than 1 week.
_________________
yup, i know, i don't speak english very well

CCS V4.057
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Jun 22, 2009 10:36 am     Reply with quote

You should be able to read the touch panel by the PIC ADC. The basic method is to apply 0 and 5 V to one axis and measure the voltage by an ADC input at one terminal of the other axis. The voltage gives the relative position along the first axis. Then apply 0/5 V at the other axis and measure respectively.

Because PIC16F877 doesn't support arbitrary configuration of inputs in analog mode, you need 5 or 6 IO ports in total.

P.S.: I see, that the last remark is wrong. Analog mode doesn't exclude driving the pin as output, it only disables the analog input buffer. Sorry for causing confusion. So you can set AN0..3 as analog inputs and use standard I/O built-in functions to set the pins to low, high and tristate as required.
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Mon Jun 22, 2009 12:37 pm     Reply with quote

Nice, but how do I put an output in high-impedance?
_________________
yup, i know, i don't speak english very well

CCS V4.057
Ttelmah
Guest







PostPosted: Tue Jun 23, 2009 2:27 am     Reply with quote

Depends on the date of your compiler.
If reasonably 'modern', look at 'output_float' in the manual.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Jun 23, 2009 2:57 am     Reply with quote

If you consider, that an I/O pin can either be output (low impedance) or input (high impedance), the answer seems to be obvious.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Tue Jun 23, 2009 6:07 am     Reply with quote

sliders_alpha wrote:
nice, but how do i put a output in high-impedance?

Any pin set as an INPUT is high-impedance. The latest versions of the CCS compiler have an explicit output-float function. But for older versions just read the pin and it becomes high-impedance.
_________________
The search for better is endless. Instead simply find very good and get the job done.
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 3:01 am     Reply with quote

so, here is what i've done :

a fonction that know when the screen is touched
a fonction that read coordinate following texas-instrument order



here is my main :

Code:

#include <16F876A.H>
#fuses HS, NOWDT, NOPROTECT
#DEVICE ADC=10
#use delay(clock = 20000000)

#define GLCD_WIDTH         320
#define GLCD_HEIGHT        240
#define GLCD_CHAR_WIDTH    8
#define GLCD_CHAR_HEIGHT   8

#define LARGE_LCD 1
#include <RA883516F876A.c>
#include <graphics.c>
#include <Touchlib.c>

void main(void)
   {
   
   int16 xcoord, ycoord;
   setup_adc_ports( ALL_ANALOG );
   setup_adc(ADC_CLOCK_DIV_32);
   
   output_low(YM);
   output_low(XP);
   output_low(YP);
   output_low(XM);
   
   glcd_RAinit();
   
   while(1)
      {
      while(TS_readRaw(xcoord, ycoord) == 1){}
      delay_ms(200);
      }
   }


here are my functions :

Code:

#define YM  Pin_A0            // Y- plate
#define XM  Pin_A1            // X- plate
#define YP  Pin_A2            // Y+ plate
#define XP  Pin_A3            // X+ plate

#define ADCYM  0            // Y- plate
#define ADCXM  1            // X- plate
#define ADCYP  2            // Y+ plate
#define ADCXP  3            // X+ plate

#define  TS_UNTOUCHED 70

int8 TS_touched(void)
        {
        long x;
        output_Float(YM);
        output_high(XP);
        output_low(YP);
        output_high(XM);
       
        set_adc_channel (ADCYM);
        x = read_adc();
        output_low(XP);
        output_low(XM);
        output_low(YM);
       
        if(x > TS_UNTOUCHED)
          {
           return(1);
          }
        return(0);
        }


int8 TS_readRaw(int16 px, int16 py)
   {
    int16  x, y;
    int16 xc, yc;
   
    if(TS_touched() == 0) return(1) ;
   
   //lecture abscisse
   output_float(XP);
   output_float(XM);
   output_low(YM);
   output_high(YP);

   set_adc_channel(ADCXP);
   delay_us(100);
   x = read_adc();
   
   //lecture ordonĂ©e

   output_float(YP);
   output_float(YM);
   output_low(XM);
   output_high(XP);

   set_adc_channel(ADCYP);
   delay_us(100);
   y = read_adc();
   
   //desactivation panneau

   output_low(XP);
   output_low(XM);
   output_low(YP);
   output_low(YM);
   
      GlcdGotoTextXY(1,1);
      printf(GlcdPutC,"                         ");
      GlcdGotoTextXY(1,1);
      printf(GlcdPutC,"x = %ld",x);
      GlcdGotoTextXY(1,2);
      printf(GlcdPutC,"                         ");
      GlcdGotoTextXY(1,2);
      printf(GlcdPutC,"y = %ld",y);
   
   return(0);
   }


as you can see i'm reading the pannel according to TI

http://sliders.alpha.free.fr/GLCD/320240/4%20Wire%20Driving.pdf
(page 3)
and i'm reading coherent data, but still, its weird

y is goind from 170 to 680 and x from 90 to 830

shouldn't they all go from 0 to 1023?
_________________
yup, i know, i don't speak english very well

CCS V4.057
mkuang



Joined: 14 Dec 2007
Posts: 257

View user's profile Send private message Send e-mail

PostPosted: Fri Jun 26, 2009 8:46 am     Reply with quote

Not sure about the rest of your code but there appears to be a couple of bugs here:

Code:

int8 TS_touched(void)
        {
        ........       
        set_adc_channel (ADCYM);
        x = read_adc();
        ......
       
        if(x > TS_UNTOUCHED)
          {
           return(1);
          }
        return(0);
        }

Where is your little bit of delay (20-100us or whatever) between setting the adc channel and reading it?

Aren't you also missing an "else" statement before the return(0) ?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 11:20 am     Reply with quote

Code:
shouldn't they all go from 0 to 1023?
Most likely not. You have also series resistances of the output ports and a dead zone outside the sense area. You simply should calibrate the position by a linear scaling of x and y coordinates. The read_raw() function looks good, I don't see any reason in the code to get wrong measurements. If the touched sensing is also working correctly (I didn't check this part), everything is O.K.
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 3:01 pm     Reply with quote

mkuang wrote:
Not sure about the rest of your code but there appears to be a couple of bugs here:

Code:

int8 TS_touched(void)
        {
        ........       
        set_adc_channel (ADCYM);
        x = read_adc();
        ......
       
        if(x > TS_UNTOUCHED)
          {
           return(1);
          }
        return(0);
        }

Where is your little bit of delay (20-100us or whatever) between setting the adc channel and reading it?

Aren't you also missing an "else" statement before the return(0) ?


delay are useless
no, an else is useless cause if return(1) is executed then the function quit


Quote:

Most likely not. You have also series resistances of the output ports and a dead zone outside the sense area. You simply should calibrate the position by a linear scaling of x and y coordinates. The read_raw() function looks good, I don't see any reason in the code to get wrong measurements. If the touched sensing is also working correctly (I didn't check this part), everything is O.K.


indeed, everything was solved with a bit of math

But now I have a new problem, my touche-detect function do not cover all the screen (upper right is offgrid), and if I make her more sensitive then sometimes noise trigger it.

Any ideas?
_________________
yup, i know, i don't speak english very well

CCS V4.057
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 3:51 pm     Reply with quote

As I said, I didn't check the TS_touched() code, but I see, that it's not good. (I reordered the lines for clarity)
Code:
output_high(XP);
output_high(XM);
output_low(YP);
output_Float(YM);
set_adc_channel (ADCYM);

When the toched point is near YP, the AD voltage change is only small, while is maximal near YM. I see these alternatives:
- Pulling YP and YM low alternatingly and measure at the opposite terminal respectively, than taking the max value of both AD-readings.
- Performing a dynamic measurement: pulling an Y terminal low and releasing it to float, then starting the measurement with a few us delay
- Needing a hardware modification: Connect a Port B pin with a switchable weak pullup as load for the touched sense additionally.
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Sat Jun 27, 2009 6:15 pm     Reply with quote

Sorry for my late answer, I wasn't at home.

Well, I've tried to read Ym and Yp BUT:

First :

If I do not put the data-direction directive in this order, it won't work :
Code:

        output_Float(YM);
        output_high(XP);
        output_low(YP);
        output_high(XM);


Second :

If I put two reading in the same function, it won't work either :
Code:

        long x, p;
       
        output_Float(YM);
        output_high(XP);
        output_low(YP);
        output_high(XM);
       
        set_adc_channel (ADCYM);
        x = read_adc();

        output_Float(YP);
        output_high(XP);
        output_low(YM);
        output_high(XM);
       
        set_adc_channel (ADCYP);
        p = read_adc();
       
       //desactivation panneau

       output_low(XP);
       output_low(XM);
       output_low(YP);
       output_low(YM);

This is not working, data (x and p) are barely moving.

This is working for the lower left part of the screen:
Code:

        long x;
       
        output_Float(YM);
        output_high(XP);
        output_low(YP);
        output_high(XM);
       
        set_adc_channel (ADCYM);
        x = read_adc();
       
       //desactivation panneau

       output_low(XP);
       output_low(XM);
       output_low(YP);
       output_low(YM);

Can I put an internal pullup on only one pin of the B port?
_________________
yup, i know, i don't speak english very well

CCS V4.057
sliders_alpha



Joined: 03 Mar 2008
Posts: 55

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 12:52 am     Reply with quote

huuum, I think I wasn't clear, it was 2:00am and I was coming back from a party.

Here is a better explanation :

I've now done two functions, one that read the lower left part of the screen and one that read the upper right.

Definition :
Code:

#define YM  Pin_A0            // Y- plate
#define XM  Pin_A1            // X- plate
#define YP  Pin_A2            // Y+ plate
#define XP  Pin_A3            // X+ plate

#define ADCYM  0            // Y- plate
#define ADCXM  1            // X- plate
#define ADCYP  2            // Y+ plate
#define ADCXP  3            // X+ plate

#define  TS_UNTOUCHED 80


Lower left:
Code:

int8 TS_touched_LL(void)
        {
        long x;
       
        output_Float(YM);
        output_high(XP);
        output_low(YP);
        output_high(XM);
       
        set_adc_channel (ADCYM);
        x = read_adc();
       
       //pannel de-activation

       output_low(XP);
       output_low(XM);
       output_low(YP);
       output_low(YM);
   
       GlcdGotoTextXY(1,1);
       printf(GlcdPutC,"                         ");
       GlcdGotoTextXY(1,1);
       printf(GlcdPutC,"ym = %ld",x);
     
        if(x > TS_UNTOUCHED)
          {
           return(1);
          }
        return(0);
        }


Upper right:
Code:

int8 TS_touched_UR(void)
        {
        long x;
       
        output_Float(YP);
        output_high(XP);
        output_low(YM);
        output_high(XM);
       
        set_adc_channel (ADCYP);
        x = read_adc();
       
   
       //pannel de-activation

       output_low(XP);
       output_low(XM);
       output_low(YP);
       output_low(YM);

       GlcdGotoTextXY(1,2);
       printf(GlcdPutC,"                         ");
       GlcdGotoTextXY(1,2);
       printf(GlcdPutC,"yp = %ld",x);
       
        if(x > TS_UNTOUCHED)
          {
           return(1);
          }
        return(0);
        }


and now the main code :
Code:

#include <16F876A.H>
#fuses HS, NOWDT, NOPROTECT
#DEVICE ADC=10
#use delay(clock = 20000000)

#define GLCD_WIDTH         320
#define GLCD_HEIGHT        240
#define GLCD_CHAR_WIDTH    8
#define GLCD_CHAR_HEIGHT   8

#define LARGE_LCD 1
#include <RA883516F876A.c>
#include <graphics.c>
#include <Touchlib.c>

void main(void)
   {
   
   int16 xcoord, ycoord;
   setup_adc_ports( ALL_ANALOG );
   setup_adc(ADC_CLOCK_DIV_32);
   
   output_low(YM);
   output_low(XP);
   output_low(YP);
   output_low(XM);
   
   glcd_RAinit();
   
   while(1)
      {
      while(1)
         {
         TS_touched_LL();
         TS_touched_UR();
         delay_ms(500);//let me time to read the screen
         }
      }
   }

Here it's not working, data (ym and yp) are stuck around 40.

But if I comment one of them, then the uncommented line is working.
_________________
yup, i know, i don't speak english very well

CCS V4.057
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group