Oude afstandsbedieningen hergebruiken: Bouw slimme apparaten met Arduino
Onderdelen en benodigdheden
| Onderdeel | Aantal | Opmerking |
|---|---|---|
| Arduino Nano R3 | 1 | |
| 5 mm LED: Rood | 3 | Eén voor status, kleur van de rest niet kritiek |
| 5 mm LED: Groen | 1 | Kleur niet kritiek |
| 5 mm LED: Geel | 1 | Kleur niet kritiek |
| Blauwe LED | 2 | Kleur niet kritiek |
| Solderloos breadboard (volledige grootte) | 1 | |
| Draadjes (generic) | 1 | |
| Wipschakelaar (SPST, Off-On) | 1 | Elke SPST wipschakelaar werkt |
| SparkFun Breadboard Voeding 5V/3.3V | 1 | Optioneel als 5V elders vandaan komt |
| IR-ontvanger (generic, bv. KY-022 37.9 kHz) | 1 |
Over dit project
Dit project laat u oude afstandsbedieningen van videorecorders, TV's, DVD-spelers, enz. hergebruiken om apparaten zoals lampen, verwarming, enz. aan te sturen via relays, power-transistors of wat ook een 5V-signaal kan schakelen. In de demo worden 6 LED's getoggled.
Hoe het werkt
De sketch leert 6 IR-codes van een willekeurige afstandsbediening (bijv. toetsen 1–6) en slaat ze op in de EEPROM van de Arduino Nano. De codes blijven bewaard na reset of stroomuitval. Elke onbekende IR-code fungeert als reset en zet alle uitgangen uit.
Programmeren (Learn-modus)
- Zet de wipschakelaar op "Learn" → rode status-LED brandt.
- LED 1 knippert: druk de gewenste toets op de afstandsbediening.
- Bij herkenning knippert de status-LED snel (trillingseffect) en gaat het naar LED 2.
- Herhaal voor alle 6 LED's.
- Na afloop knippert de status-LED langzaam (1 Hz) → zet schakelaar terug op "Run".
Dubbele codes worden gedetecteerd bij opstarten; de betrokken LED's knipperen ter waarschuwing.
Uitbreiding naar relays
De uitgangen kunnen in parallel met relays worden geschakeld om 230V-apparaten te besturen. Let op: sommige relays schakelen op 0V (laag), anderen op 5V (hoog). Gebruik eventueel een CD4011 quad NAND-gate voor signaalinversie. Wees voorzichtig met netsspanning – gevaar voor levensgevaarlijke schokken!
Code
/* Toggle 6 LEDs met IR-afstandsbediening – hergebruik oude remotes
Paul M Dunphy VE1DX, maart 2020 */
#include <IRremote.h>
#include <EEPROM.h>
long unsigned int intIRCode;
long unsigned int savedIRCodes[6];
long unsigned int dupeCheck[6];
const int Recv_Pin = 2;
const int PinOne = 12, PinTwo = 11, PinThree = 10, PinFour = 9, PinFive = 8, PinSix = 7;
const int switchPin = 4;
const int statusPin = 5;
const unsigned long int repeatKeyPress = 0xFFFFFFFF;
boolean learnMode, first_iteration;
int togglestate1=0, togglestate2=0, togglestate3=0, togglestate4=0, togglestate5=0, togglestate6=0;
int remote_code_1, remote_code_2, remote_code_3, remote_code_4, remote_code_5, remote_code_6;
IRrecv irrecv(Recv_Pin);
decode_results results;
// EEPROM helpers voor 32-bit integers
void EEPROMWritelong(int address, long value) {
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
EEPROM.write(address, four);
EEPROM.write(address+1, three);
EEPROM.write(address+2, two);
EEPROM.write(address+3, one);
}
long EEPROMReadlong(long address) {
long four = EEPROM.read(address);
long three = EEPROM.read(address+1);
long two = EEPROM.read(address+2);
long one = EEPROM.read(address+3);
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
int Flip_LED(int led, int toggle_state) {
if (toggle_state == 0) { digitalWrite(led, HIGH); return 1; }
else { digitalWrite(led, LOW); return 0; }
}
void Reset() {
digitalWrite(PinOne, LOW); digitalWrite(PinTwo, LOW); digitalWrite(PinThree, LOW);
digitalWrite(PinFour, LOW); digitalWrite(PinFive, LOW); digitalWrite(PinSix, LOW);
togglestate1=togglestate2=togglestate3=togglestate4=togglestate5=togglestate6=0;
}
void guessType() {
Serial.print("Remote appears to be a ");
switch (results.decode_type) {
case NEC: Serial.println("NEC"); break;
case SONY: Serial.println("SONY"); break;
case RC5: Serial.println("RC5"); break;
case RC6: Serial.println("RC6"); break;
case DISH: Serial.println("DISH"); break;
case SHARP: Serial.println("SHARP"); break;
case JVC: Serial.println("JVC"); break;
case SANYO: Serial.println("SANYO"); break;
case MITSUBISHI: Serial.println("MITSUBISHI"); break;
case SAMSUNG: Serial.println("SAMSUNG"); break;
case LG: Serial.println("LG"); break;
case WHYNTER: Serial.println("WHYNTER"); break;
case AIWA_RC_T501: Serial.println("AIWA_RC_T501"); break;
case PANASONIC: Serial.println("PANASONIC"); break;
case DENON: Serial.println("DENON"); break;
default: Serial.println("UNKNOWN"); break;
}
}
void Confirm() {
for(int i=0; i<=20; i++) { digitalWrite(statusPin, HIGH); delay(50); digitalWrite(statusPin, LOW); delay(50); }
digitalWrite(statusPin, HIGH);
}
void learn_Mode() {
int pins[6] = {12,11,10,9,8,7};
if (first_iteration) { Serial.println(); Serial.println("Entering learn mode"); Serial.println(); }
int location = 0, j = 0;
while (j <= 5) {
for(int i=0; i<=25; i++) {
digitalWrite(pins[j], HIGH); delay(200);
if (irrecv.decode(&results)) { intIRCode = results.value; irrecv.resume(); }
digitalWrite(pins[j], LOW); delay(200);
if (irrecv.decode(&results)) { intIRCode = results.value; irrecv.resume(); }
if (intIRCode != repeatKeyPress && intIRCode != 0) { i=30; }
}
if (intIRCode != repeatKeyPress && intIRCode != 0) {
if (j==0) guessType();
Serial.print("Writing to EEPROM Location "); Serial.print(location);
Serial.print(" IR code = "); Serial.println(intIRCode, HEX);
EEPROMWritelong(location, intIRCode);
location += 4; j++; Confirm(); intIRCode = 0; irrecv.resume();
}
}
Serial.println(); Serial.println("Put Arduino back in run mode.");
while (digitalRead(switchPin) == HIGH) { digitalWrite(statusPin, HIGH); delay(1000); digitalWrite(statusPin, LOW); delay(1000); }
Serial.println("Returning to run mode.");
delay(50); Serial.flush(); delay(50); asm volatile ("jmp 0");
}
void run_Mode() {
if (first_iteration) Serial.println("Entering run mode");
if (irrecv.decode(&results)) {
if (results.value != repeatKeyPress) {
current_remote_code = results.value;
Serial.print("Key press detected, IR code = "); Serial.println(current_remote_code, HEX);
if (current_remote_code == remote_code_1) togglestate1 = Flip_LED(PinOne, togglestate1);
else if (current_remote_code == remote_code_2) togglestate2 = Flip_LED(PinTwo, togglestate2);
else if (current_remote_code == remote_code_3) togglestate3 = Flip_LED(PinThree, togglestate3);
else if (current_remote_code == remote_code_4) togglestate4 = Flip_LED(PinFour, togglestate4);
else if (current_remote_code == remote_code_5) togglestate5 = Flip_LED(PinFive, togglestate5);
else if (current_remote_code == remote_code_6) togglestate6 = Flip_LED(PinSix, togglestate6);
else Reset();
}
delay(500); irrecv.resume();
}
}
void setup() {
first_iteration = true;
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(PinOne, OUTPUT); pinMode(PinTwo, OUTPUT); pinMode(PinThree, OUTPUT);
pinMode(PinFour, OUTPUT); pinMode(PinFive, OUTPUT); pinMode(PinSix, OUTPUT);
Reset();
pinMode(statusPin, OUTPUT); pinMode(switchPin, INPUT);
// Controleer EEPROM op 0xFFFFFFFF (nieuwe Nano's)
boolean defaultToSony = false;
long unsigned int IRCode; int location = 0;
for(int i=0; i<=5; i++) { IRCode = EEPROMReadlong(location); if (IRCode == repeatKeyPress) defaultToSony = true; location += 4; }
if (defaultToSony) {
Serial.println("0xFFFFFFFF in EEPROM gevonden. Standaard Sony RM-YD104 codes geladen.");
EEPROMWritelong(0, 0x10); delay(50);
EEPROMWritelong(4, 0x810); delay(50);
EEPROMWritelong(8, 0x410); delay(50);
EEPROMWritelong(12, 0xC10); delay(50);
EEPROMWritelong(16, 0x210); delay(50);
EEPROMWritelong(20, 0xA10); delay(50);
}
// Lees opgeslagen codes
Serial.println(); Serial.println("Reading stored IR remote codes...");
location = 0;
for(int j=0; j<=5; j++) {
savedIRCodes[j] = EEPROMReadlong(location);
Serial.print("Location "); Serial.print(location); Serial.print(" = "); Serial.println(savedIRCodes[j], HEX);
dupeCheck[j] = savedIRCodes[j]; location += 4;
}
// Dubbele codes detecteren (opeenvolgend)
for(int i=0; i<5; i++) for(int j=i+1; j<6; j++)
if (dupeCheck[i] == dupeCheck[j]) {
Serial.println("Duplicate codes found. Suggest re-running learn mode");
for(int k=0; k<=5; k++) {
digitalWrite(pins[i], HIGH); digitalWrite(pins[j], HIGH); delay(1000);
digitalWrite(pins[i], LOW); digitalWrite(pins[j], LOW); delay(1000);
}
}
remote_code_1 = savedIRCodes[0]; remote_code_2 = savedIRCodes[1]; remote_code_3 = savedIRCodes[2];
remote_code_4 = savedIRCodes[3]; remote_code_5 = savedIRCodes[4]; remote_code_6 = savedIRCodes[5];
delay(1000); Serial.println("Stored codes read."); Serial.println();
}
void loop() {
learnMode = (digitalRead(switchPin) == HIGH);
if (learnMode) { first_iteration = true; Reset(); digitalWrite(statusPin, HIGH); learn_Mode(); Reset(); first_iteration = false; }
else { digitalWrite(statusPin, LOW); run_Mode(); first_iteration = false; }
}
Schema
Zie de bijgevoegde schema-afbeelding voor de bedrading op het breadboard.
Productieproces
- Light-Emitting Diodes: Van Ontstaan tot 100-Jarige Levensduur
- Externe weerbewaking met Raspberry Pi 3 en PubNub
- Een Professionele Raspberry Pi Universele Afstandsbediening Bouwen met LIRC
- Remote Hartslagmonitoringssysteem met AWS IoT-waarschuwingen
- Arduino Coffin Dance Melodie Project – Bouw & Speel de Virale Tune
- Je Oude Telefoon Ombouwen Tot Een Slimme Remote Switch
- Single-LED Lichtschilderen: Bouw Dynamische Afbeeldingen met een DIY Gemotoriseerd Systeem
- Geluidsgeactiveerd 8-LED Lichtdisplay met Arduino
- Bouw een Slimme Arduino Vierpotige Robot: Stap-voor-Stap Handleiding
- De 5 Belangrijkste Criteria voor het Selecteren van een Besturingsplatform
- Veilige & Efficiënte Verwijdering Van Verouderde Industriële Machines