3 SENSOR ISI + 3 SENSOR NEM KESME PROBLEMi ! 16F877

Başlatan sinasos, 04 Ocak 2018, 11:21:46

sinasos

Merhaba arkadaşlar,
     4x20 LCD ve 16f877 ile bir sistem yapmaya çalışıyorum. Benim gibi acemilerin çektiği en büyük zorluklardan birisi kesme'dir. ben dosyayı yüklüyorum vakti olup yardımcı olabilecek arkadaşlardan destek bekliyorum.
Sorunum şu ;
     Devrede bir adet püskürtme süresi (saniye) ve bir adet bekleme süresi (dakika) var. ama maalesef yaptığım sistemde kesme yapılan işlemlerden midir yoksa kurgu yanlışlığından mıdır düzgün çalışmıyor. Amaç serada 3 noktadan ısıyı kontrol edecek düşükse ilgili rölelleri çekip ısıtma sağlayacak, soğuksa diğer rölelerle soğutacak,
     Nemde aynı mantık ama sensör olarak 3 adet arduino toprak nem sensörü kullanılıyor.(YL-69) onlarıda adc ile okuyorum, ve nem düşükse püskürtme süresi kadar ilgili röle çekiyor, bekleme süresi kadar röleyi kapatıyor beklemenin sonunda nem hala düşükse aynı işlemi tekrarlıyor.
     Zaman tek başına çalışınca sorunsuz çalışıyor ama ds18b20 ve YL-69 lar ilave edilince çok hızlı (salise gibi) ve duraklayarak çalışıyor. ayrıca sensör okumalarında atladığım birşey varmı ? daha sadeleşebilirmi ? o kunudada fikirlerinizi bekliyorum
Duayenler el atarsa sevinirim.
Saygılarımla.

ete

DS18B20 sensörü bir okuma çevrimini 750 ms de tamamlar. Sensörü okumak için programı oraya yönlendirdiğinizde;
Bekle:
           OWIN    Comm_Pin, 4, [Busy]    ' Busy değerini oku
           IF      Busy = 0 THEN Bekle
komut satırları nedeni ile okuma işlemi tamamlanıncaya kadar program orada bekler. Bu ise orada sistemin en azından 750 ms zaman harcaması anlamına gelir. Aynı sorun diğer sensör okumasında da mevcut.  Kısaca program 750 ms lik ilk dilimde birinci sensörü okumak için zaman harcıyor ikinci sensörde de aynı süreyi harcayıp geri kalan işleri artan zamanda yapıyor.
Bu durumda Sıcaklık semsörlerini daha akıllıca bir yöntemle okumak gerekir. Nedir daha akıllıca yöntem;
Dikkat edilirse sıcaklık okumada işlem adımları şöyle;
1. sensöre okuma emri veriliyor  (OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku)
2. Sonra okuma çevrimi tamamlanıncaya kadar orada bekleniyor
3. Sonra okuma işlemi tamamlanıp sıcaklık hesabı yapılıyor.

Bu çevrimi bu şekilde değilde şöyle çalıştırsak nasıl olur;
1. Okuma emrini verelim. Burada üç sensöre de aynı anda okuma emri verilmesi uygun olacaktır.
2. Bir zaman tutalım bu tutulan zaman yaklaşık 750 ms olsun. Ancak bu zaman zarfında bekleme yapmayalım. Aksine diğer işlerimizi halledelim. Mesela, ADC okumalarını ve nem hesabını yapalım.  Süre tutulması işlemini TMR1 sayacı ile yapabiliriz.
3. Süre sonunda hazır olması gereken 3 sıcaklık bilgisini alıp sıcaklık hesaplarını yapalım.
4. Sıcaklık hesabını yapar yapmaz hemen yeniden 3 sensörün okuma emrini verebiliriz.
Bu sistemle mevcut sistemin arasındaki fark şudur. Mevcut sistemde 3 sensör okuması neredeyse 2,3 saniyede tamamlanmaktadır. Bu esnada kesmede çalıştığı için süre hesabında aksamalar olması doğaldır. Tarif ettiğim sistemde ise bütün çevrim neredeyse 1 sn içinde tamamlanabilmektedir.

ADC okumasında alt programa Defimne komutları yazılmış. Define komutları programa yalnızca 1 kere verilmesi gereken komutlardır. Bu komutlar iligli register ayarlarını yapar. Her okuma rutininde aynı değerleri yenidenvermek boşuna program gecikmesi yaratmaktan başka bir işe yaramaz. Define komutlarını programın başına yerleştirip ADC okuma kısmını sadeleştirin.

Son olarak Sensör okuma işlemi nasıl yapılacak onu anlatayım. Ben birini analatacğım sen diğerlerini buna göre ayarlarsın.
SENSOROKU:
           OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku   komut satırından sonra bir return vererek programı oradan çıkarıyoruz.
SENSOROKU:
           OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku
            RETURN
şeklinde.
Bu durumda programın başında 3 sensörede okuma emrini vermek gerekiyor. Dahada devam edersem anlattıklarım karmaşık hale gelecek.
En iyisi programın en azından baş ksımını ve sensör okumalarına bu anlattıklarıma uygun hale getireyim sonucu gör istersen ilişiktedir.
Program birden kavranmayacak kadar karmaşık geliyor şu anda bana her şeyine hakim olamadığım için fazla değişiklik yapamadım. Yapmak günlerimi alır. Ancak sen hakim olmalısın. Bu son değişikliğe göre yeniden düzenle istersen. Bu arada SAYICI kısmına göndermeye gerek yok diye düşünüyorum artık. Zaman paylaşımına gerek kalmıyor. Ama yinede karar veremedim.
Yadıklarımı incele çalıştır ve farkı hissetmeye çalış bakalım.
Ete

Not: ADC kanalların ayarlanmasında da sorun var. 16F877A da istediğin kanalı analog istediğini digital kullanma imkanın yok. Onun yerine data sheet de ADCON1 registeri açıklamalarına verilen tablodaki standart ayarlamaları kullanman gerekiyor. Sana 3 analog pin lazım gerisi digital olmalı. Bu durumda en uygun seçenek. AN0-AN1-AN3 analog , PORTA.2,4,5, ise digital kullanıma ayrılmalı. Bunun için ADCON1 registerine %10000100 değerini verip AN2 ile AN3 fonksiyonlarını yer değiştirmen gerekir. Eklediğim programda bunlarıda düzelttim. Programın gher yerine ADCON1=7 komutu eklemişsin. Bu analog pinleri iptal ediyor sonrada program hata veriyordu.



sinasos

HOCAM
compile esnasında opcode expected instead of '_config' hatası alıyorum !

sinasos


onurinci

bu soruya yanıtım yok ,ama düzgün ve kısa yanıt beklerseniz,
makinanızın işletim sistemi nedir ve kaç bit 32 bit...64 bit vscs

derleyici versiyon numarası gibi forumda çözümler mevcut kısa bir aramada bulabilirsiniz

mesaj derki ,config satırınız hatalı...

ete

Muhtemelen 32 bit makina ile 64 bit olarak derleme yapıyorsunuz. Daha doğrusu programdaki config satırı (sigorta ayarları) 64 bit makinaya göre ve derlemenin MPASM kullanılarak yapılmasını gerektiriyor. Siz ise direk 32 bit makina gibi MPASM kullanmadan derleme yapmaya çalıştığınız için bu hatayı veriyor.
Çözüm şu, makina 32 bit ise prohramdaki 64 bitlik sigorta ayarını kapatıp diğer sigorta ayarlarını aktif hale getirin öyle derleyin.
Makinanız 64 bit ise MCS de program& Compile options seçeneğinde Assembler seçip sağda yer alan use Mpasm kutusunu işaretli (seçili) hale getiriniz. Bunu yapınca MCS ye birde MPASM klasörü göstermeniz gerekecektir.
Ete

sinasos

merhabalar,
'@ device pic16F877A, CP_ALL   ===>bu satır kapalı
@ device pic16F877A, WRT_256
@ device pic16F877A, CPD_ON
@ device pic16F877A, LVP_OFF
@ device pic16F877A, BOD_OFF
@ device pic16F877A, PWRT_ON
@ device pic16F877A, WDT_OFF
@ device pic16F877A, XT_OSC
DEFINE OSC 4

şeklinde derleme yaptığımda sorun olmuyor. ancak cp_all satırını kapatmak zorunda kaldım. Ayrıca bu satırında anlamını söylemeniz mümkünmü ? webde açıklayıcı bir bilgiye rastlayamadım.
teşekkür ederim...

sinasos

