adc yanlış okuma

Başlatan f_machine, 06 Haziran 2009, 20:42:06

f_machine

merhaba arkadaşlar ;

bitirme projemde 128*64 glcd nin üzerinde analog çıkış veren bir
dokunmatik panel kullanıyorum.Panelden adc ile veriyi alıp nereye dokunduğumu anlıyorum.Bunu elimdeki unids 3 geliştirme kartı üzerinde
yaptım,çalıştırdım.Ancak baskı devresini çizdikten sonra, orada
denediğimde adc yanlış ölçüm yapıyor.Baskı devrenin çiziminde  herhangi
bir hata, kısa devre filan yok.Nerede hata yapıyor olabilirim?

CLR

Touch screenler sıcaklığa ve diğer çevre şartlarından etkilenirler dolayısıyla yanlış okumayı önlemek için her açılışta kalibrasyon yapmalısın veya dişarıya kalibrasyon tuşu birakmalısın.
Knowledge and Experience are Power

f_machine

cevap için teşekkürler ama benim sorunum,adc aynı ortamda deneme kartı üzerinde farklı değer okuyor,baskı devre üzerinde farklı değer okuyor,onu çözemedim...

ahmet2004

Pic'in adc uç bağlantıları ve touch adc okuma kodlarını

ekleyebilirseniz çok yardımcı olur yardım için.

Unids3 de MCP3204 12bit adc var aynı devreyi mi yaptınız?

Daha fazla bilgi vermelisin.

f_machine

evet haklısın daha fazla detay veriyorum.Picin kendi adc modulünü
kullandım.


sürücü devresi




kodlar

#include <htc.h>
#include <delay.c>
#include <glcd.c>
#include <adc.c>
#include <stdio.h>
#include "resimler.h"





   unsigned int x_koordinat(void );
   unsigned int y_koordinat(void );
   unsigned char basma_kontrol(void );
   void gosteri(void );

	

   






  	__CONFIG(1,HSPLL);											//
	__CONFIG(2,BORDIS&BORV43&PWRTEN&WDTDIS);				//KONFİGÜRASYON
	__CONFIG(3,MCLRDIS&LPT1DIS&PBDIGITAL&CCP2RC1);			//BİTLERİ
	__CONFIG(4,XINSTDIS&DEBUGDIS&LVPDIS&STVREN);				//







unsigned int adc_deger;
unsigned char txt[]="           ";


void main ()  {
	
	



	
  ADCON1bits.PCFG=0x0D;      //RA0,RA1 ANALOG, GERİSİ DİJİTAL
  ADCON1bits.VCFG=0x00;      // REFERANS GERİLİM YOK
  ADFM=1;  
                    //ÇEVRİM SONUCU SAĞA DAYALI
  
                              // RA2 and RA5 as digital pins
  PORTA  = 0x00;             // configure RA0 and RA1 as inputs,
  TRISA  = 0x03;             // RA2 and RA5 as outputs
  PORTA=0;
  
  	DelayMs(100);
  
    glcd_init();
  	
	glcd_clear();
	
	
	
		
         

	
            
           
	

	
  
  for (;;)  {
	  
	  


		

	
	  
	  	while (!basma_kontrol()); //panele dokunuldu mu?
  		

  
          
           
           adc_deger=x_koordinat(); // x koordinatını al	
           sprintf(txt,"X=%d",adc_deger); //stringe dönüştür
           glcd_goto(7,10);	//glcd konumla
           glcd_puts(txt);   //koordinatı ekrana yaz
           	
           	                                                                                                                                                                     		
  			
           adc_deger=y_koordinat(); // y koordinatını al
           sprintf(txt,"Y=%d",adc_deger); //stringe dönüştür
           glcd_goto(7,60); //glcd konumla
           glcd_puts(txt); //koordinatı ekrana yaz  
           
          
           
           
           
            DelayMs(10);
			
            
           
                    
  }         
           	
           	       
  }




unsigned int x_koordinat() {

  unsigned int sonuc;
        TRISA0=0;  // porta 0. bit çıkış
  		PORTA=0;   //porta yı temizle  
		
		RA2=1;           // Y+ yüksek empedans    
  		RA5 = 0;         // X+ +5v
  		DelayMs(5);

        sonuc=adc_read(1); // X koordinatını al
    
    TRISA0=1;  //porta 0.bit analog giriş
    return sonuc;
}



unsigned int y_koordinat() {

     unsigned int sonuc;
 	
  	TRISA1=0;  //porta 1.bit çıkış
  	PORTA=0;	//porta yı temizle 
  	RA2 = 0;         // Y+ +5v
  	RA5 = 1;         // X+  yüksek empedans

  DelayMs(5);
  sonuc = adc_read(0); // Y koordinatını al
  TRISA1=1;
  return sonuc;
  
  
}





