|
|
View previous topic :: View next topic |
Author |
Message |
sliders_alpha
Joined: 03 Mar 2008 Posts: 55
|
reading a 4 wire touch panel |
Posted: Mon Jun 22, 2009 10:15 am |
|
|
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
|
|
Posted: Mon Jun 22, 2009 10:27 am |
|
|
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
|
|
Posted: Mon Jun 22, 2009 10:31 am |
|
|
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
|
|
Posted: Mon Jun 22, 2009 10:36 am |
|
|
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
|
|
Posted: Mon Jun 22, 2009 12:37 pm |
|
|
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
|
|
Posted: Tue Jun 23, 2009 2:27 am |
|
|
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
|
|
Posted: Tue Jun 23, 2009 2:57 am |
|
|
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
|
|
Posted: Tue Jun 23, 2009 6:07 am |
|
|
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
|
|
Posted: Fri Jun 26, 2009 3:01 am |
|
|
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
|
|
Posted: Fri Jun 26, 2009 8:46 am |
|
|
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
|
|
Posted: Fri Jun 26, 2009 11:20 am |
|
|
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
|
|
Posted: Fri Jun 26, 2009 3:01 pm |
|
|
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
|
|
Posted: Fri Jun 26, 2009 3:51 pm |
|
|
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
|
|
Posted: Sat Jun 27, 2009 6:15 pm |
|
|
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
|
|
Posted: Sun Jun 28, 2009 12:52 am |
|
|
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 |
|
|
|
|
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
|