ESP RainMaker Getting Started Tutorial with ESP32 and Arduino IDE

In this ESP32 tutorial, we will introduce you to ESP RainMaker with ESP32 using Arduino IDE. The ESP RainMaker is an innovative and newly launched cloud based IoT platform which enables customers to quickly build their own AIoT solutions based on enterprise-grade cloud computing, with a single-click deployment.

ESP RainMaker tutorial with ESP32 and Arduino IDE

We have used Blynk application and Arduino IoT cloud before, but this platform offers much more such as self adapting mobile app, free integration of Alexa and Google assistant, members sharing, Wi-Fi provisioning through VR code and much more. The great attribute about using this IoT platform is that it is free for its users and offers great features.

In this getting started guide of ESP RainMaker with Arduino IDE, we will create a project with this platform whereby we will be able to monitor sensor data and control an LED connected with the ESP32 output pin from our mobile over the cloud. The ESP RainMaker mobile application will update data in real-time. However, you will require a steady internet connection.

Introducing ESP RainMaker

ESP RainMaker is an IoT platform developed by Espressif, which is compatible with ESP32 development boards. It is very easy to create a project in this platform as no configuration is required for the application. The mobile application is self adapting. So we just need to write the code and the application will be generated automatically.

Working of ESP RainMaker

Let us now demonstrate how ESP RainMaker is able to communicate with the IoT cloud and how the mobile application is configured by itself.

  • When the ESP32 board is programmed for ESP RainMaker, it generates a QR code. This QR code is scanned by the mobile application to access it.
  • Once the QR code is successfully scanned by the ESP RainMaker mobile app, a BLE communication will start between the app and the ESP32 development board.
  • The network credentials (Wi-Fi) will be provided by the mobile app to the ESP32 board via Bluetooth.
  • ESP32 now will communicate with the router after successfully connecting to the network. This will enable it to communicate with the ESP RainMaker cloud. All the data that we have programmed in our ESP32 will be communicated to the ESP RainMaker cloud which will then be shown inside the mobile app. The mobile application will adapt accordingly.
  • The ESP RainMaker mobile app communicates with the cloud while being on the same network as the ESP32 board.
  • The user can monitor sensor readings and control appliances through the mobile application.

ESP RainMaker Keywords

There are some keywords that you need to familiarize before working in ESP RainMaker.

Node: The device is referred to as the node. For example we can name the node as “ESP32” etc.

Devices: Inside the node, there are devices. For example led, buzzer, DHT22 sensor etc.

Parameter: Inside the Device, we have Parameter. This is the input to the devices or the output obtained from the devices. For example power, brightness etc.

ESP RainMaker Project with Arduino IDE

To start working with RainMaker with Arduino IDE, we will be required to set up some configurations in the IDE. So let us begin!

Install ESP32 2.0 board package in Arduino IDE

The ESP32 board Packages version 2.0 has support for ESP RainMaker. We need to add that for our ESP32 board.

Open your Arduino IDE, and head over to File > Preferences. Now paste the following link in the additional Boards Manager URLs and press Ok.

 https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
ESP32 2.0 boards package

Head over to Tools > Board > Board Manager. Search for ‘ESP32’ and you can view that the version 2.0.1 is already installed.

ESP32 Boards Manager

For demonstration purposes, we will interface our ESP32 board with a DHT22 sensor and an LED and monitor DHT sensor data and control an LED from our RainMaker mobile app. The app will consist of widgets showing the sensor readings that will update after every 5 seconds. Moreover, there will also be a widget of a switch to toggle the LED ON/OFF.

DHT22 is a sensor which measures relative humidity and temperature. It provides a calibrated digital output with a 1-wire protocol. DHT sensors are pre-calibrated. We can directly connect them with ESP32 to obtain sensor output reading. They are internally composed of a humidity sensing sensor and a thermistor. These two components measure humidity and temperature. 

DHT22 Pinout 

This following figure shows the pinout diagram of DHT sensors. DHT sensor consists of four pins. But on DHT modules only three pins are exposed to the pinout of the module and10k ohm pull-up resistor is internally connected to pin 2. 

dht11 dht22 pinout diagram

Pin Description

The following lists the pinout of the DHT sensor and their brief description. Pin number starts from left to right when you hold the sensor from the front end. 

