Aynı anda iki butona basılması durumu (pic, ccs c)

Başlatan neo, 20 Mart 2018, 00:31:53

neo

Merhaba :) devrede 3 tane butonum var. Herbirinin bir işlevi var, ayrıca butonlardan ikisine (örneğin c0 ve c1'e) beraber basıldığında farklı bir işlevi yerine getirmesi gerekiyor. Çok uğraştım ancak bir çözüm bulamadım. Her buton için basıp bıraktığımda kendi fonksiyonuna gidiyor.

İki butona basılması durumunda, "hangi butona daha önce basıldığı" veya "hangi butonun daha önce bırakıldığı" durumları kafamı karıştırıyor. Bu problemin genel kullanılan bir çözümü/yöntemi/algoritması var mıdır? Çözümü nedir?

aşağıdaki kod, main() fonksiyonu içinde;

Kod: [Seç]
if(input(pin_c0)==1)//..................................starta basıldığında
{
      while(input(pin_c0)==1);
      fonkStart();
}
if(input(pin_c1)==1)//..................................artıya basıldığında
{
      while(input(pin_c1)==1);
      fonkArti();
}
if(input(pin_c2)==1)//..................................eksiye basıldığında
{
       while(input(pin_c2)==1);
       fonkEksi();
}
Have you ever questioned the nature of your reality?

sımışka

if buton1&&buton2 ikisi birlikte
if buton1&&!buton2 yalnızca buton1
if !buton1&&buton2 yalnızca buton2


vitruvius

Ya buyuk resme bakacaksin, once kesisim kumelerine bakip sonra alt kesisim ve yalin kumelere bakacaksin, ya da bir butona basildigi durum icinde diger butonlarin da durumunu kontrol edeceksin. Tabi debounce olayina dikkat etmek lazim butonlarla calisirken.

Ilk dedigim icin bir ornek verecek olursak:
#include <stdio.h>
#include <stdbool.h>

int main()
{
    bool pin_c0 = false;
    bool pin_c1 = false;
    bool pin_c2 = true;
    
    if (pin_c0 && pin_c1 && pin_c2)
    {
        printf("You pressed all three buttons.\n");
    }
    else
    {
        if (pin_c0 && pin_c1)
        {
            printf("You pressed c0 and c1\n");
        }
        else
        {
            if (pin_c0 && pin_c2)
            {
                printf("You pressed c0 and c2\n");
            }
            else
            {
                if (pin_c1 && pin_c2)
                {
                    printf("You pressed c1 and c2\n");
                }
                else
                {
                    if (pin_c0)
                    {
                        printf("You pressed c0\n");
                    }
                    
                    if (pin_c1)
                    {
                        printf("You pressed c1\n");
                    }
                        
                    if (pin_c2)
                    {
                        printf("You pressed c2\n");
                    }
                }
            }
        }
    }

    return 0;
}

kimlenbu

#3
@vitruvius en önemli kısmını açıklamış, eğer ilk önce butonların tek basılma durumlarını kontrol edersen hiçbir zaman alttaki koşullara gidilmez. Önce 3'lü ardından 2'li kombinasyonları kontrol etmen gerekir.


Benim eklemek istediğimse işler mcu tarafında oldukça hızlı olduğu için en başa bir kontrol daha koyman gerekiyor. Bu kontrolde eğer herhangi bir tuşa basıldıysa biraz beklemen lazım ki kullanıcı 2. butona basacak süreyi bulsun. Gerçek şartlarda hiçbir zaman iki tuşa birden aynı anda basamazsın. Aşağıdaki kontrolün ardından vitruvius un çözümünü uygularsan olur.


    if (pin_c0 || pin_c1 || pin_c2)    {        delay(100);    }

neo

Anladığım kadarıyla aşağıdaki çözümü önermişsiniz. Ancak şöyle bir sorun var. start butonuna bastığımda eğer bekleme süresinden (aşağıda 3 saniye) daha fazla bekleyip diğer butona basarsam, sonra iki butondan da elimi çektiğimde program, sadece start butonuna bastığımı söylüyor.
İkinci problem de şu, eğer sadece start'a basmak istiyorsam en az bekleme süresi kadar basılı tutup sonra bırakmam gerekiyor. Aksi halde program, hiçbir butona basmamışım gibi davranıyor. Bu problemi gidermek için bekleme süresini (örneğin) 500ms'ye düşürdüğümde ise starta bastıktan sonra en fazla 500ms içinde + butonuna basmam gerektiği için problem yaşıyorum.

Şunu da belirteyim;
1. sadece start butonuna basılması,
2. sadece + butonuna basılması,
3. sadece - butonuna basılması,
4. start ve + butonuna basılması,
5. + ve - butonuna basılması.

Sadece bu 5 durum olacak.

#include <18f45k22.h>
#fuses xt, nowdt, noprotect
#use delay (clock=4000000)
#use fast_io(d)
#use fast_io(c)
#define use_portd_lcd TRUE
#include <lcd.c>

void main()
{
   set_tris_d(0x00);
   output_d(0x00);
   set_tris_b(0x00);
   set_tris_c(0xFF);
   lcd_init();
   
   //pin_c0, start  	        butonu
   //pin_c1, +	  	  	butonu
   //pin_c2, -	  	  	butonu
   
  	while(TRUE)
  	{
  	  	if(input(pin_c0) || input(pin_c1) || input(pin_c2))
  	  	{
  	  	  	delay_ms(3000);
  	  	  	
  	  	  	if((input(pin_c0) && input(pin_c1)) || (input(pin_c1) && input(pin_c2)))
  	  	  	{
  	  	  	  	if(input(pin_c0) && input(pin_c1))
  	  	  	  	{
  	  	  	  	  	while(input(pin_c0) || input(pin_c1));
  	  	  	  	  	printf(lcd_putc,"\fstart ve +");
  	  	  	  	}
  	  	  	  	if(input(pin_c1) && input(pin_c2))
  	  	  	  	{
  	  	  	  	  	while(input(pin_c1) || input(pin_c2));
  	  	  	  	  	printf(lcd_putc,"\f+ ve -");
  	  	  	  	}
  	  	  	}
  	  	  	else
  	  	  	{
  	  	  	  	if(input(pin_c0))
  	  	  	  	{
  	  	  	  	  	while(input(pin_c0));
  	  	  	  	  	printf(lcd_putc,"\fstart");
  	  	  	  	}
  	  	  	  	if(input(pin_c1))
  	  	  	  	{
  	  	  	  	  	while(input(pin_c1));
  	  	  	  	  	printf(lcd_putc,"\f+");
  	  	  	  	}
  	  	  	  	if(input(pin_c2))
  	  	  	  	{
  	  	  	  	  	while(input(pin_c2));
  	  	  	  	  	printf(lcd_putc,"\f-");
  	  	  	  	}
  	  	  	}
  	  	}
  	}
}


Have you ever questioned the nature of your reality?

fide

Merhaba.
Devreyi yeniden düzenleme şansınız varsa 3 butonu işlemciye bağladığınız yerden birer tane diyot çıkarıp tasarımınıza göre dirençle pullup yada pull down yapın.
Hangi butona basılırsa basılsın interrupt pinibdeki furum değişir hale getirin. ( butona basılınca 1 çıkışı alıyorsanız pull down, butona basınca 0 alıyorsanız pullup yapın)
Şimdi butona basınca interrupt içine girersiniz. Burda 100-200 ms bekleyip buton durumlarını okutun ve karşılaştırma kısmında önce çift buton değerlerini sonra tek buton değerlerini else if kullanıp karşılaştırın. Böylece hem buton 1 hem de 1-2 beraber basılınca buton 1 rutini çalışmaz.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

ete

1. sadece start butonuna basılması,
2. sadece + butonuna basılması,
3. sadece - butonuna basılması,
4. start ve + butonuna basılması,
5. + ve - butonuna basılması.
şeklinde  5 durum kontrolü yapılacak ise bunu yolu şöyledir. Bu yolları açıklarken çift basılacak butonlarda öncelik değişeceği göz önüne alınmıştır. Örneğin Start ve + butonlarına çift basılırken Önce Start sonra + veya önce + sonra Start butonlarına basılabilir. Algoritma he riki konumuda algılayabilmelidir. Diğer çift seçenek olan - ve + butonlarında da durum aynı olup aşağıdaki açıklamaya uygun işlem yaptırılması gerekir.

1. Start butonuna basılmışmı bakılır. Basılmış ise çift basılma ihtimaline karşın + butonunada basılımı onuda kontrol ederiz.
a) Basılmış ise o zaman Start ve + butonlarına basılmış ise ne yapılacak ise onu yaparız.
b) Basılmamış ise Yalnızca start butonuna basılınca ne yapılacak ise onu yaparız.

