Blynk, NRF24l01 and esp handling multiple sensors

I am working on a wireless network using Arduinos connected to NRF24 modules, these are communicating with a esp8266 which is sending the sensor data to the Blynk server.
I can get the data on the Blynk app to work perfectly with only one sensor reading represented by a virtual pin, if I add a second then the signials occasionally get mixed up and I will get values from V0 on the V1 wiget in the app, if I add a third then things get really messed up.

I am wondering the best way to take multiple analog readings on a virtual pin and send them to the app.

The problem may be between the NRF24l01 modules, any input would be great thank you.

Here is the Transmitter code:

 #include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00001", "00002"};    //Setting the two addresses. One for transmitting and one for receiving


int led = 3;
int moisture = A3;
int gTemp = A0;
int gTempON = 5;
 
void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(gTempON, OUTPUT);
  
  Serial.begin(9600);
  radio.begin();                            //Starting the radio communication
  radio.openWritingPipe(addresses[0]);      //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[1]);   //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MAX);            //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
}
void loop() 
{

      int V = readVcc();
      
     digitalWrite(gTempON, HIGH); 
      int gTempRAW = analogRead(gTemp);
      int gTempC = map(gTempRAW,266 ,591 ,0 ,36);
       float gTempF  = (gTempC * 1.8) +32;
      
      digitalWrite(gTempON, LOW);


       int value = analogRead(moisture);
       int val = map(value, 460, 860, 100, 0);
     
   radio.stopListening();

    radio.write(&gTempF, sizeof(gTempF));

    radio.write(&val, sizeof(val));

     radio.write(&V,sizeof(V));


       
}
 long readVcc() 
    { 
    long result; // Read 1.1V reference against AVcc 
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle 
    ADCSRA |= _BV(ADSC); // Convert 
    while (bit_is_set(ADCSRA,ADSC)); 
    result = ADCL; 
    result |= ADCH<<8; 
    result = 1126400L / result; // Back-calculate AVcc in mV 
    
    return result; 
    
    }

Here is the Reciever:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00001", "00002"};    //Setting the two addresses. One for transmitting and one for receiving


int led = 3;
int moisture = A3;
int gTemp = A0;
int gTempON = 5;

 
 
void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(gTempON, OUTPUT);
  
  Serial.begin(9600);
  radio.begin();                            //Starting the radio communication
  radio.openWritingPipe(addresses[0]);      //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[1]);   //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MAX);            //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
}
void loop() 
{

      int V = readVcc();
      
     digitalWrite(gTempON, HIGH); 
      int gTempRAW = analogRead(gTemp);
      int gTempC = map(gTempRAW,266 ,591 ,0 ,36);
       float gTempF  = (gTempC * 1.8) +32;
      
      digitalWrite(gTempON, LOW);


       int value = analogRead(moisture);
       int val = map(value, 460, 860, 100, 0);
     
   radio.stopListening();

    radio.write(&gTempF, sizeof(gTempF));

    radio.write(&val, sizeof(val));

     radio.write(&V,sizeof(V));


       
}
 long readVcc() 
    { 
    long result; // Read 1.1V reference against AVcc 
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle 
    ADCSRA |= _BV(ADSC); // Convert 
    while (bit_is_set(ADCSRA,ADSC)); 
    result = ADCL; 
    result |= ADCH<<8; 
    result = 1126400L / result; // Back-calculate AVcc in mV 
    
    return result; 
    
    }

Have you posted the correct code?
Where is your Blynk related code?

How are you identifying which transmitter the received data is coming from?

Pete.

Sorry I posted the transmitter code twice

Here is the receiver with the Blynk portion

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

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

char auth[] = "";
char ssid[] = "";
char pass[] = "";

BlynkTimer timer; // Announcing the timer
#define PIN_UPTIME V5


RF24 radio(D2, D8); // CE, CSN
const byte addresses [][6] = {"00001", "00002"};  //Setting the two addresses. One for transmitting and one for receiving

