Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Pilot IR , odczyt kodów z pilota w Arduino

akr18 02 Dec 2020 18:44 1626 18
  • #1
    akr18
    Level 10  
    Mam pilota który po krótkim naciśnięciu przycisku wysyła za każdym razem inny kod, dioda led zapala się prawidłowo , ale przy ciągły naciskaniu przycisku tylko pierwszy kod jest prawidłowy np. 16724175 , a przy dalszym dłuższym naciskaniu pilot wysyła cały czas kod 4294967295 i tak jest na wszystkich przyciskach , a chciałbym aby dioda świeciła tylko w czasie naciskania wybranego przycisku , a gasła po zwolnieniu przycisku, jest jakiś sposób na to ?
  • Helpful post
    #2
    kulmar
    Level 28  
    Ten pierwszy kod (różny dla różnych klawiszy) jest kodem funkcji pilota. Ten drugi, który się nie zmienia przez cały czas naciskania klawisza jest kodem repetycji - czyli oznacza właśnie to, że klawisz jest cały czas wciskany. Musisz reagować na ten pierwszy kod zapaleniem diody i trzymać ją zapaloną tak długo, jak długo wysyłany jest ten drugi kod.
  • #3
    akr18
    Level 10  
    Nie wiem jak to zrobić , arduino reaguje na ten pierwszy kod , dioda się zapala , jak pojawia się kod repetycji to gaśnie.
  • #4
    emarcus
    Level 38  
    akr18 wrote:
    Nie wiem jak to zrobić , arduino reaguje na ten pierwszy kod , dioda się zapala , jak pojawia się kod repetycji to gaśnie.


    Jeżeli dioda zapala się na kod np. 16724175 (0xFF30CF) i pojawia ci się w kolejnej sekwencji kod repetycji w postaci 4294967295 (0xFFFFFFFF) to mu wpisz że otrzymany kod w tym przypadku jest też ten pierwszy. Sprawdzaj co jakiś czas (powiedzmy co 200 ms) czy w dalszym ciągu IR otrzymuje sygnał (stosuj do tego funkcję millis() aby nie blokować programu). Jeżeli brak sygnału; (odczyt= 0x00000000) to zgaś diode.
    To tak mniej/więej w skrócie...

    e marcus
  • #5
    akr18
    Level 10  
    Stosuję switch i case , może trzeba użyć if? Kod repetycji jest taki sam dla wszystkich przycisków.
  • #6
    emarcus
    Level 38  
    akr18 wrote:
    Stosuję switch i case , może trzeba użyć if? Kod repetycji jest taki sam dla wszystkich przycisków.

    Tak, trzeba użyć 'IF' ów.
    Oczywiście kod repetycji jest ten sam (0xFFFFFFFF) , bo to jest standard dla protokołu NEC.

    e marcus
  • #7
    akr18
    Level 10  
    Wraz z zaswieceniem diody ustawiać jakąś zmienną pomocniczą i porównywać ja z kodem repetycji?
  • #8
    akr18
    Level 10  
    Ustawiłem licznik który zwiększa swoją wartość podczas wysyłania kodu repetycji , licznik zatrzymuje się gdy kod repetycji się nie pojawia, jak to zrobić żeby wtedy dioda gasła ?
  • Helpful post
    #9
    emarcus
    Level 38  
    akr18 wrote:
    Ustawiłem licznik który zwiększa swoją wartość podczas wysyłania kodu repetycji , licznik zatrzymuje się gdy kod repetycji się nie pojawia, jak to zrobić żeby wtedy dioda gasła ?

    Pokaż choćby kawałek twojego kodu.....
    Jak dotychczas, nie jest wiadomo co dodać lub co poprawić!
    Luźne i fragmentaryczne podpowiedzi mogą 'nie być zbieżne' (?) z zaczętym konceptem twojego programu.

    e marcus
  • #10
    akr18
    Level 10  
    Ok, jak wrócę do domu to wpiszę ten fragment.

    Dodano po 4 [godziny] 5 [minuty]:

    kod:


    #include <IRremote.h>
    #define pin A2
    #define led A0

    IRrecv irrecv(pin);
    decode_results results;
    int dioda;
    int licznik1 = 0;
    int licznik2 = 0;

    void setup() {

    pinMode(pin, INPUT);
    pinMode(led, OUTPUT);
    irrecv.enableIRIn();

    Serial.begin(9600);

    }

    void loop() {

    if (irrecv.decode(&results)) {
    Serial.println(results.value);

    if (results.value == 16724175) {
    dioda = 1;
    licznik1++;
    }
    if (results.value == 4294967295) {
    if (dioda == 1) {
    licznik2++;
    }

    }
    Serial.println(licznik1);
    Serial.println(licznik2);

    irrecv.resume();
    digitalWrite(led, dioda);

    }
    }
  • Helpful post
    #11
    emarcus
    Level 38  
    akr18 wrote:
    Ustawiłem licznik który zwiększa swoją wartość podczas wysyłania kodu repetycji , licznik zatrzymuje się gdy kod repetycji się nie pojawia, jak to zrobić żeby wtedy dioda gasła ?


    Przestudiuj tą poniżej prezentację:

    https://dronebotworkshop.com/using-ir-remote-controls-with-arduino/

    W okolicy 29-30 minut masz omówioiny ten koncept na przykładzie strowania serva.
    O ile dla servo, czy też steppera nie ma problemu , z uwagi na naturalny, skokowy charakter ich pracy, to dioda może okresowo mrugać.
    Zamiast tego końcowego delay zastosuj raczej opóźnienie mierzone funkcją millis() .

    e marcus
  • #12
    akr18
    Level 10  
    Dzięki , fajna stronka , nie wiem jak to wykorzystać w moim kodzie , dla mnie wystarczyłoby żeby wykryć zatrzymanie licznik2 oznaczające brak sygnału repetycji z pilota i wtedy wykonać zgaszenie diody .
  • Helpful post
    #13
    mpier
    Level 28  
    Witam,
    prawidłową odpowiedź dostałeś już na samym początku od kolegów kulmar i emarcus. Zapomnij o C, spróbuj najpierw zrozumieć problem, wymyśl rozwiązanie (kompletne) i na koniec dopiero zapisz i przetestuj. Samo "kodowanie" to będzie wtedy dziesięć minut. Sposób w jaki to zrobisz nie będzie miał większego znaczenia, ważne żeby na papierze działało. Od tego bym zaczął.
  • Helpful post
    #14
    emarcus
    Level 38  
    akr18 wrote:
    Dzięki , fajna stronka , nie wiem jak to wykorzystać w moim kodzie , dla mnie wystarczyłoby żeby wykryć zatrzymanie licznik2 oznaczające brak sygnału repetycji z pilota i wtedy wykonać zgaszenie diody .

    Przecież sam koncept wykorzystania kodu repetycyjnego możesz 'wyłowić' z tej prezentacji.
    Skoro wybrałeś stosowanie liczników, co jest moim zdaniem wybranie' drogi okrężnej', potrzebowałbyś wprowadzić jakiś timer i w regularnych odstęach sprawdzać czy ten licznik 2 'trzyma' nie zmieniona wartość.
    Prościej jest zamiast incrementować licznik 2, zerować ten timer w momencie otrzymania kodu repetycyjnego i jezeli w wyniku przekroczenia tego 'dozwolonego' czasu, wyłączyć diodę.
    Mniej/więcej tak jak sugerowałem w pierwszym moim poście...
    Na przykład:
    Code: c
    Log in, to see the code
  • #15
    akr18
    Level 10  
    Dopiero próbuję się uczyć, zrozumieć, bardzo dziękuję za pomoc, wyjaśnienie i poświęcony czas!
  • #16
    akr18
    Level 10  
    mpier wrote:
    Witam,
    prawidłową odpowiedź dostałeś już na samym początku od kolegów kulmar i emarcus. Zapomnij o C, spróbuj najpierw zrozumieć problem, wymyśl rozwiązanie (kompletne) i na koniec dopiero zapisz i przetestuj. Samo "kodowanie" to będzie wtedy dziesięć minut. Sposób w jaki to zrobisz nie będzie miał większego znaczenia, ważne żeby na papierze działało. Od tego bym zaczął.


    Jak powinien wyglądać zapis i testowanie na papierze , mógłbym prosić o jakiś prosty przykład?
  • #17
    mpier
    Level 28  
    Bardzo prosty i oklepany przykład:
    Pilot IR , odczyt kodów z pilota w Arduino
    Zaczynasz od lewej i interesujesz się tylko jednym konkretnym stanem, np. LED_OFF. Przejście do stanu LED_ON jest oczywiste. W drugą stronę podobnie. Na rysunku brakuje jeszcze jednego zdarzenia wymuszającego przejście z LED_ON do LED_OFF (wynika z działania pilota ir), możesz dorysować.
  • #18
    emarcus
    Level 38  
    mpier wrote:
    Bardzo prosty i oklepany przykład:

    Zaczynasz od lewej i interesujesz się tylko jednym konkretnym stanem, np. LED_OFF. ......


    Taki model by zalecany I stosowany jakieś 40 do 50 lat temu; lata 70’ i 80’ , kiedy procesory były kosztowne i programowalne 1 tylko raz(!) , które wymagały relatywnie skomplikowanego programatora (21V), a papieru wtedy było ‘pod dostatkiem’ – kraj był mocna zalesiony, a lasy nie były tak przerzedzone i palone (!).
    Ponadto, w owym czasie nie było praktycznie żadnej możliwości debugowania czy też programowej symulacji. Po wielu rozwojowych latach, o wiele łatwiej i szybciej jest napisać jedną, lub dwie/kilka linii kodu w edytorze, ‘wrzucić’ na rzeczywisty uController aby widzieć natychmiastowy skutek.
    Niektóre środowiska IDE mają wbudowany symulator, pomagający zasymulować funkcjonalność programu przed jego finalną wersją gotową na ‘upload’ do uC.
    Często też środowisko programowania wskaże na ewentualnie popełnione błędy, tuż przed próbą kompilacji; a papier raczej ‘cienki’ zalecany jest zwijać w rolki i zawieszać w szaletach miejskich, z nadzieją że ludzie może zaprzestaną pisać po ścianach niezrozumiałe slogany w stylu ‘|||’ czy też: 111 (sto jedenaście).
    Nie znaczy to jednak że mają coś pisać na tym papierze!!!

    W obecnym czasie praktykuje się, że koncept i algorytm programu, jest tworzony w głowie programisty, a edytor/kompiler służy jako narzędzie pośrednie pomiędzy myślą a procesorem, podobnie tak jak dłuto/młotek, pędzel w rękach rzemieślnika/artysty.
    Nawet kowal wie co ma robić zaczym rozgrzeje żelazo...

    e marcus
  • Helpful post
    #19
    powerT
    Level 9  
    Wykorzystaj inną bibliotekę i po temacie. Też walczyłem z tematem i mi się znudziło. W załączniku masz 3 pliki, wrzuć je do katalogu z projektem i wklep tylko to. Kody otrzymujesz w postaci liczb od 0 do 99, nie ma błędów i dziwnych innych kosmicznych cyferek


    Code:

    #include "RichUNOIRremote.h";
    #define pilot_PIN 11

    IRrecv PILOT(pilot_PIN);                             

    void setup
    {
         Serial.begin(9600);
         PILOT.enableIRIn();
    }

    void loop
    {
      unsigned int kod = 100;                            // do kod będzie zapisywany keycode z pilota
     
      if (PILOT.decode())                         
      {                                                         
        if(PILOT.isReleased()) kod = PILOT.keycode;     
        PILOT.resume();                                           
      }     
     
      if(kod != 100)
      {
         Serial.print(F("Kod zczytany to :"));
         Serial.println(kod);
       }
    }


    ewentualnie dopisz zamiast if(kod!=100){} to, jak się zgadzają, bo to standardowy dołączany pilot do czujników IRremote. Mi na 3 pilotach pokazywało tak samo (tych z zestawu) chyba, że korzystasz z innego bo czy to od TV, Bluraya itp itd też czyta i podaje konkretne liczby. Przed break; wpisujesz funkcję do wywołania i pilot rozgryziony :)

    Code:

    switch (kod)                                                 
      {                                                           
            case  22:  break;                         // 22 to klawisz 0
            case  12:  break;                         // 12 to klawisz 1
            case  24:  break;                         // 24 to klawisz 2
            case  94:  break;                         // 94 to klawisz 3
            case   8:   break;                         //  8 to klawisz 4
            case  28:  break;                        // 28 to klawisz 5
            case  90:  break;                        // 90 to klawisz 6
            case  66:  break;                        // 66 to klawisz 7
            case  82:  break;                        // 82 to klawisz 8
            case  74:  break;                        // 74 to klawisz 9
            case  13:  break;                       //Serial.println("Press  C"); 
            case  25:  break;                       //Serial.println("Press  -");
            case  64:  break;                       //Serial.println("Press  +");
            case  21:  break;                        //Serial.println("Press  OK");
            case  68:  break;                       //Serial.println("Press  TEST");
            case  67:  break;                        //Serial.println("Press  BACK");
            case   7:  break;                         // 7 to klawisz w lewo (poprzedni) key 20
            case   9:  break;                        // 9 to klawisz w prawo (następny) key 21
            case  69:  break;                      //Serial.println("Press  ON/OFF");
            case  71:  break;                      //Serial.println("Press  MENU"); 
      }