Ads_700x200

tme

piątek, 19 października 2012

IR TOUCH - wyłącznik bezdotykowy

Witam,

Ponieważ mnie także zainspirował niesamowicie temat konkursu jaki zorganizował na forum, kolega NIEBO!,
to już tak całkowicie poza konkursem i po jego zakończeniu postanowiłem też zrobić sobie we własnym zakresie podobny wyłącznik ;) W zasadzie uznałem, że bardzo przydatne do tego celu okażą się sposoby do obsługi (wprawdzie zwykłych) klawiszy, to jednak - przecież tematem zadania jest także klawisz - tyle że bezdotykowy a dokładniej mówiąc taki na podczerwień. Popełniłem zatem króciutki kod źródłowy, wgrałem do mikrokontrolera i przetestowałem. Ku mojej uciesze okazało się, że prześlicznie zaczęło to działać. Hmmm jedyne czego jeszcze nie sprawdzałem - to fakt czy np przelatująca mucha lub komar będą w stanie włączyć taki klawisz ;) ... ale spokojnie, będę musiał założyć jakąś małą hodowlę owadów, przetresować je do zadań specjalnych i jak śmigłowce wysyłać w okolice wyłącznika ;) .... o tym jeszcze w razie czego poinformuję, tymczasem przejdźmy do rzeczy.



Na początek film prezentujący działanie wyłącznika bezdotykowego "w praniu" ;)



Nie będę długo się rozwodził na temat kodu programu, bo każdy zapewne zauważy, że wykorzystałem tutaj WPROST bez żadnych sentymentów funkcję do obsługi klawisza, którą stworzyłem w 3 części artykułu na temat rzekomych efektów drgań styków ;)


Kod źródłowy wzbogaciłem jednak o generowanie nośnej 36 kHz na potrzeby odbiornika podczerwieni TSOP ;) .... To od razu mówi jakiego sposobu użyłem do realizacji zadania. Prościutko:


  1. TSOP 36 kHz podłączony do pinu PD6 (ICP1) mikrokontrolera ATmega32 (zgodnie ze sztuką jego podłączania)
  2. Dioda nadawcza IR podłączona do pinu PB3 (OC0) mikrokontrolera ATmega32 tyle że za pomocą tranzystora PNP

Mniej więcej tak wygląda podłączenie diody i odbiornika TSOP do procesora:




Najważniejsze to tylko odpowiednie zaizolowanie diody nadawczej IR. Do tego celu użyłem po prostu czarnej rurki termokurczliwej, którą nasunąłem na diodę ;) .... Poniżej prezentuję cały kompletny kod źródłowy, i nie będę go tutaj już opisywał. Każdy może zajrzeć do części III artykułu do której podałem wyżej link. Ale jeśli pojawią się jeszcze jakieś pytania to oczywiście chętnie odpowiem.
--------------------------------------------
--------------------------------------------

Za to na koniec zwrócę uwagę na pewną ciekawostkę. Otóż mam zrzut ekranów z oscyloskopu podczas operacji wciśnięcia i zwolnienia takiego klawisza. Spójrzcie, przypomina to nomen omen, wprost jakby oscylogramy z wciskania typowego klawisza mechanicznego tyle że jakie piękne przebiegi drgań styków ;) szczególnie widoczne są te "ala drgania" przy "wciśnięciu" bezdotykowego klawisza. Ich piękny charakter, tzn równe poziomy logiczne oraz strome zbocza opadające i narastające wywołane są oczywiście zadziałaniem tak na prawdę jakichś szczątkowych odbić nośnej od obiektu, który wchodzi w zakres widoczności czujnika podczerwieni ;) ... A wiemy przecież z poprzednich artykułów - szczególnie z tego


że w świecie prawdziwych mechanicznych klawiszy nie ma takich idealnie równych przebiegów ;) to wygląda wręcz jak po prostu modelowy przykład drgań styków. Na takim modelu zwykle się je omawia. A zatem spójrzmy:


20 komentarzy:

  1. Zastanawiam się, co z problemem reagowania np. na pilota telewizora, czy nie powinno to być w jakiś sposób modulowane?

    OdpowiedzUsuń
    Odpowiedzi
    1. To jest oczywiście tylko jakiś wstępny przykład - a rozwijać można dalej wg uznania. Jeśli chodzi o zakłócanie pilotów podczerwieni to nie powinno być problemu jeśli się właśnie ograniczy zasięg tegoż wyłącznika do takich odległości o jakich piszę i pokazuję na tym filmiku ;)

      Usuń
  2. To jest to samo co SHARP - GP2D120XJ00F
    Idea działania jest taka sama
    Nie wiem po co tyle zachodu

    OdpowiedzUsuń
    Odpowiedzi
    1. Przepraszam ale mało wiesz na temat tego Sharpa o którym wspomniałeś. To co tu zaprezentowałem nie jest nawet namiastką lub odpowiednikiem takiego modułu. Sharp jest po stokroć lepszy jeśli chodzi o stabilność działania od prezentowanej tu metody. Jest przede wszystkim bardzo dobrze skalibrowany i na 100% nie działa na tej samej zasadzie.

      A to co tu pokazałem nie jest żadnym zachodem czy chęcią zastąpienia takich Sharpów, tylko pokazaniem ciekawej metody jak można wykorzystać podczerwień w prosty sposób mając pod ręką procesor oraz odbiornik TFMS z diodą nadawczą podczerwieni. Przy okazji biorąc nawet pod uwagę procesor to i tak wyjdzie o wiele taniej niż zakup tego Sharpa.

      Jeśli nie lubisz majsterkować, programować procesorów, nie jest to twoim hobby - to daj sobie spokój z komentowaniem tylko idź do sklepu i kup sobie sharpa.

      Usuń
  3. Malkontenci zawsze się znajdą niestety... Mnie artykuł się podoba bo można zobaczyć jak w interesujący i w sumie nietuzinkowy sposób, wykorzystać funkcję pierwotnie obsługującą klawisze, co obrazuje też jak pisać kod uniwersalny.
    A przecież wychodząc z takiego prostego projektu już każdy, kto ma odrobinę chęci i samozaparcia, może "wykombinować" coś co będzie mu w 100% odpowiadało.
    Dzięki Mirek za Twoje artykuły i wkład pracy w to co prezentujesz.

    OdpowiedzUsuń
    Odpowiedzi
    1. Aaaaa tu Cię mam panie Mirek ;) ... ja też dziękuję jeszcze raz tobie za cenną uwagę na Youtube do jednej z części kursu o wskaźnikach, strukturach itp ...

      Z takimi ludźmi to można podyskutować.

      Usuń
  4. Mam takie pytanie czy na schemacie z tsopem jest kondensator ceramiczny 4,7 uF?
    Jeśli tak ,to jest taki , i czy można go zamienić na elektrolitycznego?
    Pewnie pytanie jest dosyć głupie ale się dopiero uczę.

    OdpowiedzUsuń
    Odpowiedzi
    1. Dlaczego głupie pytanie? nie rozumiem ? ... kto pyta nie błądzi ;) .... oczywiście że można zamienić go na elektrolityczny 4,7uF czy 2,2uF - jak najbardziej.

      Usuń
  5. Witam. Jaki prąd ma płynąć przez led ir ?

    OdpowiedzUsuń
    Odpowiedzi
    1. zależy jaki chcesz? zależy jaka dioda? zależy jaki ma być zasięg ? ... tu nikt nic nie narzuca - sam musisz go sobie dobrać do projektu

      Usuń
  6. Super sprawa tego właśnie wszędzie szukałem :)

    Jedna rzecz jest jedynie dla mnie nie jasna ,otóż w przerwaniu ISR jest tworzona zmienna

    uint16_t n;

    ,następnie jest zmniejszana --n.

    Dlaczego jest tworzona w przerwaniu? ,czy nie będzie tak ,że za każdym razem jak wywoła się przerwanie to uint16_t n; ,będzie tworzone na nowo i inicjowane 0 ,nie lepiej byłoby założyć zmienną volatile przed main ?

    Widzę ,że projekt jednak działa ,więc to z moim myśleniem coś nie tak ,rozumiem jedynie ,że to zmienna tworzona "w locie" na potrzeby przerwania. Ale dlaczego akurat tak ? ,może myślę zbyt liniowo :) ,mógłby ktoś przybliżyć zagadnienie, pozdrawiam.

    OdpowiedzUsuń
    Odpowiedzi
    1. Bo zmienna ta ma specyfikator static panie kolego ;) ... Jeśli posiadasz Bluebooka?

      http://atnel.pl/mikrokontrolery-avr-jezyk-c.html

      to rzuć proszę okiem do książki .... wyjaśniam w niej w czym rzecz ...

      a jeśli nie masz to tutaj krótkie wyjaśnienie, specyfikator static powoduje że zmienna w funkcji/przrewaniu zachowuje się tak jak globalna. Ale pamiętaj to bardzo uproszczone tłumaczenie i na szybko. Warto to doczytać w książce żeby dobrze zrozumieć.

      Usuń
  7. Mam bluebooka tam jest przykład na 4 timerach, tam z kolei jest uint16_t x;

    ,ale również nie ma przed nią słówka static.

    Czy to oznacza ,że w przerwaniu jest automatycznie tworzona zmienna static?

    Nie powinno być tak?

    ISR(TIMER2_COMP_vect) {

    static uint16_t n;

    n = Timer1; /* 100Hz Timer1 */
    if (n) Timer1 = --n;

    }

    ,może to literówka i się czepiam ,ale bardzo chciałbym zrozumieć.

    Czy jest to związane może z AVR GCC ,który dopuszcza taką pisownię , przypomina mi się też przykład z const char ,gdzie Atmel toolchain nie popuści ,a AVR GCC ,nic nie jąknie. To coś w tym rodzaju?

    OdpowiedzUsuń
    Odpowiedzi
    1. automatycznie ? jak to ? to kto to wpisuje w kodzie ? kompilator ? ;)

      Panie kolego jeśli masz bluebooka to zajrzyj proszę chociażby do rozdziału:

      "3.5.5.3. Zmienne i funkcje statyczne"

      numer rozdziału może być inny jeśli masz starsze wydanie książki (w miękkiej oprawie"

      Usuń
    2. No i też to pytanie twoje o static mówi mi - że na pewno po zakupieniu książki nie przysiadłeś RAZ - żeby ją tak w całości przeczytać, a to bardzo ważne - bo jest napisana w specyficzny sposób, i później już można czytać na wyrywki ... Tyle że nawet jak nie pamiętasz o co chodzi np ze static - to w głowie (zapewniam cię) będziesz miał - że hmmm było gdzieś o tym w książce - tylko wystarczy poszukać ...

      A jak się jej nie przeczytało RAZ w całości - no to później ma się takie luki.

      Usuń
    3. ach widzisz - czyli to moja wina bo z doskoku spojrzałem na pytanie - często tak mam jak wciąż pracuję - a teraz też jestem w pracy ...

      Już wyjaśniam - tutaj w tym konkretnym przypadku nie potrzeba specyfikatora static dla zmiennej o nazwie n

      jest to tylko zmienna tymczasowa i służy do optymalizacji - szybkości wykonywania się kodu. TAK będzie ona za każdym razem tworzona na nowo ale tak ma być ;)

      tzn można byłoby się obejść i bez niej - można byłoby w przerwaniu pisać sobie wprost tak:

      if (Timer1) Timer1 = --Timer1;

      sprawdź to też zadziała ;) wydaje się prostsze do zrozumienia i nie wywołuje w głowie pytania - po co ta zmienna n ? zgadza się ?

      ale teraz porównaj sobie jak obydwa kody ten ze zmienną n i bez niej - jak wyglądają w asemblerze .... Wtedy zobaczysz dlaczego ten ze zmienną n wykonywać się będzie dużo szybciej

      Usuń
  8. U mnie jest to rozdział 4.5.5.3 ,czytałem kilkukrotnie ,teraz sobie też powtórzyłem i rozumiem znaczenie słówka static ,chodzi mi o to ,że tu w kodzie przerwania go nie ma,

    //*** przerwanie Timer2 CompareM
    ISR(TIMER2_COMP_vect) {

    uint16_t n;

    n = Timer1; /* 100Hz Timer1 */
    if (n) Timer1 = --n;

    }

    ,dlatego zapytałem czy nie powinno wyglądać tak:

    //*** przerwanie Timer2 CompareM
    ISR(TIMER2_COMP_vect) {

    static uint16_t n;

    n = Timer1; /* 100Hz Timer1 */
    if (n) Timer1 = --n;

    }

    Nie chodzi mi o to by się kłócić ,bo kod działa jak widać na filmiku na Youtubie.

    Tutaj tego słówka nie ma ,dlatego mam problem ze zrozumieniem jak to może działać ,pozdrawiam.

    OdpowiedzUsuń
  9. Oj asembler to jeszcze za wysokie progi, ale dziękuję za wyjaśnienie. :)

    Faktycznie if (Timer1) Timer1 = --Timer1; ,brzmi przyjaźniej. I ma dla mnie większy sens.
    Jeszcze raz dziękuję za pomoc i owocnej pracy życzę!!! (nad 3 książką może? :) ) ,pozdrawiam i dziękuję.

    OdpowiedzUsuń
    Odpowiedzi
    1. Brzmi przyjaźniej ale proszę pamiętać że trwa sporo dłużej a w przypadku obsługi timerów programowych to wcale nie jest korzystne aby trwało dłużej.

      A niestety jeszcze nie nad 3 książką ... na nią przyjdzie nam jeszcze poczekać "troszkę"

      Usuń
  10. Ok już kapuję ,może nie rozumiem asemblera ,ale rozwiązanie pojawiło się na stronie 92 przy przykładzie predekrementacji.
    Te minusiki --n ,leżą przecież przed zmienną ,więc to jest klucz do zrozumienia.

    Chodzi o to ,że do zmiennej n jest przypisana zawartość Timera ,a potem w linijce z predekrementacją jest zmniejszana o 1.

    Zmienna volatile Timer1 tak naprawdę przechowuje zawartość timera2 więc nie istotne ,że mnienna n jest tworzona i zerowana na nowo (służy przecież tylko do zmniejszania o jeden),
    bo w kolejej linijce kodu znów będzie przyrównana do Timera programowego tylko ,że mniejsza o 1.

    Pisżę ,bo pewnie nie jednej osobie się przyda.



    Już zaznaczam sobię na żółto mazaczkiem ,coraz więcej tego żółtego w książce :) ,na przyszłość będę wiedział gdzie zajrzeć.


    Cieszę się ,że zapytałem ,bo ciężko było na to wpaść ,jeszcze raz dziękuję.

    OdpowiedzUsuń