int led_pin = D4;

int V ;
int val;
float gTempF ;

// This function tells Arduino what to do if there is a Widget
// which is requesting data for Virtual Pin (5)
BLYNK_READ(PIN_UPTIME)
{
  // This command writes Arduino's uptime in seconds to Virtual Pin (5) 
Blynk.virtualWrite(PIN_UPTIME, millis() / 1000); 


  
}
  



void setup() 
{

  Blynk.begin(auth, ssid, pass);
timer.setInterval(1000L, TimerV); 

  
Serial.begin(9600);
  pinMode(led_pin, OUTPUT);
  radio.begin();                           //Starting the radio communication
  radio.openWritingPipe(addresses[1]);     //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[0]);  //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MAX); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver. 
}

void TimerV()
{ 
    int V =0 ; 
  
 radio.startListening(); //This sets the module as receiver
  if(!radio.available());
  {
   
radio.read(&gTempF,sizeof(gTempF));
Serial.print("gTempF  "); Serial.println(gTempF);
   
   radio.read(&V,sizeof(V));
Serial.print("V  "); Serial.println(V);

radio.read(&val,sizeof(val));
Serial.print("val  "); Serial.println(val);

      
 
  
  Blynk.virtualWrite(V2, gTempF);
  Blynk.virtualWrite(V0, val);
 Blynk.virtualWrite(V1, V);


  
  
  
}
}

void loop() 
{ 

  Blynk.run();
  timer.run();
  
}

For now I only have one transmitter, they are identified by the address from the radio. I can get the Voltage (V) and the Temp (gTempF) to work fine, the issue seems with the sensor value (val)?

Okay, so when you were talking about multiple sensors I thought you were meaning that these were connected to multiple transmitters.

I think your Tx code is missing a txStandBy() after each radio.write()

Pete.

Great! that helped thank you. After implementing I noticed that the values were alternating with a zero value on the receiver side so I just set some conditions to not write to Blynk if it was a zero. Now the timer is determined by the frequency of the transmission instead of the Blynk timer but I have it displaying 4 different sensor readings through one radio channel to the Blynk server.

Thank you Pete

1 Like

Can You help me with your code… I have same issue.
Thanks

I have a wemos d1 mini as RX, and two arduino unos as TX. when only one tx is connected, it works ok, when both tx are connected, the data is mixed. On serial to wemos, I can read the sensors correctly, only in Blynk it doesn’t work.

Code for TX1

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float temp1;

RF24 radio(9, 10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

void setup(void) {
Serial.begin(115200);
sensors.begin();
radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[1]);
//radio.startListening();
}

void loop(void)
{
sensors.requestTemperatures();
temp2 = sensors.getTempCByIndex(0);
radio.write(&temp1, sizeof(temp1));
Serial.println(temp1);
delay(10);
}

Code for TX2

#include <Adafruit_AHTX0.h>

#include <SPI.h>

#include "nRF24L01.h"

#include "RF24.h"

Adafruit_AHTX0 aht;

RF24 radio(9, 10);

const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

float temp2;

float humidity2;

void setup() {

  Serial.begin(115200);

  Serial.println("Adafruit AHT10/AHT20 demo!");

  radio.begin();

  radio.setDataRate(RF24_250KBPS);

  radio.openWritingPipe(pipes[2]);

  if (! aht.begin()) {

    Serial.println("Could not find AHT? Check wiring");

    while (1) delay(10);

  }

  Serial.println("AHT10 or AHT20 found");

}

void loop() {

  sensors_event_t humidity, temp;

  aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data

  Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");

  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");

  temp2 = temp.temperature;

  humidity2 = humidity.relative_humidity;

  radio.write(&temp2, sizeof(temp2));

  radio.write(&humidity2, sizeof(humidity2));

  Serial.println(temp2);

  Serial.println(humidity2);

  delay(500);

}

Code for RX


// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "xxxxxx"
#define BLYNK_DEVICE_NAME "xxxxxx"