2. + butonuna basılmışmı bakılır. Basılmış ise yine çift buton basılmaihtimaline karşı sırası ile;
a) - butonuna basılmış mı bakılır basılmış ise (+ ve -) butonlarına basılmış ise ne yapılacak ise o yapılır.
b) - butonuna basılmamış ise bu seferde Start butonuna basılmış mı ona bakarız basılmış ise 1a ya göndeririz orada bunun cevabı mevcut.
c) start butonuna basılmanış ise yalnızca + butonuna basılınca ne yapılacak ise  onu yaptırırız.

3. Eksi butonuna basılmışmı bakarız. Basılmış ise
a) Artı butonuna basılmışmı bakarız. Basılmış ise 2a ya göndeririz
b) artıya basılmamış ise yalnızca eksiye basılınca ne yapılacak ise onu yaptırırız.

Aslında bu gibi durumları direk buton pinlerini gurup olarak okuyarak işem görmek en güzelidir.
Örneğin PORTB.0 - PORTB.1 - PORTB.2 de bağlı olan bu butonlarda DURUM=PORTB & %00000111 şeklinde alınır. Butonlar Pullup lı iseler  DURUM=7-(PORTB & %00000111) şeklinde okumak daha uygun olur ve ;
Durum=1 ise yalnızca PORTB.0 daki butona (diyelimki start)
DURUM=2 ise yalnızca PORTB.1 deki butona (diyelimki +)
DURUM=4 ise yanızca PORTB.2 deki butona (diyelimki oda - olsun)
DURUM=3 ise START ile + tuşuna aynı anda
DURUM=6 ise Eksi ile ARtı tuşlarına aynı anda basıldığını kolaylıkla anlayabilirsiniz.

Hepsi bu kadar.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Ziya

Butonların bağlı olduğu pinleri tek tek kontrol etmektense portu doğrudan okutup (buton basılma tespit edilmiş veya bir önceki değerden farklı değer okunmuş ise 200-300 ms gecikme ekleyin), maskeleme yaptıktan sonra, elde edilen bir baytlık değişkeni kontrol edin. Filtreleme sonrası örneğin 0x01 (tek buton), 0x02 (diğer buton), 0x03 (her ikisi birden basılı) gibi kontrolleri yapabilirsiniz.
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

neo

İki butona basma durumunda, butonlara basma sürelerinin farklı olması burada bi sorun çıkarmaz mı?

Diyelim ki kullanıcı önce start butonuna bastı (henüz bırakmadı), sonra program start butonuna basılma durumuna dallandı. Kullanıcı daha sonra artı butonuna bassa bile program bunu görmez.

Hangi butona/butonlara basıldığı kontrolünü, elimizi butondan çektiğimiz anda yaptırsak diye düşünüyorum. Bu sefer de iş çok uzayacak. Hangi butondan elimizi çektik, başka bir butona basılı mı, vs vs...
Have you ever questioned the nature of your reality?