merhabalar,
'@ device pic16F877A, CP_ALL   ===>bu satır kapalı
@ device pic16F877A, WRT_256
@ device pic16F877A, CPD_ON
@ device pic16F877A, LVP_OFF
@ device pic16F877A, BOD_OFF
@ device pic16F877A, PWRT_ON
@ device pic16F877A, WDT_OFF
@ device pic16F877A, XT_OSC
DEFINE OSC 4

şeklinde derleme yaptığımda sorun olmuyor. ancak cp_all satırını kapatmak zorunda kaldım. Ayrıca bu satırında anlamını söylemeniz mümkünmü ? webde açıklayıcı bir bilgiye rastlayamadım.
teşekkür ederim...

Alıntı yapılan: sinasos - 06 Ocak 2018, 09:57:26
bilgisayarım XP işletim sistemi 32 bit bir makina. Pbp de çok kolay işlem yaptığım için bu sistemi kullanıyorum. bu bilgisayarla sadece PBP işlemi yaptığımdan yeni işletim sistemi yüklemedim.


ete

Demek 32 bit derleme yapıyormuşsun. CP_ALL (code protect tamamı anlamına geliyor)
Ete

sinasos

hocam şimdide şöyle bir sorun oluştu. ds18b20 ısılarını ayarlanan değerlerin üzerine çıkartınca veya düşürünce ilgili röleller çekmiyor. bende yanlarına birer pause koydum aynı flip-flop gibi röleleri çekip bırakıyor.
ilgili satır ;
"
ISIKONTROL:
if isi1<term then gosub bir
if isi2<term then gosub iki
if isi3<term then gosub uc
IF MENU=1 THEN  GOTO AYAR_MENUSU
return

bir:
IF ISI1<TERM THEN  'ISI 1.SENSÖREDEN OKUNAN DEĞERDEN DÜŞÜKSE 1.ISITMAYI ÇALIŞTIR
ROLE1=1:IKAZ=1:ROLE10=1 :pause 300
ELSE
ROLE1=0:IKAZ=0:ROLE10=0
ENDIF
IF MENU=1 THEN  GOTO AYAR_MENUSU
return

iki:
IF ISI2<TERM THEN      'ISI 2.SENSÖREDEN OKUNAN DEĞERDEN DÜŞÜKSE 2.ISITMAYI ÇALIŞTIR
ROLE2=1:IKAZ=1:ROLE10=1:pause 300
ELSE
ROLE2=0:IKAZ=0:ROLE10=0
ENDIF
IF MENU=1 THEN  GOTO AYAR_MENUSU
return

uc:
IF ISI3<TERM THEN  'ISI 3.SENSÖREDEN OKUNAN DEĞERDEN DÜŞÜKSE 3.ISITMAYI ÇALIŞTIR
ROLE3=1:IKAZ=1:ROLE10=1 :pause 300
ELSE
ROLE3=0:IKAZ=0:ROLE10=0
ENDIF
IF MENU=1 THEN  GOTO AYAR_MENUSU
return
"
bu şekilde bir anormallik mi var ! yoksa hani adc yüzünden mi bu şekilde davranıyor. ? simülasyonda da aynı işlemi yapıyor. isteseniz ekte dosyanın tamamı da var !

ete

Bu tür sorunlar iki farklı şeyden oluşur.
Birincisi röleyi çalıştıracak şart komutun röleyi aktif hale getirir ama aynı röleyi pasif edecek bir komutun vardır oda kapatmaya çalışır. Programın başında röle aktşf olur alt satırlarda başka bir şart onu pasif eder. Bu konuyu araştır.
İkincisinde ise histerisiz denilen açma ile kapama dereceleri arasındaki farkın az olması yada hiç olmamasından kaynaklanır,
Adc den okunan bir değere göre aç ve kapamyapıyorsan bazen kritik noktalarda adc bir aşağı bir yukarı oynayabilir. Şayet komutun 2 farktan azında aç kapa yapıyor ise bu şekil sorun ortaya çıkar.
Kısaca açmak için bir değer kullanmış isen kapatmak için o değerden en azından 5 birim  fark kadar bir aralık olması gerekir. Örnek vereyim 19 derecede aç dedi isen 24 derecede kapat demelisin. Aksi halde aç kapa yapar sistemin.

Ete

mg1980

@Ete Hocam, 19 derece ile 24 derece arasında 5 derece fark var. Fazla değil mi ? Bunu ondalık hanelere indirgemek daha doğru olmaz mı ? Örneğin 19 derecede aç denmişse  19,5 derecede kapat şeklinde. Saygılar.

ete

