Friday, June 25, 2021

Alarm !!! Using the Time and TimeAlarms libraries

For an index to all my stories click this text

In a previous story I showed you how to get the actual time from an NTP server. This is essential for this story so re-read that story here http://lucstechblog.blogspot.com/2020/02/time-is-of-essence.html

Once you got the real-life-time you need to do something with it. Naturally you can build a clock with the accurate time. That should not be to difficult. Later on in this story you'll find a setup for that.

I am doing a large project with my son in law. We are building an aquaponics system. He is doing the mechanics and I am doing the electronic part.
In an aquaponics system it is essential that the water pump runs every XX minutes for some pre-defined time. Further the lights should go on at scheduled times, and the fish need to be fed etc. etc. etc.

Getting the time as discussed in the previous story was just the first step. We now have to do something with that time.

I am going to show you how you can schedule certain events to happen at a certain time. In the example I will use 3 leds and they will all bet set on and off at regular intervals.

Libraries.

To use the time efficiently with an ESP8266 or ESP32 we need several libaries:


ESP8266WiFi.h  is the wifi library for the ESP8266
Wifi.h         is the wifi library for the ESP32

 
NTPClient.h    is the library that processes the time from the NTP server
WiFiUDP.h      is the UDP library needed for communicating with the NTP library

These were discussed in the previous story:  http://lucstechblog.blogspot.com/2020/02/time-is-of-essence.html

Next we need libraries to make processing the time easier and to set alarms.
 
TimeLib.h      a library for processing the time
TimeAlarms.h   a library for setting alarms

Both libraries can be installed directly in the Arduino IDE.
In the Arduino IDE open the sketch tab and chose Include Libraries and from the shown drop-down menu choose Manage Libraries.

You can also download the zip-libraries from their Github pages and install them with the library manager as zip-libraries. You can find both libraries on Github with the following links:

https://github.com/PaulStoffregen/Time
https://github.com/PaulStoffregen/TimeAlarms

Before I give you the example project I will give a short description of these libraries. I am sure you will find a lot of usefull purposes for them.

Time library

The time library has usefull commands for setting the time and for getting time details like hour, minute and seconds.
These are the most important commands:
 
setTime(t);                      // set the system time to the give time t
setTime(hr,min,sec,day,mnth,yr); // same as above, yr is 2 or 4 digit yr

We can use the above commands to set the time. You can do that manually but you can also first get the time from the NTP server and use that with the time library. Another option would be to attach a Real Time Clock (RTC) to your ESP. The RTC is a small PCB with a chip and a battery that keeps the time running accurately even if the ESP (or Arduino) has been powered down.

IMPORTANT !!
The setTime command must be the first command in your setup() routine. Otherwise certain alarm functions will not work properly..

This library makes sure we need to get the time from thye NTP server only once every xx hours so we will not overload the NTP server.

time_t t = now(); // store the current time in time variable t

hour(t);          // returns the hour for the given time t

minute(t);        // returns the minute for the given time t

second(t);        // returns the second for the given time t

day(t);           // the day for the given time t

weekday(t);       // day of the week for the given time t

month(t);         // the month for the given time t

year(t);          // the year for the given time t


Once the time is set we can use these commands to get the hour, minute, seconds in our program.

TimeAlarms library

Normally when we want to check the state of something you will make a loop that tests that state. If we would do that with the time library you would make a loop like this:

if (second(t) == 4)
{
 led1 = HIGH);
}


So you would presume that this will set led1 ON every 4 seconds. However that is not true. This will set led1 only everytime second(t) has the value 4. That's just once a minute.
As this might be fine for some purposes, sometimes we want to set the led on every 4 seconds, every 2 hour or every day at 8 o'clock.
That can be done with the TimeAlarms library.

If you look at the github page you can find a detailed explanation for all the commands. I will highlight a few here.

Alarm.alarmRepeat(2,30,0, getntptime);

This commands the library to run the getntptime routine every day at 02.30 This way you only check the actual time once a day. You can use this command multiple times and each new version can call a different routine for example setting lights on or off or to start your lawn sprinkler once a day etc etc.

Alarm.alarmRepeat(dowSunday, 20,15,0, Sundaytrigger);

This would command the library to call the Sundaytrigger routine once a week on Sunday evening at 20:15 hour in the evening.

Alarm.timerRepeat(Period, TimerFunction);

This would call the TimerFunction every Period. Period being time in seconds. This is what you would use, for example, to blink a led every 4 seconds or so.

Alarm.timerRepeat(2, 10, 0, TimerFunction);

This would call the TimerFunction every 10 minutes after the second hour. So at 2, 4, 6, 8 etc hour and ten minutes.

Alarm.delay(1000);

