En etkili buton okuma yöntemi?

Başlatan Ramiz, 21 Aralık 2013, 19:26:11

bocek

#15
4 pin ile 65 tuşu kontrol ediyor (isis simulasyonu var)

kullanılabilir değil ama ilginç olduğu için ekledim:

4-65key.zip indir

bu da benim ourdev.cn sitesinden uyarladığım etkili ve kullanışlı bir algoritma (isis simulasyonu var)
http://www.upload.gen.tr/d.php/www/y1KE0/scan_button.zip.html

bazı tuşlar çalışmıyor çünkü programlanmamış. istenirse onlar da eklenebilir.
main.c dosyası
#include <avr/io.h>
#include <util/delay.h>
//#include "macros.h"

#define DELAY(x) for(int _delayint_=0;_delayint_<x;_delayint_++) _delay_ms(1);


#define KEY_0 0x01 // 1
#define KEY_1 0x02 // 2
#define KEY_2 0x04 // 4
#define KEY_3 0x08 // 8
#define KEY_4 0x10 // 16
#define KEY_5 0x20 // 32
#define KEY_6 0x40 // 64
#define KEY_7 0x80 // 128

#define BUTTON_PORT PORTB
#define BUTTON_PIN  PINB
#define BUTTON_DDR  DDRB

#define BT0 PB0
#define BT1 PB1
#define BT2 PB2
#define BT3 PB3
#define BT4 PB6

unsigned char Trg,Cont,Mask,Release;

//#################################################################
void SayiYaz(char satir, char sutun, unsigned char sayi)
{
   LCD_write_char(satir,sutun,sayi/100+48);
   LCD_write_char(satir,sutun+1,(sayi%100)/10+48);
   LCD_write_char(satir,sutun+2,sayi%10+48);
}
//#########################################################
void sys_init(void)
{
	// buton pinleri giriş olarak ayarlanıyor.
	BUTTON_DDR  &= (0 << BT0) | (0 << BT1) | (0 << BT2) | (0 << BT3) | (0 << BT4);
	// giriş pinleri için pull-up dirençler aktif.
	BUTTON_PORT |= (1 << BT0) | (1 << BT1) | (1 << BT2) | (1 << BT3) | (1 << BT4);
	// diğer pinlerle karışmasın diye maskeleme yapılıyor
	// maskeleme için buton pinleri 1 yapılıyor.
	Mask = (1 << BT0) | (1 << BT1) | (1 << BT2) | (1 << BT3) | (1 << BT4);
	LCD_init();  // lcd ayarlanıyor
}

//#################################################################
void KeyRead(void)
{ 
	unsigned char ReadData = BUTTON_PIN^Mask;	// 1) tuşlar okunuyor
	Trg  = ReadData & (ReadData^Cont); 			// 2) basılan tuş(lar) kaydediliyor
	Release = (ReadData ^ Trg ^ Cont); 			// 3) bırakılan tuş(lar) kaydediliyor
	Cont = ReadData;                   			// 4) basılı tuş(lar) kaydediliyor
   // herhangi bir tuşa basılmazsa Trg = Release = Cont = 0 oluyor.
   // birden fazla tuşa basılırsa basılı tuşlar Cont değişkenine ekleniyor.
   // örneğin : 0, 2 ve 4'e aynı anda basılırsa:
   // Cont = 1 + 4 + 16 = 21 oluyor.
}
void KeyProc(void)
{
		if(Trg)
		{
			SayiYaz(1,0,Trg);
			LCD_write_string(1,5,"basildi  ");
		}
		if(Release)
		{
			SayiYaz(1,0,Release);
			LCD_write_string(1,5,"birakildi");
        }
		if(Cont)
		{
			LCD_write_string(2,0,"Cont=");
			SayiYaz(2,6,Cont);
		}
}

//################################# Main function #################################
int  main()
{
	sys_init();
	while(1)
	{
		KeyRead();
		KeyProc();
	}
	return 0;
}
1 ya da 0. işte 'bit'ün mesele..

Andromeda

Buton okumaya parazite karşı gecikme koysak 65 tuş için süre çok uzamaz mı?
Değişik bir algoritma mı var..
" Tanrı, iradesini hakim kılmak için yeryüzündeki iyi insanları kullanır, yeryüzündeki kötü insanlar ise kendi iradelerini hakim kılmak için Tanrı'yı kullanırlar." ..." Tanrı'dan mesaj gelmiyor, biz Tanrı'ya mesaj gönderiyoruz"

