Introduction: Easy IOT - ESP32 Based RF Sensor Hub

This tutorial is part of a series of tutorials, building a network of devices that can be controlled via a radio link from a central hub device. For the tutorial series overview please follow this link:

In this tutorial we will assemble the HC-12 Serial radio module and connect it to the ESP32. Then we will write a program for the ESP32 Module using the Arduino IDE that will allow us to check the radio settings, and then start a webserver so we can communicate with the hub from our phone.


You will need:

· ESP32 Module

· HC-12 Module

· An Android Device

· Micro USB cable

· Female-Female Dupont Jumper Wires

· Soldering Iron

· 47uF Capacitors (and 10uF to fix boot issue)

Step 1: Assembling and Connecting the HC-12 Module

The HC-12 Module is a serial radio transceiver module that we will be using to communicate with the different remote nodes in our system. The device takes simple serial (text) input on the pins and transmits exactly what it receives. The receiving device then outputs that text as serial data again.

This means that we can build a method of communicating between devices that is very transparent and easy to understand.

The modules can easily be found on Amazon and eBay, and can be bought for less than $2 from China.

They come with a small spring antenna, which is not great, but should be sufficient for most of our tests. This antenna needs soldering on and an Electrolytic capacitor added to the power input of the device. If you are running the device off 5V it should also have a 1N4007 diode in series with the input voltage, but in this tutorial we will power it off the 3.3V pin on our ESP32 Dev Board.

The image below shows the components needed to assemble the HC-12 Module. In this tutorial series, every sensor node we build will need one of these, so it may be worth building a few at a time. To keep testing simple, we are using dupont jumper wires to connect to the microcontroller. At a later stage, for a permenant application you may want to cut these off and solder both sides to make a more secure connection.

For the HC-12 module you will need the following:

· HC-12 Module

· Spring antenna

· 47uF Capacitor (or anything between 10uF and 1000uF)

· Dupont wires

· Soldering iron

· Solder

Step 2: Antenna

The first step is to solder on the antenna, try to keep the solder blob small, neat and round. Alternatively, if you want better range, you can use the u.FL connector to attach a better antenna.

Step 3: Capacitor

Place the capacitor across the VCC and GND pads at the other end of the board. Make sure the stripe of the capacitor (negative) is facing the GND side then solder it in. Once in place, cut off the legs.

Step 4: Wiring

Once the capacitor is soldered in, strip and tin the ends of the wires then solder onto the HC-12 Module. Keep the colours consistent to avoid confusion later. I use:






Now your HC-12 Module is assembled.

Step 5: Connecting HC-12 Module to ESP32

We can now connect it to the ESP32 as follows:

VCC = RED => 3.3V


RXD = ORANGE => TX2 (17)

TXD = YELLOW => RX2 (16)

SET = GREEN => 5

Step 6: Enclosure

To make it a bit neater and easier to use without damaging the connections, we’re going to put the ESP32 and HC-12 module inside an enclosure. This is optional.

If you wish to do this, find an enclosure big enough to fit the electronics in with the micro USB connected. File out a section of one end just big enough to tightly grip the USB connector.

Then carefully squeeze in the electronics. Make sure that nothing can short out or easily become disconnected. VHB tape is very useful for doing this

Finally check that the lid fits on still. I would not screw it in yet, as you may find (as I did) that the ESP32 module is one of the ones that requires the BOOT button to be pressed in order to program.

I would now skip ahead to the tutorial Step 8 and test the board with a Blink Sketch. If your board does not program without holding the BOOT button down, you may want to follow the instruction on the next page to rectify this problem.

Step 7: Fixing the BOOT Button Issue (Optional)

If the board won’t program without pressing the BOOT button (you see the error shown in the image), this is obviously a problem when the board is sealed in an enclosure. Luckily this can be solved by soldering a 10uF capacitor between the EN pin and Ground (last pin on the ESP32 module) as shown in the picture.

Step 8: Setting Up Arduino IDE for ESP32