unsigned char basma_kontrol(void ) {

     unsigned int     ADC_ESIK_DEGER=1000;  //esik deger (5/1024)*(1000)=3.9v 
     unsigned char sonuc;
      

            TRISA1=1; // RA0 analog giriş
           TRISA0=1; //RA1 analog giriş
           PORTA=0;  //portayı temizle
             
           RA2=1;  // Y+ +5v
           RA5=0;  //X+ yüksek  empedans 
            
           adc_deger=adc_read(1); // y koordinatını al
            

                              

  sonuc = (adc_deger > ADC_ESIK_DEGER);    // okunan değer eşik değerden büyükse sonuc=1 

  
  DelayMs(2);
  adc_deger = adc_read(1);  // hata olasılığı için işlemi tekrarla
  sonuc = sonuc & (adc_deger > ADC_ESIK_DEGER);
  return sonuc;    //basıldıysa 1,basılmadıysa 0 olur
     

}



benim sorunun basma_kontrol fonsiyonunda
panele dokunulmadığında 500 gibi bir değer okunması lazım,daha
sonra panele dokunulğunda 1000 olması lazım böylece panele basılıp
basılmadığını anlıyorum.Bu devre unids 3 üzerinde, dediğim gibi çalışırken
baskı devre üzerinde panele dokunmasam dahi 1020 gibi bir değer çıkıyor,sonra yavaş yavaş iniyo filan,anlayamadım ne olduğunu?

ahmet2004

Bu kod ile hangi derleyiciyi kullanıyorsun?

CLR

ahmet2004
Yapı Microchip C18 gibi ama microchip hitect'i aldığı için hitech olma ihtimali yüksek çünkü header "htc".

f_machine;
Okuma mantığın doğru ama eksiklerin var. Touch'ın hangi omajlar arasında çalışıyor, nereye bastığında yaklaşık kaç volt okuyacağını bilmen gerekiyor.
Ve ADC yanlış okumaz, yanlış okumaya elektroniksel veya yazılımsal olarak sebebiyet verirsin.
Knowledge and Experience are Power

f_machine

Alıntı yapılan: "ahmet2004"Bu kod ile hangi derleyiciyi kullanıyorsun?

hitech picc18 pro

CLR

@f_machine

Ne yaptın çözebildin mi veya sorunu bulabildin mi?
Knowledge and Experience are Power

arslan74

Merhaba,

Gördüğüm kadarıyla okuma mantığında hata var.

Aşağıdaki linke touch screen okuma mantığını anlatan site var. Onu incele.

http://www.micro-examples.com/public/microex-navig/doc/079-touchclock.html

Selamlar

f_machine

@arslan74

ilgilendiğin için sağol ama,okuma ile ilgili bir sorunum yok.Devre unids3 üzerinde çalışıyor zaten,sadece baskı devre üzerinde picin adc si yanlış değer okuyor.Sorunum bununla ilgili,panel baskı devre üzerinde de düzgün çalışıyor ama,pic 2 voltu 5 volt ölçüyor.

@eemkutay

maalesef,çalıştıramadım.

ahmet2004

Kullandığın pic hangisi ?

arslan74

Alıntı yapılan: "f_machine"@arslan74

ilgilendiğin için sağol ama,okuma ile ilgili bir sorunum yok.Devre unids3 üzerinde çalışıyor zaten,sadece baskı devre üzerinde picin adc si yanlış değer okuyor.Sorunum bununla ilgili,panel baskı devre üzerinde de düzgün çalışıyor ama,pic 2 voltu 5 volt ölçüyor.

@eemkutay

maalesef,çalıştıramadım.

Merhaba,

Senin kullandığın okuma mantığı ile sana gönderdiğin linkteki okuma mantığı aynı değil. O yüzden bu linki gönderdim orada ki okuma mantığını kullanırsan belki doğru çalıştırabilirsin diye söyemiştim.

Orada okuma mantığını acıklamış.


Alıntı Yap
This is how the library reads the X raw coordinate of a touch  :

X+ and X- are in high Z : RA0 and RA2 are inputs
Y+ is set to +5V : RA3 is output high
Y- is set to 0V : RA1 is output low
X+ voltage is read by ADC
Y+ is set to 0V : RA3 is output low
Y- is set to 5V: RA1 is output high
X- voltage is read by ADC and averaged with X+ value, the result is the raw X coordinate.

Burada kodunuda vermiş.



#include "TSconfig.h"
#include "TSlib.h"

TS_CONFIG tsConfig ;            // touchscreen configuration

/*
 * return 1 if screen is touched, 0 otherwise
 */
unsigned char TS_touched()
        {
        int x ;

        /*
         * activate two opposite plates
         */
        TS_TRIS(0, 0, 0, 1) ;
        TS_PORT(1, 0, 1, 0) ;

        /*
         * read another plate
         */
        x = ADC_Read(TS_ADCYM) ;

        /*
         * deactivate plates
         */
        TS_TRIS(0, 0, 0, 0) ;
        TS_PORT(0, 0, 0, 0) ;

        /*
         * voltage is not null when screen is touched
         */
        if(x > TS_UNTOUCHED)
                {
                return(1) ;
                }

        return(0) ;
        }

/*
 * read row values of X and Y plates
 * return -1 if screen is not touched, 0 otherwise and result is stored
 * in variables pointed to by px and py
 */
