12f675 akım sensörü

Başlatan oguztkn, 25 Ağustos 2014, 03:46:45

oguztkn

Öncelikle herkese iyi günler
Acs714 +- 5 amper sensör kullanmak istiyorum.Sensör 2.5 volt referans üzerine +- 185mv/A çıkış veriyor.Ben bunu 12f675 in An0 ucuna girdim.Çıkış olarak da 1 led ve 1 röle koydum. +- 3 amperi geçince röle çekecek ve başka bir devreyi koruyacak.Bunun mantığını nasıl yapabilirim.Adc den okuduğum değeri nasıl işlemeyilim fikir danışmak istedim.Sensörün datasheeti ve devrenin şemasını ekliyorum.
Şimdiden Teşekkürler,İyi Çalışmalar....


Sensör linki : http://www.robotistan.com/ACS714-Akim-Sensoru-ACS714-Current-Sensor-Carrier-5-to-5A-PL-1185,PR-1110.htm

ete

Bu sensör akımın aktığı yöne göre çıkış verdiği için bir tarafa doğru 0-5 A için 0-2,5V diğer tarafa doğru da 0-5A için 2,5-5V arası çıkış vermektedir.
Bu durumda devre şemanı nasıl düzenleyeceğin önem kazanmaktadır.
Diyelimki bir motoru sürüyorsun ve onun çektiği akımı izleyeceksin. Sensörü , motorun + besleme hattına koydun ve motor hep aynı yöne dönüyor ise diyelimki 0-2,5V arasında çıkış alırsın. Ama motoru ters yönde çevirmeye kalkarsan bu seferde akımın yönü değişecek ve sensörü bu sefer 2,5V ile 5V arasında bir çıkış verecektir sana.
Akıllılık edip sensörü besleme hattına koyarsan motor ters de dönse sensör hep bir yönde çıkış verir. Bunu şöyle açıklayabiliriz. Bir H köprü devren var. Sensör motor uçlarından birine seri bağlanırsa motor yönü değişince akım yönüde değişir. Ama sensörü H köprü devresinin besleme hattına yerleştirirsen sensör hep bir yönde çıkış verecektir.