Ramiz

Alıntı yapılan: bocek - 22 Aralık 2013, 08:46:49
4 pin ile 65 tuşu kontrol ediyor (isis simulasyonu var)

kullanılabilir değil ama ilginç olduğu için ekledim:

4-65key.zip indir

bu da benim ourdev.cn sitesinden uyarladığım etkili ve kullanışlı bir algoritma (isis simulasyonu var)
http://www.upload.gen.tr/d.php/www/y1KE0/scan_button.zip.html

bazı tuşlar çalışmıyor çünkü programlanmamış. istenirse onlar da eklenebilir.
main.c dosyası
#include <avr/io.h>
#include <util/delay.h>
//#include "macros.h"

#define DELAY(x) for(int _delayint_=0;_delayint_<x;_delayint_++) _delay_ms(1);


#define KEY_0 0x01 // 1
#define KEY_1 0x02 // 2
#define KEY_2 0x04 // 4
#define KEY_3 0x08 // 8
#define KEY_4 0x10 // 16
#define KEY_5 0x20 // 32
#define KEY_6 0x40 // 64
#define KEY_7 0x80 // 128

#define BUTTON_PORT PORTB
#define BUTTON_PIN  PINB
#define BUTTON_DDR  DDRB

#define BT0 PB0
#define BT1 PB1
#define BT2 PB2
#define BT3 PB3
#define BT4 PB6

unsigned char Trg,Cont,Mask,Release;

//#################################################################
void SayiYaz(char satir, char sutun, unsigned char sayi)
{
   LCD_write_char(satir,sutun,sayi/100+48);
   LCD_write_char(satir,sutun+1,(sayi%100)/10+48);
   LCD_write_char(satir,sutun+2,sayi%10+48);
}
//#########################################################
void sys_init(void)
{
	// buton pinleri giriş olarak ayarlanıyor.
	BUTTON_DDR  &= (0 << BT0) | (0 << BT1) | (0 << BT2) | (0 << BT3) | (0 << BT4);
	// giriş pinleri için pull-up dirençler aktif.
	BUTTON_PORT |= (1 << BT0) | (1 << BT1) | (1 << BT2) | (1 << BT3) | (1 << BT4);
	// diğer pinlerle karışmasın diye maskeleme yapılıyor
	// maskeleme için buton pinleri 1 yapılıyor.
	Mask = (1 << BT0) | (1 << BT1) | (1 << BT2) | (1 << BT3) | (1 << BT4);
	LCD_init();  // lcd ayarlanıyor
}

//#################################################################
void KeyRead(void)
{ 
	unsigned char ReadData = BUTTON_PIN^Mask;	// 1) tuşlar okunuyor
	Trg  = ReadData & (ReadData^Cont); 			// 2) basılan tuş(lar) kaydediliyor
	Release = (ReadData ^ Trg ^ Cont); 			// 3) bırakılan tuş(lar) kaydediliyor
	Cont = ReadData;                   			// 4) basılı tuş(lar) kaydediliyor
   // herhangi bir tuşa basılmazsa Trg = Release = Cont = 0 oluyor.
   // birden fazla tuşa basılırsa basılı tuşlar Cont değişkenine ekleniyor.
   // örneğin : 0, 2 ve 4'e aynı anda basılırsa:
   // Cont = 1 + 4 + 16 = 21 oluyor.
}
void KeyProc(void)
{
		if(Trg)
		{
			SayiYaz(1,0,Trg);
			LCD_write_string(1,5,"basildi  ");
		}
		if(Release)
		{
			SayiYaz(1,0,Release);
			LCD_write_string(1,5,"birakildi");
        }
		if(Cont)
		{
			LCD_write_string(2,0,"Cont=");
			SayiYaz(2,6,Cont);
		}
}

//################################# Main function #################################
int  main()
{
	sys_init();
	while(1)
	{
		KeyRead();
		KeyProc();
	}
	return 0;
}




