Control Your 433MHz Sockets With NodeMCU and a RF Transmitter Module

Stephan Schrijver
6 min readMar 29, 2020

--

The steps below will show you how to control 433MHz sockets with a NodeMCU (with an ESP8266 Wi-Fi chip). I’m currently using this to turn my lights on and off. In this guide I will also cover several ways to communicate with the NodeMCU and how to integrate its functionality with Google Assistant, so you can turn your lights on and off by using your voice!

Prerequisites:

  • NodeMCU
  • 433MHz RF Transmitter-Receiver Module
  • Working setup of 433MHz Remote and Sockets
  • Arduino IDE with rc-switch library installed

Reading 433MHz Signal of Remotes

Upload the following sketch to your NodeMCU and connect the data pin of the 433MHz RF receiver module to the D2 pin, also connect the ground and 5v pins to your NodeMCU.

/*
Example for receiving

https://github.com/sui77/rc-switch/

If you want to visualize a telegram copy the raw data and
paste it into http://test.sui.li/oszi/
*/
#include <RCSwitch.h>RCSwitch mySwitch = RCSwitch();static const uint8_t D2 = 4;void setup() {
Serial.begin(115200);
mySwitch.enableReceive(D2);
}
void loop() {
if (mySwitch.available()) {
Serial.println(mySwitch.getReceivedValue());
output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
mySwitch.resetAvailable();
}
}

You’ll now be able to open the serial monitor and you can then push the buttons on the remote that you want to simulate with the NodeMCU. The signal being send will be shown in the serial monitor.

I will be using the binary code, so I’ll save that one for later along with the pulse length and protocol. In the wiki of the rc-switch library you can also find how to use the tri-state and decimal values.

Transmitting the 433MHz Signal

With the following sketch and the 433MHz RF transmitter connected to the NodeMCU, we will try to simulate the signal of the remote. You should fill in the binary code, which was in your serial monitor, in the transmitter.send('...') command and you should also be setting the protocol and pulse length, in my case these were the same for every signal I wanted to transmit so I set these in the setup() function. In my case, it will switch on/off my lights every second and it works!

/*
Example for receiving

https://github.com/sui77/rc-switch/

If you want to visualize a telegram copy the raw data and
paste it into http://test.sui.li/oszi/
*/
#include <RCSwitch.h>
RCSwitch transmitter = RCSwitch();
static const uint8_t D2 = 4;
void setup() {
Serial.begin(115200);
transmitter.enableTransmit(D2);
transmitter.setProtocol(1);
transmitter.setPulseLength(319);
}
void loop() {
transmitter.send("000000000001010100010001"); // ON
delay(1000);
transmitter.send("000000000001010100010100");// OFF
delay(1000);
}

I’ve “tweaked” the antenna a bit, because the I noticed the signal of the RF transmitter module wasn’t that strong.

Exposing the NodeMCU Functionality by Setting up a Webserver/API

Transmitting signal is now working, now we need a way to communicate with the NodeMCU so we can trigger its functionality. You need the 433MHz RF transmitter attached to the NodeMCU for this setup.

One way to do expose its functionality, is by setting up a webserver/API on the NodeMCU. This is not the best way, because there will be some security issues by exposing a device, especially if you make it publicly accessible. You are therefore responsible for carrying out the following steps.

Below you can find the sketch which will setup a webserver on your NodeMCU. Please note you have to set the SSID/Wi-Fi name and it’s password. You can also generate a secret token that needs to be used to interact with the endpoints (has to be provided as query parameter). It is a HTTP webserver, not an HTTPS webserver, so you have to wonder to what extent this is really safe.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <RCSwitch.h>
#ifndef STASSID
#define STASSID "WIFINAMEHERE"
#define STAPSK "WIFIPASSWORDHERE"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
String token = "super-secret-token";static const uint8_t D2 = 4;RCSwitch transmitter = RCSwitch();ESP8266WebServer server(80);const int led = 13;void handleRoot() {
if (!validToken()) {
server.send(403, "text/plain", "Unauthorized");
return;
}
digitalWrite(led, 1);
server.send(200, "text/plain", "hello from esp8266!");
digitalWrite(led, 0);
}
void handleLightsOn() {
if (!validToken()) {
server.send(403, "text/plain", "Unauthorized");
return;
}
transmitter.send("000000000001010100010001");
server.send(200, "text/plain", "lights are on!");
}
void handleLightsOff() {
if (!validToken()) {
server.send(403, "text/plain", "Unauthorized");
return;
}
transmitter.send("000000000001010100010100");
server.send(200, "text/plain", "lights are off!");
}
void handleNotFound() {
digitalWrite(led, 1);
server.send(404, "text/plain", "404: Not Found" );
digitalWrite(led, 0);
}
bool validToken() {
return !(server.arg("Token") == "" || server.arg("Token") != token);
}
void setup(void) {
transmitter.enableTransmit(D2);
transmitter.setProtocol(1);
transmitter.setPulseLength(319);
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);server.on("/lightsOn", handleLightsOn);
server.on("/lightsOff", handleLightsOff);
server.onNotFound(handleNotFound);server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
MDNS.update();
}

Note the line: Serial.println(WiFi.localIP()), this will show the local IP of your NodeMCU in the serial monitor, which you have to use to access the webserver from your PC/laptop that’s in the same network. Let’s assume the IP of the NodeMCU webserver is 192.168.2.5, we can then browse to http://192.168.2.5/lightsOn.

Because we did not provide ?Token=super-secret-token we will (hopefully) end up with a 403 Unauthorized error. If we do provide it by browsing to http://192.168.2.5/lightsOn?Token=super-secret-token, the handleLightsOn will pass the token check and perform the transmit.

I wanted to be able to communicate with the NodeMCU even when I was not at home (so outside my home network), so I opened these ports on my modem. Once again, only do this when you’re know what you’re doing. It doesn’t feel right to me and I’m already working on a way to phase this out (will also be covered in this article, will attach it as soon as possible).

Triggering Endpoints with Google Assistant

Now we’ve setup endpoints that allow us to transmit 433MHz signals without being physically connected to the NodeMCU, we can think about ways to trigger the endpoints. I have a Google Hub, so my wish was to be able to switch my lights on and off with Google Assistant voice commands, without having to upgrade to Philips Hue or whatsoever. Luckily, this is pretty easy with IFTTT, one downside is that it’s not supporting every language.

  1. Create a new applet, search for the Google Assistant service and click that.

2. Choose for “Say a simple phrase” (depending on your needs, of course).

3. Define with what sentences you want to trigger a specific endpoint.

4. Click “that” to define the actual action.

5. Search for Webhooks and click it.

6. Enter the endpoint you want to trigger. In my case it had the following structure: http://mypublicIPhere/lightsOn?Token=mytoken.

Below you can find an overview of my settings:

Now we can test this IFTTT applet by talking to our Google Assistant.

Voilà, I can now switch on and off my lights with Google Assistant. Since I do this by exposing an endpoint, I’ve also used it for Apple Shortcuts. When I disconnect with Apple CarPlay after a given time and I’m nearby home, the lights will turn on.

Interact through MQTT and AWS IoT

Since I don’t want to expose a webserver and/or device, I want to interact with the NodeMCU through MQTT and AWS IoT. Since this is still work in progress, I will attach that as soon as possible!

Questions or Feedback

If you have any questions or feedback regarding this article, please let me know!

--

--