Sensörü yerleştirme şekline göre hesap mantığıda değişecektir. İkisinide örnekle açıklayayım.
Diyelimki tek yönlü çalışıyorsun sensör 0-2,5V arası çıkış veriyor yalnızca. Bu durumda ADC hattından 0-511 arası bir değer okuyacaksın demektir. Bu durumda kullanacağın akım formülü;
AKIM=(ADC_Değer+1)*/25)
Bu formül ile elde ettiğin akım değeri sana gerçek akımın 10 ile çarpılmış halini verir. Böyece ondalık değerde kullanabilirsin. Örnek yapalım diyelimki okunan ADC değerimiz 379 hemen akım değerini hesaplayalım. AKIM=(379+1)*/25=380*25/256=37. O halde çekilen akım 3,7 A imiş diyebilirsin.
(Akım=37/10 , Ondalık=37//10 şeklinde hesaplanır.)
Şayet yine tek yönlü çalışıyorsun ama okunan değer 2,5V-5V aralığında oluyor ise okuduğun ADC değerleri 511-1023 arasında değişecektir. Bu durumda yukarıdaki hesabı ADC=ADC_Değer-511 formülünden sonra yaparsın sonuç değişmez.

Gelelim çift yönlü çalışmaya, Akım bir yönde çekilince ADC değerin 0-511 arasında değişecek, diğer yönde çekilince adc değerin 512-1023 arasında değişecektir. O halde öncelikle ADC değerinin hangi aralıkta olduğunu tespit etmek ve şayet 512-1023 aralığında ise onu 0-511 aralığına indirgemek gerekir
IF ADC_Değer>511 then ADC_Deger=(ADC_Deger-511)
sonrada formülümüzü uygulamak akımı bulmak için yeterli olacaktır.

AKIM=(ADC_Deger+1)*/25

Bir örnek daha yapalım. Şayet bir yönde çekilen akım 3,7A ise ADC den okunacak değer 380 olacaktır.
Motor yönü değiştiğinde aynı akım çekilecek ama bu sefer ADC den okunan değer 891 olacaktır.
Şimdi diyelimki ADC den 891 okuduk buna göre hesap yapalım,
ADC_Deger=891-511=380
AKIM=(380+1)*/25=37 olarak bulunur.
Aynı hesabı 380 ile de yaparsak sonuç değişmeyecek ve 37 olarak hesaplanacaktır.

Hepsi Bu kadar
Ete

oguztkn

Hocam cevabınız için teşekkür ederim. Yazdıklarınızı okudum motor devreden ayrı beslemeside ayrı bu devrede rölenin kapalı kontakları üzerinden motor çalışıyor.Sensör 3 amperi görünce röleyi çekip motoru durdurmuş olacak sistemi böyle düşündüm.Bir de deneme yaptım sensör 2.49 volt referans çıkartıyor.Ucuna bir yük bağladım 3.5 amperi çektirdim 2.49 volt 3.05'e çıktı buu pozitif yöndeki değer.
Burdan artışı yaklaşık 0.56 volt olarak buldum.Eksi yöndede aynı miktarda oluyor.Şimdi programda sadece basla etiketine kadar geldim.Sadece 0.56 volta karşılık gelen değeri bulup programda if ile sorgulamayı düşündüm ama ne kadar doğru bir yöntem olur ?

Programda da ayarlarım düzgün mü acaba bir kontrol edebilirmisiniz

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF
;*****************************************************************
ADCON0=%10000001 '7. bit 1 yapıldı 10 bit sonuç almak için.
ANSEL=%00110001 'AN0 PİNİ ANALOG GİRİŞ
CMCON=%00000111
INTCON=0
OPTION_REG=0
;*****************************************************************
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 100
DEFINE OSCCAL_1K 1
;*****************************************************************
TRISIO=%00000001
HAM    var word
AKIM   var word
x      var word
;*****************************************************************
low GPIO.2
low GPIO.4
x=0
clear
pause 300
;*****************************************************************
for x=0 to 5
high GPIO.4
high GPIO.2
pause 100
low GPIO.4
low GPIO.2
pause 100
next
Basla:
   Adcin 0,Ham
   if ADCON0.1=1 then goto basla



goto basla
end

ete

Programın bu kısmında hata yok. Ben olsam adc_sampleus değerini 100 us yazmazdım. Yanlış değil ama çok faxla. Pek çok işlemcide bu değer 20us yi aşmaz.

Ayrıca adc okuma işlemini adcin otomatik yapar senin ayrıca adcon0.1 biti ile bunu kontrol etmen gerekmez.

Ete

oguztkn

#4
Hocam programı istediğim çalıştırmayı becerdim gibi çalışıyor ama tam değil. şöyle bir sorun var 3 amperi görünce röle sürekli aç kapa yapıyor bunu nasıl engelleyebilirim.Yani gördüğü süre çekili kalsın görmediği zaman bıraksın şeklinde....(Adc değerlerini de kendim deneyerek buldum isiste)
Basla:
  adcin 0,ham
  if ham=<400 or HAM=>610 then  ;400 ile 610 arası +- 3 amper için yetiyor
  x=1
  else
  x=0
  endif
  if X=1 then 
  high GPIO.4
  high GPIO.2
  else
  low GPIO.4
  low GPIO.2
  endif
  goto basla

Burak

Hocam bu sensör ile ac akım ölçtüğümüzde nasıl bir çıkış verir ? hangi skala'da ilerler çıkış voltajı ? 0-2.5 mu yoksa 2.5 - 5 ' mi acaba ?
Ω Gens Una Sumus Ω

ete

AC voltaj altında sensörün tek yönde çıkış vermesi gerekir ama bu çıkışda AC nin Faz-Nötr bağlantısına bağlı olarak değişir. Bu benim düşüncem. Deneyip sonucu bildiren olursa sevinirim.
Ete

oguztkn

Rolenin surekli tetiklenip durmasini nasil onleyebilirim yukaridaki programda ? Soru programdami roledemi ?

Burak

sorun programda ..

Birincisi ; tek bir analog olcum alarak bu sensorden verim alamazsin .. Yani 20 adet olcum alip o olcumun ortalamasini alicaksin ki bu sekilde daha stabil bir sonuca ulasirsin.

İkinciside diyelimki rolen 30 ham adc olcum degeri ve ustunde tetikleniyor . Bu durumda adc olcumleri
28 , 32 degerleri arasinda adc cevrim sonuclari verdginde role cilginlar gibi acilip kapanacak

Bunu onlemek icin
if ham>30 then
While ham>28
high role
Wend
Endif
Seklinde bir alt esik seviyesi  ile kontrol altina alinmis olur

Burak.
Ω Gens Una Sumus Ω

oguztkn

Alıntı yapılan: Burak GÜNAY - 26 Ağustos 2014, 14:40:39
sorun programda ..

Birincisi ; tek bir analog olcum alarak bu sensorden verim alamazsin .. Yani 20 adet olcum alip o olcumun ortalamasini alicaksin ki bu sekilde daha stabil bir sonuca ulasirsin.

İkinciside diyelimki rolen 30 ham adc olcum degeri ve ustunde tetikleniyor . Bu durumda adc olcumleri
28 , 32 degerleri arasinda adc cevrim sonuclari verdginde role cilginlar gibi acilip kapanacak

Bunu onlemek icin
if ham>30 then
While ham>28
high role
Wend
Endif
Seklinde bir alt esik seviyesi  ile kontrol altina alinmis olur

Burak.



Arkadaşım bu dediğini yaptım iyice sapıttı devre son hali bu


Basla:
  gosub oku
  if Akim>=610 then
  while akim=>600
  high GPIO.4
  high GPIO.2
  wend
  endif
  if akim<=590 then
  while akim=<600 
  low GPIO.4
  low GPIO.2
  wend
  endif
  goto basla
oku:
    for z=0 to 20
    Adcin 0,Ham
    Toplam=toplam+ham
    next z
    AKIM=toplam/20
    z=0
    return
end 

Burak

Alıntı yapılan: OgUz - 26 Ağustos 2014, 22:24:38


Arkadaşım bu dediğini yaptım iyice sapıttı devre son hali bu


Basla:
  gosub oku
  if Akim>=610 then
  while akim=>600
  high GPIO.4
  high GPIO.2
  wend
  endif
  if akim<=590 then
  while akim=<600 
  low GPIO.4
  low GPIO.2
  wend
  endif
  goto basla
oku:
    for z=0 to 20
    Adcin 0,Ham
    Toplam=toplam+ham
    next z
    AKIM=toplam/20
    z=0
    return
end

Birader birincisi 590 ile 610 arasında napıyo devren programı ezbere yazmışsın gibi geldi bana birazcık .. Ben yol gösterir diye sana bir kontrol bloğu oluşturdum . while wend öbeği içinde elbette bir gosub oku ifadesi olması gerekiyor bunu kendin düşünürsün sandım bu yüzden sapıtması gayet tabii ...

bir ikinciside for döngüsüne iyi bakarsan orada 20 adet ölçüm değil 21 adet ölçüm yapıldığını göreceksin  .. (0 dahil)
Ω Gens Una Sumus Ω

ete

Programda bir kaç hata var.
Birincisi ,
FOR Z=0 to 20
şeklinde döngüye başlamadan önce TOPLAM=0 şeklinde toplam değişkenini sıfırlaman gerekir.
Sıfırlamaz isen bir önceki toplam değeri yenisine eklenir ve sürekli yanlış değer hesaplarsın.

İkinci yanlış, 0 to 20 şeklinde kurulan döngü toplamda 21 adet döngü yaratır. Bu durumda , AKIM=TOPLAM/20 şeklinde hesap yanlış olur. Ya döngüyü 0 to 19 şeklinde kuracaksın yada hesabı AKIM=TOPLAM/21 şeklinde yapacaksın.

Burak da belirtmiş ben bir kez daha açıklayayım;
  if Akim>=610 then
  while akim=>600
  high GPIO.4
  high GPIO.2
  wend
  endif
şeklinde kurulmuş bir program parçası içinde yer alan;
While akim=>600
..
..
Wend  döngsü programın orada takılıp kalmasına sebep olur. Türkçe açıklaması şöyle bu parçanın.
Diyelimki AKIM=620 okundu ve program bu satırlara geldi,
Akım 600e eşit yada 600 den büyük ise
  high GPIO.4
  high GPIO.2
komutlarını yerine getirdi ve akım bu döngü içinde okunmadığı için hiç bir şekilde değişmeyecek ve hep 620 olarak kalacağı için programda bu döngüden çıkmayacaktır. Buradan kurtulmanın tek yolu
wend komutundan önce GOSUB OKU şeklinde bir komut yerleştirmektir. Böyece arada akım değeri yeniden okunacağı için akım değeri 600 den küçük olunca otomatik olarak program döngüden çıkacaktır.
Tabiiki aynı hata bir sonraki if-while-wend-else döngüsünde de yapılmış durumda. Bu hali ile programın çalışması mucize.
İşlemci programları tamamen mantık muhakemesine dayanır. Mantığınızı çalıştırıp her konumu (alternatifi) düşünmek zorundasınız. Bunları düşünmez ve ezberden program yazarsanız sonuç böyle oluyor genellikle. Düşünerek yazın lütfen.

Ete

oguztkn

#12
Hocam hatalarımdan dolayı özür dilerim belki kızıyorsunuz ama ben bir şeyi öğrenirken hata yaparak öğrenmeyi daha faydalı buluyorum bu bazen saçma sapan bazende yerinde bir hata oluyor.Çünkü doğru tek olmadığı gibi hata da tek değildir.Farklı hataları şimdiden görmek ileride daha iyi tecrübe sağlıyor.Şimdi sizin ve diğer arkadaşın dediklerini uyguladım.Program şuan yükü takınca hem -3 te hemde +3 te çıkış veriyor ama deliler gibi aç kapa yapıyor.Arkadaş adc değerlerini ezbere yazmış demiş o değerleri ben 3 amper yük altında yakaladım isis yardımıyla.Programın son hali ve denediğim isis şeması ekte hala nerde hata yapıyorum ? İsis te normal gözüküyor ama gerçek devrede aç-kapa yapıyor

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF
;*****************************************************************
ADCON0=%10000001 '7. bit 1 yapıldı 10 bit sonuç almak için.
ANSEL=%00110001 'AN0 PİNİ ANALOG GİRİŞ
CMCON=%00000111
INTCON=0
OPTION_REG=0
;*****************************************************************
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 20
DEFINE OSCCAL_1K 1
;*****************************************************************
TRISIO=%00000001
HAM    var word
AKIM   var word
TOPLAM var word
x      var byte
y      var byte
z      var byte
;*****************************************************************
low GPIO.2
low GPIO.4
x=0:y=0:z=0
clear
pause 300
;*****************************************************************
high GPIO.4:high GPIO.2
pause 100
low GPIO.4:low GPIO.2
pause 100
x=0:akim=0:toplam=0
Basla:
  gosub oku
  while akim>455 and akim<575
  low GPIO.4
  low GPIO.2
  gosub oku
  wend
  while akim=>580
  high GPIO.4
  high GPIO.2
  gosub oku
  wend
  while akim=<450
  high GPIO.4
  high GPIO.2
  gosub oku
  wend
  goto basla
oku:
    toplam=0
    for x=1 to 10
    adcin 0,ham
    toplam=toplam+ham
    next
    akim=toplam/10
    return 
end 

ete

  high GPIO.4
  high GPIO.2
komutları hem akım 580 den büyük olunca hemde akım 450 den küçük olunca çalışıyor.
Bu durumda buradan pek anlam çıkarmak mümkün değil bence.

ADC kanalından üst üste okunan bilgi hiç bir zaman bir birinin aynısı değildir.
Üstelik 10-20 tane okuma da bu işe çözüm getirmez. İyi bir adc okuması için farklı ve ayrı ref. voltajı kullanmak gerekir. Aksi halde devrende röle çekince besleme voltajın anlık olarak düşer o anda yapılan ADC okumasıda bir öncekinden epeyce farklı olur.
Bu nedenle bir birine yakın değerleri kullanaraka işlem yapmak yerine aralık vermek en güzelidir. Histerisiz denilen ve işin içine biraz tolerans katan bir sistemide kullanmak uygun olur.
Mesela senin kodlarında yer alan kodlara göre şöyle bir şey yapılsa belkide daha uygun olur.

-Akım 450 den küçük ise işlem yapmasın başa dönüp yeniden akım okusun.
-Akım 450 den büyük ve 550 den küçük ise çıkışlar LOW olsun
-Akım 550den büyük ve 580 den küçük ise hiç işlem yapmasın başa dönüp yeniden akım okusun
-Akım 580 den büyük ise çıkışlar LOW olsun
şeklinde olabilir.
Buda çözüm getirmiyor ise digital filtre uygulamak gerekebilir. Digital filtrede üst üste en az 20-30 adet okuma yapılır. Sonra bunları küçükten büyüğe doğru sıraya dizeriz. sonra ortadan 5 tanesini alırız toplarız ve ortalamasını alıp ADC okuması olarak kullanırız. Buna ait örneği sitede vermiştim. Digital filtre diye aratırsan bulursun.

Diğer bir çözüm de Darrel Taylor'un uyguladığı 10 bitlik okumayı 12 bite çıkartıp ilk başta yer alan 2 biti atarak kalan bilgiyi kullanmak olur. Buna ait örneğide geçtiğimiz hafta vermiştim.
Özellikle bu son alternatif epeyce kararlı ölçüm sonuçları vermektedir.

Ete

oguztkn

En son dijital filtre yazınızdaki kodları kullandım.Adc yi 8 bite çevirdim word değişkenlerinide byte çevirip programı derledim ve attım.Sonuç eskisi kadar hızlı değil ama hala açıp-kapanma var.Başka yapılabilecek birşey var mı yada opamp kullanmak aklıma geldi.Karşılaştırıcı olarak kullanıp referans voltajını gerilim bölücülerle ayarlayıp çıkışıda direk transistöre girmeyi düşündüm.Ne kadar doğru bir yöntem olur acaba birde sağlıklı çalışırmı ?

Powered by EzPortal