10Bit çevirme heasbı

Başlatan onurinci, 25 Aralık 2022, 17:58:14

onurinci

hocam selam örneklerden 3 LED'i ADC değeri ile Analog kısıp açan proje ile uğraşıyorum bunu 8 LED'e çıkardım.
8 bit ADC ile uygun hesaplamalar ile düzgün bir şekilde çalıştırabiliyorum
fakat ADC'yi 10 Bit yapınca değişkeni Word olarak tanımlasamda hesaplamalar doğru gitmiyor.nerede hata yapıyorum. LED'lerim Kandela olarak oldukça parlak.sanki 10 Bit ile daha ince step'lerle daha güzel çalışacaklar.Ardu ile yapan çok Basic 10 Bit örneği bulamadım.
' Name        : VUX2.pbp
' Compiler    : PICBASIC PRO Compiler 2.6
' Assembler   : PM or MPASM
' Target PIC  : 28/40-pin PIC types compatible with LAB-X2 board
' Hardware    : LAB-X2 Experimenter Board
' Oscillator  : 4MHz external crystal
' Keywords    : ADCIN, PWM
' Description : PICBASIC PRO program to display result of ADC in 3
' segment bargraph. The last LED in the graph dims or brightens with
' changes in the analog input.
'
#CONFIG
 __CONFIG _XT_OSC & _WDT_OFF &_PWRTE_ON & _CP_OFF 
#ENDCONFIG

REM 16F877A
DEFINE OSC 4

' Define ADCIN parameters
Define ADC_BITS     8   ' Set number of bits in result
Define ADC_CLOCK    3   ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50  ' Set sampling time in uS

adval    Var Byte       ' ADC result variable
i        Var Byte       ' For-loop variable
position Var Byte       ' LED position variable
bright   Var Byte       ' Brightness variable

   ADCON1 = %00000010   ' Set PORTA analog

