nrf24l01 losing my array value

Hey guys

I'm using nrf24s to send and receive some datas. I send these as an array in the following code. When I print them out from the transmitter all values are filled properly. Here is the transmit code.

Transmit Code

Serial.print("Water Temperature ");
Serial.println(water_temp);
//
Serial.print("Air Temperature ");
Serial.println(air_temp);
//
Serial.print("Heat Index ");
Serial.println(heat_index);
//
Serial.print("Humidity ");
Serial.println(humidity);


  weather[0] = air_temp;
  weather[1] = humidity; 
  weather[2] = heat_index;
  weather[3] = water_temp; 
  
   
  delay(4000);              // wait for a second




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

When I receive the array on the other side weather[3] has a value of 0.00. Here is the receive code.

Receive Code

// ######################################### MAIN LOOP #####################################

void loop()
{
  if ( radio.available() )
  {
   
    while (radio.available())
    {
      radio.read( weather, sizeof(weather) );

  display.display();

  display.clearDisplay();
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

//  weather[0] = air_temp;
//  weather[1] = humidity; 
//  weather[2] = heat_index;
//  weather[3] = water_temp; 


  display.print("Air Temp ");
  display.println(weather[0]);
  
  display.print("Humidity ");
  display.println(weather[1]);

   display.print("Heat Index ");
  display.println(weather[2]);

  display.print("Water Temp ");
  display.println(weather[3]);
  

    
    }
  }
  else
  {
    //Serial.println("No radio available");
  }
}

The last array element value is 0.00 after receiving.

I've over come this by expanding the array by one element on the transmit and receive sides but it still doesn't explain why the last value seems to disappear.

I need to know why the last element keeps loosing it's value. Have any of you come across this before?

You have probably removed some important info from the code we can see.

We do not know the variable types for example.

Post your full code.

Further:

Your receive code is fishy…

