Adc hesap formülü ?

Başlatan ylmz, 29 Ocak 2013, 08:50:11

ylmz

Bende ete hoca ne zmaan cevap verır dıyordum ıcımden hızır gıbısın çok sağol valla :) mehmet hocam sanada çok teşekkürler
Regülatör Dns Trafo | Regülatör | Redresör | Ups

Extreme

ete hocam cevabın iyi oldu yakın zamanda bu kodlar benimde işime yarıycak.

harmanx

Alıntı yapılan: ete - 29 Ocak 2013, 12:16:51
Hesap formülünde yanlış gibime geliyor. Doğru hesap yöntemi şöyle olmalı.
Ölçeceğin voltaj 50V ondalıklı ölçme yapacağına göre bu değeri 500 olarak düşünmek gerekir.
ADC den okuyacağın değer (tam 50V da) 1023 dür. Sıfır dahil bu 1024 kademe demektir. O halde;
500/1024=0,48828125 gibi bir değer hesaplanır. Hesaplamada */ işlemini kullanınca sonuç otomatikman 256 ya bölünmüş olarak geleceği için bu değeri önceden 256 ile çarpmak gerekir.
0,48828125 * 256= 125 olarak bulunur. Bu senin sabit çarpan değerindir. O halde formülün;
Ham_Volt=(ADCDeger+1)*/125  şeklinde hesaplanır. Buradan
Volt= Ham_Volt/10
MVolt=Ham_Volt//10 
şeklinde uygulanır.

ADC ölçümünde oynama kaçınılmazdır. Hele büyük bir voltajı bölerek okuma yapıyorsan işin dahada zor demektir. Kullandığın bütün gerilm bölme dirençleri %1 toleranslı olmalıdır. Oynamayı asgari düzeye indirmek için ortalama almak bir yöntemdir ama pek fazla etkisi olacağını sanmıyorum. En iyisi digital filtre uygulamak.
Toplam 30 adet ölçüm alırsın. Bunların her birini 30 elemanlı bir dizi değişkenine yerleştirirsin. Sonra bunları sıraya dizersin. Küçükten büyüğe doğru. Sonra ortadaki 10 adeti alıp toplar sonra 10'a bölersin Böylece nispeten ekranda fazla değişmeyecek bir değer elde edersin.

İstersen birde örnek vereyim;
For I=0 to 29
  ADCIN 0,HAM
  OKU[I]=HAM+1
   Pauseus 100
Next
'buraya kadar 30 ölçüm yapmış ve bunları da OKU isimli dizi değişkenine yerleştirmiş olduk.
Şimdi bunları sıraya dizelim
FOR X=0 to 28
FOR Y=(X+1) to 29
   IF OKU[X]>OKU[Y] THEN
     TEMP=OKU[X]
     OKU[X]=OKU[Y]
     OKU[Y]=TEMP
   ENDIF
NEXT
NEXT
'Buraya kadar sıraya dizmiş olduk.
'Şimdi ortadan 10 adedi alıp toplayacağız
TOPLAM=0
FOR I=10 TO 19 
   TOPLAM=TOPLAM+OKU[I]
NEXT
HAM=TOPLAM/10
'İşte filtrelenmiş ADC değerin HAM değişkenine yerleşmiş değer olacaktır.


Ete




Saygılar...
sayı ete hocam
bar göstergeli voltmetre  bir sorun var proteusta denmede sorun yok fakat devre üzerinde ondalık değer ve onluk sayıda onama oluyor
ete hocam verdiğiniz program öğrneğini yapamadım yardımınza ihtiyacım var..



