Autor: Dondu
W uzupełnieniu nadesłanych rozwiązań problemu braku pinów do zrealizowania zadania Klawiatura gdy mało pinów, pozwolę sobie na uporządkowanie przypadku klawiatury opartej o ADC (przetwornik analogowo-cyfrowy) wraz z drabinką rezystorowo-przyciskową.
Drabinka rezystorowo-przyciskowa.
Rozwiązanie z klawiaturą opartą o ADC wykorzystuje dzielnik rezystorowy:
Wzorem rządzącym dzielnikiem jest:
Wzór 1 - Dzielnik napięcia. |
W przypadku realizowania klawiatury na drabince rezystorowo-przyciskowej można podejść do tematu tak jak kol. twomoonsofmars w swoim rozwiązaniu, czyli zastosowanie jednakowych rezystorów. Zaletą jest właśnie to, że rezystory są jednakowe, ale odbywa się to kosztem nieliniowej zmiany napięcia.
O ile w przypadku kilku przycisków nie ma to większego znaczenia, o tyle w przypadku kilkunastu i więcej ma już kolosalne znaczenie, z powodu dochodzenia do ograniczeń ADC oraz dokładności rezystancji (tolerancji wykonania) tym bardziej, gdy temperatura rezystorów ulega zmianie.
Dlatego można zastosować inne podejście obliczając rezystory w taki sposób, by napięcia generowane przez przycisk i odpowiadający mu dzielnik rezystorowy (powstający z drabinki), były w miarę możliwości jak najbardziej liniowe.
W celu obliczenia wartości rezystorów posłużymy się wzorem dzielnika rezystorowego przekształconego do postaci:
Wzór 2 - Obliczanie wartości rezystora górnego w dzielniku napięcia. |
Schemat drabinki
Poniżej schemat drabinki rezystorowo-przyciskowej, wraz z podłączeniem do wejścia przetwornika ADC mikrokontrolera ATmega8A (wersja A ponieważ można ćwiczyć dla różnych napięć Vcc).
Rys. Schemat przykładu. |
Mamy więc 6 przycisków i odpowiadającą im drabinkę złożoną z 6 rezystorów plus rezystor dolny. Jeżeli żaden przycisk nie będzie naciśnięty, rezystor dolny zwiera wejście ADC do masy, co oznacza że odczyta on poziom bliski 0V. Naciśnięcie przycisku S1 spowoduje podanie napięcia Vcc i takie też odczyta ADC.
Naciśnięcie natomiast każdego innego przycisku spowoduje powstanie dzielnika rezystorowego i ustalenie jakiegoś napięcia na wejściu przetwornika ADC mikrokontrolera. Napięcie będzie zależne od tego jaki dzielnik powstanie:
Na rysunku powyżej możesz zauważyć jak różne dzielniki napięcia tworzą się w zależności, który przycisk przyciśniesz. Rezystor dolny (R2 we wzorze) jest zawsze ten sam. Rezystor górny (R1 we wzorze) składa się z jednego lub kilku rezystorów połączonych szeregowo. I tak dla przycisku S2 rezystor górny składa się z rezystora R-S2. W przypadku przycisku S4 rezystor górny składa się z sumy rezystorów R-S2, R-S3 oraz R-S4.
"Jakiegoś napięcia", czyli jakiego?
Takiego jak sobie założymy dobierając odpowiednio rezystory, które obliczymy za pomocą wzoru 2.
Przycisk S1 zawsze będzie dawał Vcc na wejście ADC, stąd pozostało nam do ustalenia jakie napięcia ma generować pozostałe 5 przycisków. Należy więc tak podzielić (za pomocą dzielnika rezystorowego - drabinki) napięcie Vcc , by zachować liniowość jego zmian na wejściu ADC.
Możesz to zrobić we własnym zakresie lub użyć przygotowanego przeze mnie kalkulatora. W ten sposób możesz sprawdzić poprawność obliczeń oraz szybko nauczyć się korzystać z kalkulatora.
Przykład:
Poniżej przykład wykresu napięć wyjściowych drabinki, obliczonych za pomocą poniższego kalkulatora dla rezystorów z szeregu E24 (tolerancja 5%), napięcia Vcc=5.00V, rezystora dolnego 1000Ω oraz 6 przycisków:
Jak widzisz tak obliczone rezystory pozwalają osiągnąć prawie idealnie liniową zmianę napięcia wyjściowego drabinki. Charakterystyka drabinki byłaby jeszcze bardziej zbliżona do idealnej, gdybyś zastosował rezystory z szeregu E96. Obliczenia możesz sprawdzić korzystając z kalkulatora, gdzie czekają przygotowane dane dla powyższego wykresu:
Kalkulator klawiatury na ADC
(dla liniowej charakterystyki drabinki rezystorowej)
(dla liniowej charakterystyki drabinki rezystorowej)
Wynik obliczeń:
Ustaw parametry i kliknij przycisk Oblicz.
Jak posługiwać się tabelką z wynikami obliczeń?
Opis według numeracji kolumn:
- Zawiera oznaczenia przycisków zgodne ze schematem powyżej. Jest ich tyle ile zażądałeś, lecz nie więcej niż 50.
- Zawiera napięcia "idealne", które chcemy osiągnąć na wyjściu dzielnika (podłączonego do wejścia ADC) w zależności, który przycisk naciśniesz. Napięcia te policzone są tak, aby zachować równomierne odstępy i liniowość.
- Zawiera wyliczone wartości rezystorów poszczególnych przycisków, z możliwie największą dokładnością ("idealne"), które pozwalają nam osiągnąć napięcia idealne (wyliczone w kolumnie 2. Niestety w większości przypadków takie rezystory nie są produkowane. Należy więc przyjąć zbliżone do nich z wybranego szeregu.
- Zawiera wartości rezystorów poszczególnych przycisków, które powinieneś użyć, by osiągnąć najbardziej zbliżony wynik do napięć idealnych wyliczonych w kolumnie 2. Rezystory wybrane są z rezystorów szeregu, który ustawiłeś w parametrach kalkulatora.
- Takie napięcia faktycznie otrzymasz po zastosowaniu rezystorów podanych w kolumnie nr 4. Zauważ, że napięcia te niewiele różnią się od napięć idealnych z kolumny 2. I o to chodziło :-)
- Kolumny 6, 7 i 8 zawierają wyniki pomiarów ADC (w zależności od zastosowanej rozdzielczości), które powinieneś otrzymać pod warunkiem, że całą drabinkę zbudujesz z rezystorów podanych w kolumnie 4. Na czerwonym tle podane są progi decyzji, o których przeczytasz w dalszej części niniejszego artykułu. Dane te ułatwią Ci napisanie programu wykrywającego poszczególne klawisze.
Algorytm identyfikacji i program
Skoro mamy już dopracowaną część dot. elektroniki, pora zabrać się za program. Na początek sprawdzimy jak zachowuje się nasza klawiatura i czy pomiary są zgodne z obliczeniami kalkulatora.
W tym celu dodamy wyświetlacz LCD:
I wykorzystamy poniższy program:
/* Klawiatura na ADC z drabinką rezystorów i przycisków. Program testujący pomiary ADC dla poszczególnych przycisków. Program przygotowany dla zegara mikrokontrolera: 1MHz z wykorzystaniem bibliotek LCD: http://radzio.dxp.pl/ */ #include <avr/io.h> #include <stdio.h> #include <util/delay.h> #include <avr/interrupt.h> #include "HD44780.h" char wynik[17]; //bufor LCD volatile unsigned char ADC_pomiar; //zmienna przechowująca ostatni wynik //pomiaru ADC //----- PRZERWANIE Z ADC ----------------------------------------- ISR(ADC_vect) { //obsługa przerwania po zakończeniu pomiaru ADC ADC_pomiar = ADCH; //zapamiętaj pomiar w zmiennej } //---- PROGRAM GŁÓWNY ----------------------------------------------- int main(void) { //===== LCD ====================== _delay_ms(50); //opóźnienie wymagane przez niektóre wyświetlacze. LCD_Initalize(); //inicjalizuj LCD //Napis startowy LCD_GoTo(0, 0); LCD_WriteText("Test klawiatury"); LCD_GoTo(0, 1); LCD_WriteText("na ADC."); _delay_ms(2000); LCD_Clear(); LCD_GoTo(0, 0); LCD_WriteText("ADC pomiar: "); //===== inicjalizacja ADC ====================== //napięcie referencyjne AVcc + zewnętrzny kondensator 100nF na Aref //kanał ADC0 na pinie PC0 (domyślny) //ADC w trybie Free Running Mode //preskaler 128, by przy 1MHz częstotliwość ADC była jak najmniejsza //co da nam czas trwania jednego pomiaru około 1,66ms //przerwanie po skończeniu pomiaru //wynik wyrównaj do lewej, ponieważ będziemy korzystać tylko //z 8 najstarszych bitów #define VREF 5.0 //napięcie referencyjne ADC 5V ADMUX = (1<<REFS0) //napięcie odniesienia z AVcc + kondensator na AREF | (1<<ADLAR); //wynik wyrównaj do lewej ADCSRA = (1<<ADEN) //ADEN=1 włączenie przetwornika ADC) | (1<<ADSC) //start pierwszego pomiaru | (1<<ADFR) //włącz Free Running Mode | (1<<ADIE) //włącz przerwania z ADC | (1<<ADPS0) //ustawienie preskalera na 128 | (1<<ADPS1) | (1<<ADPS2); sei(); //włącz przerwania globalne while(1){ //pętla główna LCD_GoTo(0, 1); sprintf(wynik,"%d ", ADC_pomiar); //konwersja na łańcuch znakowy LCD_WriteText(wynik); //Wyświetlenie pomiaru LCD_GoTo(6, 1); sprintf(wynik,"%.2fV", ADC_pomiar * VREF/255); //konwersja napięcia LCD_WriteText(wynik); //Wyświetlenie napięcia _delay_ms(250); //opóźnienie } }
Pliki źródłowe + projekt (AVR Studio 4) + plik HEX (dla1MHz): TEST-KLAW-ADC-1.zip
Efekt działania programu:
Jak widzisz wyliczona kalkulatorem drabinka rezystorów, prawidłowo odczytywana jest przez mikrokontroler. Wyniki są zgodne z obliczeniami pomimo, że faktycznie zastosowane przeze mnie niektóre rezystory drabinki są złożone z dwóch mniejszych ponieważ nie miałem pod ręką rezystorów w wersji THT, dokładnie takich jak wyliczone przez kalkulator. Drabinka nie jest więc idealnie taka jak wyliczona, ale wyniki i tak są prawie idealne :-)
Identyfikowanie przycisków na podstawie pomiaru ADC
Teraz zajmiemy się programem, który wykorzysta pomiary do zidentyfikowania naciśniętego przycisku. Program ten można napisać na "tysiąc sposobów". Ja pokażę najprostsze, by łatwo można było je zrozumieć.
Obliczyliśmy i sprawdziliśmy wartości zmierzone przez ADC dla poszczególnych klawiszy. Ale sprawdzanie wystąpienia dokładnie tych wartości, nie jest dobrym sposobem na identyfikowanie konkretnego przycisku.
Dlaczego? Ponieważ pomiary ADC + tolerancja rezystorów + zmiana temperatury, mogą powodować, nieznaczne "pływanie" wyników pomiarów. Dlatego należy ustalić pewne zakresy dla każdego przycisku. Zrobił tak kol. twomoonsofmars w swoim rozwiązaniu.
Ja jednak proponuję inne podejście do tego problemu, znacznie ułatwiające pisanie programu, bardziej przejrzyste i co najważniejsze bardziej uniwersalne.
Ustalamy wartości pomiarów ADC w środku pomiędzy stanami odpowiadającymi dwóm sąsiednim przyciskom, czyli tzw. progi decyzji.
Przykład:
Dla przycisków S1 i S2 według kalkulatora (dla rozdzielczości 8 bitów) mamy odpowiednio 255 i 213.
Obliczamy różnicę:
255 - 213 = 42
Bierzemy połowę tej liczby:
42 / 2 = 21
i odejmujemy od 255:
255 - 21 = 234
Otrzymaliśmy zatem próg decyzji, powyżej którego uznawać będziemy, że wciśnięty jest przycisk S1.
Takie obliczenia powinieneś wykonać dla wszystkich przedziałów, w tym także pomiędzy ostatnim przyciskiem, a masą (0V). Na szczęście nie musisz tego robić ręcznie ponieważ powyższy kalkulator robi to za Ciebie :-)
Algortym 1:
Najprostszym i najdokładniejszym jest poniższy algorytm, bazujący na wyliczonych progach podejmowania decyzji:
//Wyznaczamy środki przedziałów wskazań ADC (progi) i sprawdzamy jedynie, //czy aktualny pomiar jest większy do danego środka przedziału if (ADC_pomiar > 234 ) przy_stan = PRZY_S1; //naciśnięty S1 else if(ADC_pomiar > 191 ) przy_stan = PRZY_S2; //naciśnięty S2 else if(ADC_pomiar > 148 ) przy_stan = PRZY_S3; //naciśnięty S3 else if(ADC_pomiar > 107 ) przy_stan = PRZY_S4; //naciśnięty S4 else if(ADC_pomiar > 66 ) przy_stan = PRZY_S5; //naciśnięty S5 else if(ADC_pomiar > 22 ) przy_stan = PRZY_S6; //naciśnięty S6 else przy_stan = PRZY_ZADEN; //żaden przycisk nie jest naciśnięty
Algorytm 2:
Drugi algorytm także bazuje na progach, ale realizowany jest poprzez wzór matematyczny liczący numer przycisku. Można sobie na to pozwolić ponieważ kalkulator policzył rezystory drabinki w taki sposób, by napięcie zmieniało się liniowo w równych odstępach:
przy_stan = (char) (((( (ADC_pomiar-21) * 10 ) / 42) + 9 ) / 10);
gdzie:
ADC_pomiar - wynik pomiaru ADC,
42 - przedział pomiędzy pomiarami ADC sąsiednich przycisków,
21 - połowa przedziału pomiędzy pomiarami ADC sąsiednich przycisków,
10 - mnożnik i dzielnik w celu uniknięcia operacji na liczbach zmiennoprzecinkowych,
9 - wykorzystane do prawidłowego zaokrąglania liczb pomnożonych przez 10 i dzielonych przez 42.
Algorytm ten numeruje klawisze w odwrotnej kolejności w stosunku do algorytmu 1.
Specjalnie zastosowałem dużą ilość nawiasów, by łatwiej było zrozumieć działanie wzoru.
Algorytm 2 podaję jako ciekawostkę, a sugeruję wykorzystywanie algorytmu 1.
Drgania styków.
Czy w przypadku tak zbudowanej klawiatury na ADC, istnieje problem drgań styków? Oczywiście!
Dlatego na koniec niniejszego artykułu, kompletny program wraz z rozpoznawaniem naciśniętego przycisku oraz eliminacją drgań styków. W programie znajdziesz dokładny opis wraz z dwiema wersjami miejsca, w którym algorytm rozpoznawania przycisku i eliminacji drgań może być umieszczony.
/* Klawiatura na ADC z drabinką rezystorów i przycisków oraz eliminacją drgań styków. 2012 Dondu http://mikrokontrolery.blogspot.com */ #include <avr/io.h> #include <stdio.h> #include <util/delay.h> #include <avr/interrupt.h> #include "HD44780.h" char wynik[17]; //bufor LCD volatile unsigned char przy_stan; //zmienna przechowująca stan przycisku //po eliminacji drgań styków volatile unsigned char ADC_pomiar; //aktualny pomiar ADC volatile unsigned char flaga_klaw; //flaga żądania analizy klawiatury #define PRZY_ZADEN 0 #define PRZY_S1 1 #define PRZY_S2 2 #define PRZY_S3 3 #define PRZY_S4 4 #define PRZY_S5 5 #define PRZY_S6 6 //------------------------------------------------------ void sprawdz_klawiature(void){ #define ILOSC_POMIAROW 10 //zmienne lokalne static unsigned char licznik_stabilnosci; //licznik stabilności styków static unsigned char stan_poprzedni; //stan poprzedni klawiatury static unsigned char stan_aktualny; //stan aktualny klawiatury static unsigned char zliczaj; //zgaś flagę żądania sprawdzenia klawiatury flaga_klaw = 0; //ustalamy, który przycisk jest naciśnięty, porównując pomiar //z progami decyzji obliczonymi przez kalkulator na blogu if (ADC_pomiar > 234 ) stan_aktualny = PRZY_S1; //naciśnięty S1 else if(ADC_pomiar > 191 ) stan_aktualny = PRZY_S2; //naciśnięty S2 else if(ADC_pomiar > 148 ) stan_aktualny = PRZY_S3; //naciśnięty S3 else if(ADC_pomiar > 107 ) stan_aktualny = PRZY_S4; //naciśnięty S4 else if(ADC_pomiar > 66 ) stan_aktualny = PRZY_S5; //naciśnięty S5 else if(ADC_pomiar > 22 ) stan_aktualny = PRZY_S6; //naciśnięty S6 else stan_aktualny = PRZY_ZADEN; //żaden przycisk nie jest naciśnięty //Eliminacja drgań styków if(stan_poprzedni != stan_aktualny){ //stan klawiatury inny niż poprzednim razem licznik_stabilnosci = 0; //zeruj licznik zliczaj = 1; //włącz zliczanie stan_poprzedni = stan_aktualny; //zapamiętaj aktualny stan }else{ //stan klawiatury taki sam jak poprzednim razem //czyli: stan_poprzedni = stan_aktualny //czy mamy zliczać czas trwania aktualnego stanu klawiatury? if(zliczaj){ //tak zliczamy czas i sprawdzamy, czy przez wymagany czas //stan przycisku jest stabilny licznik_stabilnosci++; //zwiększ licznik stabilności //czy osiągnął już wymagany czas stabilności styków? if(licznik_stabilnosci > ILOSC_POMIAROW){ //tak, stabilny stan przycisku został potwierdzony przy_stan = stan_aktualny; //zapisz do zmiennej globalnej zliczaj = 0; //wyłącz zliczanie } } } } //------------------------------------------------------ //obsługa przerwania po zakończeniu pomiaru ADC ISR(ADC_vect) { //odczytaj pomiar z ADC ADC_pomiar = ADCH; //W e r s j a 1 //Jeżeli dla twojego przypadku, nie ma przeciw wskazań, to możesz wywołać //sprawdzanie klawiatury bezpośrednio w przerwaniu //wtedy flaga_klaw jest niepotrzebna //sprawdz_klawiature(); //W e r s j a 2 //Jeżeli chesz, by przerwanie wykonywało się jak najszybciej, //zamiast wywoływania tutaj funkcji sprawdzenia klawiatury, //ustawiamy flagę żądającą jej sprawdzenia np. w main() //więcej na ten temat znajdziesz pod tym linkiem: //http://mikrokontrolery.blogspot.com/2011/04/problemy-c-volatile.html flaga_klaw = 1; } //------------------------------------------------------ int main(void) { //===== LCD ====================== _delay_ms(50); //opóźnienie wymagane przez niektóre wyświetlacze. LCD_Initalize(); //inicjalizuj LCD //Napis startowy LCD_GoTo(0, 0); LCD_WriteText("Test klawiatury"); LCD_GoTo(0, 1); LCD_WriteText("na ADC."); _delay_ms(2000); LCD_Clear(); LCD_GoTo(0, 0); LCD_WriteText("Przycisk: "); //===== inicjalizacja ADC ====================== //napięcie referencyjne AVcc + zewnętrzny kondensator 100nF na Aref //kanał ADC0 na pinie PC0 (domyślny) //ADC w trybie Free Running Mode //preskaler 128, by przy 1MHz częstotliwość ADC była jak najmniejsza //co da nam czas trwania jednego pomiaru około 1,66ms //przerwanie po skończeniu pomiaru //wynik wyrównaj do lewej bo będziemy korzystać tylko //z 8 najstarszych bitów ADMUX = (1<<REFS0) //napięcie odniesienia z AVcc + kondensator na AREF | (1<<ADLAR); //wynik wyrównaj do lewej ADCSRA = (1<<ADEN) //ADEN=1 włączenie przetwornika ADC) | (1<<ADSC) //start pierwszego pomiaru | (1<<ADFR) //Free Running Mode | (1<<ADIE) //włącz przerwania z ADC | (1<<ADPS0) //ustawienie preskalera na 128 | (1<<ADPS1) | (1<<ADPS2); sei(); //włącz przerwania globalne while(1){ //pętla główna // ... tutaj Twój program główny //aktualny stan klawiszy po eliminacji drgań styków jest przechowywany // w zmiennej globalnej: przy_stan //możesz usunąć wywołanie funkcji sprawdz_klawiature() z funkcji //obsługi przerwania zastępując ją flagą żądania sprawdzenia //klawiatury: flaga_klaw //Natomiast w main() sprawdzać flagę i wywołać funkcję, gdy żądano. //czytaj opis w funkcji ISR() if(flaga_klaw) sprawdz_klawiature(); //sprawdź klawiaturę gdy żądano //wyświetla testowe napisy pokazujące, który klawisz jest naciśnięty LCD_GoTo(10, 0); if(przy_stan){ sprintf(wynik,"S%d ", przy_stan ); //konwersja na łańcuch LCD_WriteText(wynik); //Wyświetlenie przycisku }else{ LCD_WriteText("zaden"); } } }
Pliki źródłowe + projekt (AVR Studio 4) + plik HEX (dla 1MHz): TEST-KLAW-ADC-2.zip
Uwagi praktyczne
Parę uwag praktycznych:
- Im więcej przycisków planujesz użyć, tym dokładniejsze rezystory powinieneś zastosować, czyli wybrać szeregi o większych numerach (mniejszej tolerancji). W takim przypadku powinieneś szczególnie zadbać o aspekty dot. dokładności pomiarów za pomocą ADC.
- Ponieważ rezystory mają swoją tolerancję, faktycznie osiągniesz wyniki nieco inne niż obliczone.
- Nie buduj drabinki "na styk" (czyli nie stosuj zbyt dużej ilości przycisków), ponieważ np. zmiana temperatury, może zmienić właściwości rezystorów, a w konsekwencji dzielnika napięcia i spowodować nieprawidłowe przypisywanie naciśniętych przycisków.
- W powyższych przykładach programów, ADC działa w trybie Free Running, czyli automatyczny start nowego pomiaru zaraz po zakończeniu poprzedniego. Ale wcale tak nie musi być. Można użyć jakiś timer, który będzie odliczał czas np. co 10ms i w przerwaniu uruchamiał pomiar ADC. Reszta już jak w programie powyżej.
- Eliminację drgań styków można zrobić za pomocą kondensatora podłączonego pomiędzy wyjście drabinki, a GND (masę). Należy jednak uważać, by nie przesadzić z wielkością kondensatora ponieważ razem z rezystorami drabinki dla każdego przycisku tworzy się inny filtr RC, co może zakłócić działanie algorytmu. Ale zachęcam do prób :-)
- Wprawdzie kalkulator umożliwia liczenie drabinki do 50 przycisków, w praktyce odradzam, aż tak duże ilości przycisków.
Jeżeli zbudujesz własną klawiaturę i będziesz miał jakieś ciekawe spostrzeżenia, zachęcam do przedstawienia za pomocą komentarzy do niniejszego artykułu.
Kiedyś robiłem taką klawiaturę na ATtiny. Tam to było jedyne możliwe rozwiązanie, bo zależało mi na malutkim mikrokontrolerze, a musiałem mieć coś około 4 przycisków i 5 kontaktronów. Dobrałem drabinkę na oko, bo nie chciało mi się liczyć. Nie była więc liniowa, ale dałem radę. Przewody do kontaktronów na szczęście były krótkie.
OdpowiedzUsuńDziałało bardzo fajnie i nie miałem z tym żadnych problemów.
Warto wspomnieć o układach 7490 i 74154, wtedy za cenę dwóch dodatkowych pinów możemy zyskać 16 linii, a pod każdą możemy dać drabinkę. To daje 16x8=128 przycisków.
OdpowiedzUsuńWersja 2x3
To na górze, to substytut licznika i demultipleksera.
A odnośnie tabelki to bym ją zrobił inaczej. Autor proponuje (dla 4 V by było prościej) poziomy 4V, 2.65V i 1.33V. Ja proponuję to zrobić tak, by trafiać w środki przedziałów. A przedziały są 4:
OdpowiedzUsuń0-1 - tu mamy 0V czyli niewciśnięte,
1-2 - 1.5V
2-3 - 2.5V
3-4 - 3.5V.
Jak rozpoznać dziesiętnie wskazanie? Ano wystarczy zaokrąglić, np. 1.8657421 to na pewno 1.5V, bo to jest 1 z hakiem: przycisk nr 1.
A binarnie? Jak mamy 7 przycisków i 8 poziomów to po prostu jedna linijka C:
wynikADC >> 5
czyli:
xxxyyyyy| -> 00000xxx|(yyyyy)
przesunięcie bitowe, (yyyyy) znika!
no i mamy bajt z numerem przycisku
Pomysł fajny. A jak obsłużyć tym sposobem wciśnięcia kilku przycisków jednocześnie? Jest na to jakiś sprawdzony schemat i kalkulator?
OdpowiedzUsuńGdyby dokładnie policzyć wszystkie możliwe kombinacje, gdyby rezystory były idealne, gdyby nie zmieniały rezystancji wraz z temperaturą, to teoretycznie ... tylko teoretycznie :-)
OdpowiedzUsuńNie przesadzajmy z tym pesymizmem. Zmianę temperatury da się prosto skompensować, dobór rezystorów zastąpić 2 minutową procedurą kalibracyjną dla każdego pcb. Wystarczy również dodać multiplekser aby obsługiwać np. 16 przycisków, wykrywać naciśnięcie jednoczesne i uruchomić dosyć skomplikowany układ korzystając z najtańszego na rynku uC. A jak wiadomo cena czyni cuda (czasem).
UsuńPozdrawiam, Grzesiek
Dominik pisał o wykrywaniu przyciśnięcia kilku przycisków jednocześnie, więc kalibracja oczywiście jest wskazana i w pewnym stopniu pomoże, jednakże nawet dodatkowe zastosowanie rezystorów o mniejszej tolerancji mogą nie zapewnić należytej poprawności odczytu klawiatury w takim przypadku. Zależy to oczywiście od ilości przycisków w klawiaturze oraz ilości jednocześnie przyciśniętych.
UsuńCo do miltipleksera, to artykuł ten dotyczy cyklu "Klawiatura, gdy mało pinów ..." i pokazuje jak zrobić klawiaturę na jednym pinie, dlatego zastosowanie multipleksera odpada.
W praktyce da radę, ale należy zwrócić uwagę na fakt potrzeby przerobienia schematu (!) - w obecnej chwili wciśnięcie jakiejkolwiek kombinacji przycisków zaowocuje wykryciem tego, który jest niżej w drabince, bo tworzy on obejście rezystorów wszystkich wyższych przycisków. Do poprawnego działania układu należałoby dodać rezystory w pionie (na linii +VCC) dzięki czemu będzie się tworzyła kombinacja szeregowo-równoległa rezystorów. W tym przypadku bez żadnych zewnętrznych układów jest możliwość obsłużenia do 5 (bezpieczna wartość przy wykorzystaniu rezystorów z tolerancją 1%) przycisków i wszystkich ich kombinacji wciśnięcia.
UsuńŻeby była jasność dla czytelników piszesz o przypadku jednoczesnego wciskania przycisków i wtedy schemat musi być taki jak napisałeś.
UsuńJak mogłoby to wyglądać dla np. 4 przycisków?
UsuńOd jakiegoś czasu szukam rozwiązania, w którym naciśnięcie jednego z trzech przełączników chwilowych (typu dzwonkowego) zostanie odczytane przez jakiś układ (najchętniej na attiny13 z racji że mam ich kilka :) ), zaś na wyjściu pojawi się na stałe jedna z trzech wartości - oczywiście do czasu naciśnięcia innego przełącznika. Innymi słowy - np mam powyższy układ na 3 swiczach podający do attiny napięcie max - 1/2 - min, zaś na wyjściu attiny będę miał podawane to co pojawiło się na wejściu po naciśnięciu przycisku chwilowego.
OdpowiedzUsuńDrugą potrzebą jest by układ zapamiętywał stan po odłączeniu i ponownym załączeniu zasilania. Wiem że jest coś takiego jak elektroda (do której sam odsyłasz), jednak ostatnimi laty jej poziom - mówiąc delikatnie - bardzo się obniżył..
Czy byłbyś w stanie pomóc add programu, a jeśli tak - proszę o kontakt na rumcajsas@o2.pl. Nie ukrywam że miałbym jeszcze jeden temat do rozważenia, ale całość chyba nie jest odpowiednia by dyskutować w komentarzach na tej stronce :)
Pozdrawiam - Sławek
Ten komentarz został usunięty przez autora.
OdpowiedzUsuńWitam.
OdpowiedzUsuńKalkulator kilka razy już mi się przydał.
Szkoda, że teraz nie działa.
Konkretnie nie działa: http://dondu.elektroda.eu/_mikro_blog/blog/kalk/dd_kalk_drab_rez.php