Butona uzun süre basmada farklı görev atama

Başlatan Cemre., 04 Eylül 2015, 20:40:38

Cemre.

Karakter LCD ile menü uygulaması yapmaya çalışıyorum. "menu" ve "option" adında iki değişkenim var. Bunların değerlerine göre LCD'ye menü sayfası yazdıran bir de fonksiyonum var. Ancak tek bir buton ile butona kısa basıldığında "option" değişkenimi bir artırmak ve buna göre alt menü değiştirmek, butona uzun basılırsa "menu" değişkenimi bir artırıp üst menü değiştirmek istiyorum.

Buton okumak için kullandığım kodlarım

main fonksiyonu içerisindeki sonsuz döngü;
for(;;){
              count = 0;
              if (Button(&PORTB, 0, 1, 1)) {                // Detect logical one
                 oldstate = 1;                              // Update flag
                 while((count < 100) && Button(&PORTB, 0, 1, 1)){
                    count++;
                    Delay_ms(10);
                 };
              };
              if (oldstate && Button(&PORTB, 0, 1, 0)) {    // Detect one-to-zero transition
                 if(count == 100){
                    menu += 1;
                 }else{
                    option += 1;
                 };
                 showmenu(menu,option);
                 oldstate = 0;                              // Update flag
              };
     };


menu ve option değişkenlerinin değerlerine göre karar verip LCD'ye yazdıran fonksiyonum;

void showmenu(int i, int j){
     if(i == 0){
          if(j == 0){
               Lcd_Cmd(_LCD_CLEAR);
               Lcd_Out(1,1,"Kocaeli Uni");
               Lcd_Out(2,1,"buraya konu");
          }else if(j == 1){
               Lcd_Cmd(_LCD_CLEAR);
               Lcd_Out(1,1,"Kocaeli Uni");
               Lcd_Out(2,1,"buraya isim");
          }else{
               option = 0;
          }
     }else if(i == 1){
          if(j == 0){
               Lcd_Cmd(_LCD_CLEAR);
               Lcd_Out(1,1,"    Settings    ");
               Lcd_Out(2,1,"################");
          }else if(j == 1){
          Lcd_Cmd(_LCD_CLEAR);
               Lcd_Out(1,1,"    Settings    ");
               Lcd_Out(2,1,"Ayar 1");
          }else if(j == 2){
               Lcd_Cmd(_LCD_CLEAR);
               Lcd_Out(1,1,"    Settings    ");
               Lcd_Out(2,1,"Ayar 2");
          }else{
               option = 0;
          }
     }else{
           menu = 0;
     }
}


Nerede hata yaptığımı kestiremiyorum. Yardımlarınız için şimdiden teşekkürler, herkese iyi akşamlar..

selimkoc

Button(&PORTB, 0, 1, 1)


fonksiyonu RB0 pinini 1ms Hi yaptığında demektir. Burada eğer buton bağlantısı Hi aktif ise doğrudur. Ancak Low aktif ise yanlış olur. O zaman

Button(&PORTB, 0, 200, 0)


Burada RB0 200ms süresince Low'a düşerse demektir.

Daha teferruatlı bilgi için;

https://elektrokod.wordpress.com/2013/11/18/buton-kontrolu/

Cemre.

#2
Alıntı yapılan: selimkoc - 04 Eylül 2015, 20:59:18
Button(&PORTB, 0, 1, 1)


fonksiyonu RB0 pinini 1ms Hi yaptığında demektir. Burada eğer buton bağlantısı Hi aktif ise doğrudur. Ancak Low aktif ise yanlış olur. O zaman

Button(&PORTB, 0, 200, 0)


Burada RB0 200ms süresince Low'a düşerse demektir.

Daha teferruatlı bilgi için;

https://elektrokod.wordpress.com/2013/11/18/buton-kontrolu/


Evet hocam haklısınız. Gerekli düzeltmemi yaptım. Ancak hala uzun basılmayı algılayamıyorum. Kısa basmada problem yok.

Şuan ki durum bu;
for(;;){
              count = 0;
              if (Button(&PORTB, 0, 1, 0)) {
                 oldstate = 1;
                 while((count < 100) && Button(&PORTB, 0, 1, 0)){
                    count += 1;
                    Delay_ms(10);
                 };
              };
              if (oldstate && Button(&PORTB, 0, 1, 1)) {
                 if(count >= 99){
                    menu += 1;
                 }else{
                    option += 1;
                 };
                 showmenu(menu,option);
                 oldstate = 0;
              };
     };


Neden uzun bastığımda menu 1 artmıyor da yine option 1 artıyor?

mustafabat

Butona basıldıktan sonra uygun gecikme süresi koyup süre sonunda butonun basılı olup olmadığını kontrol edip ona göre işlem yapabilirsin.

BLİZZARD

#4
@huseyin67  normalde PBP kullandım .. Yardımcı olabilsin diye küçük bir algoritma yazmak istiyorum.

İnt a=1
While ((portx.y=1) && (a=<100))  // burda portx.y button nun hangi portun hangi girişine bağlı ... ve durumu 1 ise.... için kullandım
{
  a+=1;
  Delay(10);
}
...
İf((a>=1)&&(a<=40))      //ilk 10ms ile 400ms arasında  while da ki delaydan ötürü bekler...  (bir nevi)
{
optionu bir arttır komutu
}
if ((a>=41)&(a<=100))     // bu da 410ms den sonra 1000m'se kadar   while da ki delaydan ötürü bekler...
{
menü ye git ... komutu
}
...
Tabii PicBasicProdaki gibi yazmadım .. Yaptığım while 'ı if in dışında port girişini saydirmak... umarım bunu anlar kendi komutuna uyarlayabilirsin  ... çünkü  bu şekilde doğru olacagını düşünüyorum

Cemre.

#5
Çünkü while döngüsünden çıkıldığı halde elimi butondan çekmediğim için ikinci if'e girilmiyor ve count değişkenim sıfırlanıyor. Peki buna çözümüm ne olacak?

mesaj birleştirme:: 05 Eylül 2015, 13:01:05

for(;;){
              if (Button(&PORTB, 0, 1, 0)) {                                    //Butona basılı
                 oldstate = 1;                                                  //Butona bir kez basıldı
                 while((count > 0) && Button(&PORTB, 0, 1, 0)){                 //count 0'dan büyükse ve hala butona basılıysa
                    count -= 1;                                                 //count 1 azalt
                    Delay_ms(100);                                              //100ms bekle
                    LED2 = ~LED2;                                               //Uyarı LED'i konum değiştir
                 };
              };
              if (oldstate && Button(&PORTB, 0, 1, 1) && count < 18) {          //Butona bir kez basılmış, butona basılı değil, butona en az 200ms basılmış
                 option += 1;                                                   //Alt menü değiştir
                 showmenu(menu,option);                                         //Menüyü LCD'de göster
                 oldstate = 0;                                                  //Buton bayrağını temizle
                 count = 20;                                                    //Count değerini yükle
              }else if(count == 0){                                             //Eğer butona 2sn'den fazla basılmışsa
                 menu += 1;                                                     //Ana menü değiştir
                 showmenu(menu,option);                                         //Menüyü LCD'de göster
                 oldstate = 0;                                                  //Buton bayrağını temizle
                 count = 20;                                                    //Count değerini yükle
              }
     };


Bu şekilde çalışıyor. Açıklama satırları adım adım yazdım unutmamak adına. Belki birinin daha işine yarar. Onun dışında düzeltilmesi gereken bir yer görüyorsanız yazın lütfen..