This works the same as the normal Arduino delay function. However you MUST use this instead of the normal delay() function as Alarm.delay() will not interfere with the TimerAlarms library and the normal delay() function will disrupt the alarms.

Stopping an alarm

It is possible to reset an alarm or just stop it. To do this you first need to make a function from the alarm. This sounds more difficult as it is. Lets look at an example that puts an alarm off after it has run 10 times.

AlarmId idalarm4;

int countalarm4 = 0;

First part is to make a new variable into which we will place the function. We also create a second variable that defines how often the alarm has been activated before it is stopped. Put these at the beginning of your program where you define all variables.


idalarm4 = Alarm.timerRepeat(0,30,0, runalarm4);

This would activate the runalarm4() routine every 30 minutes. It is assigned to the idalarm4 variable. Put this line in your setup() routine.

void runalarm4()
{
  Serial.println("alarm 4 starts");
  digitalWrite(Led, HIGH);   // turn the LED on
  Alarm.delay(500);          // wait for half a second
  digitalWrite(Led, LOW);    // turn the LED off
  countalarm4 ++;

  if (countalarm4 >10)

     {
     Alarm.disable(idalarm4);
     }
}

What happens here is that each time the alarm is activated the countalarm4 variable is increased by 1. When it reaches 10 the alarm is disabled.

There is one important thing left:

void loop() 
{
  Alarm.delay(1000); 
}


IMPORTANT !!!
You MUST put at least the Alarm.delay() command in your loop(). If you don't the alarms will not be triggered !!!!

The amount of delay is arbitrary. Just do not make it too short like under one second. Don't make it too long either as the alamrs will fail. So one to 5 seconds will be ok.

These are the most important commands. As stated earlier you can find more commands on the Github page of this library: https://github.com/PaulStoffregen/TimeAlarms

You can set 6 alarms when using an Arduino. If you use this library with an ESP8266 you can set 20 alarms. 

Advanced users.

You can expand the number of alarms in the TimeAlarms header file.

#if !defined(dtNBR_ALARMS )
#if defined(__AVR__)
#define dtNBR_ALARMS 6   // max is 255
#elif defined(ESP8266)
#define dtNBR_ALARMS 20  // for esp8266 chip - max is 255
#else
#define dtNBR_ALARMS 12  // assume non-AVR has more memory
#endif
#endif

The header file can be found in your documents, arduino, libraries folder.
You can edit this file with any text editor.

#if !defined(dtNBR_ALARMS )
#if defined(__AVR__)
#define dtNBR_ALARMS 6   // max is 255
#elif defined(ESP8266)
#define dtNBR_ALARMS 20  // for esp8266 chip - max is 255
#elif defined(ESP32)
#define dtNBR_ALARMS 20  // for esp32 chip - max is 255
#else
#define dtNBR_ALARMS 12  // assume non-AVR has more memory
#endif
#endif

This is how you make the code universal for Arduino, ESP8266 and ESP32. I just added an extra elif statement that tests for the ESP32 and then sets the amount of alarms to 20.

This was a lot of theory so let's see how this works practically.

Breadboard

I made a simple setup to test these libraries with 3 leds.



The setup is indeed very simple. Just an ESP8266 being a Wemos D1 mini with 3 resistors attached to D5, D6 and D7 through current delimiting resistors of 220 Ohm

Example 1

The first program is a simple program that blinks the 3 leds each at a different pace. The first led will blonk every 4 seconds, the second every 8 seconds and the last every 16 seconds.

#include <TimeLib.h>
#include <TimeAlarms.h>

#define Led1 D5
#define Led2 D6
#define Led3 D7

void setup() 
{
  Serial.begin(115200);
  
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);

  setTime(0,0,0,0,0,0);

  Alarm.timerRepeat(4,  alarm1); //
  Alarm.timerRepeat(8,  alarm2); //
  Alarm.timerRepeat(16,  alarm3); // 

  digitalWrite(Led1, LOW);
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW);
}

void loop()
{
  Alarm.delay(5000);
}

void alarm1() 
{
  Serial.println("ALARM 1");
  digitalWrite(Led1, HIGH);   // turn the LED on (HIGH is the voltage level)
  Alarm.delay(500);                       // wait for a second
  digitalWrite(Led1, LOW);    // turn the LED off by making the voltage LOW
}

void alarm2() 
{
  Serial.println("ALARM 2");
  digitalWrite(Led2, HIGH);   // turn the LED on (HIGH is the voltage level)
  Alarm.delay(500);                       // wait for a second
  digitalWrite(Led2, LOW);    // turn the LED off by making the voltage LOW
}

void alarm3() 
{
  Serial.println("ALARM 3");
  digitalWrite(Led3, HIGH);   // turn the LED on (HIGH is the voltage level)
  Alarm.delay(500);                       // wait for a second
  digitalWrite(Led3, LOW);    // turn the LED off by making the voltage LOW
}