'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 30.10.2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
'******************************************************************************
Define   LOADER_USED   1
Define LCD registers and bits
DEFINE LCD_DREG	PORTB	'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT	4		'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT	3		'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG  PORTB   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT  2       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	1		'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS	4		'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2		'LCD Kaç sıra yazabiliyor
'*******************************************************************************
' Define ADCIN parameters
DEFINE  ADC_BITS        10        ' Set number of bits in result
DEFINE  ADC_CLOCK       3        ' Set clock source (3=rc)
DEFINE  ADC_SAMPLEUS    50       ' Set sampling time in uS
'*******************************************************************************
' Declare variables
adval        VAR WORD         ' Create adval to store result          Sonucu depolamak için adval Oluştur
fullbars   VAR   BYTE         ' Number of full bars at left of graph  Grafiğin sol tam bar sayısı
barval      VAR   BYTE         ' Value passed to bargraph routine     Değer Grafiği rutin çubuk geçti
partbar      VAR   BYTE         ' ASCII code for partial bar character Kısmi çubuğu karakteri için ASCII kodu
pad         VAR   BYTE         ' Number of spaces to pad to the right of graph   Number of spaces to pad to the right of graph
DEGER VAR WORD

TRISA = %11111111       ' Set PORTA to all input
ADCON1=%10001110 '7. bit 1 yapıldı 10 bit sonuç almak için.
'ADCON1 = %10000010      ' Set PORTA analog and right justify result
' PORTE remains digital to allow operation of the LCD
        
'Low PORTE.2            ' LCD R/W line low (W)
Pause 500               ' Wait .5 second
        
' Load the custom characters to LCD CGRAM. The blank at $0 makes the graphing math work faster.
        
LCDOut $FE,64,REP $0\8         ' Load blank character (ascii $0)
LCDOut $0,REP $10\6,$0         ' Load | character (ascii $1)
LCDOut $0,REP $14\6,$0         ' Load || character (ascii $2)
LCDOut $0,REP $15\6,$0         ' Load ||| character (ascii $3     
       
LCDOut $FE, 1               ' Clear the display
'*************************************************************************

loop:    ADCIN 0, adval               ' Read channel 0 to adval (0-1023)
'adval = (adval */ 500)>>2      ' equates to: (adval * 500)/1024
'LCDOut $FE,2,"DC Volts= ",DEc2 (adval/5),".", DEC1 adval   ' Display the decimal value 


adval = (adval */ 1000)>>2      ' equates to: (adval * 500)/1024
LCDOut $FE,2,"GR mm%= ",DEc2 (adval/10),".", DEC1 adval   ' Display the decimal value 



'LCDOut $FE,2,"DC Volts= ",DEc2 (adval/5),".", DEC2 adval   ' Display the decimal value 



'barval = (adval/11)+1         ' Scale 0-500 to 60 segment bargraph (1-56)
 barval = (adval/21)+1         ' Scale 0-500 to 60 segment bargraph (1-56)

        
        GoSub bargraph               ' Update bargraph with new barval

        GoTo loop                   ' Do it forever
        



bargraph:

fullbars = (barval MIN 60)/3      ' Calculate number of full bars (|||). 
     
' partbar holds the ascii code for the partial bar character: $0=" ", $1="|", or $2="||"

partbar = (barval MIN 60) // 3      ' Calculate ascii code for partial bar character       
     
pad = 19 - fullbars               ' Number of spaces to fill display width.
     
LCDOut $fe,$c0, REP $3\fullbars, partbar, REP " "\pad   ' Display the bar on second line
   
Return

ete

#18
'****************************************************************
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
'******************************************************************************
Define   LOADER_USED   1
Define LCD registers and bits
DEFINE LCD_DREG	PORTB	'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT	4		'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT	3		'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG  PORTB   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT  2       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	1		'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS	4		'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2		'LCD Kaç sıra yazabiliyor
'*******************************************************************************
' Define ADCIN parameters
DEFINE  ADC_BITS        10        ' Set number of bits in result
DEFINE  ADC_CLOCK       3        ' Set clock source (3=rc)
DEFINE  ADC_SAMPLEUS    50       ' Set sampling time in uS
'*******************************************************************************
' Declare variables
adval      VAR WORD         ' Create adval to store result          Sonucu depolamak için adval Oluştur
fullbars   VAR BYTE         ' Number of full bars at left of graph  Grafiğin sol tam bar sayısı
barval     VAR BYTE         ' Value passed to bargraph routine     Değer Grafiği rutin çubuk geçti
partbar    VAR BYTE         ' ASCII code for partial bar character Kısmi çubuğu karakteri için ASCII kodu
pad        VAR BYTE         ' Number of spaces to pad to the right of graph   Number of spaces to pad to the right of graph
TEMP       VAR BYTE
OKU        VAR BYTE[35]
X          var byte
Y          var byte
DEGER      VAR WORD
TOPLAM     VAR WORD

