Su Akış Kontrol Sistemi ile ilgili sorular

Başlatan toktur zoidberg, 16 Ocak 2014, 01:50:18

toktur zoidberg

Merhaba arkadaşlar,

Mikrodenetleyiciler konusunda pek bilgili sayılmam. Ancak tez konum gereği mikroc kullanarak su akış kontrol sistemi tasarlamam gerekiyor. anlamadığım bir çok nokta var ve bu konularla ilgili internette çözüm arıyorum ancak bazen sonuç bulamıyorum. Proje bitiş zamanına da çok az kaldı, bu yüzden acele bir şekilde tamamlamak istiyorum. Her sorum için ayrı ayrı başlık açıp, forum kirliliğine neden olmak yerine, bir başlık açıp oradan sorularımı sorayım istedim. yardımcı olursanız sevinirim.

Şimdi projeden biraz bahsedeyim. Özetle, projenin amacı eğer ev tesisatındaki su borularından bir tanesinde sızıntı varsa ya da musluklardan bir tanesi açık unutulmuşsa sistemin suyu kesmesidir. Bunu yapma mantığı ise, debi sensöründen geçen su miktarı belli bir süre boyunca değişmezse, selenoid valf suyu kesiyor. Bunun için tesisatın girişine bir akış sensörü, bir de selenoid valf koymayı düşünüyorum. Hatta malzemelerimi de aldım. Kullandığım mikrodenetleyici ise 16f877a. aldığım akış sensörü 1-wire iletişim modeli kullanıyor sanırım, bu yüzden proteusta programı simule etmek için, ds18b20 sıcaklık sensörünü kullandım. selenoid vana yerine ise led kullandım. aldığım selenoid vana normalde kapalı olduğu için, proteus'ta açık olması durumu için ledin yanmasını, kapalı olması durumu için ise ledin yanmamasını yapmaya çalıştım.

ben bir şeyler yaptım ancak, sıcaklık ne kadar süre sabit kalırsa kalsın, led bir türlü sönmüyor. kodun ilgili kısmını buraya yazıyorum, acaba nerede hata yaptığımı söyler misiniz?

ISI =  Ow_Read(&PORTE, 2);                   //LSB byteı okundu
ISI = (Ow_Read(&PORTE, 2) << 8) + ISI;       //MSB byteı okundu

ISI_Yeni = ISI;

if (ISI_Eski == ISI_Yeni) {
    sayac++   ;
}

ISI_Eski = ISI_Yeni;

if (sayac == 20) {
TRISC.RC0 = 0;
}

Display_Temperature(ISI);

Delay_ms(500);

yukarıdaki kodlar do-while döngüsünün son kısmına ait. sıcaklığın ölçülüp lcd'ye gösterildiği kısımda bir sıkıntı yok, simulasyonda görebiliyorum. yukarıda tanımladığım sayaç 0'dan başlıyor, ve her yarım saniyede bir yapılan ölçümlerde, sıcaklık değerinin, bir önceki sıcaklıkla aynı olması durumunda 1 artıyor. 20 olduğunda ise, c portunun 0. pinine lojik 0 verip ledi söndürmesini umuyorum ancak bu olmuyor.

acemi olduğumu baştan belirtmiştim, aptalca bir hata yapmış olabilirim. anlayışlı cevaplarınızı bekliyorum.

JKramer

TRIS, ilgili pin'i giriş(1) ya da çıkış(0) yapmak içindir. Lojik seviye için PORT (PORTC.RC0 olabilir) kullanmanız gerekiyor.

toktur zoidberg

#2
Alıntı yapılan: JKramer - 16 Ocak 2014, 08:50:34
TRIS, ilgili pin'i giriş(1) ya da çıkış(0) yapmak içindir. Lojik seviye için PORT (PORTC.RC0 olabilir) kullanmanız gerekiyor.

basit bir hata yapabileceğimi biliyordum ama bu kadar da basit olabileceğini düşünmedim, çünkü bildiğim bir konuydu. teşekkür ederim hocam.

bu arada;

