czwartek, 14 kwietnia 2011

Przycisk - drgania styków - bouncing


Autor: Dondu

Każdy przycisk lub styki przekaźnika, kontaktronu, czy impulsatora stykowego (enkodera) mają tendencję do drgania w czasie zwierania i/lub rozwierania. Zjawisko to jest stricte mechaniczne i zwane jest drganiem styków (ang. Bouncing).

Zjawisko to trwa od 
 kilkudziesięciu mikrosekund do kilkudziesięciu milisekund, zarówno przy zwieraniu jak i rozwieraniu styków:

Rys. 2.3 - Drgania styków (źródło)

Rys. 2.3b - Drgania styków (źródło Wikipedia)


Na przykład przycisk firmy C&K ma podany w datasheet maksymalny czas drgań styków 20ms:



Link: datasheet


Jakie są typowe objawy drgań styków ? 
  • menu przeskakuje o kilka pozycji,
  • nastawiane liczby przeskakują losowo,
  • pomyłki kierunku obrotu i ilości impulsów w enkoderze (impulsatorze),
  • itp

Na poniższym filmiku autor demonstruje projekt, który nie jest zabezpieczony przed drganiami styków. Program powinien po naciśnięciu przycisku zmienić stan diody na przeciwny. Ale losowa ilość drgań styków, powoduje losowe zmiany stanu diody LED:





Każdy styk drga inaczej.

Styk stykowi nierówny więc i drgania bywają różne. Styki jakiegoś elementu tego samego producenta i typu (np. microswitch, czy kontaktron), ale pochodzące z dwóch różnych partii mnogą mieć różne właściwości, przez co różne okresy drgań.

Aby pokazać zjawisko wykonałem prosty test 14 różnych elementów stykowych wykorzystując mikrokontroler ATmega8 taktowany kwarcem 16MHz. Test polegał na zliczaniu drgań styków od momentu wykrycia pierwszego zbocza i zakończeniu po wystarczająco długim czasie, by uznać stan styków za stabilny.

Elementy stykowe były podłączane do wejścia T0 Timer0, co pozwoliło zliczać ilość drgań przy przełączaniu przycisków z maksymalną możliwą dla tego mikrokontrolera prędkością (zgodnie z: Jak mikrokontroler "widzi" sygnał cyfrowy?):




Zwróć uwagę na różnice w ilości drgań styków:
  • tych samych elementów stykowych pomiędzy kolejnymi próbami,
  • występujące pomiędzy poszczególnymi testowanymi elementami.


Z dokumentacji producenta przekaźników Relpol S.A w temacie drgań styków przekaźnika:

Źródło: Relpol S.A


Jak temu zaradzić?
  • sprzętowo - np. prosty filtr RC lub specjalne układy takie jak MAX6816, MAX6817 czy MAX6818,
  • programowo (kilkukrotne sprawdzenie, czy stan styków (przycisku, przekaźnika, itp) jest taki sam w ciągu np. 20 milisekund).

Technik pozbywania się tego problemu (ang. Debouncing) jest bardzo dużo i zależą od tego, jakie peryferia masz dostępne w swoim mikrokontrolerze. Budując swój projekt musisz zabezpieczyć się przed tym zjawiskiem.


Co zrobić, gdy nie znam parametru maksymalnego czasu drgań?

Jeżeli nie znasz parametru gwarantowanego maksymalnego czasu drgań styków danego elementu (brak dokumentacji lub producent nie podał w niej tej danej) powinieneś podejść do tego problemu od drugiej strony. Wystarczy przyjąć maksymalny możliwy czas reakcji (opóźnienia) jaki możesz dopuścić na stwierdzenie, że styki zostały rozwarte, czy też zwarte.

Przykład 1:

Jeśli mówimy o zwykłym przycisku (który będzie przyciskany palcem) wystarczy przyjąć, że nie będzie on mógł być wciśnięty częściej niż na przykład 8 razy na sekundę. Dlaczego 8 razy? Spróbuj pobić ten wynik :-)

Mamy więc 8 okresów złożonych ze stanów wysokich i niskich, czyli łącznie 16 kolejnych stanów styków. W związku z czym możemy przyjąć czas drgań równy 1/16 sekundy, czyli 62,5ms, co jeśli będziesz potrzebował możesz zaokrąglić w dół na przykład do 60ms.


Przykład 2:

Jakieś urządzenie załącza przekaźnik, którego styki podłączone są do wejścia mikrokontrolera. Przekaźnik włączany i wyłączany jest w dużych odstępach czasowych np. raz na 10 minut, a styki zwarte są przez sekundę. Reakcja mikrokontrolera nie może być spóźniona więcej niż 0,5 sekundy

Jaki maksymalny czas eliminacji drgań styków więc przyjąć?
Odpowiedź: Nieco krócej niż 0,5 sekundy.

Takie zasady postępowania dają pewność prawidłowej eliminacji drgań styków dla każdego przypadku jaki spotkasz na swojej drodze.


Zawsze jest jakieś ale:

Przykład 3:

Załóżmy że mamy przypadek enkodera (impulsatora) pokrętła głośności we wzmacniaczu audio. Pokręcenie nim z dużą prędkością kątową może spowodować, że styki nie zdążą się ustabilizować, gdy już muszą zmienić stan na przeciwny. Dochodzi wtedy do zjawiska nałożenia się drgań, co skutkuje brakiem możliwości prawidłowego rozpoznania poszczególnych faz obrotu enkodera. Na ten temat więcej znajdziesz w artykule: Impulsator stykowy

Jaki wtedy należy przyjmować maksymalny czas drgań styków?
Można lub należy przyjmować więc standardowy jak w przypadku wolnego kręcenia na zasadzie przykładu nr 1, ale dodatkowo zastosować trochę cyfrowej "inteligencji", czyli  np. jeśli to wspomniany wzmacniacz audio, to można przyjąć, że:
  • jeśli wcześniej był nastawiony głośno, to oznacza chęć szybkiego zmniejszenia głośności,
  • jeśli wcześniej był nastawiony cicho, to oznacza, że może przez przypadek pokręcił zbyt szybko i nie należy gwałtownie zwiększać głośności.
