Connecting two ESP32 to one Blynk App

My project has two ESP32 boards, one connecting with some sensors (DHT22 , MQ2, O2 sensor) , and the other one is connecting with air purifier.
The first ESP take the readings to show on the blynk app , and I need when some readings go over threshold, a signal sent to the second esp to turn on the purifier.

I tried to connect the two esp with the same blynk credentials (template name, ID and auth), and make one virtual pin shared with the two devices, but it does not work.

Any suggestions to do it

Here is my code for the first and the second devices:

#define BLYNK_TEMPLATE_ID "TMPL6p2Ldf19V"
#define BLYNK_TEMPLATE_NAME "Smart bracelet"
#define BLYNK_AUTH_TOKEN "40TNvmRyx_hSJgmxmyfj7xUXXIi5SAOi"

#define BLYNK_PRINT Serial


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

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#include "DFRobot_OxygenSensor.h"
#define Oxygen_IICAddress ADDRESS_3
#define COLLECT_NUMBER  10             // collect number, the collection range is 1-100.
DFRobot_OxygenSensor oxygen;

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 4   

#define DHTTYPE    DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;
float temp; 
float humidity;

int flag = 0;

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wi-Fi";
char pass[] = "12341234";

BlynkTimer timer;

void myTimerEvent(){
  float oxygenData = oxygen.getOxygenData(COLLECT_NUMBER);
  oxygenData -= 2;
  float smokeData = (analogRead(34)/4091.0)*100.0;
  
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  }
  else {
    //Serial.print(F("Temperature: "));
    temp = event.temperature;
    //Serial.print(event.temperature);
    //Serial.println(F("°C"));
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println(F("Error reading humidity!"));
  }
  else {
    //Serial.print(F("Humidity: "));
    humidity = event.relative_humidity;
    //Serial.print(event.relative_humidity);
    //Serial.println(F("%"));
  }

  if(smokeData > 50 || temp > 40 || humidity > 75){
    if(flag == 0){
    Blynk.virtualWrite(V5, 1);
    timer.setTimeout(500L, ActionOFF);}
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(36, 5);
  display.print("O2: ");
  display.print(oxygenData);
  display.println("%");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(31, 23);
  display.print("smoke: ");
  display.print(smokeData);
  display.println("%");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(32, 37);
  display.print("Temp: ");
  display.print(temp);
  display.println("C");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20, 53);
  display.print("Humidity: ");
  display.print(humidity);
  display.println("%");
  display.display(); 
  
  Blynk.virtualWrite(V0, oxygenData);
  Blynk.virtualWrite(V1, smokeData);
  Blynk.virtualWrite(V2, temp);
  Blynk.virtualWrite(V3, humidity);
}

void ActionOFF(){
  Blynk.virtualWrite(V5, 0);
  flag = 1;}

void setup(){
  Serial.begin(115200); 
  analogReadResolution(12);  
  while(!oxygen.begin(Oxygen_IICAddress)){
    Serial.println("I2c device number error !");
    delay(1000);
  }
  Serial.println("I2c connect success !");

  dht.begin();
  Serial.println(F("DHTxx Unified Sensor Example"));
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Temperature Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
  Serial.println(F("------------------------------------"));
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Humidity Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));


    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(32000);
  // Clear the buffer
  display.clearDisplay();
  // Debug console
  
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  timer.setInterval(1000L, myTimerEvent);
  flag = 0;
}

void loop(){
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

The second:

#define BLYNK_TEMPLATE_ID "TMPL6p2Ldf19V"
#define BLYNK_TEMPLATE_NAME "Smart bracelet"
#define BLYNK_AUTH_TOKEN "40TNvmRyx_hSJgmxmyfj7xUXXIi5SAOi"

#define BLYNK_PRINT Serial

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


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wi-Fi";
char pass[] = "12341234";

BlynkTimer timer;

BLYNK_WRITE(V5){
  int pinValue = param.asInt(); // assigning incoming value from pin V5 to a variable
  
  if(pinValue == 1){ActionON();}
}

void ActionON(){
  digitalWrite(16, LOW);  // Set pin high
  timer.setTimeout(500L, ActionOFF);  // Run ActionOFF function in 5 seconds
}

void ActionOFF(){
  digitalWrite(16, HIGH);  // Set pin Low
}

void setup(){
  Serial.begin(115200); 
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  timer.setInterval(1000L, myTimerEvent);
  pinMode(16,OUTPUT);
  digitalWrite(16,HIGH);
}

void loop(){
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

Take a look at Automations.

Pete.

If you only need simple communication between two devices connected to the same LAN, using Udp or tcp might be the easiest way to proceed.

But @Barahim doesn’t just want simple communication between two devices connected to the same LAN, be also wants communication with the Blynk cloud server from at least one of the devices.
Managing device-to-device communication without interfering with the device to Blynk communication isn’t easy, which is one of the reasons why people struggle so much with ESP_NOW plus Blynk.

The official Blynk solution is to have both devices connected to Blynk and use Automations to pass values from one to the other.
It’s a clunky solution in my opinion, and eats-up devices and messages (if you’re using a free account) but it’s easier than any of the alternatives.

Pete.

Hi Pete,

with the services provided by the WiFiUdp.h library, an ESP8266 can concurrently connect to the Blynk server and communicate with other devices (Blynk connected or not) on the same LAN using udp.write and udp.read. There is no interaction between these two communication channels at all.

To keep it simple, I use static IP@ and my Blynk config is non-edgent. I use application layer ACK and retransmission only for critical data.

My main reasons for not using automations are threefold:

  • the limited number of devices allowed in my maker plan.
  • the lack of unified dashboard covering multiple devices (in my plan).
  • I do not want Blynk to have any active role in the operational behaviour of my home system. Blynk is merely considered to be a remote UI.

In addition, I considered setting up an MQTT environment for my simple communication needs to be an overkill.

regards,

Piet.

FYI, my main critical device connects at the same time with the Blynk server, the Arduino Cloud server, uses https to retrieve initial values of virtual pins from the Blynk server, and uses udp to exchange control and status info between devices in my local network. Connecting to both Blynk and Arduino Cloud servers allowed for a hit-free backup incase something unexpected would happen to my Blynk plan.

1 Like