simulasyonu yaparken ds18b20 sıcaklık sensörü kullanmıştım ama benim sistemimde onun yerine akış sensörü kullanacağım ve ölçme metodları çok farklı. akış sensörü içinden geçen sıvının, içindeki tekeri döndermesiyle pulse sinyali oluşturuyor. böylelikle pulse sinyaline göre %3 hatayla sıvı akışını öğrenebilirim. peki ben bu sinyalin frekansını nasıl ölçebilirim?

selimkoc

iki şekilde ölçebilirsin;

1. CCP birimini kullanarak,

2. Timer harici tetiklemesini kullanarak (timer0 veya timer1).

toktur zoidberg

Alıntı yapılan: selimkoc - 16 Ocak 2014, 17:55:52
iki şekilde ölçebilirsin;

1. CCP birimini kullanarak,

2. Timer harici tetiklemesini kullanarak (timer0 veya timer1).

teşekkür ederim hemen uğraşıyorum.

toktur zoidberg

tekrardan merhabalar, bir önceki sorumu henüz çözemedim, hala kitaplardan ve internetten araştırma yapıyorum.

şimdi başka bir konuda soru sormak istiyorum. projemde giriş gerilimi vermesi açısından gerilimi ayarlanabilir bir adaptör aldım.  internette ve kitaplarda gördüğüm örneklerde pic giriş gerilimi hep 5 volt olarak verilmiş, benim adaptörümün ayarlanabilir gerilimleri ise 3-4,5-6... diye gidiyor. PIC16F877A mikrodenetleyicisi için giriş gerilimi olarak 4,5 Volt ya da 6 Volt kullanmam bir sıkıntı olur mu? araya ayrı bir entegre ya da direnç atmam gerekir mi? eğer sıkıntı olmazsa bu verdiğim gerilim değerleri çıkış gerilimimi değiştirir mi?

bazı yerlerde PIC mikrodenetleyicinin 3 ila 5,5 V besleme gerilimleriyle çalışabildiği yazıyordu, yine de emin olmak istedim.

şimdiden teşekkürler.

not: konunun güncel kalması için arka arkaya post gönderdim, flood yapma niyetinde değilim.

engerex

 Bu üründen MCU'dan MCU'ya değişmekle beraber bahsi geçen MCU'da
Operating Voltage Range (V)   2 to 5.5

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010242

toktur zoidberg

#7
herkese tekrardan merhaba;

daha önceki mesajlarımda sormuş olduğum pulse sinyalinin frekansını ölçmeyi başardım, frekansı da lcd'ye yazdırmayı başardım. fakat ben lcd'ye frekans değil debi yazdırmak istiyorum.

sensör datasheetinde yazdığına göre yaklaşık olarak her 8.2 hertz pulse sinyali için, debi 1litre/dakika artıyor. lcd'ye debi yazdırırken de virgülden sonra 1 basamak daha göstermesini istiyorum. bunun için sırasıyla frekansı, 8.2'ye bölüp, daha sonra onu 10 ile çarpıp, yuvarlıyorum. daha sonra bu değeri lcd'ye yazdırıyorum, fakat en sağdaki basamağı yazdırmadan önce virgül koyuyorum. fakat virgülden sonraki basamak her zaman için 0 oluyor ve nedenini anlayabilmiş değilim. nerede yanlış yapıyorum?

işte ilgili kodlar:

sonsuz döngü:

while(1)
     {
         frekans = timer_degeri;
         Lcd_out(1,1,"Debi:");
         Lcd_out(1,12,"Lt/Dk");
         debiondalik = frekans / 8,2 ;
         OndalikIfadeBul(debiondalik);
         LcdIntYaz(1,7,debi10tam);
      }


10 ile çarpıp, tam sayıya yuvarlama fonksiyorunu:

void OndalikIfadeBul(unsigned int deger)
{

     debi10ondalik = deger * 10;
     altyuvarlama = floor(debi10ondalik);
     ustyuvarlama = ceil(debi10ondalik);
     
     if((debi10ondalik-altyuvarlama)<(ustyuvarlama-debi10ondalik))
          {
          debi10tam = altyuvarlama;
          }
     else if ((debi10ondalik-altyuvarlama)>=(ustyuvarlama-debi10ondalik))
          {
          debi10tam = ustyuvarlama;
          }

}


LCD'ye debi yazdırma fonksiyonu:

void LcdIntYaz(int sat,int sut,unsigned int  deger)
{
     char tmp = 0;

     tmp = (deger/100);
     Lcd_chr(sat,sut,tmp+48);
     tmp = (deger/10)%10;
     Lcd_chr(sat,sut+1,tmp+48);
     Lcd_Out(sat,sut+2,",");
     tmp = deger%10;
     Lcd_chr(sat,sut+3,tmp+48);

}


değişken tanımlamaları:

unsigned long timer_degeri = 0;
unsigned double frekans = 0;
unsigned double debiondalik = 0;
unsigned double debi10ondalik = 0;
unsigned int debi10tam = 0;
unsigned int ustyuvarlama;
unsigned int altyuvarlama ;
int sayac=0, timer1_sayac = 0;
unsigned long rb0_kesmeSayisi = 0;
char txt[5];


şimdiden teşekkürler

edit: ondalıklı değer ifadesini bulmak için tanımladığım fonksiyonda değeri int olarak tanımlamıştım, sorun oymuş. double olarak tanımladım düzeldi.

toktur zoidberg

sonunda programı yazdım, simule ettim, sıkıntısız çalışıyor isis'te ancak board üzerinde kurduğumda çalışmıyor.EasyPic4 ile programı yüklediğim zaman, onun üstündeki lcd'de yazılanları görebiliyorum ama, board'da lcd'nin ilk satırında siyah kareler çıkıyor.

programa göre, frekans okunup, debiye çevriliyor. lcd'nin üst satırında debi, alt satırında debinin sabit kaldığı zaman gösterilmesi lazım.
// LCD module connections
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections

unsigned long timer_degeri = 0;
unsigned double frekans = 0;
unsigned double debiondalik = 0;
unsigned double debi10ondalik = 0;
unsigned int debieski = 0;
unsigned int debi10tam = 0;
unsigned int ustyuvarlama;
unsigned int altyuvarlama ;
int sayac=0, timer1_sayac = 0;
unsigned long rb0_kesmeSayisi = 0;
unsigned saniye = 0;
int su = 0;
char txt[5];


void LcdIntYaz(int sat,int sut,unsigned int  deger)
{
     char tmp = 0;
     if (PORTE.RE0 == 1){
     tmp = (deger/100);
     Lcd_chr(sat,sut,tmp+48);
     tmp = (deger/10)%10;
     Lcd_chr(sat,sut+1,tmp+48);
     Lcd_Out(sat,sut+2,",");
     tmp = deger%10;
     Lcd_chr(sat,sut+3,tmp+48);
     }
}

void OndalikIfadeBul(unsigned double deger1)
{

     debi10ondalik = deger1 * 10;
     altyuvarlama = floor(debi10ondalik);
     ustyuvarlama = ceil(debi10ondalik);
     
     if((debi10ondalik-altyuvarlama)<(ustyuvarlama-debi10ondalik))
          {
          debi10tam = altyuvarlama;
          }
     else if ((debi10ondalik-altyuvarlama)>=(ustyuvarlama-debi10ondalik))
          {
          debi10tam = ustyuvarlama;
          }

}

void DebiSabitmi (int eskidebi, int yenidebi){
     if (eskidebi == yenidebi){
        saniye = saniye + 1;
     }

     else {
          saniye = 0;
          su = 0;
     }
     
     delay_ms (742);

     debieski = debi10tam;
}
void DebiSifirmi (int deger){
     if (deger == 0){
        saniye = 0;
     }
}
     


void SaniyeYazdir(int sat,int sut,unsigned int deger){

char tmp = 0;

     tmp = (deger/10000);
     Lcd_chr(sat,sut,tmp+48);
     tmp = (deger/1000)%10;
     Lcd_chr(sat,sut+1,tmp+48);
     tmp = (deger/100)%10;
     Lcd_chr(sat,sut+2,tmp+48);
     tmp = (deger/10)%10;
     Lcd_chr(sat,sut+3,tmp+48);
     tmp = deger%10;
     Lcd_chr(sat,sut+4,tmp+48);
     
}

void SuyuKes1 (int deger)     {

     Lcd_out(1,1,"Debi:");
     Lcd_out(1,12,"Lt/Dk");

     if (deger == 30) {
        PORTE.RE0 = 0;
        saniye = 0;
     }
}

