18f4550 ile usb ve ADC haberleşme

Başlatan ademgolcuk, 27 Aralık 2015, 00:22:59

ademgolcuk

merhaba. 18f4550 mikrodenetleyicisi kullanarak gömülü sistemle usb haberleşme yapıyorum, Dijital çıkışlı sensörlerden I2C protokolü ile veri okuyorum ve 4-20ma çıkışlı sensörlerden ADC ile veri okuyorum. pici programını Proton basic kullanarak yazıyorum. USB ve I2C iletişimim sorunsuz çalışıyor. aslında açı sensöründen okuduğum ADC'de çalışıyor ama okuduğum değerler sabit olmuyor. örneğin açı sensörü 90 derecedeyken okuduğum değer 88 ile 93 arasında sürekli değişiyor. beslemeyi LM-2576-05 ile yapıyorum. bu regülatörden önce ve sonra 1000uF, 470uF kondansatörlerim var. ayrıca picin ve INA122'nin besleme geriliminde de 100nF kondansatör kullandım.  ADC ile ilgili kodlarım aşağıdaki gibidir. 20MHz osilatör kullanıyorum ve xtall=48 olarak ayarladım(usb haberleşme için gerekli).

ADCON2.7 =1                   'adc 10bit sağa dayalı
Declare Adin_Res 10         'ADC ÇÖZÜNÜRLÜĞÜ 10 BİT 0...1023
Declare Adin_Tad 8_FOSC         'Clock  kaynağı
Declare Adin_Stime 50       'ÖRNEKLEME ZAMANI 50 US
TRISA = %00011111 


Sensor_Oku:
    HAM=ADIn 0                ' 0 nolu kanaldan  Analog değeri oku ve HAM değişkenine aktar.
    DelayMS 10
    ACI1=(HAM - 204)*0.44
Return

okuduğum değerler daha sabit hale getirilebilir mi, yoksa normal mi?

Hattuşa

usta neden okuduğun adc değerini (HAM degeri) filtreden geçirmiyorsun? 3-5 çeşit filtre var onlardan birisini deneyebilirsin.

ademgolcuk

#2
Moving Averager filtresini uyguladım. dalgalanma biraz yavaşladı ama yine değer sabit değil. normal derecenin 3 derece altını ve üstünü görebiliyorum. aşağıda uyguladığım filtre komutları var. gerçi siz HAM değişkeni demişsiniz ben ACI1 için uyguladım ama farkeden birşey olmaz diye düşünüyorum. bu arada cevabınız için teşekkür ederim.

'///////// SENSÖR OKUMA ALT PROGRAMI
Sensor_Oku:
    HAM=ADIn 0                ' 0 nolu kanaldan  Analog değeri oku ve RAW değişkenine aktar.
    DelayMS 10
    VOLT=(HAM*5)/1024
    ACI1=(HAM - 204)*0.44
Return


'///////// FİLTRE ALT PROGRAMI
Filtre:
      For i=9 To 1 Step -1
          ACI1_F [ i ] = ACI1_F[i-1]
      Next i     
      ACI1_F[0]=ACI1
     
      If ACI_SAYAC<10 Then
        ACI_SAYAC=ACI_SAYAC+1
      Else
        ACI1=ACI1_F[0]
        For i=1 To 9
            ACI1=ACI1 + ACI1_F[ i ]
        Next i
        ACI1=ACI1/10
      EndIf
Return

Hattuşa

#3
usta yerinizde olsam ham değerini boble short ile denerdim.

Alıntı YapSensor_Oku:
    HAM=ADIn 0                ' 0 nolu kanaldan  Analog değeri oku ve RAW değişkenine aktar.
    DelayMS 10
    VOLT=(HAM*5)/1024
    ACI1=(HAM - 204)*0.44
Return

yerine


for x =0 to 30
ham[x] =adin 0
delayms 1
next

for x =0 to 29
for y =(x +1) to 30
  if ham[x] >ham[y] then
  temp =ham[x]
ham[x] =ham[y]
ham[y] =temp
next
next

hamsonuc =(ham[10] +ham[11] +ham[12] +ham[13]) /4



şimdi bu hamsonuc değeriniz ile işlemlerinizi deneyin.hatta süre ile ilgili sorununuz yoksa işlemlerden sonra kendi filtrenizide peşine takın. okuma işiniz yavaşlayacak ama biraz daha stabilleşecektir diye umuyorum

F®T

Selami hocam bunu denedinizmi.Sonuç nasıl.
"Hakk" şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

Hattuşa

Alıntı yapılan: F.T - 28 Aralık 2015, 18:24:03
Selami hocam bunu denedinizmi.Sonuç nasıl.