signed char   TS_readRaw(int *px, int *py)
        {
        int     x, xx, y, yy ;
        long    l ;

        /*
         * return if screen is not touched
         */
        if(TS_touched() == 0) return(-1) ;

        /*
         * activate X plate
         */
        TS_TRIS(1, 0, 1, 0) ;
        TS_PORT(0, 0, 0, 1) ;
        x = ADC_Read(TS_ADCXP) ;        // read opposite X plate
        TS_PORT(0, 1, 0, 0) ;           // switch X plates
        xx = ADC_Read(TS_ADCXM) ;       // read opposite X plate
        *px = (x - xx) / 2 ;            // average

        /*
         * activate Y plate
         */
        TS_TRIS(0, 1, 0, 1) ;
        TS_PORT(0, 0, 1, 0) ;
        y = ADC_Read(TS_ADCYM) ;        // read opposite Y plate
        TS_PORT(1, 0, 0, 0) ;           // switch Y plates
        yy = ADC_Read(TS_ADCYP) ;       // read opposite Y plate
        *py = (y - yy) / 2 ;            // average

        TS_TRIS(0, 0, 0, 0) ;           // de-activate plates
        TS_PORT(0, 0, 0, 0) ;

        return(0) ;
        }

/*
 * read absolute X and Y coordinates of touched location
 * return -1 if no touch
 * return field number otherwise
 */
signed char   TS_read(int *px, int *py, TS_FIELD *scr)
        {
        int     x, xx, y, yy ;
        long    l ;
        static signed char old = 0 ;

        /*
         * return if screen is not touched
         */
        if(TS_readRaw(px, py) == -1)
                {
                // debounce
                if(old == 1)
                        {
                        Delay_ms(300) ;
                        }
                old = 0 ;
                return(-1) ;
                }

        // debounce
        if(old == 0)
                {
                Delay_ms(20) ;
                old = 1 ;
                return(-1) ;
                }
                
        old = 1 ;
        /*
         * adjust X coordinate
         */
        l = *px - tsConfig.pxmin ;
        l *= SCREEN_WIDTH - 1 ;
        l /= (tsConfig.pxmax - tsConfig.pxmin) ;
        *px = l ;

        /*
         * adjust Y coordinates
         */
        l = *py - tsConfig.pymin ;
        l *= SCREEN_HEIGHT - 1 ;
        l /= (tsConfig.pymax - tsConfig.pymin) ;
        *py = l ;

        /*
         * check for limits
         */
        if(*px < 0) *px = 0 ;
        if(*px >= SCREEN_WIDTH) *px = SCREEN_WIDTH - 1 ;
        if(*py < 0) *py = 0 ;
        if(*py >= SCREEN_HEIGHT) *py = SCREEN_HEIGHT - 1 ;

        /*
         * parse fields if pointer is not null
         */
        if(scr != TS_NULL)
                {
                while(scr->num)
                        {
                        /*
                         * check if touch coordinates are in box
                         */
                        if((*px >= scr->c1) && (*px < scr->c3) && (*py >= scr->c2) && (*py < scr->c4))
                                {
                                /*
                                 * return number
                                 */
                                return(scr->num) ;
                                }

                        scr++ ;         // next field
                        }
                }

        return(0) ;
        }

/*
 * get calibration coordinates
 */
void    TS_calibrate(int *px, int *py)
        {
        /*
         * wait for screen to be touched and get coordinates
         */
        while(TS_readRaw(px, py) == -1) ;

        /*
         * debounce
         */
        Delay_ms(100) ;
        while(TS_touched()) ;
        Delay_ms(100) ;
        }


Bu kodu denemeni tavsiye ederim.

Selamlar

f_machine

@arslan74

evet o linki daha önce incelemiştim.Benim kodum mikroelektronikanın verdiği kodun biraz değiştirilmiş hali o da çalışıyor yani,ama senin verdiğini de bi deniyim belki o zaman düzelir.

Benim kullandığım kodda bu,devreyi ve kodu biraz değiştirdim.


mikroe touch panel



@ahmet2004

18f4620, 18f452 ile bacak yapıları aynı ama 64kb hafızası var.

ahmet2004

ADCON2bits.ADCS = ?
 ADCON2bits.ACQT = ?

değerleri yok göremedim?



ADCON2:

bit 7 ADFM: A/D Result Format Select bit
            1 = Right justified
            0 = Left justified
bit 6 Unimplemented: Read as ?0?
bit 5-3 ACQT2:ACQT0: A/D Acquisition Time Select bits
            111 = 20 TAD
            110 = 16 TAD
            101 = 12 TAD
            100 = 8 TAD
            011 = 6 TAD
            010 = 4 TAD
            001 = 2 TAD
            000 = 0 TAD(1)
bit 2-0 ADCS2:ADCS0: A/D Conversion Clock Select bits
            111 = FRC (clock derived from A/D RC oscillator)(1)
            110 = FOSC/64
            101 = FOSC/16
            100 = FOSC/4
            011 = FRC (clock derived from A/D RC oscillator)(1)
            010 = FOSC/32
            001 = FOSC/8
            000 = FOSC/2