DHT22 PinESP32
1 (Vcc)3.3V 
2 (Data Out)Any GPIO pins of ESP boards along with a 10k ohm pull-up resistor
3 (NC)Not used
4 (GND)Ground
  • Vcc is the power supply pin. Apply voltage in a range of 3.3 V to 5.0 V to this pin
  • Data Out is the digital output pin. It sends out the value of measured temperature and humidity in the form of serial data
  • N/C is not connected
  • GND: Connect the GND pin 

Circuit Diagram of ESP32 with DHT22 sensor and LED

We will need the following components.

Required Components

  1. ESP32 board
  2. DHT22
  3. 10k ohm resistor (not required if using the DHT22 sensor module)
  4. 5mm LED
  5. 220 ohm current limiting resistor
  6. Bread Board
  7. Jumper wires

The first pin the DHT22 sensor is a power supply(VCC) pin. Connect it with the 3.3 volt pin of ESP32.

Data out is the pin through which we get temperature and humidity samples from the DHT sensor. Connect this pin with GPIO33 of ESP32 and also connect the data pin with a 10k pull-up resistor. But you can also use any digital pin of ESP32.

A Pull-up resistor is used to keep the data pin high for proper communication between the microcontroller and sensor. You can check the datasheet of DHT22 to get more information about it. DHT22 is also known by the name of AM2302.

  • Third pin is not used
  • Connect the fourth pin (GND) to the ground pin of the ESP32 board

The anode pin of the LED is connected with GPIO32 through a 220 ohm current limiting resistor. The cathode pin is grounded.

Connect ESP32 with DHT22 and an LED as shown in the schematic diagram below:

ESP32 with DHT22 and LED connection diagram
ESP32 with DHT22 and LED

Install DHT11/DHT22 Library in Arduino IDE

Both DHT11 and DHT22 provide the output of temperature and humidity in the complex digital output format which can not be directly read with GPIO pins without writing any technique which can read these output signals. These sensors provide data through a single wire two-way communication protocol. A single process communication consists of 40 bits. But we do not need to worry about the working of these sensors and on which protocol we can receive this data. We have an Arduino library for DHT sensors which can be easily used to get values of temperature and humidity only by calling two lines of functions. We will see later on how to do it. Now let’s see how to install the DHT library in Arduino. This library is provided by Adafruit. Follow these steps to install the DHT sensor library:

Open Arduino IDE and click on Sketch > Library > Manage Libraries.

When you click on the manage libraries option, you will get this window. In this window write ‘DHT sensor‘ in the search bar and press enter.

You will see many options available for DHT11 and DHT22 libraries. Select Adafruit library and click on the install button. You can select the latest version from the version window.

The same library can be used for both DHT11 and DHT22/AM2302 sensors.

Adafruit also provides libraries for other sensors. So they provided a support package which is used to handle all sensor libraries. We also need to install the Adafruit Unified Sensor library. To install this, paste the  Adafruit Unified Sensor search bar and select this option and click on the install button.

Adafruit unified sensor library arduino ide

After installation of the libraries, restart your IDE.

You may also like to read:

Install SimpleTimer Library

We will also install the SimpleTimer library by Alexander Kiryanenko. Open Arduino IDE and click on Sketch > Library > Manage Libraries.

When you click on the manage libraries option, you will get this window. In this window write ‘SimpleTimer‘ in the search bar and press enter.

Install the latest version of the library as highlighted below:

SimpleTimer library

ESP RainMaker ESP32 Sketch

Open your Arduino IDE and go to File > New to open a new file. Copy the code given below and save it.

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include "DHT.h"
#include <SimpleTimer.h>

// BLE Credentials
const char *service_name = "PROV_12345";
const char *pop = "1234567";

static uint8_t gpio_reset = 0;
static uint8_t DHTPIN = 33;
static uint8_t led_pin = 32;
bool led_pin_state = false;

bool wifi_connected = 0;

DHT dht(DHTPIN, DHT22);

SimpleTimer Timer;

 //declare devices
static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");
static Switch button("LED", &led_pin);

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
      printQR(service_name, pop, "ble");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
      printQR(service_name, pop, "softap");
#endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      wifi_connected = 1;
      delay(500);
      break;
    case ARDUINO_EVENT_PROV_CRED_RECV: {
        Serial.println("\nReceived Wi-Fi credentials");
        Serial.print("\tSSID : ");
        Serial.println((const char *) sys_event->event_info.prov_cred_recv.ssid);
        Serial.print("\tPassword : ");
        Serial.println((char const *) sys_event->event_info.prov_cred_recv.password);
        break;
      }
  }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  Serial.println(device_name);
  const char *param_name = param->getParamName();

  if (strcmp(device_name, "LED") == 0)
  {
    if (strcmp(param_name, "Power") == 0)
    {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      led_pin_state = val.val.b;
      (led_pin_state == false) ? digitalWrite(led_pin, LOW) : digitalWrite(led_pin, HIGH);
      param->updateAndReport(val);
    }
  }
}


void setup()
{
  Serial.begin(115200);
  
  pinMode(gpio_reset, INPUT);
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin,LOW);
  
  dht.begin();
  
  //declare node
  Node my_node;
  my_node = RMaker.initNode("Microcontrollerslab");

  button.addCb(write_callback);

  //Add devices
  my_node.addDevice(temperature);
  my_node.addDevice(humidity);
  my_node.addDevice(button);


  //This is optional
  RMaker.enableOTA(OTA_USING_PARAMS);
  //If you want to enable scheduling, set time zone for your region using setTimeZone().
  //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
  // RMaker.setTimeZone("Asia/Shanghai");
  // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
  RMaker.enableTZService();
  RMaker.enableSchedule();

  Serial.printf("\nStarting ESP-RainMaker\n");
  RMaker.start();

  // Timer for Sending Sensor Data
  Timer.setInterval(5000);

  WiFi.onEvent(sysProvEvent);

#if CONFIG_IDF_TARGET_ESP32
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

}


void loop()
{
  if (Timer.isReady() && wifi_connected) {                    
    Serial.println("Sending Sensor Data");

    float hum = dht.readHumidity();
    float temp = dht.readTemperature();

    Serial.print("Temperature: "); 
    Serial.println(temp);
    Serial.print("Humidity: "); 
    Serial.println(hum);

    temperature.updateAndReportParam("Temperature", temp);
    humidity.updateAndReportParam("Temperature", hum);
    Timer.reset();                        
  }

  // Read GPIO0 (external button to reset device
  if (digitalRead(gpio_reset) == LOW) { //Push button pressed
    Serial.printf("Reset Button Pressed!\n");
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while (digitalRead(gpio_reset) == LOW) delay(50);
    int endTime = millis();

    if ((endTime - startTime) > 10000) {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.\n");
      wifi_connected = 0;
      RMakerFactoryReset(2);
    } else if ((endTime - startTime) > 3000) {
      Serial.printf("Reset Wi-Fi.\n");
      wifi_connected = 0;
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);
}

How the Code Works?

We will start by including the necessary libraries for this project. As we are using the DHT22 sensor to monitor humidity and temperature readings, hence we include DHT.h. The <SimpleTimer.h> library will be used to add intervals between the sensor readings.

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include "DHT.h"
#include <SimpleTimer.h>

As the ESP32 communicates with the mobile application using Bluetooth, hence we will specify the BLE credentials which are set as default.

const char *service_name = "PROV_12345";
const char *pop = "1234567";

Define ESP32 GPIO pins connected with the DHT sensor and the LED. Moreover declare another variable called ‘gpio_reset’ to hold GPIO0.

static uint8_t DHTPIN = 33;
static uint8_t led_pin = 32;

static uint8_t gpio_reset = 0;

Next create two bool variables, one for the LED pin state and another for Wi-Fi connection.

bool led_pin_state = false;
bool wifi_connected = 0;

Next we will create the object of DHT according to our defined pin number and DHT type. The first parameter is the ESP32 GPIO pin connected with the DHT sensor. The second parameter is the DHT type. In our case it is ‘DHT22.’ You can use this with DHT11, DHT21, and DHT22 sensors.

DHT dht(DHTPIN, DHT22);

Declare Devices

Next we will declare devices. The framework provides some standard devices such as Switch, temperature sensor, Lightbulb etc. Refer to the official RainMaker website to get to know which standard devices you can use in your code.

Here we have declared two TemperatureSensor devices and one Switch device. The first device is for temperature and its widget name is called “Temperature.” The second device is for humidity and its widget name is called “Humidity.” The third device’s name is button and its widget will be called “LED” as specified in the first parameter. The second parameter specifies the ESP32 GPIO pin connected with the LED.

static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");
static Switch button("LED", &led_pin);

System Provisioning Event function

Next we have sysProvEvent(), which is the default function for system provisioning event. This function will obtain the Wi-Fi credentials and connect ESP32 to the router.

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
      printQR(service_name, pop, "ble");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
      printQR(service_name, pop, "softap");
#endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      wifi_connected = 1;
      delay(500);
      break;
    case ARDUINO_EVENT_PROV_CRED_RECV: {
        Serial.println("\nReceived Wi-Fi credentials");
        Serial.print("\tSSID : ");
        Serial.println((const char *) sys_event->event_info.prov_cred_recv.ssid);
        Serial.print("\tPassword : ");
        Serial.println((char const *) sys_event->event_info.prov_cred_recv.password);
        break;
      }
  }
}

