Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.

czwartek, 3 marca 2011

Klawiatura na ADC + kalkulator drabinki


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:

Dzielnik rezystorowy.


Wzorem rządzącym dzielnikiem jest:

Dzielnik rezystorowy - wzór.
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:

Dzielnik rezystorowy - wzór przekształcony, dla obliczenia rezystora górnego.
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).

Schemat klawiatury na przetworniku ADC podłączonej do przykładowego mikrokontrolera ATmega8.
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-S2R-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:

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)

Rezystory wybieraj z szeregu (tolerancja %)
Napięcie VccV
Rezystor dolnyΩ
Ilość przyciskówszt

Wynik obliczeń:

Ustaw parametry i kliknij przycisk Oblicz.


Jak posługiwać się tabelką z wynikami obliczeń?

Opis według numeracji kolumn:
  1. Zawiera oznaczenia przycisków zgodne ze schematem powyżej. Jest ich tyle ile zażądałeś, lecz nie więcej niż 50.
  2. 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ść.
  3. 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.
  4. 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.
  5. 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 :-)
  6. 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:

Klawiatura na przetworniku ADC - układ testowy z wyświetlaczem 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.

Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

11 komentarzy:

  1. 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.

    Działało bardzo fajnie i nie miałem z tym żadnych problemów.

    OdpowiedzUsuń
  2. 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.

    Wersja 2x3

    To na górze, to substytut licznika i demultipleksera.

    OdpowiedzUsuń
  3. 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:
    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

    OdpowiedzUsuń
  4. 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ń
  5. 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ń
    Odpowiedzi
    1. 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).
      Pozdrawiam, Grzesiek

      Usuń
    2. 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.

      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.

      Usuń
    3. 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ń
    4. Żeby była jasność dla czytelników piszesz o przypadku jednoczesnego wciskania przycisków i wtedy schemat musi być taki jak napisałeś.

      Usuń
    5. Jak mogłoby to wyglądać dla np. 4 przycisków?

      Usuń
  6. 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.
    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

    OdpowiedzUsuń

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.