Yarım derece bana göre çok düşük bir değer. Sensör bile okurken yardım derece tolerasnla okur ve bir açar bir kapar sistem.
Aslında devreyi yapıp sistemin tepkisine bakmak daha doğru olur ama ben min 3 derece maksimum 5 derece fark kullanırım.
Birde neyi açıp kapadığında önemli tabiiki ama 2-3 derecelerden daha az bir fark kesin olarak sıklıkla aç kapa yaptırır.
Ete

sinasos

hocam ilginize çok çok teşekkür ederim. sorunu buldum, yazılımla alakalı değil donanımla alakalıymış. ben rölelleri sürdüğüm transistörlerin beyz leri ile işlemci arasına transistör atmayı unutmuşum. sonradan farkettim. algoritma tamam, yazılım tamam, donanım tamam...
herşey için teşekkür ederim. şimdilik bir sıkıntı görünmüyor. sadece anlayamadığım bir kısım var. vaktiniz olduğunda o konuda da bilgi verebilirseniz minnettar olurum.
"
BASLA: 
        gosub SENSOROKU
        GOSUB SENSOROKU1
        GOSUB SENSOROKU2
DELAY: 
       SAY=3
       T1CON=%00110001      'bölme oranı 1/8 ve timer1 aktif edildi
       PIR1.0=0             'Kesme bayrağı sıfırlandı
             
DELAY_BIR:
           TMR1H=$85:TMR1L=$EE     
           while PIR1.0=0
             gosub adc_kontrol
             GOSUB NEMHESAP
           WEND 'KESME OLUŞUNCAYA KADAR BEKLE
           PIR1.0=0       
           SAY=SAY-1
           IF SAY>0 THEN DELAY_BIR
           T1CON=0
           GOSUB SENSORAL
           GOSUB SENSORAL1
           GOSUB SENSORAL2
"
bu kısımı çok fazla anlayamadım ! kusura bakmayın.

ete

DS18B20 sensörleri bir okuma çevrimini 750 ms de tamamlıyor. Sende 3 adet var. 3x750 ms=2250 ms de yada yaklaşık 2,25 sn de her üç sensördeki sıcaklık değerlerini okuyabiliyorsun. Bu uzun bir süre ve kısaltmaya çalıştım.
Orjinal programda ;
- Sensöre okuma emri veriliyor
- daha sonra Busy bitine bakılarak sıcaklık çevrimi tamamlanmış mı diye bakılıyor. Bu işlem işte 750 ms sürüyor ve sonunda busy biti işlem tamamdır diyerek çevrilen sıcaklık okunuyor.
Bu şu anlama geliyor. Sıcaklık okuma merini verdikten yaklaşık 750 ms sonra okunan sıcaklığı sensörden alıyorsun. O halde orada boşuna neden 750 ms bekleyeyim diye düşündüm.  Bu nedenle yukarıdaki kod şunu yapıyor,
- Önce 3 ayrı sensöre de Oku emrini verip oradan ayrılıyor. (RETURN ile)
- Sensörlerin her biri kendi sıcaklığını okuyup hazır hale getirmeye çalışıyor.
- Ben geri döndükten sonra 750 ms lik bir TMR1 sayacı çalıştırıyorum. Her bir kesme peryodu 250 ms olacak şekilde. Bunu 3 defa çalıştırınca 750 ms geçmiş oluyor ve bu süre sonunda gidip 3 sensörden de çevrilmiş sıcaklıkları okuyorum.
- 750 ms lik bekleme süresi boşuna geçmesin diye bu süre içinde ADC okumalarını yapıp nem hesabını da yaptırıyorum.
- Böylece 750 ms lik peryot tamamlanınca ben ne okumalarınıda bitimiş oluyorum. Sonra gidip sıcaklıkları okuyup hesaplarını yapıp işlemi yada bir döngüyü tammalıyorum.

Aynı işi sen nasıl yapıyordun onu anlatayım.
1. nolu sensörden sıcaklık okuyordun 750 ms sonra geri geliyordun.
2. Nolu sensörden sıcaklık okuyordun ve 750 ms sonra geri dönüyordun
3. nolu sensörden sıcaklık okuyup 750 ms sonra geri dönüyordun.
4. daha sonra ADC okumalarını yapıp nem hesaplarını yapıyordun. Bu işler sonucunda senin döngün yaklaşık 3 sn sürerken ben hepsini 1 sn den daha az sürede yapmış oluyorum. Olay budur.
Ete

Powered by EzPortal