Merhaba vaktim dar olduğundan(yarın sınavım var) yazılımı detaylı olarak inceleyemedim ve bu yüzdende butoların nasıl okunduğunu tam olarak kavrayamadım. Fakat şemanız çok karışık duruyor. Onun yerine size tavsiyem, microchip in 16 bit io expander ini kullanmanız. 8 adet chip i aynı tel üzerine bağlarsınız. 8*16=128 adet butonu 2 tel ile okursunuz. 256 butonuda 4 tel ile okursunuz :)

Benim şimdilik 8 buton bile gerekli değil ve ayrıca, bu konuyu açmak için iki sebebim vardı.

1.si Bizler yazılımsal kafa ile çalışan delileriz :) Bizim için bir butonun kullanışlı olup olmaması önemli değildir. Nasıl basılınca algıladığını anlar, ona göre kullanırız o aleti(mesela basılı tutunca sürekli algılıyor, basıp bırakmak gerekiyor, hızlı hızlı basınca algılıyor, algılamıyor vs gibi)

Ama bizim gibi deli :) olmayan insanlar için(sıradan insanlar) butonların çok önemli olduğuna inanıyorum. Çünkü onlar ne mantıkla çalıştığını bilmez yada tahmin edemezler. Bu yüzden yaptığınız cihazları kötülerler. Siz mükemmel bir üründe tasarlasanız, bir butonu yüzünden onu lekeleyebilirler. O yüzden kullanıcı ile iletişim sağlayan her birim benim için çok önemli!!

2.si Buton sayısına göre en uygun donanımı ve yazılım algoritmasını geliştirmek. Buton kullanımı analog elektronikte başlar. Dijital elektronik öğrenildiğinde önem arz eder. Mcu öğrendiğinizde ise ilk yaptığınız uygulamalardan birisi olur ama işler bu kadar basit değil aslında. Birinci maddede dediğim gibi ürünler kusursuz olmalıdır. O mükemmeliyeti, bir adet basıldığında geç algılayan buton bitirir.


Herkesin basit gördüğü ama aslında çok önemli olan bir konuya değindiğime inanıyorum. Daha çok yazılım algoritmalarına ihtiyacımız var. Mesela eski model cep telefonlarındaki bir tuş a hızlıca basarak 2-a-b-c gibi karakter oluşturmak için en iyi algoritmayı bulalım.

Örnek:

Electrical & Electronics Engineering -> Step one

MCansız

konudan farklı ama bu nokia nın telefonlarında kullanılan mikrodenetleyici modeli nedir birde bunlarda rtos mu kullandılar bu detefonların iç yapısını merak ediyorum

bocek

4 butonla 65 tuş okumak zaten yeterince deli işi değil mi?
Onu sadece örnek olsun diye verdim.
Yardımcı çip kullanarak tuş okumanın milyon tane yolu vardır herhalde, o ayrı ama burda değişik algoritmaları tartışalım diye de ikinci örneği verdim. O örnekte de tuş okuma algoritmasının özü şurda:

//#################################################################
void KeyRead(void)
{ 
    unsigned char ReadData = BUTTON_PIN^Mask;	// 1) tuşlar okunuyor
    Trg  = ReadData & (ReadData^Cont); 			// 2) basılan tuş(lar) kaydediliyor
    Release = (ReadData ^ Trg ^ Cont); 			// 3) bırakılan tuş(lar) kaydediliyor
    Cont = ReadData;                   			// 4) basılı tuş(lar) kaydediliyor
   // herhangi bir tuşa basılmazsa Trg = Release = Cont = 0 oluyor.
   // birden fazla tuşa basılırsa basılı tuşlar Cont değişkenine ekleniyor.
   // örneğin : 0, 2 ve 4'e aynı anda basılırsa:
   // Cont = 1 + 4 + 16 = 21 oluyor.
}

Bura da Trg değişkeni basılan tuşu, Release önceden basılı olup ta bırakılan tuşu, Cont değişkeni de o anda basılı konumda olan tuşları saklıyor.
Program atmel için yazıldı pic'e nasıl uyarlanır bilmiyorum ama burada BUTTON_PIN aslında PINB oluyor yani AVR mcu'larda portun değerini okumak için kullanılan register.
1 ya da 0. işte 'bit'ün mesele..

haydarpasamikro

Bir de 74hc922 var. Tamamen lojik. Tuş süresi ve aralığı harici kondansatörleri ile ayarlıyor. İş yükünü hafifletir. Ancak tedariki sıkıntı olabilir.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