Now you might expect that at certain times they blink all together. But no there is a slight delay. In this example it makes the leds blink after eachother. In a real world example you would not have lamps or pumps switching at such short interval after eachtother, so that would not pose a problem.

You can watch the Serial Monitor as some information is printed there. Adjust it all to your own liking.

Example 2

Example 2 shows you how to get the time from the NTP server and have the leds blink on the same intervals as the previous program. Only now the time is the real life time. As a bonus there is a clock printed in the Serial Monitor and it also shows you the sequence of the alarms. The clock part was shamelesly stolen from the demo program included in the library.

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUDP.h>

#include <TimeLib.h>
#include <TimeAlarms.h>

// WiFi credentials for your router
const char* ssid = "XXXXXXXXXXXXXX"; 
const char* password = "YYYYYYYYYYYYY"; 

#define Led1 D5
#define Led2 D6
#define Led3 D7

#define NTP_OFFSET   60 * 60      // In seconds
#define NTP_ADDRESS  "europe.pool.ntp.org"

WiFiUDP ntpUDP;

NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET);

void setup() 
{
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  Serial.begin(115200);

  Serial.print("Starting the connection");
  WiFi.begin(ssid, password); // Connect to WiFi

  while (WiFi.status() != WL_CONNECTED) 
    {
      delay(500);
      Serial.print(".");
    }

  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Alarm.timerRepeat(4,  alarm4); //
  Alarm.timerRepeat(8,  alarm8); //
  Alarm.timerRepeat(16,  alarm16); // 

  timeClient.update();
  String newtime = timeClient.getFormattedTime();
  Serial.print("the time is : ");
  Serial.println(newtime);
  Serial.print("Hour    : ");
  Serial.println((newtime.substring(0,2)).toInt());
  Serial.print("Minute  : ");
  Serial.println((newtime.substring(3,5)).toInt());
  Serial.print("Seconds : ");
  Serial.println((newtime.substring(6,8)).toInt());
  Serial.println(timeClient.getFormattedDate());
  setTime((newtime.substring(0,2)).toInt(),(newtime.substring(3,5)).toInt(),(newtime.substring(6,8)).toInt(),1,1,20); 
}

void loop() 
{
  digitalClockDisplay();
  Alarm.delay(1000); // show clock every second
}

void alarm4() 
{
  Serial.println("ALARM 4 ACTIVATED");
  digitalWrite(Led1, HIGH);   // turn the LED on 
  Alarm.delay(500);           // wait for half a second
  digitalWrite(Led1, LOW);    // turn the LED off 
}

void alarm8() 
{
  Serial.println("ALARM 8 ACTIVATED");
  digitalWrite(Led2, HIGH);   // turn the LED 
  Alarm.delay(500);           // wait for half a second
  digitalWrite(Led2, LOW);    // turn the LED off 
}

void alarm16() 
{
  Serial.println("ALARM 16 ACTIVATED");
  digitalWrite(Led3, HIGH);   // turn the LED on 
  Alarm.delay(500);           // wait for half a second
  digitalWrite(Led3, LOW);    // turn the LED off 
}

void digitalClockDisplay() 
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void printDigits(int digits) 
{
  Serial.print(":");
  if (digits < 10)
  Serial.print('0');
  Serial.print(digits);
}


As usual: do not forget to replace the XXXXXX and YYYYY with your own routers credentials.

You can re-read how to fetch the time from the NTP server in this story: http://lucstechblog.blogspot.com/2020/02/time-is-of-essence.html

Real life use.

As stated before this is part of the software I need for a large project: building a complete aquaponics system for my son in law.

This is however suitable for may time oriented projects like a clock with an Oled screen or just a TM1637 4 digit seven segment screen. You can use this to set your lampos on and off on unpredictable times when you are not at home, to scare away the burglars. Or just to have a trigger to log data from a thermometer or whatever.
Use your imagination and.......

Have fun
Till next time

Luc Volders

Friday, June 11, 2021

Examine before throwing away

 For an index to all my stories click this text

I found some first generation 12 Volt led-lamps that did not function anymore. So we had to replace them. The strange thing was that althouogh they did not work anymore they made some humming sound. So I took them with me to have a closer look.



Upon opening I stumbled upon this. I never suspected that they had a fan inside !!!



I added a resistor to the photo as a reference so you can see it is indeed a very small fan.

I attached 3 AA batteries in series to the fan as a power supply. They started spinning immediately. The mystery of the humming sound revealed and ......... I have some real good working fans that can operate at 5 volts.

Moral of the story: do not throw anything away before having a closer examination.

Till next time
have fun

Luc Volders

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