Home Automation blog

Skip to Content

Arduino universal remote

Posted by Chris

Date posted:

For my first home automation project I built an Arduino universal remote for my home theatre room. It's an IR transmitter (blaster) built into my ceiling for controlling the projector, amp/receiver, bluray player and anything else in the future that can receive IR signals.

Built using:

Arduino universal remote diagramHow it works:

The Ardunio uses the IRremote library to send the IR signal which it receives as a string sent over the network via MQTT protocol from my Raspberry Pi server running Node-RED with homekit nodes.

I use the NPN transister to act as a switch for the IR LED transmitter. The LED requires 5v to run at 100% which the normal Arduino digital pins don't provide, otherwise the LED wasn't bright enough to reach across the room.

I use another Ardunio with the IR receiver to "record" my various appliances' remote's signals. Store them within Node-RED.

The code

#include <stdlib.h>
#include <IRremote.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <SPI.h>


// Ethernet https://www.miniwebtool.com/mac-address-generator/
byte device_mac[] = {0x64, 0x72, 0x59, 0xD3, 0x3F, 0xA3};
EthernetClient device;

// MQTT
IPAddress mqtt_ip(XXX, XXX, XXX, XXX);
PubSubClient mqtt(device);
String mqtt_client = "cinemaremote";
const char mqtt_user[] = "XXXX";
const char mqtt_pass[] = "XXXX";
const char mqtt_sub[] = "device/cinema/remote";

// IR Remote
IRsend ir_send;
String ir_type;
unsigned long ir_code;


void setup()
{
// Wait for network connection while (Ethernet.begin(device_mac) == 0)
{
delay(1000);
}
// Initializes the pseudo-random number generator randomSeed(micros());
// Configure MQTT mqtt.setServer(mqtt_ip, 1883); mqtt.setCallback(mqttReceive); } void loop() { Ethernet.maintain(); if (!mqtt.connected()) { mqttReconnect(); } mqtt.loop(); } void mqttReconnect() { while (!mqtt.connected()) { if (mqtt.connect(String(mqtt_client + String(random(0xffff), HEX)).c_str(), mqtt_user, mqtt_pass)) { mqtt.subscribe(mqtt_sub); } else { delay(5000); } } } void mqttReceive(char* topic, byte* payload, unsigned int leng) { char type[4] = ""; for (int i = 0; i < 3; i++) { type[i] = payload[i]; }
type[4] = '\0'; char code[leng-2] = ""; for (int i = 3; i < leng; i++) { code[i-3] = payload[i]; }
code[leng-2] = '\0'; ir_type = String(type).substring(0, 3); ir_code = strtol(code, NULL, 0); switch (ir_type) { case "NEC": ir_send.sendNEC(ir_code, 32); break; case "SAM": ir_send.sendSAMSUNG(ir_code, 32); break; case "PAN": ir_send.sendPanasonic(ir_code, 32); break; case "JVC": ir_send.sendJVC(ir_code, 32, false); break; case "LG ": ir_send.sendLG(ir_code, 32); break; case "SON": ir_send.sendSony(ir_code, 32); break; case "RC5": ir_send.sendRC5(ir_code, 32); break; } }

 

Node-RED

Node-RED's HomeKit plugin nodes simulate HomeKit compatible devices/accessories. These are presented as actionable devices within the iOS Home app. But can also accept input from other Node-RED nodes.

My projector requires the off-button on the original remote to be pressed twice (to confirm action). So I route the "off" action's output from Node-RED twice with a 1 second delay between them.

Writing all the logic in Node-RED allows you to change the rules on the fly without having to re-compile the Ardunio or restart the Pi / homekit.

The MQTT message string sent with the IR encoding in the first 3 characters and the HEX code in the remainder of the message:

NEC0x4CB340BF

 

What's next?

I plan to 3D-print housing for Ardunio compatible motion/PIR sensors for each room to toggle on/off the downlights. In the home theatre room I'll combine the motion sensor and IR LED in the one housing. For now the Ardunio sits in the ceiling within a box and a face-plate with a hole for the IR LED, pretty discrete looking.

View similar posts categorised as: Arduino Node RED HomeKit