Pic girişine bağlı potansiyometre değerine göre çıkış süresini değiştirme

Başlatan blueboard, 26 Kasım 2015, 13:20:52

blueboard

Ete Hocam, yapmaya çalıştığım sistemi kısaca anlatmaya çalışayım. Pic girişinde 1 k civarı trimpot koyacağım ve ADC çevrimi yapacağım. ADC çevrim 10 bit olacak. Trimpotun en üst seviyesinde okuyacağım değer maksimum 1023 olacak. Ardından okuduğum değerlere göre pic çıkışını min 500 ms maksimum 3000 ms aralığında high'ta tutacağım.
ADC okuma kısmında sorun yok.Bu kısmı rahatlıkla yaparım. Sorun şurada ; picin çıkış süresini ayarlamada okunan her ADC değerine tek tek çıkış süresi yazmak istemiyorum. Yani                             "    if  HamA= 520 portc.1=1 : pause 600 : portc.1=0
      if  HamA= 550 portc.1=1 : pause 700 : portc.1=0
      if  HamA= 600 portc.1=1 : pause 800 : portc.1=0"
gibi bir sürü komut yazmak istemiyorum. Bunun yerine trimpot çevrildiğinde okunan yeni değere göre c.1 çıkışını otomatik olarak 500 ms ile 3000 ms arasında değiştirecek bir komut yazılabilir mi? Teşekkür ederim.


blueboard

Benim yapmak istediğim devrede kesme kullanılmayacak. Trimpot belli bir noktaya ayarlandığında çıkış süresi diyelim ki yeterli gelmedi . Sistemin enerjisi kesilip trimpotun değeri değiştirelecek ve bu yeni değere göre pic'in çıkış süresi artırılacak.

ete

Min. 500ms ve maksimum ise 3000ms olacak diyorsun. O halde değişken olan kısım 3000-500=2500ms dir.
Pot bu süreyi ayarlayacaktır. Yani pot sıfır noktasında iken 500ms , 5V noktasında iken ise 2500+500=3000ms süre ayarlanması gerekiyor.
Formül şöyle bulunuyor:
2500/1024=2,44140625
BU değeri 256 ile çarparak 625 değerini buluyoruz. Bu bizim */ operatöründe çarpan değerimiz olacaktır.
O halde formül,
SURE=(ADC+1)*/625+500  şeklinde uygulanır ise potun değişimine bağlı olarak bize 500-3000 aralığında bir değer verir.
Örnek yapalım. Pot tam orta doktada ikne bize 511 ADC değerini verir. Bunu formüle koyalım;
SURE=((511+1)*625)/256+500=1750 ms
Potun tamamı 2500 ms olunca ortası 1250ms vermesi gerekecek ve sondaki eklenen 500ms ile birlikte sonucun 1750 çıkması gerekirdiki öyle çıkıyor.
Evet böylece tek bir formül ile bütün işin hallolmuş olacak.

Ete

blueboard

Ete Hocam, kızmazsanız anlamadığım son bir yeri sormak istiyorum.
Tanımlama kısmında ;
SURE var byte  şeklinde tanımlama yapacağım.
Ardından komut satırında ADC çevriminden sonra sizin belirttiğiniz formülü kullanarak
SURE=(ADC+1)*/625+500     SURE değişkenini hesaplatacağım.
Peki Sure değişkenini bulduktan sonra bu değişkene göre pic çıkışını Sure değişkenini kullanarak nasıl high konumuna alacağım? Örnek olarak sanırım portc.1=sure şeklinde olmayacak.Anlatmak istediğim portc.1 pinini sure değişkenine göre nasıl high konumunda tutacağım?  Teşekkür ederim.

muyat

portc.1=1
pause sure



komutu olması gerekiyor istediginiz.


muyat

Tabi komutun sonuna da portc.1=0 eklemeniz gerekiyor.Süre dolduktan sonra çıkış 0 olcak

blueboard

Ete Hocam, bir süre önce potansiyometre değerine göre çıkış süresini 0,5 ms- 3000 ms arasında ayarlama konusunda yardım etmiştiniz.Şimdi çıkış süresini min 500 ms (0.5 sn ) ile 180000 ms( 3 dakika) için düzenlemeye çalışıyorum.Ancak programı derleyip simulasyonda çalıştırdığımda isteğim süre aralıklarında çıkış alamıyorum. Led tahmini 1 'er saniye aralıklarla yanıp sönüyor.Hatam nerede? Hama ve Sure değişkenini word olarak belirledim. Kodlar şunlar:

HAMA  VAR WORD
SURE VAR WORD
PAUSE 100                     
         

BASLA:   
' 180000-500=179500     179500/1024=175,29       175.29*256=44875
ADCIN 0, hamA 
Sure=(((hamA+1)*44875)/256)+500    ' SUREYI HESAPLA   0,5-3 DK   
portc.1=1
PAUSE SURE
portc.1=0
PAUSE 1000         
     Goto basla
end

blueboard

Ete Hocam, forumdaki açıklamalarınız doğrultusunda son olarak kodları şu şekilde yazdım. Sanırım sorun yok.
BASLA:   

adcin 0, ham              'ADC KANALINI OKU
     sure=((ham+1)*/4375+500)   'SÜREYİ HESAPLA 0,5-3 dk
portc.1=1    'ledi yak
Gosub zaman
portc.1=0
gosub zaman
goto BASLA

ZAMAN:
For I=0 to sure      ' "0" DAN SUREYE KADAR SAY
     Pause 8              ' 8 ms bekle
Next
Return
END

ete

Son formülün doğru gibi ancak unuttuğun bir şey var. 3 dakika ms ye çevrilince 180.000 ms eder.
Bundan 500 ms çıkartırsan 179.500 ms kalır ve bunuda formule edersen sabit çarpanın 44.875 gibi büyük bir rakam çıkar. Zaten 3 dakika için hesaplayacağın 180000 değeri hiç bir değişkene yerleştiremeyeceğin kadar büyük bir değer. Bu nedenle tavsiyem bu sistemi 1-3 sn aralığında çalıştırman yönünde.
Yada daha akıllıca bir yol söyleyeyim. Zaman tutmak için TMR1 sayacını kullan. Sayacı her 500 ms de bir kesme yapavak şekilde ayarla. Böylece elinde 0,5 sn lik dilimler olmuş olur.
Bu durumda pot dan hesaplayacağın sayı dilim adedi olmalıdır. 3 dakika içinde 6 dilim vardır.
6/1024=1,5 çıkar. Bunu 10 ile çarpıp 15 olarak kullanmak gerekecek. Sonucuda tekrar 10 a bölersek eşitlik bozulmamış olacaktır.
Zaman=((adc */15)/10)-1 şeklinde uygulanabilir.
Bir alt program ayarla zamantut diye isim ver.
Zamantut:
Tmr1L=$DC:Tmr1H=$0B:PIR1.0=0:T1CON=%00110001
Şeklinde timer kurulsun.
Sonra while PIR1.0=0: wend şeklinde 500 ms lik dilimleri çalıştır.
Altında kes=kes+1 yap ve kes sayısı zaman sayısına eşit olmuşmu bak eşit değil ise yeniden timer kurmaya yolla aynı dilim yeniden çalışsın. Sonuçta kes=zaman olunca pot ile ayarladığın zaman geçmiş olacaktır. Return ile geri dön.

Aynı işi 500 ms lik dilim adedini hesaplayarak alt programda 0 to zaman şeklinde döngü kurup içine pause 500 yazarakta yapabilirsin. Şöyle;
ZamanTut:
For X=0 to ZAMAN
PAUSE 500
NEXT
RETURN


Daha kolay olur senin için.
Ete


blueboard

Ete Hocam, açıklamalarınız doğrultusunda bir şeyler yapmaya çalıştım ama her şey karıştı. Dosyaları ekliyorum.Bakabilir misiniz.

ete

Bazı hatalarımız var seninde benimde. Seninkilerden başlayalım. Bu hesaplanan timer1 gecikme sistemi 4 Mhz lik kristal frekansına göre hesaplanmış idi. Sen programı 8 Mhz de çalıştırınca işler değişiyor. Zira 8Mhz de TMR1 sayacından 500 ms lik gecikme almak mümkün değil. Onun yerine 250 ms lik gecikme alınabilir. Bu durumda ;
3 /0,25 sn=12 adet 250 ms lik dilim üzerinden çalışmamız gerekir. Bunun 500 ms lik kısmı (2 dilim) default değerimiz olacağı için 12-2=10 dilim üzerinden hesap yapacağız. (10/1024)*256=2,5 çıkacaktır. Bunu 10 ile çarparak formülümüzü şöyle düzenleyeceğiz.
ZAMAN=((HAM+1)*/25)/10+2   (benim hatamda önceki formülde +1 yerine -1 yazmış olmam.)
Diğer tanımlamalar değişmiyor. Ancak değişken değerlerinin alacağı değerleri dikkate alarak bazılarını Byte olarak tanımlamamız daha uygun olacağı için değiştirdim onlarıda.
Bu durumda program şöyle olmalı;
DEFINE OSC 8
OSCCON=%01111100 'dahili osc 8Mhz e ayarlandı  %0 XXX 11 00 8MHZ=111, 4mHZ=110,

DEFINE ADC_BITS 10     ' ADCIN resolution  (Bits)
DEFINE ADC_CLOCK 2     ' ADC clock source  (Fosc/32)
DEFINE ADC_SAMPLEUS 20 ' ADC sampling time (uSec)

PortA=0:TrisA=%00000011 'portA yı sıfırladık ve analog pinleri pinleri giriş olarak ayarladık
PortB=0:TrisB=0 'portB yi sıfırladık ve pinleri çıkış olarak ayarladık
PortC=0:TrisC=0 'portC yi sıfırladık ve pinleri çıkış olarak ayarladık
ADCON1.7=1  '%10000100 'AN0 , AN1 ve AN3 analog diğerleri digital oldu.
ANSEL= 3 'A portu analog pinler iptal
ANSELH=0  'B portu Analog pinler iptal
CM1CON0=0 'C1 Komparatör iptal
CM2CON0=0 'C2 Komparatör iptal
WPUB=0  'PORTB pullup lar kapalı d   
     
ZAMAN VAR BYTE
KES VAR BYTE
HAM VAR WORD

PAUSE 200                       
         

BASLA:   

adcin 0, ham              'ADC KANALINI OKU
     Zaman=(((HAM+1) */25)/10)+2  'SÜREYİ HESAPLA 0,5-3 dk
portc.1=1    'ledi yak
Gosub say
portc.1=0
gosub SAY

goto BASLA

SAY:
    T1CON=%00110001:KES=0
SAYBIR:   
       Tmr1L=$DC:Tmr1H=$0B:PIR1.0=0
       WHILE PIR1.0=0:WEND
       KES=KES+1
       IF KES=ZAMAN THEN
         T1CON=0
         RETURN
       ENDIF 
       GOTO SAYBIR

END

blueboard

Ete Hocam, akşam eve geldiğimde ilk işim yazdığınız dosyayı denemek oldu. Denedim ancak gerek isis'te olsun gerekse gerçek devrede olsun ledin yanık kalma süresi potansiyometrenin orta konumunda(2.5 volt) 3 sn civarı, potansiyometrenin %100 konumunda( gerçek devrede 4.84 v)  4 saniyeye yakın oluyor.
u süre sonunda led sönüyor. Ete Hocam sizce led neden 3 dakika yanık kalma süresine ulaşamıyor?Sizin de belirttiğiniz gibi algoritmada gerçekleşiyor. Benim çalışma frekansının 8 Mhz olmasından kaynaklanabilir mi? Çalışma frekansının 8 Mhz veya 4 Mhz olmasının benim için bir önemi yok.Önemli olan 0.5-3 dk aralığında çalışması. Bir de gerçek devrede şu dikkatimi çekti; ADC gerilimi 2 voltun altına düştüğünde led yanmıyor. Teşekkürler.

ete

Hata-1: Programa ADCON0=%10000001 komutunu ilave etmemişsin. Bu nedenle ADC ölçümünün Sağa yaslı (0-1023) arasında yapılacağını bilmiyordu program. Bunu hemen ADCON1 komutunun altına ilave et.

Hata-2: Zaman hesabını yanlış yapıyoruz. Alt program her 250 ms de bir kesme üretiyor. Bu 1000 ms de yani 1 sn de 4 kesme eder. Peki 3 dakikada kaç kesme eder= 3*4*60=720 kesme etmesi gerekirken biz bunu 12 aldık. Saniye ile dakikayı karıştırdım sanırım. Her neyse  500 ms lik bir default süremiz olduğu için 718/1024=179,5 ve bunuda 1795 olarak alınca işler düzelecektir.
Bu durumda yeni formül ;
Zaman=(((HAM+1) */1795)/10)+2  şeklinde olacaktır. Bu değişiklikleri yap program doğru çalışır.

Ancak zaman ve Kes isimli değişkenlerin değerleri artık byte sınırını aşacağı için word cinsinden tanımlanmaları gerekir.

Aslında ADC tanımlamalarını aşağıdaki şekilde değiştirirsen daha düzgün çalışacaktır.

DEFINE ADC_BITS 10     ' ADCIN resolution  (Bits)
'DEFINE ADC_CLOCK 2     ' ADC clock source  (Fosc/32)   'bu satır kapalı kalsın açma.
DEFINE ADC_SAMPLEUS 5 ' ADC sampling time (uSec)

Senin son yüklediğin rar dosyasını değiştirip doğru programı oraya yerleştirdim. Oradan da alabilirsin.

Ete


Powered by EzPortal