Należy jednak wziąć pod uwagę, że zasada taka może być stosowana w popularnym sprzęcie, ale dla DJ-a może być nie do zaakceptowania :-)

Resumując:

To my decydujemy co jest dla nas ważne i to my decydujemy o tym, jaki czas drgań styków (przy braku danych z dokumentacji) należy przyjąć - myśl jednocześnie jak inżynier i użytkownik urządzenia, które projektujesz, ale nie ryzykuj (skracając czas eliminacji drgań styków), gdy nie ma ku temu powodów.


Delay - jest be!

Przy tej okazji należy wspomnieć, że powyższe ogólne zasady postępowania przy braku dokumentacji elementu zawierającego styki mogą być nieakceptowalne dla przypadków, w których programista używa funkcji opóźnień typu delay() i trudno zaakceptować, że mikrokontroler będzie kręcił się w kółko przez np. 0,5 sekundy.

Należy więc podkreślić, że eliminację drgań styków warto (gdy jest to możliwe) opierać o timer i przerwania. Większość projektów urządzeń opartych o mikrokontrolery wykorzystuje jakiś timer do odmierzania stałych okresów. Wystarczy więc fragment programu eliminacji drgań styków dodać do przerwania tego timera i już mamy problem z głowy :-)

Co więcej większość projektów nie wykorzystuje wszystkich timerów, można więc często zaprząc jeden z nich tylko i wyłącznie do obsługi zadania eliminacji drgań styków.





Eliminacja programowa

Eliminacja drgań za pomocą programu nie jest zadaniem trudnym. Jednakże ze względu na to, że zależy ona od tego, co masz dostępne w swoim mikrokontrolerze oraz ile masz wolnej mocy obliczeniowej (czyli de facto jak napisany jest Twój główny program), stąd nie ma jednego najlepszego rozwiązania.

Oto kilka linków do programowego pozbywania problemu:

Zalety:
  • brak dodatkowych elementów zewnętrznych

Wady:
  • zwiększenie obciążenia mikrokontrolera dodatkowym zadaniem, co czasami jest nieakceptowalne.



Eliminacja sprzętowa za pomocą kondensatora

Rys. 3.1
Najczęstszą formą jest zastosowanie kondensatora podłączonego równolegle do przycisku. Kondensator eliminuje drgania "wygładzając" sygnał podawany do mikrokontrolera.

Ale to nie jest bezpieczne rozwiązanie!!! 
W momencie gdy przycisk zostanie naciśnięty, cały zgromadzony w kondensatorze ładunek, w ułamku sekundy zwierany jest do masy, a prąd który płynie przez przycisk jest, co najmniej duży :-)



Jest to na tyle istotne zagrożenie, że na przykład Atmel postanowił w marcu 2011r. zmienić swoją notę AVR042 z 2005r. na nową i opisał to zjawisko na przykładzie podłączenia przycisku do pinu RESET:



Przetłumaczony tekst:

Atmel AVR042 - 03/2011:
W czasie gdy przycisk zostanie naciśnięty zwiera kondensator do masy, prąd płynący przez przycisk może osiągać bardzo duże wartości (tzw. szpilki).

Niestety drugie zdanie z powyższej kopii fragmentu noty AVR042 jest nieco mylące, ponieważ informuje o tym, że te szpilki powodują drgania styków.

Faktycznie jest inaczej! 
To drgania styków w połączeniu z dużym prądem rozładowania kondensatora i innymi elementami (o tym piszę w dalszej części), powodują powstanie szpilek w ilości odpowiadającej ilości drgań przycisku.

Potwierdził to support Atmela w odpowiedzi na moje pytanie o nieścisłość tego zapisu i zapewnił, że zmienią notę przy najbliższej okazji:

Atmel 21.10.2011 14:22

Dear Jacek,

Yes you are correct. The current through the switch from the capacitor does not make the switch to bounce.
...
We will have this intimated to our internal resources and hope will be made easy to understand in future as soon as possible.

Best Regards,
Atmel Technical Support Team

Trzymam Atmela za słowo i zobaczymy, czy i kiedy to zmienią :-)

W dalszej części noty Atmel dokładnie wyjaśnia dlaczego te szpilki powstają:


No to tłumaczymy zjawisko:
  • ścieżki na płytce PCB oraz przycisk mają pewną indukcyjność (małą, ale jednak jest)
  • w momencie przyciśnięcia przycisku następuje zwarcie kondensatora do masy,
  • duży prąd zwarcia oraz indukcyjność, powodują wygenerowanie szpilki zgodnie ze wzorem
  • szpilka ma ma znacznie większe napięcie, niż dopuszczalne na pinach mikrokontrolera

Jak duże napięcie ma szpilka?
Napięcie szpilki można w przybliżeniu wyliczyć z następującego wzoru:


gdzie:
Vi - napięcie wygenerowanej szpilki
L - indukcyjność ścieżek PCB i przycisku
di - zmiana prądu
dt - czas trwania przepływu prądu

Zjawisko przedstawione wzorem jest bardzo podstępne ponieważ, gdy prąd jest duży, to kondensator rozładowuje się szybko, to wartość ułamka gwałtownie rośnie. I dlatego właśnie szpilki są tak niebezpieczne.

Zobacz jak powstaje 300V na niewielkim przekaźniku zasilanym zaledwie 12V: Przekaźnik i zakłócenia

W przypadku kondensatora i przycisku, oczywiście tak duże napięcie nie powstanie, ale pamiętać należy o tym, że większość mikrokontrolerów może zostać uszkodzonych, gdy napięcie na pinie mikrokontrolera przekroczy napięcie dopuszczalne o zaledwie 0,5V-1V.