usta bu buble short filtresi, bir çok kez denedim.

ademgolcuk

pro-TR verdiğiniz çözüm çok mantıklı. test ettim ve değeri sabitleyebildim. Ama bu yöntem 3-5 sn işlemi yavaşlatıyor. tam sonucu görene kadar biraz beklemek gerekiyor. sizin verdiğiniz algoritmada 30 yerine 10 yazarak kullandım ve sabit sonuçlar okuyabildim. ama yine de bir gecikme var. ben bu şekilde projemde 5 tane sensör kullanacağım. ayrıca projemde USB haberleşme var ve 16 girişi kontrol etmem lazım. Bu yüzden bu işlemi biraz daha hızlandıracak algoritmalar geliştirmem lazım. sizin yazdığınız algoritmanın isminin Selection Sort algoritması diye biliyorum. Yardımlarınız için teşekkür ederim.

ademgolcuk

ben iki filtreyi de birden uyguladığım için çok gecikme oluyormuş. kendi filtremi devre dışı bırakınca süre kaybı da anlaşılabilir seviyeye geldi. tabi 2 fitreyi birden uygulayınca sonuç mükemmel ama zaman kaybı fazla oluyor.

Hattuşa

usta;gecikmeler aşılabilir. bunu aşmanın 1. yolu kristal seçimidir. kaç MHZ de çalışıyorsunuz? birde delay ları tam hesaplayıp gereğinden fazla gecikme vermemektir. örnek verecek olursak, sizin adc okuma rutininde 10mS vermişsiniz bu çok uzun bir bekleme süresidir. ben o süreyi 1mS olarak verdim benim verdiğim gecikmede çok uzun zira 30 adetlik bir döngü var ve bu 30mS demektir. oysa bir adc okumasında yüksek frekanslarda 5-10uS anca tutar. tabi programınızın başka yerlerinde de bu şekilde mS bazında gecikmeleriniz varsa onlarıda gözden geçirmeniz gerekmektedir. 

ademgolcuk

teşekkür ederim arkadaşım. ben sizin gönderdiğiniz algoritmadan sonra problemi çözdüm. 20MHz osilatör kullanıyorum. XTAL=48. 5 sensörü aşağıdaki gibi okuyorum ve sonuçlardan gayet menunum.

Sensor_Oku:
    For i =0 To 10
        HAM[i] =ADIn 0
        DelayMS 1
       
        HAM2[i] =ADIn 1
        DelayMS 1
       
        HAM3[i] =ADIn 2
        DelayMS 1
       
        HAM4[i] =ADIn 3
        DelayMS 1
       
        HAM5[i] =ADIn 4
        DelayMS 1
    Next

    For i =0 To 9
        For j =(i +1) To 10
            If HAM[i] >HAM[j] Then
                temp =HAM[i]
                HAM[i] =HAM[j]
                HAM[j] =temp
            EndIf
           
            If HAM2[i] >HAM2[j] Then
                temp =HAM2[i]
                HAM2[i] =HAM2[j]
                HAM2[j] =temp
            EndIf
           
            If HAM3[i] >HAM3[j] Then
                temp =HAM3[i]
                HAM3[i] =HAM3[j]
                HAM3[j] =temp
            EndIf
           
            If HAM4[i] >HAM4[j] Then
                temp =HAM4[i]
                HAM4[i] =HAM4[j]
                HAM4[j] =temp
            EndIf
           
            If HAM5[i] >HAM5[j] Then
                temp =HAM5[i]
                HAM5[i] =HAM5[j]
                HAM5[j] =temp
            EndIf
        Next
    Next

    Ham_Top  = HAM[3]  +HAM[4]  +HAM[5] +HAM[6]
    Ham_Top2 = HAM2[3] +HAM2[4] +HAM2[5]+HAM2[6]
    Ham_Top3 = HAM3[3] +HAM3[4] +HAM3[5]+HAM3[6]
    Ham_Top4 = HAM4[3] +HAM4[4] +HAM4[5]+HAM4[6]
    Ham_Top5 = HAM5[3] +HAM5[4] +HAM5[5]+HAM5[6]
   
    HamSonuc  =Ham_Top/4
    HamSonuc2 =Ham_Top2/4
    HamSonuc3 =Ham_Top3/4
    HamSonuc4 =Ham_Top4/4
    HamSonuc5 =Ham_Top5/4
   
    ACI1=(HamSonuc - 204) * 0.44
    ACI2=(HamSonuc2 - 204) * 0.44
    ACI3=(HamSonuc3 - 204) * 0.44
    ACI4=(HamSonuc4 - 204) * 0.44
    ACI5=(HamSonuc5 - 204) * 0.44
Return

Burak

