Friday, June 4, 2021

Blynk part 4: using Blynk with multiple ESP's

 For an index to all my stories click this text

This is the fourth installment in my series about working with Blynk.

In the previous stories I opened a Blynk project and used 1 ESP8266. In real life however you will want to use multiple ESP's in your home automation system. Some will control lights, others will read sensors like door and window sensors or temperature and sunlight sensors etc. etc. This story shows how to use multiple ESP8266's and ESP32's with Blynk in the same project.

Even better: this story shows how to send data from one ESP to another. This opens a myriad of possibillities. Think about an ESP-01 that pings your phone and if you are present sends that to another ESP that turns on the lights or heating. I did this with Domoticz but you can do it with Blynk too. Or have a PIR attached to an ESP and send movement data to another ESP that starts a siren. I bet you can come up with hundreds of ideas........

The first two stories gave an introduction to what Blynk is, showed how to send sensor data to Blynk and showed how to have Blynk control the GPIO pins of an ESP8266. If you are not familiar with Blynk re-read those here:
http://lucstechblog.blogspot.com/2021/03/blynk-part-1-starting-with-blynk.html
http://lucstechblog.blogspot.com/2021/04/blynk-part-2-sending-data-to-blynk.html

The third story showed how to build your own Blynk server so you are independend of the cloud and can make projects with as many widgets as you like. Re-read that story here: http://lucstechblog.blogspot.com/2021/04/blynk-part-3-your-own-blynk-server.html

Please re-read those stories first if you are not familiar with Blynk.

What we are going to do.

I am going to show you how to build a Blynk project in which you can send and receive data from an ESP8266 and an ESP32. Next to that the two controllers will be communicating with eachother through Blynk.

If you do not own an ESP32 you can alter the program easily for using two ESP8266's or you can alter the program easily if you only own ESP32's.

The hardware.

As stated this example is based on a setup with an ESP8266 and an ESP32.



This is the same breadboard setup as shown in the first story. A button is attached to D6 on the ESP8266 using a pull-up resistor of 10K. A led is attached to pin D5 with a current delimiting resistor of 220 ohm.




And here is the ESP32 setup. At the top there is a Dallas DS18B20 thermometer chip. Attached with a 4.7K pull-up resistor to pin D23. At the bottom is a pushbutton attached with a 10K pull-up resistor to pin D13.

What if you only have ESP8266's or ESP32's

Not to worry. You can build this project with any combination you have at stock. Just alter the pins in the Arduino program and use the right drivers and it will work with any combination.

How the Blynk project is organised

As you know, you can send sensor data from your ESP to Blynk. The sensors (in this case the buttons and the Dallas DS18B20) data is read with your ESP and send to a virtual pin in the Blynk app.

A Blynk project can have 255 virtual pins. So basically you can display data from 255 sensors in one project.

To make things easier to work with, you can divide the virtual pins in blocks. I decided to reserve virtual pins 1 to 10 for the ESP32 and pins 11 to 20 for the ESP8266. This means that you could use 25 ESP's in this project with each 10 sensors attached.

If you decided to assign 5 virtual pins to each ESP you could use 255/5 = 51 ESP's with each 5 sensors. More than enough for a full home automation project.

The Blynk  project.

Start with creating a new project.



Mine is called "Multiple Controllers" As board I chose the ESP32 but in fact that does not matter. If you push the "Create" button the authentification token is send to your email adress.


First thing to do is to put the widgets for the ESP32 in the project.



Start with adding a led. I called it "ESP32 button" as this led is going to show wether the ESP's button is pressed or not. I attached it to V1 and chose red as the color.



The next widget is a value widget. Just a rectangle that displays a value. I named it "Temperature" attached it to V2 and set the text to red color. Obviously this is going to display the value of the Dallas DS18B20 thermometer.



The third widget is a level widget. I tattached it also to V2. This way the text and the level will give the same temperature information. I limited the range from 0 to 30 and set the color also to red.



The next widget is the first widget for the ESP8266. This is also a led widget used to display the state of the ESP8266's button. I called it "ESP8266 Button" attached it to V12 and chose yellow as its color.