while (radio.available())
    {
      radio.read( weather, sizeof(weather) );

As soon as there is a gap in transmission, the loop will close.

Only close the loop once enough bytes are received or a timeout is hit.
PSUEDO CODE

while (time_elapsed < 1000ms && bytes_received<7)
    {
      radio.read( weather, sizeof(weather) );

Here is the full code.

Transmit Code

#include <OneWire.h>
#include <DallasTemperature.h>
 
// Data wire is plugged into pin 6 on the Arduino
#define ONE_WIRE_BUS 6
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);



// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"
#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321



// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.




//0x3c

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

#define RF_CS 9
#define RF_CSN 10

#define channel        0x4c                  // nrf24 communication channel
#define writtingPipe    0xF0F0F0F0E1LL        // nrf24 communication address
#define dataRate       RF24_250KBPS          // nrf24 data rate (lower == more distance)  RF24_1MBPS, RF24_2MBPS, RF24_250KBPS
#define paLevel        RF24_PA_MAX         // nrf24 power level  RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.

RF24 radio(RF_CS, RF_CSN);

DHT dht(DHTPIN, DHTTYPE);

//byte addresses[][6] = {"1Node"}; // Create address for 1 pipe.

int dataTransmitted;                // Data that will be Transmitted from the transmitter
  
// ######################## TEMPERATURE VARS ########################### 
  float h;
  float t;
  float f;
  float hif;
  float hic;

  
  //https://www.arduino.cc/en/Reference/Array
  // build an array to hold the weather vars.

//water_temp,air_temp,heat_index,humidity
  
float weather[4];

// ################################ SET UP ###############################

void setup() {
  Serial.begin(9600);
  Serial.println("DHT22 test!");
  printf_begin();
  
  
  dht.begin(); // begin humidty and tmp sensor


  radio.begin();  // Start up the physical nRF24L01 Radio

 //radio.setRetries(15,15); // optionally, increase the delay between retries & # of retries

 // radio.setPayloadSize(8);  // optionally, reduce the payload size. 
 
  radio.setChannel(channel);  // Above most Wifi Channels
  
  radio.setPALevel(paLevel);
 
  radio.setDataRate(dataRate);

  //radio.enableDynamicPayloads();

  radio.openWritingPipe(writtingPipe); // Use the first entry in array 'addresses' (Only 1 right now)

  radio.printDetails();

  // Start up the library for oneWire Dallas Temperature
  sensors.begin();


}

// ##################################### LOOP ################################

void loop() {
 int zeroCnt; 
  
  delay(2000); // Wait a few seconds between measurements.
  

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  
  h = dht.readHumidity();
  
  // Read temperature as Celsius (the default)
  t = dht.readTemperature();
  
  // Read temperature as Fahrenheit (isFahrenheit = true)
  f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  hif = dht.computeHeatIndex(f, h);
  
  // Compute heat index in Celsius (isFahreheit = false)
  hic = dht.computeHeatIndex(t, h, false);

  // Serial.print("Humidity: ");
  //Serial.print(h);
  //Serial.print(" %\t");
  
//  Serial.print("Temperature: ");
//  Serial.print(t);
  
  //Serial.print(" *C ");
  //Serial.print(f);
  //Serial.print(" *F\t");
  
 // Serial.print("Heat index: ");
  //Serial.print(hic);
  //Serial.print(" *C ");
  //Serial.print(hif);
  //Serial.println(" *F");

  //Serial.print(f);

  //Serial.println("");
  //Serial.print("Water temp is ");
  
  float water_temp = waterTemp();
  float air_temp=f;
  float humidity = h;
  float heat_index =hif;
  

Serial.print("Water Temperature ");
Serial.println(water_temp);
//
Serial.print("Air Temperature ");
Serial.println(air_temp);
//
Serial.print("Heat Index ");
Serial.println(heat_index);
//
Serial.print("Humidity ");
Serial.println(humidity);


  weather[0] = air_temp;
  weather[1] = humidity; 
  weather[2] = heat_index;
  weather[3] = water_temp;
  weather[4] = water_temp; 
  
   
  delay(4000);              // wait for a second

 


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

}

// ########################## GET WATER TEMP ################################

int waterTemp(){

  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  
  //Serial.println(" Requesting temperatures...");
  
  sensors.requestTemperatures(); // Send the command to get temperatures
  
  //Serial.println("DONE");

  //Serial.println("Temperature for Device 1 is: ");
  //Serial.println(sensors.getTempFByIndex(0)); // Why "byIndex"? 
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire
 
    return sensors.getTempFByIndex(0);
   
}

Receive Code

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

#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <gfxfont.h>


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


#define RF_CS 9
#define RF_CSN 10

#define channel        0x4c                  // nrf24 communication channel
#define readingPipe    0xF0F0F0F0E1LL        // nrf24 communication address
#define dataRate       RF24_250KBPS          // nrf24 data rate (lower == more distance)  RF24_1MBPS, RF24_2MBPS, RF24_250KBPS
#define paLevel        RF24_PA_MAX         // nrf24 power level  RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.



// #define char dataString[3] = {'humdity', 'air_temp', 'water_temp'}; //http://forum.arduino.cc/index.php?topic=42992.0

RF24 radio(RF_CS, RF_CSN);




const int ledPin = 6;



float weather[4];

// *****************************************************************************
void setup()   /****** SETUP: RUNS ONCE ******/
{
  
 
  
  // Use the serial Monitor (Symbol on far right). Set speed to 115200 (Bottom Right)
  Serial.begin(9600);
  printf_begin();
 
 
  radio.begin();  // Start up the physical nRF24L01 Radio


   // optionally, increase the delay between retries & # of retries
  //radio.setRetries(15,15);

  // optionally, reduce the payload size.  seems to improve reliability This implementation uses a pre-stablished fixed payload size for all transmissions. If this method is never called, the driver will always transmit the maximum payload size (32 bytes), no matter how much was sent to write().
  //radio.setPayloadSize(32);
 
  radio.setChannel(channel);  // Above most Wifi Channels
  
  radio.setPALevel(paLevel);
 
  radio.setDataRate(dataRate);

  //radio.enableDynamicPayloads();
  
  radio.openReadingPipe(1, readingPipe);
  
  radio.startListening();
 
  radio.printDetails();

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  //delay(2000);
  display.clearDisplay();
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Radio is ready...");
  
  display.display();
  //delay(2000);
  display.clearDisplay();


pinMode(7, OUTPUT);
  
}
//--(end setup )---


// ######################################### MAIN LOOP #####################################

void loop()
{
  if ( radio.available() )
  {
   // bool done = false;
    while (radio.available())
    {
      radio.read( weather, sizeof(weather) );

  display.display();
  //delay(2000);
  display.clearDisplay();
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

//  weather[0] = air_temp;
//  weather[1] = humidity; 
//  weather[2] = heat_index;
//  weather[3] = water_temp; 


  display.print("Air Temp ");
  display.println(weather[0]);
  
  display.print("Humidity ");
  display.println(weather[1]);

   display.print("Heat Index ");
  display.println(weather[2]);

  display.print("Water Temp ");
  display.println(weather[3]);
  
  
  
      
Serial.print("Water Temperature ");
Serial.println(weather[0]);
//
Serial.print("Air Temperature ");
Serial.println(weather[1]);
//
Serial.print("Heat Index ");
Serial.println(weather[2]);
//
Serial.print("Humidity ");
Serial.println(weather[3]);
    
    }
  }
  else
  {
    //Serial.println("No radio available");
  }
}

I’m a noob and not sure how to keep the loop open long enough to guarantee all datas have come through. Not sure why it would close until it was the sizeof(weather). That seems to be common code I’ve seen. I’ll work on your suggestions but can’t until next monday. Unless we have the storm hit us then I’ll be home from work.

Had to break up the post as I hit the text limit.

You don't need this WHILE

 if ( radio.available() )
  {
   // bool done = false;
    while (radio.available())
    {
      radio.read( weather, sizeof(weather) );

With the nRF24 if there is data available it will ALL be available.

Have you tried sending and receiving static data without using any sensors - that will enable you to see if the the wireless part is working properly.

What RF24 library are you using? The older ManiacBug version does not like long delay()s. I suggest you use the newer TMRh20 version of the RF24 library. Unfortunately TMRh20 did not think to change the name for his version so it is easy to get them confused. If in doubt I suggest you delete the library completely and then download and install the TMRh20 version.

This Simple nRF24L01+ Tutorial may be helpful - though I don't immediately see a problem with the RF24 part of your code.

...R

Thanks for the tip. I'll clean up the code a bit and report back.

ok, this is making me nuts. I’ve spent half the day trying to sort this out. I’m still getting corrupt data in the last element of my array after sending.

Current nRF lib is TMRh20 1.1.7

weather[4] = extra_data;

The transmit side has it as a value of 19.70 but when received it is 3.88

This is an improvement as before it was showing up 0.00

Any other ideas guys?

Transmit Code

// PROGRAM TRANSMIT SENSOR DATA

#include <OneWire.h>
#include <DallasTemperature.h>
 
// Data wire is plugged into pin 6 on the Arduino
#define ONE_WIRE_BUS 6
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);


#include "DHT.h"
#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321


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

#define RF_CS 9
#define RF_CSN 10

#define channel        0x4c                  // nrf24 communication channel
#define writtingPipe    0xF0F0F0F0E1LL        // nrf24 communication address
#define dataRate       RF24_250KBPS          // nrf24 data rate (lower == more distance)  RF24_1MBPS, RF24_2MBPS, RF24_250KBPS
#define paLevel        RF24_PA_MAX         // nrf24 power level  RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.

RF24 radio(RF_CS, RF_CSN);

DHT dht(DHTPIN, DHTTYPE);

  
// ######################## TEMPERATURE VARS ########################### 
  float h;
  float t;
  float f;
  float hif;
  float hic;
  
  float air_temp;
  float humidity ;
  float heat_index;
  float water_temp;
  float extra_data;
  
  
float weather[4];

int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 3000; // send once per second

// ################################ SET UP ###############################

void setup() {
  Serial.begin(9600);
  Serial.println("DHT22 test!");
  printf_begin();
  
  
  dht.begin(); // begin humidty and tmp sensor


  radio.begin();  // Start up the physical nRF24L01 Radio

 radio.setRetries(3,5); // optionally, increase the delay between retries & # of retries

 // radio.setPayloadSize(8);  // optionally, reduce the payload size. 
 
  radio.setChannel(channel);  // Above most Wifi Channels
  
  radio.setPALevel(paLevel);
 
  radio.setDataRate(dataRate);

  radio.enableDynamicPayloads();

  radio.enableAckPayload();

  radio.openWritingPipe(writtingPipe); // Use the first entry in array 'addresses' (Only 1 right now)

  radio.printDetails();

  // Start up the library for oneWire Dallas Temperature
  sensors.begin();


}

// ########################################################################

void loop(){
  
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
    getData();
    showData();
}
// ##################################### GET DATA ################################

void getData() {
  
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  
  h = dht.readHumidity();
  
  // Read temperature as Celsius (the default)
  t = dht.readTemperature();
  
  // Read temperature as Fahrenheit (isFahrenheit = true)
  f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  hif = dht.computeHeatIndex(f, h);
  
  // Compute heat index in Celsius (isFahreheit = false)
  hic = dht.computeHeatIndex(t, h, false);

   air_temp=f;
   humidity = h;
   heat_index =hif;
   water_temp = waterTemp();
   extra_data =19.70;
}

// ##################################### SEND ################################

void showData() {
   

Serial.print("Water Temperature ");
Serial.println(water_temp);
//
Serial.print("Air Temperature ");
Serial.println(air_temp);
//
Serial.print("Heat Index ");
Serial.println(heat_index);
//
Serial.print("Humidity ");
Serial.println(humidity);

Serial.print("Extra Data ");
Serial.println(extra_data);
}


// ##################################### SEND ################################

void send() {
   


  weather[0] = air_temp;
  weather[1] = humidity; 
  weather[2] = heat_index;
  weather[3] = water_temp;
  weather[4] = extra_data; 

  Serial.print("Extra Data ");
Serial.println(extra_data);
  


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


}


// ########################## GET WATER TEMP ################################

int waterTemp(){

  sensors.requestTemperatures(); // Send the command to get temperatures
  
  return sensors.getTempFByIndex(0);
   
}

More code to follow.

Receive Code

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

#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <gfxfont.h>


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


#define RF_CS 9
#define RF_CSN 10

#define channel        0x4c                  // nrf24 communication channel
#define readingPipe    0xF0F0F0F0E1LL        // nrf24 communication address
#define dataRate       RF24_250KBPS          // nrf24 data rate (lower == more distance)  RF24_1MBPS, RF24_2MBPS, RF24_250KBPS
#define paLevel        RF24_PA_MAX         // nrf24 power level  RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.


RF24 radio(RF_CS, RF_CSN);

char dataReceived[10]; // this must match dataToSend in the TX

int ackData[2] = {109, -4000}; // the two values to be sent to the master/transmitter
bool newData = false;


float weather[4];

// *****************************************************************************
void setup()   /****** SETUP: RUNS ONCE ******/
{
  
 
  
  // Use the serial Monitor (Symbol on far right). Set speed to 115200 (Bottom Right)
  Serial.begin(9600);
  printf_begin();
 
 
  radio.begin();  // Start up the physical nRF24L01 Radio


   // optionally, increase the delay between retries & # of retries
  //radio.setRetries(15,15);

  // optionally, reduce the payload size.  seems to improve reliability This implementation uses a pre-stablished fixed payload size for all transmissions. If this method is never called, the driver will always transmit the maximum payload size (32 bytes), no matter how much was sent to write().
  //radio.setPayloadSize(32);
 
  radio.setChannel(channel);  // Above most Wifi Channels
  
  radio.setPALevel(paLevel);
 
  radio.setDataRate(dataRate);

  radio.enableDynamicPayloads();
  
  radio.openReadingPipe(1, readingPipe);

  radio.enableAckPayload();
  radio.writeAckPayload(0, &ackData, sizeof(ackData)); // pre-load data

  
  radio.startListening();
 
  radio.printDetails();

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done

  screenInit();
  
}

// ######################################### MAIN LOOP #####################################

void loop()
{
    getData();
    showData();
    

}

//########################## GET DATA ###############################

void getData() {
  
    if ( radio.available() ) {
        radio.read( &weather, sizeof(weather) );
        updateReplyData();
        newData = true;
    }
}
// ######################### UPDATE REPLY DATA #######################

void updateReplyData() {
  
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(0, &ackData, sizeof(ackData)); // load the payload for the next time
}

//############################## SHOW DATA ###########################

void showData() {
  
    if (newData == true) {
        Serial.println("Weather Data received ");

        for(int i = 0; i < sizeof(weather); i++)
            {
             Serial.println(weather[i]);
            }
       
        Serial.print(" ackPayload sent ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        newData = false;
    }

  display.display();

  display.clearDisplay();
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  display.print("Air Temp ");
  display.println(weather[0]);
  
  display.print("Humidity ");
  display.println(weather[1]);

   display.print("Heat Index ");
  display.println(weather[2]);

  display.print("Water Temp ");
  display.println(weather[3]);
  
  
  
Serial.print("Air Temperature ");
Serial.println(weather[0]);
//
Serial.print("Humidity ");
Serial.println(weather[1]);

Serial.print("Heat Index ");
Serial.println(weather[2]);
//      
Serial.print("Water Temperature ");
Serial.println(weather[3]);
//

Serial.print("Extra Data ");
Serial.println(weather[4]);
}


// ####################################### SCREEN INIT ####################################

void screenInit(){
  
  display.clearDisplay();
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Radio is ready...");
  
  display.display();
  //delay(2000);
  display.clearDisplay();
}

In Reply #5 I asked

Have you tried sending and receiving static data without using any sensors - that will enable you to see if the the wireless part is working properly.

and you have not responded to that.

Also, have you tried any of my simple examples?

...R

Your tx array is too short, EDIT: same for the rx array

float weather[4];

  weather[0] = air_temp;
  weather[1] = humidity;
  weather[2] = heat_index;
  weather[3] = water_temp;
  weather[4] = extra_data;

Whandall:
Your tx array is too short, EDIT: same for the rx array

Full marks for spotting that.

…R

Whandall:
Your tx array is too short, EDIT: same for the rx array

float weather[4];

weather[0] = air_temp;
  weather[1] = humidity;
  weather[2] = heat_index;
  weather[3] = water_temp;
  weather[4] = extra_data;

What do you mean by it’s too short?

float weather[4];

Defines an array of 4 elements, numbered from 0 to 3. You read and write the 5th element.

  weather[4] = extra_data;

:confused:

It appears so simple now. I feel ashamed and dirty.

Seriously though, thank you guys. I appreciate your time and eyes.

r-noxious: It appears so simple now. I feel ashamed and dirty.

Don't be silly.

That's how you qualify to join the club. Welcome.

...R