mainloop:
   ADCIN 0, adval             ' Store ADC value to adval
   position = adval / 31      ' Position of last lit LED
   bright = (adval // 31) * 8 ' Brightness of last lit LED

   For i = 0 To 7             ' Set each LED
     If i < position Then
        High i  ' Turn on if lower than last lit LED 
     Else
        Low i   ' Turn off if higher than last lit
     Endif
   Next i
   PWM position,bright,5      ' Dim the last LED
   Goto mainloop              ' Do it forever

   End

ete

#1
ADC yi 10 bit çalıştırmak için;
- ADCON1 registeri 7. nolu biti 1 olmalı (Sağa yaslanmış sonuç almak için)
- ADVAL değişkeni word tipinden seçilmeli
- Define ADC_BITS    10 şeklinde değiştirilmeli.

Kullandığın yöntem 8 bit çalışmaya uygun aslında. Çünki PWM komutundaki Duty değeri 0-255 arasında değişiyor.
Bu durumda senin Bright hesaplaman değişmeli bence parlaklık için. Zira maksimum ayarda (DC=255 olduğunda) hesapladığın parlaklık 56 oluyor halbuki son parlaklık ayarın 255.
Bana kalırsa Bright=(adval//31)*8 formülündeki 8 rakamını 30 ile bir değiştir bakalım sonuç ne olacak?


Ete

onurinci

#2
karışık yandı düzgün bir sırayı takip etmedi.
bende sizin dediğiniz gibi düşünmüştüm PWM 255 sınırı 10 Bit'i desteklemiyor.
aslında 8 Bit'te çok güzel çalışıyor.acaba 10 Bit muhteşem'mi olacak sorusuna yenik düştüm.

ADC'yi 10 bit
ADVAL'i Word
7 biti 01000010
yaptım karıştı, eski parametrelere dokunmadan bright = (adval // 31) * 30  yaptım sanki daha güzel çalıştı.
peki sebebi nedir.basitçe hesap örneği verirmisiniz ? ben 8 LED için 255'i 8'e bölmüştüm..

ete

#3
Led enteresan bir ışık kaynağıdır. PWM ile sürerken şunu görürsünüz. Sisteminizde parlaklık ayarınız 0-255 arası ise ve siz parlaklık olarak 5 verdiğinizdde led epeyce bir ışık verecektir.
Bu parlaklık (Yani Duty değerini) artırdıkça parlaklık da artacak ama belirli bir seviyeden sonra artışları belirgin olarak farkedemeyeceksiniz.
Şimdi önceki programınıza bakarsak ;
Parlaklık Bright (Adval\\31)*8 formülü ile veriliyor idi. Burada maksimum olası hesaplanacak değer 56 dan fazla olamıyor idi. Halbuki komut 0-255 arasını parlaklık olarak kabul ediyor ama siz 56 yı aşamıyorsunuz. Başka bir ifade ile 56/255=%21,9 ~ yaklaşık %22 lik bir parlaklık uyguluyorsunuz.
Bu nedenle orada 8 ile çarpmak yerine 30 ile çarpın demiştim. Çünki Adval 255 yani maksimum değerinde iken onu 31 e bölerseniz kalan 7 oluyor ve onunda 8 ile çarpımı size 56 değerini veriyor. 255/7 dersek 36,42 değerini veririki demekki orada 8 yerine en azından 30-36 arasında bir değer kullanmak daha akıllıca olacaktır. Böylece maksimumda maksimum parlaklık elde edilmiş olacaktır.

10 bit çalıştığınızda Pozisyon hesabı için  ;
maksimum ADC değeriniz 1023 olacaktır. pozisyon max değeri ise 8 dir. O halde 8/1023=0,007820 gibi bir rakam çıkar. Bunu 256 ile çarpın 2,001955 gibi bir rakam bulursunuz.Sabit çarpan olarak 2 yi kullanırısanız 7,99 gibi bir rakam hesaplarsınız. Ama size 8 gerekiyor. Bu nedenle küsüratı yuvarlayarak 2002 gibi bir rakam kullanmak daha doğru olacaktır. Çıkan rakamıda bu durumda 1000 e bölmek gerekecektir. O halde pozisyon formülünüzün son hali Pozisyon= (adval*/2002)/1000 olacaktır.

Gelelim parlaklık meselesine. Adval 1023 iken sizinde en azından 250-254 veya 255 gibi bir rakamı hesaplamanız gerekir. O halde(255/1023)*256 =63,8123 sabit çarpan değeriniz olacak. Bu rakamı 6381 olarak kullanarak sonucun 254 çıkmasını sağlayabilirsiniz. O halde parlaklık formülünüz;
Parlaklık=(adval*/6381)/100 şeklinde olacaktır
Bu değerleri kullanarak 10 bit üzerinden yeniden deneme yapın bakalım ne olacak.

Ete

onurinci

hocam çok ayrıntılı izah etmişsiniz.çok teşekkür ederim..

onurinci

hocam selam .eğer dediklerinizi anlayabildiysem.verdiğiniz değerleri yükledim,birden fırlıyor.ve garip atlamalı çalışıyor..
' Name        : VUX2.pbp
' Compiler    : PICBASIC PRO Compiler 2.6
' Assembler   : PM or MPASM
' Target PIC  : 28/40-pin PIC types compatible with LAB-X2 board
' Hardware    : LAB-X2 Experimenter Board
' Oscillator  : 4MHz external crystal
' Keywords    : ADCIN, PWM
' Description : PICBASIC PRO program to display result of ADC in 3
' segment bargraph. The last LED in the graph dims or brightens with
' changes in the analog input.
'
#CONFIG
 __CONFIG _XT_OSC & _WDT_OFF &_PWRTE_ON & _CP_OFF 
#ENDCONFIG

REM 16F877A
DEFINE OSC 4

' 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

adval    Var word       ' ADC result variable
i        Var Byte       ' For-loop variable
position Var byte      ' LED position variable
bright   Var Byte       ' Brightness variable

   ADCON1 = %01000010   ' Set PORTA analog

mainloop:
   ADCIN 0, adval                 ' Store ADC value to adval
   position = (adval*/2002)/1000  ' Position of last lit LED
   bright = (adval*/6381)/100     ' Brightness of last lit LED

   For i = 0 To 7             ' Set each LED
     If i < position Then
        High i  ' Turn on if lower than last lit LED 
     Else
        Low i   ' Turn off if higher than last lit
     Endif
   Next i
   PWM position,bright,5      ' Dim the last LED
   Goto mainloop              ' Do it forever

   End

ete

Muhtemelen duty değeri fazla geliyordur.
Deneyerek doğru değeri bulman gerekiyor.Çünki simulasyonda her şey güzel gözüküyor.
Aşağı yukarı verdiğimiiz duty değeri %99 gibi bir değer idi. %90 olmuyorsa %80 şeklinde gidip aşağı doğru %10 düşerek gitmek en uygun değerde durmak en güzeli.
%90 için hesabı vereyim sen diğerlerine uygularsın.
Max duty değerimiz 255 bunun %90'ı 229 olarak hesaplanıyor (255*90/100) . Bunu 230 alalım.
(230/1023)*256 bize sabit çarpan değerini verecektir. Sonuç 57,556 olup bunu 5756 olarak uygulayacağı. Bright=(Adval*/5756)/100=230 deneyip sonuca bakarsın olmuyorsa %80 hesaba geçersin.
Onuda vereyim ki hata olmasın. (255*80/100)=204 ,  (204/1023)*256=5105 ve
Bright=(adval*/5105)/100

Ete

onurinci

teşekkürler hocam,sağlıcakla kalınız..

onurinci

hocam mümkünse derleyip denediğiniz simule ettiğiniz programı verebilirmisiniz.neyi atlıyorum merak ediyorum..

ete

#9
Dosya ilişiktedir.
Ete

onurinci

Hocam çok teşekkür ederim ADCCON1'i yanlış set ediyormuşum.bu tür örneklekler benim için çok faydalı oluyor,gözden kaçırdıklarımı bulabiliyorum..

Powered by EzPortal