I also made a Value Display for the ESP8266 and that is going to display some random generated values. Therefore I called it "Random from ESP8266" attached it to V11 and also set its color to yellow.



For the ESP8266 to display random values I also chose a Level and attached it to the same V11 so the display and the level would give the same information. I changed the minimum values from 0 to 30 and also choose yellow as its display color.



The next widget is a Superchart. This will display a chart which gives the values of both the random values generated by the ESP8266 and the temperature from the ESP32. I named it "Mancave temperature" and chose green as value.

Chose add Datastream, and give your streams a name. Here the names are "Mancave temperature" and "ESP8266 random value" click on these names to alter their settings and attach them to the right virtual pins (V2 and V11 just like before).



I love gauges so I made two in this project. The first is attached to V2 so it will display the temperature from the DS18B20. I limited the minimum and maximum values from 0 to 30 and I gave it the same color as the value widget and level widget being red.



And another gauge. But this one displays the random values from the ESP8266. So it is also attached to V11. Its values are limited from 0 to 20 and the color is set to yellow.

The ESP32 program.

There is just a button and a Dallas DSD18B20 attached to the ESP32 so next to the Blynk libraries and commands there is nothing very special.

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#define dallasiopin 23
OneWire oneWire(dallasiopin);
DallasTemperature sensors(&oneWire);

int temp;

char auth[] = "BLYNK AUTHORISATION CODE";

char ssid[] = "YOUR ROUTERS NAME";
char pass[] = "PASSWORD";

const int btnPin = 13;

WidgetLED led1(V1);

BlynkTimer timer;

void buttonLedWidget()
{
  if (digitalRead(btnPin) == LOW)
  {
    led1.on();
  }
  else 
  {
    led1.off();
  }
}


void setup()
{
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,87), 8080);

  pinMode(btnPin, INPUT);

  sensors.begin();

  timer.setInterval(500L, buttonLedWidget);

      timer.setInterval(1000L, []() 
      {
      sensors.requestTemperatures();
      temp = (sensors.getTempCByIndex(0));
      Blynk.virtualWrite(V2, temp);
  
      Serial.print("Temperature is...");
      Serial.println(temp);
      });
}


void loop()
{
  Blynk.run();
  timer.run();
}


As usual I will highlite a few lines.

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#define dallasiopin 23
OneWire oneWire(dallasiopin);
DallasTemperature sensors(&oneWire);


The ESP32's wifi and Blynk libraries are loaded. The names of these libraries are just slightly different from the names of the ESP8266 libraries we used in the previous stories.

Next the OneWire library and the Dallas libraries are loaded. They are attached to the variable "sensors".

int temp;

char auth[] = "YOUR AUTHENTIFICATION CODE";

char ssid[] = "YOUR ROUTERS NAME";
char pass[] = "PASSWORD";

const int btnPin = 13;

WidgetLED led1(V1);

BlynkTimer timer;


A variable temp is created that will hold the value of the temperature, and variables are created that hold your projects authentification code and the name and password of your router.

If you do not know your authentification code you can look it up in the email you gotr when you created the project, or look it up in your local Blynk server (if you made one) or copy it frpom the Project Settings in the app. For more information how to do that look at the previous stories in this series.

The button is attached to pin 13 and variable btnPin. And the WidgetLED is defined as variable led1 which is attached to V1 (virtual pin 1 in the app).

An instance of the BlynkTimer is created with the name timer.

void buttonLedWidget()
{
  if (digitalRead(btnPin) == LOW)
  {
    led1.on();
  }
  else
  {
    led1.off();
  }
}


This function tests wether the button attached to the ESP is pressed and if so led1.on is send to Blynk. Otherwise led1.off is send.

void setup()
{
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,87), 8080);

  pinMode(btnPin, INPUT);

  sensors.begin();

  timer.setInterval(500L, buttonLedWidget);

      timer.setInterval(1000L, []()
      {
      sensors.requestTemperatures();
      temp = (sensors.getTempCByIndex(0));
      Blynk.virtualWrite(V2, temp);
 
      Serial.print("Temperature is...");
      Serial.println(temp);
      });
}