#10
delayms 1


Komutlarını iptal ederek deneme şansınız var mı ? Ben bu beklemeler için bir gereklilik göremiyorum ...
Nihayetinde derleyici bir satırı opere etmeden diğer satırda bir işleme başlamayacaktır .. Keza aynı şekide şarj deşarj kondansatörünü devreye alma veya çıkarma adımlarını komut sırası ile yapacaktır diye düşünüyorum,

Burak
Ω Gens Una Sumus Ω

Hattuşa

adem usta;
ya beni yanlış anlamayın ve hatam varsa lütfen düzeltin.
şimdi sanırım siz PLL yi aktif ederek 48MHZ de çalışıyorsunuz, ki başka türlüsü imkansız. 20 mhz kristal 48mhz hıza ulaşılamaz diye düşünüyorum.
20mhz xPLL1 =20
20mhz xPLL2 =40
20mhz xPLL3 =60
20mhz xPLL4 =80
yapar. oysa sizin devreye 12MHZ kristal bağlamanız ve PLL yi max. aldığınızda 12x4 =48MHZ yapar diye biliyorum. bu konuda yanlışmı düşünüyorum. Ete hocam biraz bizi aydınlatabilirmisiniz?

ete

PLL si olan pek çok 18F serisi işlemci maalesef maksimum 40 (yada 48)Mhz de çalışabiliyor. Her ne kadar ona bağlanan kristal x 4 gibi bir fikir uyandırsa da data sheetlerde buna ait ibareler mevcut. 40 Mhzden öte gidemezsin diyor. Peki derleyici ile derledikten sonra itiraz eden çıkıyormu hayır?. O halde ne olup bittiğini anlamanın tek yolu programdan çıktı alıp onu kontrol etmek başka çaresi yok gözüküyor.
Yeni nesil bazı işlemcilerde bu sınırda kaldırılmış 96 Mhz'e kadar yolu var deniliyor. Bu durumda yapılması gereken data sheetleri iyice inceleyip hız sınırı varmı kontrol etmek gerekiyor.

Eski dönemde /04P şeklinde kodlaması olan işlemcileri 20Mhz de çalıştırıyordum. Data sheete bakarsanız 04 olan en fazla 4Mhzde çalışabilir deniliyor idi. Aslında denilende yanlış değil. O entegre her ne kadar 20 Mhzde çalışsada sonrasında br yerinden falso veriyordu illaki. Hala buşekilde çalışan pic'lerim mevcut. Ama demekki henüz daha damarlarına basmamışım diyorum kendi kendime. Sonuç olarak bir işlemci için limit verilmiş ise o doğrudur Limit dışında çalışması sizi yanıltmasın bir yerlerden sıkıntı çıkartacak demektir mutlaka.

Ete

ademgolcuk

#13
Burak bey test ettikten sonra sizin sorunuza da tekrar cevap yazayım ama yanlış hatırlamıyorsam daha önce denemiştim ve verileri düzgün okuyamamıştım diye hatırlıyorum.

pro-TR arkadaşımızın sorusu için ise;
18f4550 mikrodenetleyicisinin datasheet'ini incelediğimizde bu mikrodenetleyicinin 48MHz'de çakışabildiğini görebilmekteyiz. özellikle eke eklediğim resimdeki Tablo-2.3 incelendiğinde 20MHz'lik osilatör bağlantısıyla mikrodenetleyicinin nasıl 48MHz'de çalışabileceği anlatılmaktadır.

Datasheet'en konuyla ilgili yerleri aşağıda paylaştım. Ben de PC ile USB haberleşme yapabilmek için 48MHz'lik hıza ihtiyaç duyuyorum.

Flexible Oscillator Structure:
• Four Crystal modes, including High Precision PLL for USB
• Two External Clock modes, up to 48 MHz

A Phase Lock Loop (PLL) frequency multiplier, available to both the High-Speed Crystal and External Oscillator modes, which allows a wide range of clock speeds from 4 MHz to 48 MHz.


yaptığım configürasyon ayarları aşağıdaki gibidir.




Device = 18F4550
Xtal = 48
'All_Digital=true

Config_Start
        PLLDIV = 5 ' Divide by 5 (20 MHz oscillator input)
        CPUDIV = OSC1_PLL2 ' [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
        USBDIV = 2 ' USB clock source comes from the 96 MHz PLL divided by 2
        FOSC = HSPLL_HS ' HS oscillator, PLL enabled, HS used by USB

Hattuşa

adem usta vermiş olduğunuz bilgiler için tşk ederim. ben yanılmışım. sizin söyledikleriniz doğru, benim hatamsa ezberden gidip datasheetine bakmamak oldu.

Powered by EzPortal