Skocz do zawartości

IR VS 1838B + Knight rider


Pomocna odpowiedź

Napisano

Witam mam problem. Otóż to program który napisałem działa, odczytuje klawisz pilota, gdy wciśnięty odpowiedni klawisz wywołuje funkcje start. Problem polega w tym że jest ona wykonana raz a chciałbym aby ten sam klawisz włączał i ponowne jego wciśnięcie wyłączał daną funkcje i czekał na wciśnięcie innych klawiszy np przód, tył, itp.

o to kod

/*
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/


#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
int timer=120; 

void setup()
{

Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
// użyj pętli for aby zainicjować każdy port jako wyjście
 for(int thisPin=2;thisPin<7;thisPin++){
   pinMode(thisPin,OUTPUT);
 }
}
void start(){
 // pętla od najniższego do najwyższego
 for(int thisPin=2;thisPin<7;thisPin++){
   // włączenie:
   digitalWrite(thisPin,HIGH);
   delay(timer);
   // wyłączenie:
   digitalWrite(thisPin,LOW);
 }

 // pętla od najwyższego pinu do najniższego:
 for(int thisPin=6;thisPin>=2;thisPin--){
   // włączenie:
   digitalWrite(thisPin,HIGH);
   delay(timer);
   // wyłączanie:
   digitalWrite(thisPin,LOW);
 }
}
void loop() {

if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
Serial.println(results.value);
irrecv.resume(); // Receive the next value
int key = results.value;
switch(key){
 case 0xD7E84B1B: start();
 break;
}

//button 1
//if(i1 == 0 && results.value == 0xD7E84B1B)

//{
//start();
//i1 = 0;
//}
//else if(i1 == 0 && results.value == 0xD7E84B1B)
//{
//stop();
//i1 = 0;

}

}

program ma sterować autem, załączać diody, dźwięk itp

kolejne pytanie jak przerobić ten program żeby każda funkcja była wykonywana tak długo jak jest wciśnięty dany klawisz ?

To jak, pomoże ktoś z programem dla dwóch diod Led? Jedną się świeci gdy odpowiedni klawisz jest cały czas wcisniety (puszczenie wyłączy diode) drugi przycisk pilota uruchamia mruganie druga dioda?

Jak myślisz, dlaczego nikt się nie kwapi z tłumaczeniem? Bo musiałby zrobić kolejny wykład o tworzeniu programów robiących wiele rzeczy na raz w środowisku pozbawionym wielozadaniowego systemu operacyjnego. To nie jest proste, bo wymaga całościowego spojrzenia na system, sensownego podziału zadań a przede wszystkim umiejętności dostrzeżenia zadań wykonywanych równolegle. Czas wyjść z piaskownicy, prawda?

Chciałbyś, by w jednym procesorze jednocześnie trwał odbiór komend i ich wykonywanie. Jedna diodka ma wciąż mrugać a druga nie, a jeszcze gdzieś tam musisz odbierać dane przez IR. Zacznij od tego:

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview

http://www.instructables.com/answers/multiple-processes-in-arduino/

https://ccrma.stanford.edu/~gurevich/Feijs_ArduinoMultitasking.pdf

https://github.com/ivanseidel/ArduinoThread

i generalnie szukaj w wyszukiwarce haseł multi-tasking, concurrent tasks, multithreading itp.

Podstawą w takich aplikacjach jest pisanie wszystkich funkcji tak by były nieblokujące i wracały po wywołaniu najszybciej jak się da lub użycie systemu operacyjnego z wywłaszczaniem - ale to na AVR nie jest fajne, bo pożera mnóstwo zasobów. Tak więc jeśli np. Twoja funkcja odbierająca dane z odbiornika IR zatrzymuje się (zwisa) do czasu odebrania prawidłowego kodu, jej użycie jest tu wykluczone. Kiedyś wrzuciłem tu odbiór RC5 działający wyłącznie na przerwaniu i takich przykładów w sieci jest na pewno dużo. Coś takiego będzie odbierało kody ciągle "pod spodem", niezależnie od tego co robi program główny. Drugi proces - pracujący na przerwaniu od timera może mrugać diodkami. A program główny może tym zarządzać i całosc jest wtedy elegancko prosta, przejrzysta i.. działa 🙂 - to tak w skrócie. Najpierw jednak poczytaj i sobie to wyobraź.

Rozumiem. Hmm to mam problem. A czy program który będzie sprawdzał czy klawisz jest wyciśnięty jeżeli tak to dioda bedzie się świecić lub mrugac to też skomplikowany program?

Witaj.

Tworzac pojazd sterowany pilotem od tv mialem podobny problem. Rozwiazalem go dodajac biblioteke timera, aby funkcja niby miala sie odbyc w tle. Poczytaj o wielozadaniowosci arduino bo chyba tego potrzebujesz.

Wiec znalazłem, jest tu trochę śmietnik ale zobaczmy:

#include <IRremote.h>
#include "Timer.h"

#define irPin 6
Timer t;
IRrecv irrecv(irPin);
decode_results results;
int pred;
int afterEvent;
int pred1;


void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
 pred = 0;
 pred1 = 200;
 pinMode(10, OUTPUT); //Sygnał PWM silnika nr 1
 pinMode(11, OUTPUT); //Sygnały sterujące kierunkiem obrotów silnika nr 1
 pinMode(12, OUTPUT);

 pinMode(9, OUTPUT); //Sygnał PWM silnika nr 2
 pinMode(8, OUTPUT); //Sygnały sterujące kierunkiem obrotów silnika nr 2
 pinMode(7, OUTPUT);

 digitalWrite(11, LOW); //Silnik nr 1 - stop
 digitalWrite(12, LOW);
 analogWrite(10, pred);
 digitalWrite(8, LOW); //Silnik nr 2 - stop
 digitalWrite(7, LOW);
 analogWrite(9, pred);

}
 void doAfter()
{
           analogWrite(9, 0);
           analogWrite(10, 0);  
           Serial.println(" hamulec");
           }

void loop() {
 t.update();
  if (irrecv.decode(&results)) {

     switch (results.value) {
        case 0xE0E0A659:
           afterEvent = t.after(200, doAfter);
           Serial.println("w lewo");
               digitalWrite(11, LOW); //Silnik nr 1 - obroty w lewo
               digitalWrite(12, HIGH);
               digitalWrite(8, HIGH); //Silnik nr 2 
               digitalWrite(7, LOW);
               analogWrite(9, pred1);
               analogWrite(10, pred1);
           break;

        case 0xE0E006F9:

           Serial.println("w gore");
              afterEvent = t.after(200, doAfter);         
              digitalWrite(11, HIGH); //Silnik nr 1 - obroty w lewo
              digitalWrite(12, LOW);
              digitalWrite(8, HIGH); //Silnik nr 2 - obroty w lewo
              digitalWrite(7, LOW);
               analogWrite(9, pred1);
               analogWrite(10, pred1);

           break;

        case 0xE0E046B9:
           afterEvent = t.after(200, doAfter);
           Serial.println("w prawo");
               analogWrite(9, pred1);
               analogWrite(10, pred1);
               digitalWrite(11, HIGH); //Silnik nr 1 - obroty w lewo
               digitalWrite(12, LOW);
               digitalWrite(8, LOW); //Silnik nr 2 
               digitalWrite(7, HIGH);
           break;

        case 0xE0E08679:
           afterEvent = t.after(200, doAfter);
           Serial.println("w dol");

                digitalWrite(11, LOW); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, HIGH);
                digitalWrite(8, LOW); //Silnik nr 2 
                digitalWrite(7, HIGH);
                analogWrite(9, pred1);
                analogWrite(10, pred1);

           break;

        case 0xE0E016E9:
           afterEvent = t.after(200, doAfter);
           Serial.println("srodek");
                analogWrite(9, 0);
                analogWrite(10, 0);
                digitalWrite(11, LOW); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, LOW);
                digitalWrite(8, LOW); //Silnik nr 2 
                digitalWrite(7, LOW);
           break;


        case 0xE0E01AE5:
           afterEvent = t.after(200, doAfter);
           Serial.println("return");
                analogWrite(9, pred1);
                analogWrite(10, pred1);
                digitalWrite(11, HIGH); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, LOW);
                digitalWrite(8, LOW); //Silnik nr 2 
                digitalWrite(7, LOW);
           break;

        case 0xE0E0D22D:
           afterEvent = t.after(200, doAfter);
           Serial.println("tools");
                analogWrite(9, pred1);
                analogWrite(10, pred1);
                digitalWrite(11, LOW); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, LOW);
                digitalWrite(8, HIGH); //Silnik nr 2 
                digitalWrite(7, LOW);
           break;

        case 0xE0E0F807:
           afterEvent = t.after(200, doAfter);
           Serial.println("info");
                analogWrite(9, pred1);
                analogWrite(10, pred1);
                digitalWrite(11, LOW); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, LOW);
                digitalWrite(8, LOW); //Silnik nr 2 
                digitalWrite(7, HIGH);       
              break;             

        case 0xE0E0B44B:
           afterEvent = t.after(200, doAfter);
           Serial.println("exit");
                analogWrite(9, pred1);
                analogWrite(10, pred1);
                digitalWrite(11, LOW); //Silnik nr 1 - obroty w prawo
                digitalWrite(12, HIGH);
                digitalWrite(8, LOW); //Silnik nr 2 
                digitalWrite(7, LOW);
             break;             

         case 0xE0E036C9:
             pred1 = 255;
             break;

         case 0xE0E028D7:
             pred1 = 200;
             break;

         case 0xE0E0A857:
             pred1 = 160;
             break;

         case 0xE0E06897:
             pred1 = 120;
             break;
         }

  irrecv.resume();
  }
 }

Szybki opis,
włączając silniki, uruchamiany wewnętrzny timer odliczający do zatrzymania silników.

Jako iż irda nadaje impulsowo to czasy opóźnienia dobrałem eksperymentalnie.

Czyli jeśli trzymamy przyciśnięty przycisk na pilocie timer resetuje czas odliczania a nasz pojazd się porusza, gdy puścimy przycisk mamy opóźnienia 200ms do zatrzymania auta.

Reszta jest typowa z biblioteki IRremote.h.

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...