The setup() starts the serial monitor in which we will print the temperature obtained from the Dallas sensor.

Blynk is started and connected to our local server with the IPAdress and Portnumber.

The timer.setInterval sends each 500ms (half second) the reading from the Dallas DS18B20 to virtual pin V2 in our app and prints the temperature value in the serial monitor.

void loop()
{
  Blynk.run();
  timer.run();
}


The loop() makes sure that Blynk runs constantly and that the timer stays activated.

So the value of the button is send to V1 in our app and the value of the Dallas sensor send to V2.

The ESP8266 program

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "AUTHENTIFICATION CODE";

char ssid[] = "YOUR ROUTERS NAME";
char pass[] = "PASSWORD";

const int button = D6;
int randomnr;

WidgetLED led1(V12);

BlynkTimer timer;

void buttonLedWidget()
{
    if (digitalRead(button) == LOW) 
    {
      led1.on();
    } else 
    {
      led1.off();
    }
}

void sendrandom()
{
  randomnr = random(0, 20);
  Blynk.virtualWrite(V11, randomnr);
}

void setup()
{
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,87), 8080);

  pinMode(button, INPUT);

  timer.setInterval(500L, buttonLedWidget);
  timer.setInterval(1000L, sendrandom);

  randomSeed(analogRead(0));
}

void loop()
{
  Blynk.run();
  timer.run();
}



The ESP8266 program is the same as the one in the previous story so I will not go too much into the details. Just a few very important alterations.

char auth[] = "AUTHENTIFICATION CODE";

Fill THE SAME authentification code in as you did in the ESP32's program. So both the ESP32 and ESP8266 use the same authentification code and are therfore linked to the same project !!!

WidgetLED led1(V12);

The Widget for the ESP8266 in the app is linked to V12 (virtual pin 12). And the random number is send to V11 (virtual pin 11 in the app).
Remember from the beginning of this story that V1 to V10 are used for the ESP32 and V11 to V20 for the ESP8266. This is where we use this.

So both ESP's are now linked to the same project because they use the same authentification code. But they are used to different widgets being V1 and V2 for the ESP32 and V11 and V12 for the ESP8266.

Demonstration.

 

The video tell's all.

As I put my fingers around the Dallas DS18B20 you can see that the temperature first slowly rises and then falls again. You can see that in the value widget, in the level that changes constantly and in the gauge. It is also shown in the chart.

At the same time a random value made by the ESP8266 is shown in its own value widget, level widget and Gauge as well as in the chart. All at the same time.

In between the button at the ESP32 is pressed and later the button on the ESP8266 is pressed resulting in their respective led widgets going on and off.

Controlling the led attached to the ESP8266.

As you have seen it is easy to send data from the ESP's to the projects app.

I am going to expand this by lighting the led attached to the ESP8266 with a button in the projects app. This is a bit more complicated.

The breadboard setup in the beginning of this story shows that a led is attached to D5 on the ESP8266.

In the previous article in this series you saw that we can attach a Blynk button directly to an IO pin of the ESP. When using multiple ESP's like we are doing now that is not going to work. That is because the GPIO pins are only valid for the first ESP we are using and that is the ESP32. We want however to control the led on the ESP8266.

To control the ESP8266's led we first need to add a button in our app.

Stop the app by pressing the square at the top right side of the app so it changes in the triangle and we can edit the page.



Add a button and attach it to virtual pin 13 (V13). I did not alter the name and the color. Why V13 ??? Just as a reminder in our example project I want to use V1 to V10 for the ESP32 and V11 to V20 for the ESP8266. V11 and V12 are already used for the physical button at the ESP8266 and the random value generator. So the led will be attached to V13

Now the only thing that has to be modified is the program for the ESP8266 and here is the complete version.

Sending data across Blynk and multiple ESP's

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "AUTHENTIFICATION CODE";

