Difference between revisions of "Arduino - Infrarood afstandbediening"
(→Het programma) |
(→Uitleg) |
||
| Line 127: | Line 127: | ||
De functie ''showResults()'' leunt natuurlijk erg op de ''results'' variabele zelf. Deze is van het type ''decode_results'' en heeft intern het ''decode_type'' (integer), en een ''value'' (unsigned long). Daarnaast kun je via ''decode_results'' rechtstreeks de bits van het signaal benaderen, waarbij ''rawlen'' aangeeft hoeveel bits er zijn. Voor het ''decode_type'' heeft de library een serie voorgeprogrammeerde waarden zoals NEC, SONY, en RC5. Dit zijn dus geen teksten (tussen quotjes) maar namen van (integer) constanten. | De functie ''showResults()'' leunt natuurlijk erg op de ''results'' variabele zelf. Deze is van het type ''decode_results'' en heeft intern het ''decode_type'' (integer), en een ''value'' (unsigned long). Daarnaast kun je via ''decode_results'' rechtstreeks de bits van het signaal benaderen, waarbij ''rawlen'' aangeeft hoeveel bits er zijn. Voor het ''decode_type'' heeft de library een serie voorgeprogrammeerde waarden zoals NEC, SONY, en RC5. Dit zijn dus geen teksten (tussen quotjes) maar namen van (integer) constanten. | ||
| − | De functie vergelijkt dus de waarde van ''results-> | + | De functie vergelijkt dus de waarde van ''results->decode_type'' met voorgeprogrammeerde waarden, zoals UNKNOWN, NEC, en SONY. Indien een van deze waarden wordt herkend, wordt de naam van het herkende protocol op de Serial Monitor gezet: |
<pre> | <pre> | ||
Serial.print("Decoded SONY: "); | Serial.print("Decoded SONY: "); | ||
Revision as of 16:41, 31 January 2018
Infrarood is onzichtbaar licht. De golflengte van dat licht is wat langer dan van rood licht en onze ogen zijn daarvoor ongevoelig. Infrarood licht kan wel worden waargenomen met een digitale camera. Met bijvoorbeeld de camera van je mobieltje kun je in veel gevallen zien wanneer een afstandbediening een signaal uitzendt. Maar sommige mobieltjes hebben zo'n goed infrarood filter dat het daarbij niet werkt. In elk geval zend een IR afstandbediening infrarood licht uit dat door een ontvanger wordt gezien. Het uitgezonden licht is niet gewoon een lamp die aan of uit staat, maar een snel knipperend lampje, waarbij informatie verstopt zit in de knippering. Daardoor kan zo'n afstandbediening complexe opdrachten geven.
Contents
IR communicatieprotocol
Voor het coderen van informatie in de knippering van afstandbedieningen bestaan diverse protocollen. Een veelgebruikt protocol is het NEC protocol. Hierbij wordt een digitaal signaal doorgegeven dat steeds bestaat uit 16 bits. Een bit is simpelweg een 1 of een 0. Van de 16 bits zijn de eerste 8 bits het adres, terwijl de tweede 8 bits staan voor het commando. Simpel gezegd geeft het adres aan voor wie het signaal is bedoeld (TV, Video recorder, etc.), terwijl het commando aangeeft wat er moet gebeuren. Met 8 bits heb je genoeg voor 1024 adressen en dus ook 1024 commando's. Andere protocollen zijn o.a.: SONY, RC5 en RC6.
Het NEC protocol gebruikt een standaard knipperfrequentie van 38 kHz. Dat wil zeggen dat het lapmje 38 duizend keer per seconde aan en uit gaat. Dit wordt gedaan om verstoring door andere bronnen te vermijden; de ontvanger reageert alleen op lampjes die met ongeveer 38 kHz knipperen. Andere bronnen van infrarood licht hebben dan geen effect. Voor het doorgeven van een 0-bit geeft de zender een korte tijd een knipper-signaal en zet daarna het lampje even uit. Voor het doorgeven van een 1-bit geeft de zender ook een korte tijd een knipper-signaal, maar zet daarna het lampje wat langer uit. Een 0 heeft dus een korte pauze en een 1 een lange pauze. Er komt nog wel wat meer bij kijken, maar het belangrijkste is hiermee gezegd. Overigens hebben andere protocollen andere kenmerken. Zo heeft het SONY protocol een draagfrequentie van 40 kHz en meerdere modi (12 bit tot 20 bit). In het algemeen vallen de draagfrequenties van afstandbedieningen tussen de 30 en 56 kHz en kun je mogelijk niet alle draagfrequenties met dezelfde ontvanger bedienen.
|
| Digitale 0 en digitale 1 volgens het NEC protocol |
Als zender heb je niet meer nodig dan een eenvoudige infrarood LED met weerstand. De ontvanger bestaat uit een infrarood sensor die filtert op ongeveer 40 kHz (geschikt voor alle gangbare protocollen). Meestal gebruiken we daarvoor een speciaal element: een IR ontvanger. Daarna moeten we de eentjes en nulletjes zien te ontdekken uit het ontvangen signaal. De software die hiervoor nodig is vinden we simpelweg in een kant en klare bibliotheek: IRremote.h. Met deze bibliotheek kun je zowel een infrarood zender als een ontvanger aansturen. We nemen aan dat je beschikt over een infrarood afstandbediening (zender), zodat we ons hier kunnen concentreren op de ontvanger. De bibliotheek is bovendien geschikt voor meerdere protocollen, waaronder dus NEC, SONY, RC5 en RC6. Dit zullen we in dit project ook zien zodat het voor nu niet nodig is om het protocol van je afstandbediening vooraf te weten.
De schakeling
Omdat we ons hier zuiver willen concentreren op de techniek, houden we het project zo eenvoudig mogelijk. De software geeft resultaten door aan de PC via de Serial Monitor; we gaan hier geen dingen of lampjes besturen.
Extra benodigdheden:
- 1 infrarood afstandbediening (zender)
- 1 infrarood ontvanger module
| Bestand:naam bestand.png |
| Beschrijving bovenstaande figuur |
Het programma
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results; // variabele voor gedecodeerde resultaten
void showResults(decode_results *results) { // LET OP: "*results" ipv "results" => directe toegang tot de variabele
if (results->decode_type == UNKNOWN)
{
Serial.println("Onbekend protocol: kan helaas niet decoderen");
} else {
if (results->decode_type == NEC)
{
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY)
{
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5)
{
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6)
{
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == DISH)
{
Serial.print("Decoded DISH: ");
}
else if (results->decode_type == SHARP)
{
Serial.print("Decoded SHARP: ");
}
else if (results->decode_type == PANASONIC)
{
Serial.print("Decoded PANASONIC: ");
}
else if (results->decode_type == JVC)
{
Serial.print("Decoded JVC: ");
}
else if (results->decode_type == SANYO)
{
Serial.print("Decoded SANYO: ");
}
else if (results->decode_type == MITSUBISHI)
{
Serial.print("Decoded MITSUBISHI: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
}
void setup() {
pinMode(RECV_PIN, INPUT);
pinMode(13, OUTPUT); // OnBoard LEDje knippert bij signaal
Serial.begin(9600); // Start de Serial monitor
irrecv.enableIRIn(); // Start de ontvanger software
}
bool on = false;
unsigned long last = millis();
void loop() {
if (irrecv.decode(&results))
{
// Laat het OnBoard LEDje knipperen en toon results
if (millis() - last > 250) // niet vaker dan 4x per secone (elke 250ms)
{
on = !on; // "!" is "NOT": aan gaat uit en uit gaat aan
if (on==true) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
showResults(&results); // LET OP: hier moet "&results" gebruikt omdat de functie "*results" gebruikt
}
last = millis();
irrecv.resume(); // ontvang de volgende waarde
}
}
Uitleg
De setup() methode zet de pin-modes van de pin voor de IR receiver (pin 11) en de pin van de interne LED (pin 13) in output-mode. Daarna wordt de seriele interface gestart en ook de software van de IRremote bibliotheek.
De loop() methode kijkt continu naar de receiver op pin 11. Indien de functie irrecv.decode() aangeeft dat er een signaal is uitgelezen, gaat de methode die informatie verwerken. Die informatie is dan al opgeslagen in de results variabele. Allereerst zal de OnBoard LED aan- of juist uitgezet worden (tot 4x per seconde). Daarna zal de uitgelezen waarde worden weggeschreven naar de Serial Monitor. Voor dat laatste roept het de functie showResults() aan.
De functie showResults() leunt natuurlijk erg op de results variabele zelf. Deze is van het type decode_results en heeft intern het decode_type (integer), en een value (unsigned long). Daarnaast kun je via decode_results rechtstreeks de bits van het signaal benaderen, waarbij rawlen aangeeft hoeveel bits er zijn. Voor het decode_type heeft de library een serie voorgeprogrammeerde waarden zoals NEC, SONY, en RC5. Dit zijn dus geen teksten (tussen quotjes) maar namen van (integer) constanten.
De functie vergelijkt dus de waarde van results->decode_type met voorgeprogrammeerde waarden, zoals UNKNOWN, NEC, en SONY. Indien een van deze waarden wordt herkend, wordt de naam van het herkende protocol op de Serial Monitor gezet:
Serial.print("Decoded SONY: ");
Na het printen van de naam van het protocol, print de functie de value in HEX format. Deze value is in het algemeen het gegeven waarmee je een bepaalde functie zou uitvoeren, tenminste als je echt een actie zou willen koppelen aan het gebruiken van de afstanbediening. Die value werd, nadat het protocol herkend werd, ook meteen bepaald. Ook het aantal bits waaruit die value bestaat wordt tussen haakjes weergegeven. Dit aantal is afhankelijk van het protocol.
Tenslotte worden alle details van het resultaat weergegeven in de vorm van raw data. Daarvoor dient de laatste for-loop. De loop print in feite count keer de waarde van rawbuf[] in decimaal (DEC) format. De waarde van count is eerder al gelijk gesteld aan results->rawlen zijnde het aantal bytes in rawbuf[].
Beetje spelen
Verdiepende opdrachtjes