#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
#define USE_WEMOS_D1_MINI

#include "BlynkEdgent.h"
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>

BlynkTimer timer;

float temp1;
float temp2;
float humidity2;

#define D3 0  // SI
#define D0  16  // NO I2C Bus SCL (clock)

// Set the pins up
#define CE_PIN D3
#define CSN_PIN D0
RF24 radio(0, 16);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

//BLYNK_CONNECTED() {
  //  Blynk.syncAll();
//}

void myTimer(){
  radio.read(&temp1, sizeof(temp1));
  Blynk.virtualWrite(1, temp1);
  Serial.println(temp1);
}
void myTimer1(){
  radio.read(&temp2, sizeof(temp2));
  Blynk.virtualWrite(2, temp2);
  Serial.println(temp2);
}
void myTimer2(){
  radio.read(&humidity2, sizeof(humidity2));
  Blynk.virtualWrite(3, humidity2);
  Serial.println(humidity2);
}

void setup()
{
Serial.begin(9600);
radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1, pipes[1]);
radio.openReadingPipe(2, pipes[2]);
radio.startListening();
  BlynkEdgent.begin();
  timer.setInterval(1000L, myTimer);
  timer.setInterval(1500, myTimer1);
  timer.setInterval(2000, myTimer2);
}

void loop() {
  BlynkEdgent.run();
  //read_radio_data();
  timer.run();
}

This surprises me.
Have you edited the Settings.h file of the Edgent example? If not, then you will have a conflict here:

because GPIO0 is used as the BOARD_BUTTON_PIN for Edgent.

More info here:

In addition, I don’t understand how your Wemos is meant to distinguish between temperature and humidity readings coming from your RX2 board. The board is pushing these readings out one after another at half second intervals, and your Wemos is looking for them at 1.5 and 2 second intervals, but there is no synchronisation (and no way to establish synchronisation) between the RX2 and Wemos boards.

I’d suggest that you change this part of your sketch…

to this…

void myTimer(){
  radio.read(&temp1, sizeof(temp1));
  Blynk.virtualWrite(1, temp1);
 Serial.print("temp1 = ");
 Serial.println(temp1);
}
void myTimer1(){
  radio.read(&temp2, sizeof(temp2));
  Blynk.virtualWrite(2, temp2);
  Serial.print("temp2 = ");
  Serial.println(temp2);
}
void myTimer2(){
  radio.read(&humidity2, sizeof(humidity2));
  Blynk.virtualWrite(3, humidity2);
  Serial.print("humidity2 = ");
  Serial.println(humidity2);
}

so you can better understand the data that is appearing in the Wemos serial monitor.

I would suspect that you will need to send one string of data from your TX2 device which includes both temperature and humidity, then parse the results to give you the separate values.

Pete.

Thanks Pete for the prompt and quick reply as always.

This is how I read the temperatures on the RX serial:

temp1 = 21.85
temp1 = 69.39
temp2 = 16.00
humidity2 = 21.86
temp1 = 16.00
temp2 = 21.84
temp1 = 69.35
humidity2 = 16.00

So they are all mixed together…

Yep, as I suspected.

This isn’t a Blynk issue, is an issue with the basic logic of your sketch and the way that you’re attempt to manage the communications.

Pete.

Have any ideea what i mistake ?

As I explained before, your process of running timed functions on the three devices that are i synchronised seems unlikely to work, and your results prove that it doesn’t work.

As there is no way to synchronise the three systems, you would need to use the identifiers from each transmitter board to identify the source. These are the “pipes” in your sketch, and for some reason you have three rather than two, and they aren’t being used on the receiving end to identify the two sources.

In addition, the two variables of temp and humidity would need to be sent together by the second transmitting device then parsed at the receiving end.

I’m not familiar with the hardware you are using, or the library you are using, so can’t really offer any more insight into the solution. But, as I said, it’s not a Blynk issue.

Maybe the author of the library you are using has some examples that will help you, or an NRF24 forum?

Pete.