char ssid[] = "YOUR_ROUTERS_NAME";
char pass[] = "PASSWORD";

const int button = D6;
const int led = D5;
int randomnr;

WidgetLED led1(V12);

BlynkTimer timer;

BLYNK_WRITE(V2)
{
  int tempValue = param.asInt(); 
  Serial.print("V2 temperature from esp32: ");
  Serial.println(tempValue);
}


BLYNK_WRITE(V13)
{
  int ledpinValue = param.asInt();
  Serial.print("V13 virtual button 13: ");
  Serial.println(ledpinValue);
  if (ledpinValue == 1)
  {
  digitalWrite(led, HIGH);
  }
  else
  {
  digitalWrite(led, LOW);
  }
}


void buttonLedWidget()
{
    if (digitalRead(button) == LOW) 
    {
      led1.on();
    } else 
    {
      led1.off();
    }
}

void sendrandom()
{
  randomnr = random(0, 20);
  Blynk.virtualWrite(V11, randomnr);
}

void setup()
{
  Serial.begin(9600);

  //Blynk.begin(auth, ssid, pass);
  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,87), 8080);

  pinMode(button, INPUT);
  pinMode(led, OUTPUT);
  timer.setInterval(500L, buttonLedWidget);
  timer.setInterval(1000L, sendrandom);

    timer.setInterval(1500L, []() 
    {
    sendrandom();
    Blynk.syncVirtual(V13);  // werkt goed
    Blynk.syncVirtual(V2);  // werkt goed
    });

  randomSeed(analogRead(0));
}


void loop()
{
  Blynk.run();
  timer.run();
}


The program is basically the same as the previous program in this story but with a few important changes which I will highlight here.

To read the virtual button created in the Blynk app whe need to synchronise the state of the app with the state of the ESP programs variables. To do that the Blynk library has a command Blynk.syncVirtual(Virtual pin). This command reads the value of the virtual pin in the Blynk App and we must act on that.

const int led = D5;

This line is added at the beginning of the program to tell the ESP8266 to which pin the led is attached.

BLYNK_WRITE(V2)
{
  int tempValue = param.asInt();
  Serial.print("V2 temperature from esp32: ");
  Serial.println(tempValue);
}


This function reads the value from virtual pin V2. So the ESP8266 will get the value from the ESP32's virtual pin V2 which holds the thermometer value. This program does nothing significant with it but just prints the thermometer value in the ESP8266's serial monitor.

This however opens the possibillity to get some data from an ESP and have another ESP react on that.

BLYNK_WRITE(V13)
{
  int ledpinValue = param.asInt();
  Serial.print("V13 virtual button 13: ");
  Serial.println(ledpinValue);
  if (ledpinValue == 1)
  {
  digitalWrite(led, HIGH);
  }
  else
  {
  digitalWrite(led, LOW);
  }
}


This is the function that reads the value of the Virtual pin (V13). That value is put in the variable ledpinValue. If that value is 1 then the button V13 in the app is pressed and the led is set ON. If the value is 0 then the V13 button is not pressed and the led stays off. This function is called at a regular interval from a timer that is defined in the setup() routine.

pinMode(led, OUTPUT);

Don't forget to put this line in your setup() routine otherwise the led will not react.

    timer.setInterval(1500L, []()
    {
    sendrandom();
    Blynk.syncVirtual(V13);
    Blynk.syncVirtual(V2);
    });


This routine in the setup() starts a timer every one and a half second (1500L) and calls the sendrandom() function like shown in the previous program. New however is that this timer also synchronises the V2 and V13 virtual pins and automatically calls all functions related to the defined virtual pins. So in this example it calls BLYNK_WRITE(V2) and BLYNK_WRITE(V13).

The rest of the program should be familiar.

That's all.

Expanding.

This tutorial shows how to use an ESP8266 and an ESP32 in the same Blynk app. Nothing withholds you from using multiple ESP's. So with one app you can automate many sensors and actuators in your home. Blynk does not replace a complete home automation system like Domoticz but it is a great setup for monitoring several sensors.

Till next time
Have fun

Luc Volders