TRISA = %11111111       ' Set PORTA to all input
ADCON1=%10001110 '7. bit 1 yapıldı 10 bit sonuç almak için.
'ADCON1 = %10000010      ' Set PORTA analog and right justify result
' PORTE remains digital to allow operation of the LCD
        
'Low PORTE.2            ' LCD R/W line low (W)
Pause 500               ' Wait .5 second
        
' Load the custom characters to LCD CGRAM. The blank at $0 makes the graphing math work faster.
        
LCDOut $FE,64,REP $0\8         ' Load blank character (ascii $0)
LCDOut $0,REP $10\6,$0         ' Load | character (ascii $1)
LCDOut $0,REP $14\6,$0         ' Load || character (ascii $2)
LCDOut $0,REP $15\6,$0         ' Load ||| character (ascii $3     
       
LCDOut $FE, 1               ' Clear the display
'*************************************************************************

DON:   
     for x=0 to 34
      ADCIN 0, adval               ' Read channel 0 to adval (0-1023)
      OKU[X]=adval
      pauseus 20
     next
     
     for x=0 to 33
       for y=(x+1) to 34
         IF OKU[X]>OKU[Y] THEN
           TEMP=OKU[X]
           OKU[X]=OKU[Y]
           OKU[Y]=TEMP
         ENDIF
       NEXT
     NEXT   
     TOPLAM=0
     FOR X=15 to 19
       TOPLAM=TOPLAM+OKU[X]
     NEXT
     ADVAL=TOPLAM/5         
     
'adval = (adval */ 500)>>2      ' equates to: (adval * 500)/1024
'LCDOut $FE,2,"DC Volts= ",DEc2 (adval/5),".", DEC1 adval   ' Display the decimal value 


adval = (adval */ 1000)>>2      ' equates to: (adval * 500)/1024
LCDOut $FE,2,"GR mm%= ",DEc2 (adval/10),".", DEC1 adval   ' Display the decimal value 



'LCDOut $FE,2,"DC Volts= ",DEc2 (adval/5),".", DEC2 adval   ' Display the decimal value 



'barval = (adval/11)+1         ' Scale 0-500 to 60 segment bargraph (1-56)
 barval = (adval/21)+1         ' Scale 0-500 to 60 segment bargraph (1-56)

        
        GoSub bargraph               ' Update bargraph with new barval

        GoTo DON                  ' Do it forever
        
bargraph:

fullbars = (barval MIN 60)/3      ' Calculate number of full bars (|||). 
     
' partbar holds the ascii code for the partial bar character: $0=" ", $1="|", or $2="||"

partbar = (barval MIN 60) // 3      ' Calculate ascii code for partial bar character       
     
pad = 19 - fullbars               ' Number of spaces to fill display width.
     
LCDOut $fe,$c0, REP $3\fullbars, partbar, REP " "\pad   ' Display the bar on second line
   
Return


Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

harmanx

ete hocam teşekkür ederim hamen denmesini yapıcam.. :) :) :)

harmanx

#20
sayın Ete hocam  devre üzerinde denedim oynamalr daha da çok arttı eskisinden kötü oldu
birde gösterge değerinde hata var  0 ile 100 göstermiyor  alttaki programın son satırında bir hatamı var bakabilirmisin..