Ramiz

Alıntı yapılan: bocek - 22 Aralık 2013, 17:31:19
4 butonla 65 tuş okumak zaten yeterince deli işi değil mi?
Onu sadece örnek olsun diye verdim.
Yardımcı çip kullanarak tuş okumanın milyon tane yolu vardır herhalde, o ayrı ama burda değişik algoritmaları tartışalım diye de ikinci örneği verdim. O örnekte de tuş okuma algoritmasının özü şurda:

//#################################################################
void KeyRead(void)
{ 
    unsigned char ReadData = BUTTON_PIN^Mask;	// 1) tuşlar okunuyor
    Trg  = ReadData & (ReadData^Cont); 			// 2) basılan tuş(lar) kaydediliyor
    Release = (ReadData ^ Trg ^ Cont); 			// 3) bırakılan tuş(lar) kaydediliyor
    Cont = ReadData;                   			// 4) basılı tuş(lar) kaydediliyor
   // herhangi bir tuşa basılmazsa Trg = Release = Cont = 0 oluyor.
   // birden fazla tuşa basılırsa basılı tuşlar Cont değişkenine ekleniyor.
   // örneğin : 0, 2 ve 4'e aynı anda basılırsa:
   // Cont = 1 + 4 + 16 = 21 oluyor.
}

Bura da Trg değişkeni basılan tuşu, Release önceden basılı olup ta bırakılan tuşu, Cont değişkeni de o anda basılı konumda olan tuşları saklıyor.
Program atmel için yazıldı pic'e nasıl uyarlanır bilmiyorum ama burada BUTTON_PIN aslında PINB oluyor yani AVR mcu'larda portun değerini okumak için kullanılan register.

Sınavlardan sonra kodlarınızı inceleyeceğim.

Alıntı yapılan: haydarpasamikro - 22 Aralık 2013, 20:35:23
Bir de 74hc922 var. Tamamen lojik. Tuş süresi ve aralığı harici kondansatörleri ile ayarlıyor. İş yükünü hafifletir. Ancak tedariki sıkıntı olabilir.

http://www.ebay.ph/itm/MM74HC922N-74HC922-interfaccia-tastiera-4x4-DIP-/170588122461

:) ayrıca çok pahalı bir çözüm..
Electrical & Electronics Engineering -> Step one

Gökhan BEKEN

Önemli ve çok butonlu projeler için, klavyenin(butonların) modüler olmasından yanayım, bilgisayar ile klavye iletişimini düşünelim. Bilgisayar klavyeye tarama mı yapıyor sizce?
Bilgisayar karışmaz öyle işlere, klavye birşekilde halleder ve bilgisayara ascii kod gönderir. Bilgisayarın işi hafiflemiş olur böylece.
MCU dediğimiz nane bilgisayarlardan kat kat düşük kapasite ve hızda olduğu için modüler yapmak en garantilisi.
Modül kısmı için giriş çıkışı bol olan bir MCU veya logic chipler kullanılabilir, projeye göre düşünülür.
(Tabiki, bir kaç buton için konuşmuyorum)
Özel mesaj okumuyorum, lütfen göndermeyin.

Ramiz

Alıntı yapılan: meftun - 22 Aralık 2013, 21:32:31
Önemli ve çok butonlu projeler için, klavyenin(butonların) modüler olmasından yanayım, bilgisayar ile klavye iletişimini düşünelim. Bilgisayar klavyeye tarama mı yapıyor sizce?
Bilgisayar karışmaz öyle işlere, klavye birşekilde halleder ve bilgisayara ascii kod gönderir. Bilgisayarın işi hafiflemiş olur böylece.
MCU dediğimiz nane bilgisayarlardan kat kat düşük kapasite ve hızda olduğu için modüler yapmak en garantilisi.
Modül kısmı için giriş çıkışı bol olan bir MCU veya logic chipler kullanılabilir, projeye göre düşünülür.
(Tabiki, bir kaç buton için konuşmuyorum)

Tamam işte. Benim mcp ic de aynı işi görüyor. Butona basıldığında interrupt gönderiyor mcu ya. Mcuda butonları okuyor :)
Electrical & Electronics Engineering -> Step one