write_callback()

The following callback function will be responsible for checking the particular device which sent the data and then change the parameter of the device accordingly. This callback function will be used for the device LED. If the device is ‘LED’ and its parameter is ‘Power’ then this function will check whether the state of the LED pin is HIGH or LOW. If the power is HIGH, the LED will turn ON .Similarly if the power if LOW, the LED will turn OFF.

You can refer to the official RainMaker website to get to know which parameters are available for the standard device types. As we are using the device Switch, hence it consists of two parameters: Name and Power.


void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  Serial.println(device_name);
  const char *param_name = param->getParamName();

  if (strcmp(device_name, "LED") == 0)
  {
    if (strcmp(param_name, "Power") == 0)
    {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      led_pin_state = val.val.b;
      (led_pin_state == false) ? digitalWrite(led_pin, LOW) : digitalWrite(led_pin, HIGH);
      param->updateAndReport(val);
    }
  }
}

setup()

Inside the setup() function we open the serial communication at a baud rate of 115200. Then we configure the reset pin as an input pin and the LED pin as an output pin. This is done by using pinMode() function and specifying the GPIO pin as the first parameter and the mode as the second parameter. Moreover, we will initially set the LED pin in a LOW state.

  Serial.begin(115200);


  pinMode(gpio_reset, INPUT);
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);

The dht.begin() function will initialize the DHT22 sensor and we can read temperature and humidity values from DHT11/DHT22 sensor.

dht.begin();

Next, inside the setup() function we will declare a node with the name “Microcontrollerslab.”

 Node my_node;
 my_node = RMaker.initNode("Microcontrollerslab");

Then we add devices to our node. In our case, we are adding three devices with names temperature, humidity and button respectively.

  my_node.addDevice(temperature);
  my_node.addDevice(humidity);
  my_node.addDevice(button);

We will also declare the callback function for the button device. This function aims to receive the data from the mobile app.

button.addCb(write_callback);

Then we start the RainMaker application.

RMaker.start();

Set an interval of 5 seconds between sensor readings and begin the Wi-Fi provisioning.

Timer.setInterval(5000);

  WiFi.onEvent(sysProvEvent);

#if CONFIG_IDF_TARGET_ESP32
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

loop()

Inside the loop() function, we send the DHT22 sensor data to ESP RainMaker and then reset it.

Firstly, we will send the sensor data when ESP32 is connected with the network and after 5 seconds have elapsed. Using readHumidity() method on the dht object and readTemperature() on the dht object we will get the value of humidity and temperature in Celsius from the DHT sensor. These readings will be saved in hum and temp variables respectively. The sensor data will be printed on the serial monitor. Next using temperature.updateAndReportParam() and humidity.updateAndReportParam() we will send the data. Inside the temperature device, we will update the Temperature parameter to the value saved in ‘temp.’ Likewise, inside the humidity device, we will update the Temperature parameter to the value saved in ‘hum’.

  if (Timer.isReady() && wifi_connected) {                    
    Serial.println("Sending Sensor Data");

    float hum = dht.readHumidity();
    float temp = dht.readTemperature();

    Serial.print("Temperature: "); 
    Serial.println(temp);
    Serial.print("Humidity: "); 
    Serial.println(hum);

    temperature.updateAndReportParam("Temperature", temp);
    humidity.updateAndReportParam("Temperature", hum);
    Timer.reset();                        
  }