DON:   
     for x=0 to 34
      ADCIN 0, adval               ' Read channel 0 to adval (0-1023)
      OKU[X]=adval
      pauseus 20
     next
     
     for x=0 to 33
       for y=(x+1) to 34
         IF OKU[X]>OKU[Y] THEN
           TEMP=OKU[X]
           OKU[X]=OKU[Y]
           OKU[Y]=TEMP
         ENDIF
       NEXT
     NEXT   
     TOPLAM=0
     FOR X=15 to 19
       TOPLAM=TOPLAM+OKU[X]
     NEXT
     TEMP=TOPLAM/5    '''''''''''   ADVAL=TOPLAM/5   '??????????????  burayı düzelltim skala düzeldi ... fakat sayılarda oynama çok fazla sanki
      hızlı okuyor gibi...                 

ete

Benim düzenlediğim programda adval=Toplam/5 şeklinde formül verdim. Senin yazdığında temp=toplam/5 şeklinde. Programın geri kalan kısmında adval değişkeni asıl hesaplama formülünde kullanılmaktadır. Temp kullanılması yanlış olur.
Oynama artmış olamaz kesilmemiş olabilir bu durumda devrende fiziksel bir sorun vardır.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

harmanx

#22
kaldırıldı.... :( :( :( :(

ete

Protondan anlamam. Dizideğişkeni tanımlamda sorun olsa gerek.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

harmanx

#24
Ete hocam programı yeniden yapılandırdım sizin verdiklerinizle yanlız bar grafiğini skaladaki 0ile 100 değişkenine tam oturtamadım bar çözünürlüğünü sayıya tam uyum sağlamıyor

'****************************************************************
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
'******************************************************************************
Define   LOADER_USED   1
Define LCD registers and bits
DEFINE LCD_DREG	PORTB	'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT	4		'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT	3		'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG  PORTB   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT  2       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	1		'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS	4		'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2		'LCD Kaç sıra yazabiliyor
LOW portb.2 'LCD RW PİNİ GNDYE ÇEKİLDİ
'*******************************************************************************
' Define ADCIN parameters
DEFINE  ADC_BITS        10        ' Set number of bits in result
DEFINE  ADC_CLOCK       3        ' Set clock source (3=rc)
DEFINE  ADC_SAMPLEUS    50       ' Set sampling time in uS
'*******************************************************************************

OKUNAN VAR WORD[15]  'parentez içinde kaç adet dizideğişkeni ihtiyacımız var ise o rakamı yazıyoruz . 15 adet okuma yapacağımız için değişken adedimiz 15 olacaktır. Ama sıralamada sıfır dahil olduğu için 0-14 arasını kullanacağız.
TEMP VAR WORD
TOPLAM VAR WORD
HAM VAR WORD
X VAR BYTE
Y VAR BYTE
VOLT   var  word 
Mvolt  var  byte
fullbars   VAR BYTE         ' Number of full bars at left of graph  Grafiğin sol tam bar sayısı
barval     VAR BYTE         ' Value passed to bargraph routine     Değer Grafiği rutin çubuk geçti
partbar    VAR BYTE         ' ASCII code for partial bar character Kısmi çubuğu karakteri için ASCII kodu
pad        VAR BYTE         ' Number of spaces to pad to the right of graph   Number of spaces to pad to the right of graph  


 TRISA = %11111111       ' Set PORTA to all input
 ADCON1=%10001110 '7. bit 1 yapıldı 10 bit sonuç almak için.
 pause 100

'**************************************************        
' Load the custom characters to LCD CGRAM. The blank at $0 makes the graphing math work faster.
        
LCDOut $FE,64,REP $0\8         ' Load blank character (ascii $0)
LCDOut $0,REP $10\6,$0         ' Load | character (ascii $1)
LCDOut $0,REP $14\6,$0         ' Load || character (ascii $2)
LCDOut $0,REP $15\6,$0         ' Load ||| character (ascii $3     
       
LCDOut $FE, 1               ' Clear the display
'*************************************************

basla:

'Program başladıktan sonra önce 15 adet ADC okumasını yapıp okuma değerlerini dizi değişkenine aktaracağız.

FOR X=0 to 14
  ADCIN 0, HAM
  OKUNAN[X]=HAM+1
  pauseus 20
NEXT

'Buraya kadar 15 adet değişkenimizde okunan adc değerleri rastgele yerleşmiş oldu.
'Şimdi bunları bir sıraya dizmemiz gerekiyor. Bubble Sort yöntemini kullanacağız.
FOR X=0 to 13 
FOR Y=(X+1) TO 14
IF OKUNAN[X]>OKUNAN[Y] THEN
TEMP=OKUNAN[X]
OKUNAN[X]=OKUNAN[Y]
OKUNAN[Y]=TEMP
ENDIF
NEXT
NEXT
'Buraya kadar dizi değerlerini küçükten büyüğe doğru sıraya dizmiş olduk.
'Şimdi ortadan 5 elemanı alıp ortalamasını alacağız.
TOPLAM=0
FOR X= 5  TO 9
TOPLAM=TOPLAM+OKUNAN[X]
NEXT
TEMP=TOPLAM/5
VOLT=temp-1       'filtrelenmiş sonuç ham değerden sürekli 1 fazla çıktığı için eklendi.

Volt=(ham */ 2500)/10 'Ham ile 1250 yi 32 bit olarak çarp ve 100'böl
Mvolt=volt//10
Volt=Volt/10     
      LCDOUT $FE,2," VOLT=",#VOLT,",",# Mvolt 
      'LCDOUT $FE,$C0," VOLT=",#VOLT,",",# Mvolt      
      
'***********************************************************************
'lcdout $fe,1
'lcdout $FE,2,"Ham:",dec ham
'LCDOUT $FE,$C0,"Filtreli:",dec temp
'pause 50

'goto basla
'**************************************************************************************
'LCDOut $FE,2,"DC Volts= ",DEc2 (adval/5),".", DEC2 adval   ' Display the decimal value 

'barval = (adval/11)+1         ' Scale 0-500 to 60 segment bargraph (1-56)
barval = (volt/2)         ' Scale 0-500 to 60 segment bargraph (1-56)        
        GoSub bargraph               ' Update bargraph with new barval

        GoTo basla                 ' Do it forever        
bargraph:
fullbars = (barval MIN 60)/3'3      ' Calculate number of full bars (|||). 
     
' partbar holds the ascii code for the partial bar character: $0=" ", $1="|", or $2="||"
partbar = (barval MIN 60) //3      ' Calculate ascii code for partial bar character           
pad = 19 - fullbars               ' Number of spaces to fill display width.
     
LCDOut $fe,$c0, REP $3\fullbars, partbar, REP " "\pad   ' Display the bar on second line
   
Return

ete

Bir şeyi açıklığa kavuşturmamız gerekiyor. Ben senin programındaki çözünürlükle ilgili bşr değişiklik yapmadım.
Senin programın çözünürlük için Adval değişkenini kullanıyor idi. Bu değişken değeride 0-1023 arasında değişiyor.
Benim yaptığım daha stabil bir adval hesaplamak oldu. Yoksa yaptığım ilave senin çözünürlüğünü değiştirmesz. Eskisinde ne ise yenisinde de odur.

Sen en iyisi benim yazdığımı kullanma eskisini kullan bu meselede burada kapansın gitsin.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

harmanx

biraaz başını ağrıtım herhalde pic konusunda acemiyim verdiğim rahatsızlıktan özür dilerim..

kendi başımın çaresine bakmam lazım... ::) :( :'(

ete

Yaptığım değişiklikten o kadar da emindimki ama emin olmamak gerekiyormuş. Evet haklısın dikkatimden kaçan bir husus varmış.
Oda aşağıdaki komut satırında;
OKU        VAR BYTE[35]
şeklinde verilen satırı,
OKU        VAR WORD[35]
şeklinde değiştirmek gerekiyormuş. Zira ADC den okunan değerler 10 bitlik değerler ve tanımladığımız OKU değişkeni ise Byte 8bitlik değişken olduğundan yeterli olmuyormuş. Bu durumda program eksik bar gösteriyor idi.
Dediğim değişikliği yaparsan programın düzelecektir.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

harmanx

evet halloldu isis'de denedim cuk oturdu pazartesi devre üzerinde test edicem yardımlarından dolayı teşekkür ederim... :) :) :)

harmanx

malesef real'de devre üzerinde rakamlar asena gibi isis'te olduğu gibi sabit değil zıplamalar çok hızlı acaba interup kullanmakmı lazım bunu
araştırıcam.. teoride olan malesef gerçekte olmuyor... :(