/*
* İki tuşa arayüz geliştirmek için.
* Burada Inputlar arduino arduino pin 2 ve 3
* Inputlar tactile vb tuş ile GND'ye bağlanmalı.
* tuşa basma, bırakma uzun basma ve uzun sürekli basma fonksiyonları var
* ikili basma ve ıkıli uzun basmayı da destekliyor
*
*/
// Tuş ön tanımları
#define T_EKSI 0b01 //tusOku fonksiyonunda buton okuma maskesi
#define T_ARTI 0b10 //tusOku fonksiyonunda buton okuma maskesi
#define T_IKILI 0b00
#define T_NULL 0b11 //iki tuş da basılı değil
#define T_EKSI_BAS 0
#define T_EKSI_BIRAK 1
#define T_EKSI_UZUN 2
#define T_ARTI_BAS 3
#define T_ARTI_BIRAK 4
#define T_ARTI_UZUN 5
#define T_IKILI_BAS 6
#define T_IKILI_BIRAK 7
#define T_IKILI_UZUN 8
#define T_BOS 9
#define TUS_ARTI 2
#define TUS_EKSI 3
#define UZUN_BAS_SURE 100
// tuş kontrol değişkenleri
uint8_t t_1,t_sayac2,t_up,t_durum,tusOkunan,tus_sayac;
unsigned long z0,z1,z2;
void setup() {
Serial.begin(115200);
// tuşlar
pinMode(TUS_ARTI,INPUT_PULLUP);
pinMode(TUS_EKSI,INPUT_PULLUP);
}
void loop() {
if(millis()>z0+5)
{
z0=millis();
//debounce için 5 ila 10 ms'de bir çalışan bir döngünün içine yerleştirilir
tusOku();
}
// Buton komutları
if(t_up>0) // tuşa basıldığında yapılacaklar, kullanılmayacak
{
switch(tusOkunan)
{
case T_ARTI_BAS : Serial.println(F("ARTI BAS"));t_up=0;break;
case T_ARTI_BIRAK : Serial.println(F("ARTI BIRAK"));t_up=0;break;
case T_ARTI_UZUN : Serial.println(F("ARTI UZUN"));t_up=0;break;
case T_EKSI_BAS : Serial.println(F("EKSİ BAS"));t_up=0;break;
case T_EKSI_BIRAK : Serial.println(F("EKSİ BIRAK"));t_up=0;break;
case T_EKSI_UZUN : Serial.println(F("EKSİ UZUN"));t_up=0;break;
case T_IKILI_BAS : Serial.println(F("İKİLİ BAS"));t_up=0;break;
case T_IKILI_BIRAK : Serial.println(F("İKİLİ BIRAK"));t_up=0;break;
case T_IKILI_UZUN : Serial.println(F("İKİLİ UZUN"));t_up=0;break;
default: break;
}
}
}
uint8_t tusOku (void)
{
// tenp değişkenine anlıkbuton durumunu atama
byte temp=(digitalRead(TUS_ARTI)<<1 | digitalRead(TUS_EKSI));
// debounce için ardışık okuma aynı olduğunda çalışır
if(t_durum==temp)
{
switch (t_durum)
{
case T_ARTI:
if((tus_sayac==0)&&(tusOkunan==T_BOS))
{
t_up=1;
tusOkunan=T_ARTI_BAS;
tus_sayac++;
}
else if(tus_sayac<UZUN_BAS_SURE)tus_sayac++;
// Tuş zaten basılıyken
else if((tus_sayac==UZUN_BAS_SURE)&&((tusOkunan==T_ARTI_BAS)||(tusOkunan==T_ARTI_UZUN)))
{
t_up=1;
tusOkunan=T_ARTI_UZUN;
tus_sayac=0;
}
break;
case T_EKSI:
if((tus_sayac==0)&&(tusOkunan==T_BOS))
{
t_up=1;
tusOkunan=T_EKSI_BAS;
tus_sayac++;
}
else if(tus_sayac<UZUN_BAS_SURE)tus_sayac++;
else if((tus_sayac==UZUN_BAS_SURE)&&((tusOkunan==T_EKSI_BAS)||(tusOkunan==T_EKSI_UZUN)))
{
t_up=1;
tusOkunan=T_EKSI_UZUN;
tus_sayac=0;
}
break;
case T_IKILI:
// tuşlar T_IKILI_BAS durumusunda değilse çalışabilir
// tuşun biri önce basılı okunduysa da çalışır
// tuşlar debouce süresinden önce ikili okunduysa da çalışır
if((tusOkunan==T_BOS)||(tusOkunan==T_EKSI_BAS)||(tusOkunan==T_ARTI_BAS))
{
tus_sayac=0;
t_up=1;
tus_sayac++;
tusOkunan=T_IKILI_BAS;
}
else if(tus_sayac<UZUN_BAS_SURE)tus_sayac++;
else if((tus_sayac==UZUN_BAS_SURE)&&(tusOkunan==T_IKILI_BAS))
{
t_up=1;
tusOkunan=T_IKILI_UZUN;
tus_sayac=0;
}
break;
case T_NULL:
// tuş bırakma olayını yakalayıp tanımlar, hiçbir tuş basılı eğilken çalışır
// T_NULL (tuş basılı değil) okunduğunda tusOkunan değeri update edilmemiştir
// Bu döngü son basılı tuşa göre çalışıp hangi tuşun bırakıldığını belirler
// sonra da tusOkunan olayını atar
// Button durumu değişikliğini t_up bayrağını 1 yaparak işaretler
switch(tusOkunan)
{
case T_ARTI_BAS:
tusOkunan=T_ARTI_BIRAK;
t_up=1;
tus_sayac=0;break;
case T_EKSI_BAS:
tusOkunan=T_EKSI_BIRAK;
t_up=1;
tus_sayac=0;
break;
case T_IKILI_BAS:
tusOkunan=T_IKILI_BIRAK;
t_up=1;
tus_sayac=0;
break;
default :
tusOkunan=T_BOS;
t_up=0;
tus_sayac=0;
break;
}
}
}
t_durum=temp;
return tusOkunan;
}