Difference between revisions of "Arduino - Infrarood afstandbediening"
(→Het programma) |
|||
| Line 33: | Line 33: | ||
<pre> | <pre> | ||
| − | + | #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 | ||
| + | int count = results->rawlen; | ||
| + | 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: "); | ||
| + | } | ||
| + | Serial.print(results->value, HEX); | ||
| + | Serial.print(" ("); | ||
| + | Serial.print(results->bits, DEC); | ||
| + | Serial.println(" bits)"); | ||
| + | } | ||
| + | Serial.print("Raw ("); | ||
| + | Serial.print(count, DEC); | ||
| + | Serial.print("): "); | ||
| + | |||
| + | for (int i = 0; i < count; i++) | ||
| + | { | ||
| + | if ((i % 2) == 1) { | ||
| + | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); | ||
| + | } else { | ||
| + | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); | ||
| + | } | ||
| + | Serial.print(" "); | ||
| + | } | ||
| + | Serial.println(""); | ||
| + | } | ||
| + | |||
| + | 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 | ||
| + | } | ||
| + | |||
| + | int on = 0; | ||
| + | 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 | ||
| + | digitalWrite(13, on ? HIGH : LOW); | ||
| + | showResults(&results); // LET OP: hier moet "&results" gebruikt omdat de functie "*results" gebruikt | ||
| + | } | ||
| + | last = millis(); | ||
| + | irrecv.resume(); // ontvang de volgende waarde | ||
| + | } | ||
| + | } | ||
</pre> | </pre> | ||
Revision as of 13:54, 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.
NEC protocol
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 38 kHz knipperen. 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).
|
| 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 38 kHz. Daarna moet de ontvanger de eentjes en nulletjes zien te ontdekken. Meestal gebruiken we daarvoor een speciaal element, een IR ontvanger, terwijl de bulk van de software simpelweg beschikbaar is 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, zoat we ons hier kunnen concentreren op de ontvanger. De bibliotheek os bovendien geschikt voor meerdere protocollen, waaronder dus NEC, SONY, RC5 en RC6.
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
int count = results->rawlen;
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: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++)
{
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
} else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
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
}
int on = 0;
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
digitalWrite(13, on ? HIGH : LOW);
showResults(&results); // LET OP: hier moet "&results" gebruikt omdat de functie "*results" gebruikt
}
last = millis();
irrecv.resume(); // ontvang de volgende waarde
}
}
Uitleg
Beetje spelen
Verdiepende opdrachtjes