Ile szpilek powstanie?
Ilość drgań styków jest nieprzewidywalna. Może być jedno, ale może też ich być kilkanaście. Zależy to od samego przycisku, jego stanu oraz innych czynników, jak temperatura itp. Często jest też tak, że przy naciskaniu jest generowanych więcej drgań niż przy puszczaniu, ale są wyjątki :-)


Jak długo trwa to zjawisko?
Z reguły drgania styków przycisku trwają od kilku do kilkudziesięciu milisekund.


Jakie są tego skutki?
Powstawanie szpilek o wysokim napięciu może powodować:
  • uszkodzenia mikrokontrolera,
  • generowanie zakłóceń dla całego układu. 

Generowanie zakłóceń na sąsiednich ścieżkach
Skoro wyżej napisałem już o zakłóceniach, które generowane są przez prąd z rozładowywanego kondensatora w momencie zwarcia go przyciskiem do masy, bez zastosowania rezystora zmniejszającego prąd (rys. 3.1), to zobaczmy jakie zakłócenia generowane są przez to zjawisko na sąsiednich ścieżkach urządzenia.

Eksperyment wykonany został przez janbernat dla ścieżki A znajdującej się obok ścieżki B.
Obie ścieżki o długości ok. 60mm leżące obok siebie w znacznej (jak na aktualne metody wykonywania PCB) odległości, bo aż  2mm. Do ścieżki A podłączony był przycisk oraz kondensator zaledwie 100nF (rys. 3.1).
W układzie nie użyto rezystora ograniczającego prąd rozładowania kondensatora.

Zakłócenie wygenerowane na
ścieżce B
Po prawej stronie pokazałem oscylogram powstającego zakłócenia na ścieżce B, generowanego na niej przez prąd rozładowania kondensatora (zwarcie)  na ścieżce A, w momencie naciśnięcia przycisku. Wygenerowana szpilka zakłócenia ma ponad 0,6V.

W przypadku gdy ścieżka B jest sygnałem cyfrowym, istnieje szansa, że nie wpłynie to na działanie mikrokontrolera lub całego urządzenia - szansa, a nie pewność! Ale może być także przypadek, gdy zakłócenie jest wygenerowane na wejściu przerwania zewnętrznego ustawionego na zbocze narastające lub opadające. Wtedy powstająca szpilka może być "złapana" jako żądanie przerwania.

W przypadku gdy ścieżka B jest sygnałem analogowym (np. wejście przetwornika ADC), zakłócenie może mieć znaczący wpływ na wynik pomiarów.

Oczywiście gdyby ścieżki leżały znacznie bliżej siebie, były dłuższe, grubsze, szersze, itp., to zakłócenie byłoby znacznie większe, co mogłoby spowodować nieprawidłowe działanie także wejść cyfrowych.

Wielkość zakłócenia zależeć będzie także od tego jak duży kondensator zostanie zastosowany oraz czy będzie to "przeciętny" kondensator, czy o niskim ESR (tzw. Low ESR). Największe zakłócenie powstanie, gdy będzie to duży kondensator typu Low ESR, gdyż wtedy prąd rozładowania kondensatora osiągnie możliwie największą wartość,

Nie ma jednej twardej zasady, kiedy zakłócenie będzie powodować problemy, a kiedy nie, a wszystko zależy gdzie zakłócenie trafia i jak zaprojektowana jest reszta urządzenia. Ale po co ryzykować, skoro można zastosować się do punktu opisanego poniżej.


Jak temu zaradzić?
Trzeba ograniczyć prąd rozładowania kondensatora, co można zrobić dołączając do przycisku szeregowo rezystor z przedziału 100Ω - 330Ω (rys. 3.2, rys. 3.3):


W momencie gdy przycisk zostanie naciśnięty, prąd rozładowania kondensatora będzie ograniczony i w efekcie będzie generował szpilki znacznie mniejsze lub wcaleDla eksperymentu wykonanego przez  janbernat opisanego powyżej, zastosowanie rezystora R10 o wartości zaledwie 100Ω zredukowało zakłócenia prawie do zera. Jednakże Ty stosuj zalecenia Atmela, czyli 330Ω.

Rys. 3.2 AVRy
Dlatego drugim istotnym elementem jest dioda, która zabezpiecza dodatkowo wejście  mikrokontrolera, zwierając "szpilkę" do zasilania Vcc. Niektóre mikrokontrolery posiadają diodę wbudowaną w wejście mikrokontrolera, co pozwala Ci na jej pominięcie (sprawdź w datasheet Twojego mikrokontrolera).

Także w nowszych dokumentach dot. Xmega od roku 2011 Atmel sugeruje użycie rezystora 100Ω w szereg z przyciskiem (rys. 3.3): XMEGA Schematic Checklist

Zalety:
  • eliminacja sprzętowa nie wymaga rozbudowy programu, przez co skracasz go i odciążasz mikrokontroler (nie tracisz mocy obliczeniowej),
  • zabezpieczony pin i mikrokontroler  przed szpilkami powstającymi przy naciśnięciu przycisku,

Rys. 3.3 Xmega
Wady:
  • duża ilość dodatkowych elementów zewnętrznych,
  • zbyt duży kondensator nie pozwala stosować takiego rozwiązania do impulsatorów (enkoderów) stykowych lub kontaktronów czy przycisków, które są zwierane i rozwierane z dużą częstotliwością (czytaj: Impulsator vs drgania styków).

Rezystor R8
Dla porządku należy dodać jeszcze, że w przypadku pinu RESET  w mikrokontrolerach firmy Atmel rodziny AVR (np. ATmega8), rezystor R8 powinien mieć wartość od 4,7k do 10k. W innych mikrokontrolerach mogą być inne wartości - sprawdź datasheet - więcej opisałem tutaj: Minimalne podłączanie pinów


We własnym zakresie możesz przeprowadzić prosty eksperyment:



Podsumowanie
Eliminując drgania styków sprzętowo poprzez podłączenie kondensatora, powinieneś:
  • dodać rezystor R10 - najlepiej zawsze,
  • dodać diodę - jeżeli wejście mikrokontrolera nie zawiera takiej diody.


54 komentarze:

  1. Jeszcze można dodać to:
    http://www.elektroda.pl/rtvforum/topic1095955.html
    Bardzo fajny sposób Freddiego Chopina.

    OdpowiedzUsuń
  2. Rozwiązanie Freddiego Chopina de facto sprowadza się do użycia przerwań z Timera lub opóźnienia za pomocą funkcji np. delay(), czyli zawiera się w: programowo z timerem i przerwaniami lub funkcjami opóźnienia .

    OdpowiedzUsuń
  3. Ciekawy artykuł. Mam tylko jedno pytanko: jak zrealizować sprzętowe niwelowanie drgań w klawiaturze takiej jak ta: http://images37.fotosik.pl/1196/b5738c42d91ac831gen.jpg?

    OdpowiedzUsuń
    Odpowiedzi
    1. Programowo. W programie reaguj na zbocze impulsu, potem chwila przerwy (kilka milisekund) i sprawdzenie stanu przycisku. Oczywiście polecam to zrobić na przerwaniach i timerze chyba, że masz dużo wolnego czasu, żeby zatzymać uC na np. 20 ms.

      Usuń
  4. Nie widziałem rozwiązania opartego na elementach RC. W takiej sytuacji najlepiej jest zrobić programową eliminację drgań styków.

    Jeżeli natomiast masz problem z wydajnością (bo np. Twój mikrokontroler jest na granicy maksymalnego obciążenia), to znacznie taniej dołożyć jakiś dodatkowy tani mikrokontroler za 3-5zł i wykonanie na nim samej klawiatury z eliminacją programową, a łączność z głównym mikrokontrolerem zrealizować z wykorzystaniem SPI. Takie rozwiązanie ma jeszcze jedną zaletę, że może buforować kolejne wciskane przyciski, tak jak to jest np. w klawiaturach komputerowych, co znacząco odciąża główny mikrokontroler.

    OdpowiedzUsuń
  5. Czy zamiast zewnętrznego rezystora R8 można wykorzystać wewnętrzny "pull-up"? Oczywiście nie w przypadku resetu, tylko innych przycisków. Czy może to spowodować uszkodzenie procka? Niestety zastosowałem taki układ(dla Atmegi32) i jedna padła przy programowaniu a druga przy włączeniu zasilania. Dodam, że na wejściach które były wyposażone w układ eliminacji drgań styków jest w tej chwili potencjał 1,5V. Wcześniej, bez układu eliminacji drgań(...) Atmega pracowała bez zarzutu przez jakieś pół roku. W tej chwili w ciągu miesiąca uszkodziły się dwie. Proszę o pomoc. Pozdrawiam

    OdpowiedzUsuń
  6. Oczywiście można użyć wewnętrzny pull-up zarówno w przypadku standardowych przycisków jak i RESET. Wewnętrzny pull-up ma kilkadziesiąt kΩ (50-80) i jest wystarczający, by wymusić prawidłowo stan wysoki na wejściu i podłączonym do niego przycisku. Wykorzystanie wewnętrznego pull-up nie może uszkodzić ATmega w żaden sposób.

    Nawet jeżeli zastosowałbyś zewnętrzny pull=up z rezystorem powiedzmy 1kΩ, to także nie Może uszkodzić mikrokontrolera w żaden sposób. Przyczyna uszkodzenia (o ile faktycznie ma ono miejsce) leży więc w innym miejscu, ale by to móc zdiagnozować, potrzebny jest schemat i program.

    OdpowiedzUsuń
  7. Drgania styków... Czyli fakty i mity, drgania styków są tak szybkie, ze mają znikomy wpływ na przeskakiwanie np. menu w programie, a wpływ na to ma zbyt wolna reakcja człowieka, który myśląc, ze raz wciskając przycisk wykona operację raz jednak zazwyczaj próbkowanie stanu przycisku jest wykonywane w pętli, i nim zwolni przycisk zdąży wykonać kilka pętli, a te sposoby "niwelowania drgań" działają ponieważ wprowadzają zwłokę czasową w próbkowaniu przycisku.

    OdpowiedzUsuń
  8. Zastanów się dobrze nad tym co piszesz :-)

    OdpowiedzUsuń
  9. A Ty lepiej przeprowadź eksperymenty praktyczne z szybkim oscyloskopem by zauważyć jak krótkie są te drgania styków (rzędu mikrosekund), a nie tylko opierasz się na danych znalezionych an rożnych forach. ;)

    OdpowiedzUsuń
  10. Zerknij kolego do mojego i pozostałych autorów profili na blogu :-)
    I ponownie sugeruję, byś zastanowił się nad cym co napisałeś w kontekście drugiego rysunku w tym artykule, czyli fragmentu datasheet przycisku, w którym producent pokazuje, że drgania mogą trwać nawet 20ms.

    A w Nowym Roku, życzę więcej pokory dla własnej wiedzy i mniej zaufania do przeczytanych w sieci rewelacji - pozdrawiam.

    OdpowiedzUsuń
  11. Cóż datasheet w którym pisze 20ms max to jak, tolerancja rezystora 5% może się wahać o te 5%, ale równie dobrze o 0,1%. Nigdzie nie twierdziłem, że drgania styków nie istnieją, ale uważam, ze pisząc program trzeba też pomyśleć o tym, iż w najprostszej implementacji odczytu stanu przycisku, trzeba liczyć się z tym, że będzie procedura się wykonywać w kółko póki nie zwolni się przycisku (nikt mi nie w mówi, że tak nie jest gdy ludzie w basicu piszą np.
    if portx.y = 1 then <jakas funkcja)) i miałem przez to na myśli, że nie można wszystkiego zwalać na drgania styków, gdy jest błąd logiczny w programie.

    Pozdrawiam.

    OdpowiedzUsuń
  12. O, teraz zaczyna się merytoryczna dyskusja, pozbawiona zbędnych inwektyw i emocji - nie można było tak od razu?

    To że dany przycisk, czy styki przekaźnika, kontaktronu, itp. w jednym egzemplarzu mają takie a nie inne czasy drgań, nie oznacza że inny element tej samej partii nie będzie miał czasów dłuższych. Podobnie z prędkością pracy mikrokontrolera i programu.

    Dlatego stanowcze Twoje twierdzenie cyt.

    "... drgania styków są tak szybkie, ze mają znikomy wpływ na przeskakiwanie np. menu w programie, ..."

    jest nieuzasadnione.

    OdpowiedzUsuń
  13. Przyznaje to zdanie było źle sformułowane, bardziej skrót myślowy, przez który miałem na myśli, że początkującemu więcej szkody wyrządzi, to że program wykona się kilka razy w pętli, niż że styk zadrga (oczywiście trzeba eliminować oba przypadki), bo o ile komuś można powiedzieć, ze styk drga i można to wyeliminować kondensatorem na przykład o tyle trzeba też kogoś zaczynającego przygodę z mikrokontrolerami uświadomić, iż nawet w najprostszym programie musimy wiedzieć jak dokładnie zachowa się procesor przy danej instrukcji, a nie tylko co będzie wynikiem tej instrukcji metodą prób i błędów.

    OdpowiedzUsuń
  14. Celem tego artykułu nie było pokazanie jak należy eliminować drgania, a jedynie pokazanie, że występują, i że należy to brać pod uwagę projektując urządzenie.

    Poza tym, to że styki w nowym elemencie, drgają przez X czasu, nie oznacza, że wraz z wiekiem czas drgań nie ulegnie znacznemu powiększeniu. Dlatego nie warto ryzykować i zawsze tak przygotować urządzenie, żeby było w stanie poradzić sobie z tym problemem niezależnie od czasu drgań.

    Każdy przypadek jest inny i w każdym można zastosować mniejszy lub większy kompromis sprzętowo-programowy.

    OdpowiedzUsuń
  15. Z ostatnim Twoim komentarzem zgadzam się całkowicie, tak więc chyba doszliśmy do kompromisu.

    OdpowiedzUsuń
  16. Kolego napisz sobie program który będzie negował stan diody za pomocą dwóch przycisków (ON) i (OFF) i zobacz czy drgania styków spowodują przypadkowe zapalanie diody (bo bo przecież wtedy nie będą inne) i dopiero się zastanów nad tym co piszesz.

    OdpowiedzUsuń
  17. Żeby się upewnić, o którym przypadku piszesz rozbiję go na dwa przypadki:

    1. Jeżeli negowanie ma polegać na tym, że przycisk ON ma funkcję tylko włączania diody, a przycisk OFF ma funkcję tylko wyłączania diody, to choćby każdy przycisk generował milion drgań, to przycisk ON nie zgasi diody, a przycisk OFF jej nie zapali. Dlatego w tym przypadku Twój przykład jest zły.

    2. Jeżeli natomiast miałeś na myśli negowanie za pomocą ^= na obu przyciskach, to nie można ich nazwać ON i OFF, tylko oba powinny nazywać się TOGGLE. Taki właśnie przypadek pokazany jest na filmie na początku tego artykułu i opisany.

    Sądzę, że pisałeś o przypadku nr 1, bo w przypadku nr 2 wystarczy tylko jeden przycisk, a drugi jest zbędny.

    OdpowiedzUsuń
  18. O to mi chodziło, co widać w komentarzu anonimowego, gdy mówiłem ze program trzeba pisać logicznie, wiedząc jak zachowa się przy danej procedurze mikrokontroler...

    Pozdrawiam i udanego nowego roku.

    OdpowiedzUsuń
  19. I jeszcze chciałem dodać, że aby wykryć drgania styków na przycisku w najprostszy sposób, to wydaje mi się, ze najlepiej by było zliczać zmiany zbocza na porcie, ze znaczną czułością.

    OdpowiedzUsuń
  20. Tylko, że pomysł Anonimowego zawiera wewnętrzną sprzeczność.
    Również pozdrawiam i życzę udanych projektów!
    Jacek

    OdpowiedzUsuń
  21. W całym artykule mamy do czynienia z przyciskiem reset jako przykładowym. Chciałbym poprosić o schemat realizacji przycisku RESET ale z wyprowadzeniem sygnału dalej w układ. To znaczy chciałbym posiadać w urządzeniu sprzętowy przycisk RESET ale także wyprowadzić sygnał RESET na szynę dla programatora ISP :) Opracowałby ktoś taki schemacik do tego artykułu? Poza tym nie tylko o reset chodzi. Spokojnie potrafię sobie wyobrazić sytuację, gdzie niektóre sygnały do uC generuje logika z innej części urządzenia lub człowiek za pomocą przycisku... :)

    Pozdrawiam, Daniel

    OdpowiedzUsuń
  22. Czyli nie ma innego sposobu jak przeczekanie drgań niezależnie w jaki sposób (pętla lub opóźnienie)?

    OdpowiedzUsuń
    Odpowiedzi
    1. Miałem na myśli oczywiście opóźnienie w pętli lub oparte o przerwania.

      Usuń
    2. Dobrze myślisz - nie ma innego sposobu jak odczekanie okresu drgań i stwierdzenie, że stan styków się ustabilizował. Wyjątkiem jest zastosowanie przerzutników, ale mając mikrokontroler w 99,99% przypadków nie ma sensu ich stosować.

      Natomiast sposób w jaki przeczekasz czas drgań zależy tylko od Ciebie i dostępnych zasobów mikrokontrolera.

      Usuń
  23. Przeczytałem kilka artykułów na temat drgań przycisków i doszedłem do wniosku, że treść w nich zawarta jest przydatna ale chyba tylko w konstrukcjach, które mają cechować się bezpieczeństwem i dużą niezawodnością. Zacząłem bawić się mają atmegą8 i zwykłym tact switchem. Okazało się, że bez żadnych dodatkowych elementów (rezystorów i kondensatora) dla poniższego kodu:
    ISR(TIMER0_OVF_vect){
    static uint8_t prev;
    DisplayNextDigitA(LedDigits);
    if (UP == 0 && prev == 1)
    LedDigits[0] ++ ;
    prev = UP;
    }

    uC tylko raz na może jakieś 200-300 przyciśnięć wykrył 2 zamiast jednego. Bez względu na to jak przeskaluję wywołanie timera0.

    OdpowiedzUsuń
    Odpowiedzi
    1. W twoim kodzie masz małą ukrytą formę debouncingu. Poza tym kwestia jak często to ISR się wykonuje - jeśli masz taktownaie np. 8 MHz, a timer nawet bez preskalera, to ISR wykonywany jest co 32 us, łapie zmiany stanu co 64 us. To już jakiś debouncing jest, nieuważasz? Jeśli masz preskaler, to w praktyce robisz właśnie debouncing na timerze. Zapuść swoją funkcję w main i porównaj rezultaty...
      Jest jeszcze jedna kwestia - program nie powinno się pisać tak, że raz na jakiś czas po prostu nie działa. Ma działać zawsze i pewnie. Jeśli będziesz dopuszczał sytuacje w których czasami coś nie zadziała jak należy to w każdym złożonym programie będziesz miał dziesiątki lub setki funkcji, które "czasami" nie działają. W efekcie program jako całość bedzie koszmarem działającym zupełnie losowo.

      Usuń
    2. Oczywiście, że jest, bez tego łapał ponad 10 zmian stanu przy jednym naciśnięciu. Miałem na myśli bardziej fakt , że nie trzeba od razu pisać funkcji która łapie zmiany np. po kilku ms. Taki sposób jest prosty,i prawie w ogóle nie obciąża dodatkowo uC a jeżeli za pomocą przycisków wprowadzam np. jakąś zmienną i mogę ją inkrementować i dekrementować to nic się nie stanie, jeżeli raz na 200 przypadków po wciśnięciu liczba przeskoczy mi o 2 zamiast o 1, skoro mogą ją potem zmniejszyć.
      Program nie jest w takim przypadku "koszmarem działającym zupełnie losowo".

      Usuń
    3. Dołączę się do dyskusji.

      Każda wersja programu do eliminacji drgań styków jest jakimś kompromisem. Każda z nich jest nieodporna na jakiś przypadek drgań, który może spowodować jej nieprawidłowe działanie. Jeżeli więc taki poziom błędów Ciebie zadowala, to algorytm uznać należy za wystarczająco dobry.

      Problem jednak pojawić się może w przyszłości, gdy przycisk z różnych powodów (np. zbyt dużej siły używanej przez użytkownika, wilgoci i z tym związanych problemów, itp.) zmieni swoje parametry w zakresie drgań styków w taki sposób, że poziom błędów zastosowanego algorytmu będzie zbyt duży.

      Przykłady pokazałem na filmie: Drgania styków (test 14-tu różnych elementów).

      Poza tym, teraz stosujesz jakiś konkretny przycisk, konkretnego producenta, z konkretnej partii. Za jakiś czas tym samym algorytmem będziesz obsługiwał ten sam typ przycisku, ale innego producenta i z innej partii, i okazać się może, że z tego powodu algorytm nie jest wystarczająco dobry. Takie przypadki zdarzają się często.

      Dlatego ja osobiście uważam, że wybrany sposób eliminacji drgań styków może dopuszczać błędy, ale w urządzeniach które są w zaciszu mojego domu, a ewentualna pomyłka programu nie jest elementem krytycznym (czyli przypadek taki jak opisujesz).

      Jeżeli natomiast ma to być projekt komercyjny lub przycisk ma "krytyczną" funkcjonalność, to absolutnie nie pozwolę sobie na zastosowanie kompromisu o niskim poziomie skuteczności.

      Usuń
    4. Zgadzam się z Tobą w 100 % :) .

      Usuń
  24. Zastanawiam się jak wygląda temat przy zastosowaniu optoizolatora w układzie.
    Projektuje układ który na wejściu ma przycisk załączający/odłączający 24 V. Prąd jest ograniczony wpiętym szeregowo rezystorem 10k. Dodatkowo pomiędzy 24 V a masę jest wpięty kondensator filtrujący 100 nF. Kończy się to optoizolatorem PC817.
    Zastanawiam się czy optoizolator odfiltrowuje drgania styków po stronie wyjścia i czy drgania na wejściu nie spowodują jego uszkodzenia.

    Muszę przyznać, że w takich chwilach marzę o oscyloskopie...

    OdpowiedzUsuń
    Odpowiedzi
    1. Prawidłowo zaimplementowany optoizolator jest znacznie szybszy (jakieś 1000 razy dla PC817) niż drgania styków, stąd na pewno przekaże takowe z wejścia na jego wyjście. Jeżeli dobrze rozumiem na wejściu chciałeś zastosować filtr RC, ale z Twojego opisu wynika, że kondensator jest w niewłaściwym miejscu.

      Usuń
    2. "stąd na pewno przekaże takowe z wejścia na jego wyjście" - przydatna informacja, nie byłem właśnie tego pewny.
      Tak, żeby rozjaśnić. W linku schemat:
      http://www.wolnywydech.pl/el/schemat_wejscie.png
      Muszę przyznać, że rzeczywiście wyszedł filtr RC, chociaż R pojawiło się głównie raczej by ograniczyć prąd na PC817.
      W każdym razie zacząłem się zastanawiać czy brak diody jest dopuszczalny w takim wypadku i coraz większe wątpliwości mnie nachodzą.
      I druga wątpliwość to czy w przypadku konieczności zastosowania czy dioda nie powinna być założona na przełączniku, analogicznie jak to występuje w zastosowaniach z przekaźnikami

      Usuń
  25. Panowie a jak wygląda schemacik przy kilku przyciskach? Można jakieś elementy współdzielić? Raczej nie, bo co się tanie jak naciśnie się wszystkie na raz? Bo 4 dodatkowe elementy, to dość sporo, a przy np. 3 przyciskach robi się bałagan.

    OdpowiedzUsuń
    Odpowiedzi
    1. Po prostu drgania eliminuje się programowo i nie trzeba wtedy żadnych dodatkowych elementów likwidujących drgania :)

      Usuń
  26. co to znaczy rezystor r10??

    OdpowiedzUsuń
  27. Kto przy mikrokontrolerach stosuje switche na 250V o obciążalności 2A?! A już zwłaszcza do pinu RESET? Typowe mikroswitche na 12 czy 24V mają bouncig co najmniej o 2 rzędy wielkości mniejszy.

    OdpowiedzUsuń
    Odpowiedzi
    1. Jakie ma znaczenie rodzaj urządzenia zawierającego styki dla samego zjawiska, które jest omawiane w niniejszym artykule?

      Pomijam już fakt, że typowe krańcówki w postaci przedstawionej na filmie są wykorzystywane w wielu maszynach i stanowią bardzo dobre elementy stykowe ze względu na swoją niezawodność. Jakie ma znaczenie fakt, że ich parametry pozwalają je podłączać do 250V i 2A, skoro wykorzystuje się je do sygnałów o poziomach napięć typowych dla mikrokontrolerów?

      W projektach z mikorkontrolerami nie wykorzystuje się tylko i wyłącznie przyciski przyciskane palcem i znajdujące się na płytce razem z mikrokontrolerem.

      Dwa rzędy wielkości mniejsze? To znaczy ile?

      Usuń
    2. Ano ma takie znaczenie, że na podstawie dataszita takiego styku (jak mniemam, no bo skąd) autor artykułu autorytatywnie twierdzi, że "Zjawisko to trwa od kilku do kilkudziesięciu milisekund, zarówno przy zwieraniu jak i rozwieraniu styków:". W przypadku mikroswiczy nie jest to prawdą.
      Dwa rzędy wielkości mniejszy oznacza mniej więcej 100x mniejszy http://pl.wikipedia.org/wiki/Rz%C4%85d_wielko%C5%9Bci
      Zilustrowanie zjawiska wyjątkiem jest jak najbardziej prawidłowe. I nowatorskie ;-)

      Usuń
    3. Kolego - czytaj proszę dokładnie artykuł i analizuj zamieszczone w nim materiały zanim cokolwiek napiszesz :-)

      Przecież już na początku zamieściłem przykładowy fragment datasheet microswitcha, w którym podany jest maksymalny czas 20ms. Rozumiem, że podważasz to co napisał jego producent? Parametr ten oznacza to, że dla tego konkretnego przycisku zależnie od partii czas ten może być krótszy lub dłuższy, ale nie przekroczy 20ms - to tak zwany parametr gwarantowany.

      Innymi słowy producent uczula projektanta, że w przypadku jego konkretnego typu przycisków, drgania styków mogą trwać do 20ms niezależnie, czy dotyczy to naciskania, czy puszczania przycisku i projektant MUSI wziąć taki czas pod uwagę, bo w przeciwnym przypadku jego aplikacja będzie narażona na problem.

      Każda aplikacja musi być zabezpieczona przed drganiami styków jawnie bądź niejawnie. Aplikacja nie może polegać przypadku musi więc uwzględniać fakt drgań zarówno przy zwieraniu jak i rozwieraniu styków. Należy więc uczulać początkujących do których kierowany jest niniejszy artykuł, by byli świadomi zagrożeń i odpowiednio przygotowywali sprzęt i oprogramowanie.

      To czy w przypadku konkretnego rodzaju styków jakiegoś konkretnego urządzenia stykowego drgania w trakcie zwierania styku trwają X, a w przypadku rozwierania Y czasu nie ma najmniejszego znaczenia. Jak widać na załączonym na samym początku fragmencie datasheet przycisku także producenci przycisków nie rozróżniają tych etapów podając jeden parametr w tym wypadku 20ms.

      Jest to gwarantowany maksymalny czas drgań jaki konkretnie ten przycisk (w dodatku nowy i nieużywany) może mieć miejsce. A to że w testach konkretnego takiego przycisku wyjdzie, że czas trwania X=10ms a Y=2ms, lub odwrotnie nie może mieć dla projektanta, żadnego znaczenia. Jeśli nie oprze się o parametr gwarantowany, prędzej czy później jego urządzenie będzie miało kłopoty z efektem nieprawidłowej eliminacji drgań styków.

      Co więcej przycisk także podlega procesowi starzenia i wraz z nim czasy drgań mogą ulegać zmianie. Dlatego parametr gwarantowany jest tak istotny i do niego należy dostosowywać swoje aplikacje.

      Być może w innych przypadkach (dowolnego urządzenia stykowego) producent rozróżni czasy zwierania i rozwierania styków (jeśli uzna to za możliwe i istotne) i poda jako osobne parametry. Jeśli znajdziesz taki element stykowy (dowolny niekoniecznie microswitch) z chęcią zamieszczę fragment dokumentacji.

      Reasumując:
      - artykuł nie jest tylko o switchach (o czym napisałem już na początku pierwszego zdania), ale o wszelkich urządzeniach stykowych, których styki podłączane są do wejść mikrokontrolera,
      - switche także mają różne czasy drgań w zależności od producenta, typu, a nawet partii towaru,
      - artykuł jest artykułem ogólnym skierowanym dla początkujących mający na celu pokazać zjawiska i związane z nim problemy. Nie jest to artykuł o konkretnym urządzeniu stykowym, konkretnego producenta pochodzącego z konkretnej partii produkcji i tak należy do niego podchodzić.

      Zachęcam więc do wskazywania nam dokumentacji urządzeń stykowych, w których podane są czasy drgań - z chęcią zamieścimy je jako kolejne przykłady do artykułu.

      Usuń
  28. To jeszcze raz ja, Jarząbek.
    A nawet jeżeli zastosujemy takiego potwora, to akuratnie w przypadku pinu RESET debouncing mamy za darmo. Jest coś takiego jak start up time, ustawiany fusami. Domyślnie jest to 65ms.

    OdpowiedzUsuń
    Odpowiedzi
    1. Przycisk RESET to wyjątek, artykuł nie dotyczy tylko tego pinu i tylko w mikrokontrolerach AVR, a zjawiska drgań styków jako takiego.

      Usuń
  29. Witam.
    Zbudowałem sobie obsługę klawiatury matrycowej przy pomocy przerwań i timera.
    Procesorek ATXMEGA 256A3BU
    Przerwanie od zmiany stanu wejścia uruchamia timer.
    Timer odmierza czas drgania styków i jego przerwanie odczytuje stan klawiatury.
    Następnie następuje oczekiwanie na puszczenie przycisku i zakończenie cyklu.

    Mam pytanie.
    Co się stanie gdy drganie styku nadejdzie podczas obsługi przerwania od przycisku? Przerwanie zostanie wykonane jeszcze raz po jego zakończeniu? Czy zostanie zgubione?
    Bo jeżeli nadejdzie po wykonaniu przerwania to chyba będzie wykonane ponownie.?

    Układ działa, ale dopiero teraz zdałem sobie sprawę że chyba wykonuję mnóstwo niepotrzebnych przerwań od przycisku.
    Pozdrawiam Waldek

    OdpowiedzUsuń
    Odpowiedzi
    1. Jeżeli kolejne przerwanie zostanie zgłoszone w trakcie obsługi przerwania, to zostanie zapamiętane i wykonane po zakończeniu obsługi bieżącego. Oczywiście możesz przed zakończeniem skasować flagę sygnalizującą kolejne przerwanie. W XMEGA możesz też zrobić to inaczej - podłączyć event system zamiast przerwania, który ci wystartuje timer, w którego funkcji obsługi przerwania dopiero czytasz klawiaturę. To bardzo upraszcza kod.

      Usuń
  30. Do autora - weź lepiej usuń ten pierwszy film "A switch that needs debounce" - tak pisze ktoś, kto nie rozumie idei przełączania LED jednym przyciskiem. Na tym filmiku autor pewnie używa znanej i niedziałającej metody w stylu:
    if (!(PINx & KEY)) PORTx ^= LED
    - która nie działa z prostego powodu. My oczekujemy, że przełączenie nastąpi ZBOCZEM. Czyli - wciśniemy przycisk - dioda się zapala. Dalej trzymamy przycisk, nic się nie dzieje, puszczamy, dioda dalej trzyma swój stan. Po ponownym wciśnięciu dioda gaśnie - zapalenie/zgaszenie następuje podczas zbocza wywołanego wciśnięciem przycisku.
    Na filmiku przełączanie jest podczas POZIOMU czyli naciśniemy przycisk - poziom zmieni się na aktywny i podczas tego aktywnego poziomu led będzie się włączać i wyłączać non-stop (PORTx ^= LED). Ale my tego nie chcemy!

    Druga uwaga to do rzekomego błędnego schematu z kondensatorem bez rezystora - przeglądnąłem wiele schematów profesjonalnych firm (Texas Instruments czy Analog Devices się raczej zaliczają) - stosują oni ten kondensator - bez rezystora! No, może tylko dają mniejszą, z tego co zauważyłem, wartość (typu 1-22n).

    Pozdrawiam i ponawiam uwagę do początkujących - chcemy wykrywać ZBOCZE podczas wciskania przycisku a nie POZIOM - zrozumienie tego zajęło mi trochę czasu ale jak zrozumiałem - to już do końca.

    OdpowiedzUsuń
    Odpowiedzi
    1. Pierwszy filmik jest jak najbardziej poprawny i pokazuje zjawisko drgań styków i nie ma znaczenia w jaki sposób napisał program jego autor.

      A propos rezystora i kondensatora, przeczytaj jeszcze raz artykuł i zastanów się ponownie zanim podważysz jego treść.

      Co do poziomu vs zbocze - to zależy co jest intencją projektanta i jak rozwiązuje ten problem.

      Usuń
  31. Szkoda, ze nie zbadales wlacznika rozrusznika od C360. Co by napisac, to autor i tak ma racje. Jak nie ma racji, przeczytaj zdanie powyzej.

    OdpowiedzUsuń
  32. A ta dioda to jaka ma być? Wsziędzie jest, że dioda, a nie ma podane jaka.

    OdpowiedzUsuń
    Odpowiedzi
    1. Nada się każda, ale najlepiej zastosować szybką diodę przełączająca Schottky np. BAT54, BAS85, itp.

      Usuń
    2. Ok, dzięki. Dla początkującego dużo rzeczy nie jest oczywista ;-)

      Usuń
    3. Właśnie dlatego powstała ta strona :)

      Usuń
  33. Czy dioda 1n4148 nadaje się do zabezpieczenia wejścia mikrokontrolera?
    W przypadku mojej drukarki 3D stan normalny (wyjściowy) krańcówek jest "zwarty", po dojechaniu wózków w drukarce do krańcówek przełącza je na "rozwarte". Mam już zlutowane krańcówki z elementami ze schematu (1n4148, C 100nf, R 100Ohm, R 10k), tylko przewodem muszę doprowadzić 5V VCC. Przy zamontowanych samych krańcówkach bez tych modyfikacji często nie wszystkie wózki nie dojeżdżają do krańcówek albo jeden się zatrzymuje, podobno takie rozwiązanie jak w powyższym artykule umożliwia wyeliminowanie zakłóceń i poprawną pracę drukarki.

    OdpowiedzUsuń