A few months back I started to setup a dedicated home automation system to control my ever-growing number of “smart” devices.
Smart devices are great but they usually have separate interfaces and mobile programs to install and control each device. What is really needed is a single program to control all of my devices… from a single interface.
Well that in a nutshell is Openhab, a software suite developed specifically for controlling smart devices from a range of manufacturers and industries, utilizing many different communication protocols.
One of these communication protocols is MQTT. I wont go into the specifics of this protocol, only that it is widely used in industrial applications and has even been used for face-books messenger app.
Now the reason for designing an IR blaster that uses MQTT to trigger the IR LED’s is that I’m already using it to control several appliances in my apartment.
Specifically I’m using Nodemcu boards with Arduino compatible code to receive an MQTT command and do some action… i.e. turn on or off a relay
Except this time instead of turning on and off a relay I will use a separate Arduino library called IRsend.h to activate the IR leds through a digital pin on the nodemcu board.
Here is the Arduino code for the Nodemcu boards:
include ESP8266WiFi.h
include PubSubClient.h
include ESP8266mDNS.h
include WiFiUdp.h
include ArduinoOTA.h
include IRsend.h
IRsend irsend(14); // An IR LED is controlled by GPIO pin 14 (D5) on nodemcu boards
// Update these with values suitable for your network.
//openhab MQQT settings
const char* ssid = "";
const char* password = "";
const char* mqtt_server = "xxx.xxx.xxx.xxx";
const char* brokerusername = "";
const char* brokerpassword = "";
IPAddress ip(192, 168, 0, 114); // where xx is the desired IP Address
IPAddress gateway(192, 168, 0, 1); // set gateway to match your network
IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.config(ip, gateway, subnet);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String p_payload;
for (int i = 0; i < length; i++) {
p_payload.concat((char)payload[i]);
}
Serial.println(p_payload);
// Convert from String HEX to Hex long
long hexCmd;
hexCmd = strtol(&amp;p_payload[0], NULL, 16);
irsend.sendNEC(hexCmd, 32);
Serial.print(INT);
Serial.println(hexCmd);
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection…");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str(), brokerusername, brokerpassword)) {
Serial.println("connected");
client.subscribe("apartment/livingroom/ir_blaster/state");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
irsend.begin();
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
if (!client.connected()) {
reconnect();
}
client.loop();
}
The code posted above is pretty simple, its using an MQTT communication library for receiving commands from Openhab. It subscribes to the “apartment/livingroom/ir_blaster/state” topic. Openhab publishes an IR code to this topic and the code here receives that command, and uses the IRsend library to pulse pin 14 (D5) on the nodemcu boards.
I decided on using 6 IR LED’s arranged in a semicircular pattern to entirely cover my living room. Each LED is 30 degrees from the next, with 6 LED’s its able to cover more than 180 degrees. I used a single PN222A transistor driven through pin 14, which switches the IR LED’s. There are three series pairs of IR leds in parallel running through the PN222A, with this configuration I do not require current limiting resistors.
Here is the circuit:
And then I designed and 3D printed this case:
Now all that’s left to do is send some IR codes to the device through the subscribed MQQT channel.
I recorded the IR codes from several of my favourite devices remotes and then set up some items and button in my Openhab UI.
UI currently looks like this:
It works perfectly!! Next I need to design some nice UI’s to allow control of my home entertainment system through a tablet.
If anyone wants a tutorial on how to record IR codes from remotes let me know.
Here is a shot of the IR codes being recorded: