Arduino afstandbediening

Uit RobotMC.be
Versie door BlueHaze (overleg | bijdragen) op 29 dec 2017 om 22:28
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Ga naar: navigatie, zoeken

Inleiding

Kom je ook altijd knopjes tekort op je robot? Dan is een oude afstandsbediening van een televisie o.i.d. een uitkomst. Je hebt alleen een IR detector nodig, zoals de TSOP4838. Deze heeft slechts 3 aansluitingen: 5V, massa en de uitgang. Op het internet vind je makkelijk een beschrijving hoe deze aan te sluiten.

Software

De standard Arduino library voor afstandbediening ondersteunt vele protocollen. Dat is een voordeel, maar daardoor is het een vrij zware library voor de kleinere Arduino's. Guy Carpenter een mooie, compacte library gemaakt voor het RC5 protocol. Dit protocol is oorspronkelijk door Philips ontwikkeld, maar is inmiddels wijdverbreid. Veel afstandsbedieningen van Europeese makelij gebruiken dit. En voor een paar euro koop je in het verre oosten een RC2034301 compatible afstandsbediening, die RC5 gebruikt.

De library heeft echter een nadeel: hij vraagt aandacht... Meer concreet: je moet de read() functie regelmatig aanroepen, zodat de library kan bepalen wanneer de uitgang van de IR detector van niveau verandert.

Gelukkig is er een andere library die dit voor ons in de achtergrond kan oplossen: PinChangeInt. Deze kan een functie aanroepen bij een niveauverandering op een pin. Precies wat we nodig hebben! Het enige wat nog ontbreekt is de code om dit aan elkaar te lijmen:

//---------------------------------------------------------------------------------------
// RC5 stuff start
#include <PinChangeInt.h>
#include <RC5.h> 

int Rc5Data;  // Set on receive, feel free to set to zero when done.
int IR_PIN = 7; // De TSOP uitgang is aangesloten op pin 7 van de Arduino

RC5 rc5(IR_PIN);

void Rc5Isr()
{ static unsigned int   PrevMessage;
   unsigned int Message;

   if (rc5.read(&Message)) {
      if (Message != PrevMessage) {
         Rc5Data     = Message & 0xF7FF; // strip the toggle flag
         PrevMessage = Message;
      }
   }
}
// Rc5 stuff done (but do not forget to attach Rc5Isr() to IrPin).
//---------------------------------------------------------------------------------------

Aan het begin krijgt de variabele IR_PIN de waarde 7, om aan te geven dat de TSOP op deze pin is aangesloten. Maar je kunt ook een andere pin gebruiken als dat beter uitkomt.

En zoals de laatste regel aangeeft: je moet ook een regel toevoegen aan de setup() functie:

 // Link PinChange interrupt to RC5 reader.
 PCintPort::attachInterrupt(IR_PIN, &Rc5Isr, CHANGE);

Zodra een knop wordt ingedrukt, wordt de waarde hiervan in de de variabele Rc5Data gezet. De waarde blijft ongewijzigd totdat een andere knop wordt ingedrukt. Je kunt deze waarde als volgt gebruiken:

 if (Rc5Data) {
   // doe iets met de waarde van Rc5Data, bijvoorbeeld met een switch statement:
   switch(Rc5Data) {
     case 0x3740 : /* actie hier */  break;
     case 0x3741 : /* actie hier */  break;
     default:    /* onbekende_toets actie hier */ break;
   }
   Rc5Data = 0;
 }  

Aan het einde wordt Rc5Data op 0 gezet. Dit heeft twee functies. Ten eerste zorgt dit ervoor dat je de actie maar 1x uitvoert als een toets wordt ingedrukt (en niet tot de volgende toets). Daarnaast is het nodig om te zien dat dezelfde knop opnieuw wordt ingedrukt.

Tot slot

De PinChangeInt library wordt niet langer onderhouden. Als alternatief wordt de EnableInterrupt library voorgesteld. Ik gebruik de PinChangeInt library in vele projecten. Dat werkt prima voor mij en ga dat nog niet omzetten. Maar als je nog geen pin interrupt library gebruikt, zou ik zeker deze nieuwe library proberen!