void SuyuKes2 (int deger)     {

     Lcd_out(1,1,"Debi: ");
     Lcd_out(1,11," ");
     Lcd_out(1,12,"Lt/Dk");
     if (deger == 10) {
        PORTE.RE0 = 0;
        saniye = 0;
        su = 2;
     }
}

void SuyuAc (int deger)     {

     Lcd_out(1,1,"DebiyiDegistirin");

     if (deger == 5) {
        PORTE.RE0 = 1;
        saniye = 0;
        su = 1;
     }
}

void SistemiKapat (int deger) {

     Lcd_out(1,1,"Sistemi Resetle ");


}

void interrupt()
{
     if(INTCON.INTF)
     {

      if(!sayac)
      {
       T1CON |= 0x01;
       sayac = 1;
      }
      if(sayac)
      {
         rb0_kesmeSayisi++;
      }
      INTCON.INTF = 0;
    }


   else if(PIR1.TMR1IF)
    {

       timer1_sayac++;

       if(timer1_sayac == 2)
       {
         timer_degeri = rb0_kesmeSayisi;
         rb0_kesmeSayisi = 0;
         timer1_sayac = 0;
       }

       TMR1H = 0x0B;
       TMR1L = 0xDB;

       PIR1.TMR1IF = 0;
    }


}



void main()
{

     ADCON1 |= 0x0f;
     CMCON |=0x07;

     TRISA = 0x7F;
     PORTA = 0x00;
     
     TRISD = 0x00;
     PORTD = 0x00;
     
     TRISE.RE0 = 0;
     PORTE.RE0 = 1;

     TMR1H = 0x0B;
     TMR1L = 0xDB;

     INTCON  = 0xC0; //genel kesme ile çevresel kesmeler aktif
     PIE1.TMR1IE = 1;    //timer1 ile ccp  kesmeleri aktif
     INTCON.INTE = 1;

     INTCON.INTF = 0;
     PIR1.TMR1IF = 0;

     T1CON = 0x30;

     Lcd_init();
     Lcd_cmd(_LCD_CLEAR);
     Lcd_cmd(_LCD_CURSOR_OFF);

     while(1)
     {
         frekans = timer_degeri;
         Lcd_out(2,1,"Sure : ");
         Lcd_out(2,15,"Sn");
         debiondalik = frekans / 8,2 ;
         OndalikIfadeBul(debiondalik);
         LcdIntYaz(1,7,debi10tam);
         DebiSabitmi(debieski, debi10tam);
         DebiSifirmi (debieski);
         SaniyeYazdir (2,8,saniye);
         if (PORTE.RE0 == 1 && su == 0){
            SuyuKes1 (saniye);
         }
         if (PORTE.RE0 == 0 && su == 0){
            SuyuAc (saniye);
         }
         if (PORTE.RE0 == 1 && su == 1){
            SuyuKes2 (saniye);
         }
         
         if (PORTE.RE0 == 0 && su == 2){
            SistemiKapat (saniye);
         }
         



     }

}



devrenin proteus simulasyonu:

ek açıklamalar:

osilatör 4 mhz kristal ve 22 pf'lik kapasitörlerden oluşuyor.

devrede görünmeyen Vss bağlantısını Vss, Vee(ki benim lcd'de V0 olarak gösterilmiş), Rw, D0, D1, D2, D3 ve K pinlerini toprağa, Vdd ve A pinini +4,5 volt'a bağladım. diğer bağlantılar simulasyondaki gibidir. LCD ışığı yandığına göre A ve K pinlerinde sıkıntı olduğunu düşünmüyorum, V0 pinine de kontrast için potansiyometre bağladıklarını duydum, bu yüzden toprakla arasına 10 kiloohm'a kadar değişik direnç değerleri koydum ama değişen bir şey yok.

PIC üzerinde simulasyonda görünmeyen bağlantıları yaptım. mclr pinini 10 k üzerinden +4,5 volta bağladım. 12 ve 31. pinleri toprağa bağladım. 11 ve 32. pinleri +4,5 volta ve 100 nf üzerinden toprağa bağladım.

bağlantıları multimetrenin diyotu ile test ettim, temassızlık olan bir yer yok.

yardımlarınız için şimdiden teşekkür ederim.