If you have not used the ESP32 before, you will need to do is add the ESP32 board to the Arduino IDE. To do this, follow this guide:

We then need to add the library we are going to use to run a webserver we can communicate with on the ESP32.

To add the ESPAsyncWebServer library to the IDE go to: and download the library as a zip file. Go back to the Arduino IDE and to “Sketch, Include Library, Add .ZIP Library” then find the zip file you just downloaded and click open.

This library starts an asynchronous web server on the Arduino that we can connect to over the WIFI network to tell the ESP32 to do things or read data back from the device.

Step 9: Programming the ESP32 – Blink Sketch

When starting to use a new device, it is always a good idea to test it first using a very simple sketch, for this we will use the Blink Sketch (Check that your ESP32 board has a built in LED, if not skip this step). Go to “File, Examples, 01.Basics, Blink” Once this opens you will need to add a line to the top to tell the program which pin the LED is connected to. In our case it is pin 2.

Here is the line we add: #define LED_BUILTIN 2 Put this above the “Setup()” function at the top of your code:

#define LED_BUILTIN  2
// the setup function runs once when you press reset or power the board
void setup() 
  // initialize digital pin LED_BUILTIN as an output.
// the loop function runs over and over again forever
void loop()
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second

Once you have added
this, go to “Tools, Board” and make sure the ESP32 Dev Module is selected. Then make sure you have the correct COM Port selected.

You can then upload your program. If it worked, you should see the LED blinking.

On some of the newer ESP32 boards, you need to hold the boot button to get it to program. If yours is not working, check out this article:

Step 10: Testing the HC-12 Module

You can now close the Blink sketch and open a new empty sketch. To check our connections to the HC-12 module and the settings, we can use the following sample program:

#define RXD2 16	//(RX2)
#define TXD2 17	//(TX2)
#define HC12 Serial2  //Hardware serial 2 on the ESP32

void setup() 
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);           //Normally HIGH, LOW for settings
  Serial.begin(115200);           // Serial port to computer
  HC12.begin(9600, SERIAL_8N1, RXD2, TXD2);      // Serial port to HC12

void loop() 
  while (HC12.available()) 
    // If HC-12 has data
    Serial.write(;      // Send the data to Serial monitor
  while (Serial.available()) 
    // If we have data from Serial monitor
    HC12.write(;      // Send that data to HC-12

Save this sketch as something like “ESP32_HC-12_Test” as we
may need it again later. What this program does, is read anything that is typed in the Serial Monitor, and send that to the HC-12 Module, and read anything the HC-12 module sends and writes that to the Serial Monitor. The other line we will need to use, is “digitalWrite(5, LOW)” as this controls whether the module is in its settings mode, or in the usual operation mode.

The easiest way to test that the module is connected properly and working, is to put the module into the settings mode and check that it replies. First run this sketch, open the Serial Monitor, making sure that the Baud rate is set to 115200 and the line ending is set to “Newline”.

Next type “AT” in the box at the top and press “Send”. If the device is working, you should see the work “OK” appear in the terminal window. If this works, type “AT+RX” and press send. The board will now respond with its settings. From here you can change the settings, but for now leave them as they are.

Step 11: ESP32 Webserver Code

Now we know the hardware is working, we need to start writing the actual code that the Hub will use. This code like in the previous ESP32 tutorial uses an asynchronous webserver that allows the device to receive messages we sent to it from our DroidScript app then forward those messages on to the appropriate node via the HC-12 Radio.

Create a new Arduino sketch, save it and copy the code below in. For now we are leaving out the HC-12 setup code as until we have another device to talk to it is not needed. Add your wifi router details then upload the sketch to the ESP32.

#include "WiFi.h"
#include "ESPAsyncWebServer.h"
const char* ssid = "YourSSID";             //Change this to your router SSID.
const char* password =  "YourPassword";    //Change this to your router password.
AsyncWebServer server(80);

void setup() 
  pinMode(5, OUTPUT); 
  digitalWrite(5, HIGH);       //Pull the HC12 SET pin high (LOW for AT Commands).
  WiFi.begin(ssid, password);
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

  //Wait for wifi connection.
  while (WiFi.status() != WL_CONNECTED) 
  //Once WIFI is connected:
  Serial.println(" CONNECTED");

  //Create an End Point that the server will respond to requests to.
  server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send(200, "text/plain", "HUB|OK");

Once done check the serial monitor (if you don’t see anything, try pressing the reset button). If it connects successfully you should see the IP address of the ESP32s webserver appear.

Step 12: Android App

We now need to build an app with a user interface that will

allow us to communicate with our ESP32 module. Open DroidScript on your android device and connect to the WIFI editor. If you are not sure how to do this, check out the getting started tutorials here:

Create a new JavaScript app and give it a name. Once it has opened, delete the demo code and paste the following code in:

var url = "";

//Called when application is started.
function OnStart()
    //Read the last saved Hub IP address (if exists)
    var txtIP = app.ReadFile( "/sdcard/hubip.txt" );	
    url = "http://" + txtIP;
    //Create a layout with objects vertically centered.
    lay = app.CreateLayout( "linear", "VCenter,FillXY" );   

    //Create a text label and add it to layout.
    txt = app.CreateText( "HUB IP:" );
    txt.SetTextSize( 16 );
    lay.AddChild( txt );
    //Create an text edit box.	
    edtIP = app.CreateTextEdit( txtIP, 0.6);
    edtIP.SetMargins( 0, 0.02, 0, 0 );
    lay.AddChild( edtIP );
    //Create a button to send IP.
    btnIPSave = app.CreateButton( "Save" ); 
    btnIPSave.SetMargins( 0, 0.02, 0, 0 ); 
    btnIPSave.SetOnTouch( btnIPSave_OnTouch ); 
    lay.AddChild( btnIPSave ); 
    //Create text label.
    txtLabel = app.CreateText( "HUB STATUS: " );
    txtLabel.SetTextSize( 15 );
    txtLabel.SetMargins(0, 0.03);
    lay.AddChild( txtLabel );
    //Create text label.
    txtStatus = app.CreateText( "" );
    txtStatus.SetTextSize( 15 );
    txtStatus.SetMargins(0, 0.03);
    lay.AddChild( txtStatus );
    //Add layout to app.	
    app.AddLayout( lay );   //Set a timer to check hub status every 10s
    setInterval(HubStatus ,10000);

function btnIPSave_OnTouch()
    var s = edtIP.GetText();
    app.WriteFile( "/sdcard/hubip.txt", s );
    app.ShowPopup("Saved: " + app.ReadFile( "/sdcard/hubip.txt" ));
    url = "http://" + app.ReadFile( "/sdcard/hubip.txt" );

function HubStatus()
    //Send request to remote server.
    var path = "/status";
    //var params = "data=" + data.replace("\r","");
    app.HttpRequest( "get", url, path, "", HandleReply ); 

//Handle the servers reply.
function HandleReply( error, response )
    var res = response.split("|");
    if (error)
    else if (res[0] == "HUB" ) 
	 if (res[1] == "OK")

The first section “OnStart()” is what creates the layout of the app, adding text, a text edit box and buttons and setting an interval that called the “HubStatus()” function to check the connection every 10 seconds.

btnIPSave_OnTouch() Saves the IP address in the text box to a file in the device memory.

HubStatus() Sends a GET request to the end point we created on the ESP32 Hub

HandleReply() Handles the reply from the ESP32 Hub, changing the displayed text to show “Connected” or “Disconnected” whether a valid response is received or not.

Step 13: Testing the App

You can now run your app. The first image is what you should see.

Now make sure that your ESP32 Hub is powered and connected to your WIFI. Go back to the Arduino terminal to check the IP address of the Hub, then type this address into the edit box in the your app.

Click Save and if everything has worked you will see the hub status change to “Connected”, as shown in the second image.

If you have got this far, well done! You are now ready to start building the remote nodes.

In the next tutorial, we will build a remote-controlled relay module.