Next, we will reset the RainMaker to wiping off the Wi-Fi credentials. This will be done by pressing the BOOT button present on ESP32 to reset it. To reset ESP32, we will read the state of GPIO0 (gpio_reset) and reset ESP RainMaker accordingly.


  if (digitalRead(gpio_reset) == LOW) {    //BOOT button pressed
    Serial.printf("Reset Button Pressed!\n");
    delay(100);
    int startTime = millis();
    while (digitalRead(gpio_reset) == LOW) delay(50);
    int endTime = millis();

    if ((endTime - startTime) > 10000) {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.\n");
      wifi_connected = 0;
      RMakerFactoryReset(2);
    } else if ((endTime - startTime) > 3000) {
      Serial.printf("Reset Wi-Fi.\n");
      wifi_connected = 0;
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);

Demonstration

Choose the correct board and COM port before uploading your code to the board. Therefore go to Tools > Board and select ESP32 Dev Module.

If you are using ESP32, select the ESP32 Dev module as follows:

select esp32 board

Next go to Tools > Partition Scheme and select RainMaker.

ESP32 Partition Scheme RainMaker

Then, go to Tools > Port and select the appropriate port through which your board is connected.

Click on the upload button to upload the code to ESP32 development board. After the code is successfully uploaded, open the serial monitor and set the baud rate to 115200.

Now press the ENABLE button of ESP32.

ESP32 enable reset button

ESP RainMaker Mobile Application

The ESP RainMaker will start. You will receive the QR code and also the link to access it clearly.

ESP32 RainMaker project serial monitor

Copy the HTTP address in a new web browser and press enter. You will be able to view the QR code clearly now.

ESP RainMaker QR Code for ESP32 Project

This is the QR code that we will scan with our ESP RainMaker app to configure it. Install RainMaker app in your smartphone from Play Store or App Store. It is available for both Android and iOS.

Configure ESP RainMaker app 1

After you open the ESP RainMaker app, you will be required to Sign in. You can choose to create a new RainMaker account by signing up or sign in using GitHub or Google.

Configure ESP RainMaker app 2

After you have successfully signed in, the Devices page will open. Here click Add Device button.

Configure ESP RainMaker app 3

Turn the Bluetooth of your smartphone on. Scan the QR code that we accessed before using the app and pair by clicking on the pair button when the Bluetooth pairing request pops up.

Configure ESP RainMaker app 4

Now the Claiming process starts.

Configure ESP RainMaker app 5

Now select the Wi-Fi network to connect to. Here the app has scanned some nearby networks for us. We can join other network as well.

Configure ESP RainMaker app 6

Specify the SSID and password of the Wi-Fi network and click the Start button.

Configure ESP RainMaker app 7

Now the Provisioning process starts. It consists of a number of steps which are verified before the device is successfully added. Click done after all steps are ticked.

If for some reason, any one one of the step fails, you can reset the ESP32 board to factory settings by long pressing the BOOT button for more than 10 seconds.

Configure ESP RainMaker app 8

Now we can see that our widgets are created. We have three widgets, one for Temperature, another for Humidity and another for LED. The temperature and humidity readings will continuously update after every 5 seconds. These are also printed in the Arduino serial monitor.

Configure ESP RainMaker app 9

We can control the LED connected with ESP32 by tapping the LED ON/OFF button to toggle it.

ESP32 RainMaker project demo

Watch the video below to see how we are controlling the LED with the LED switch widget.

Additional Features of ESP RainMaker

One of the great attributes of ESP RainMaker as compared to Blynk application and Arduino IoT cloud is that it provides some great handy features such as linking Alexa and Google Assistant with your ESP RainMaker account for voice control.

Go to Settings > Voice Services. Here you will be able to view Amazon Alexa and Google Assistant as supported voice services. You just have to link your ESP RainMaker account with the particular service and you will be easily able to control the LED through voice commands.

Moreover, we can also automate our project by including Scheduling services provided by the RainMaker app. Go to Schedules and click the Add Schedules button. After naming the schedule, you can select the time at which to turn the LED ON or OFF. Select whether you want to repeat this task throughout the week and then select the action whether you want to turn the LED ON or OFF. This way the LED will automatically turn ON or OFF at the particular time without making any changes to the code.

Additionally, ESP RainMaker also allows member sharing feature whereby another user can access your devices of a particular node on their cell phone and control them as well. This is done by entering the ID of the member you want to add by going to your Node details and add the user. Go to Node Details > Add Member and specify the user’s RainMaker email and click the Add button.

You may also like to read:

Leave a Comment