Sending data via DHT22 together with nrf24 project *SOLVED*

EDIT - Solved with the final code posted in post #31. May help in the future for somebody else

Hello

First off, I've changed this thread from the original post, to save doing a new post as I've progressed further along

This is a project which I want to build with the intention to montitor my sons bedroom as he is like his mum and enjoys the room being at a warm temperature. Also, he has asthma, which is another reason I want to keep an eye on the humidity.

I had the project working without the rf24, which worked perfectly. I can get the rf24 modules to work on their own but when the two projects are merged, the serial monitor on the Transmitter shows NAN and the display of the Receiver displays NAN on the oled.

I just can't figure out why this is happening, looking online this appears to be a common problem but nothing seems to work.

The dht library is by adafruit and the rf24 is the TMRH20 library.
The DHT22 in use is on a breakout board with the pullup resistor in place.

Has anybody got any tips?

Thank you in advance

Tx

#include "DHT.h"
#include <SPI.h>  
#include "RF24.h"

#define DHTPIN 2  
#define DHTTYPE DHT22 
//#define _pin

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};
const int led_pin = 13;

struct package
{
  float temperature ;
  float humidity ;
};


typedef struct package Package;
Package data;

DHT dht(DHTPIN, DHTTYPE, 15);

void setup()
{
    Serial.begin(9600);
    pinMode(led_pin, OUTPUT);
    dht.begin();
    myRadio.begin();  
    myRadio.setChannel(115); 
    myRadio.setPALevel(RF24_PA_MAX);
    myRadio.setDataRate( RF24_250KBPS ) ; 
    myRadio.openWritingPipe( addresses[0]);
    delay(1000);
}



void loop()
{
 // digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
  readSensor();
  Serial.println(data.humidity);
  Serial.println(data.temperature);
  myRadio.write(&data, sizeof(data)); 
  //digitalWrite(led_pin, LOW);
  digitalWrite(DHTPIN, HIGH);// added
  delayMicroseconds(50);// added
//  delay(2000);
}

void readSensor()
{
 data.humidity = dht.readHumidity();
 data.temperature = dht.readTemperature();
}

Rx

#include "DHT.h"          //https://github.com/adafruit/DHT-sensor-library
#include "RF24.h"        //https://github.com/TMRh20/RF24
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

//#define DHTPIN 8 
struct package
{
  float temperature ;
  float humidity ;
}; 

typedef struct package Package;
Package data;


//#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};

float remoteHumidity = 0.0;
float remoteTemperature = 0.0;

void setup() {

Serial.begin(9600);
    Serial.begin(9600);
    dht.begin();
    myRadio.begin();  
    myRadio.setChannel(115); 
    myRadio.setPALevel(RF24_PA_MAX);
    myRadio.setDataRate( RF24_250KBPS ) ; 
    myRadio.openWritingPipe( addresses[0]);
  
    delay(2000);
  
  Wire.begin();
  dht.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C
}

void displayTempHumid(){
  delay(2000);
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
 
{
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont(&FreeMono9pt7b); //added for font test
  //display.setFont(&FreeSans9pt7b); //added for font test
  //display.setTextSize(1);
  display.setCursor(4,13);
  display.print("Temp:"); 
  display.print(t,1);
  display.print(" C"); 
  display.setCursor(4,28);
  display.print("Humid:"); 
  display.print(h,1);
  display.print("%");


//void displaytemp(float temp, char C_F)   // function to display temp, takes temperature and character C or F from calling function void dispTemp(void)
 //{
  display.drawRect(1, 1, display.width()-1, display.height()-1, WHITE);   // draws the outer rectangular boundary on the screen
  display.setTextColor(WHITE);   // i have white OLED display, you can use other colors in case you have multicolored display
  display.setTextSize(1);        // i have used large font to display temperature, it can be varied as per your taste
  display.setFont(); //added for font test
  display.setCursor(107,2);
  display.print("o");            // this prints the "o" symbol to show Degree 
 // display.setTextSize(2);
  //display.setCursor(112,10);    
  //display.print(C_F); 

}


void loop() {

  displayTempHumid();
  display.display();
}

Updated the original post, which is the reason for the bump. Thanks

Maybe this should be moved to the sensor section? Thanks

There are lots of problems with the code as posted. The radio part won't work because of several major errors.

Basically, you need to start over and get each part (temp read & display, data transmission via radio) working separately, before merging them together.

jremington:
There are lots of problems with the code as posted. The radio part won't work because of several major errors.

Basically, you need to start over and get each part (temp read & display, data transmission via radio) working separately, before merging them together.

Ah okay. I do have separate codes, where both projects work but not together. I’ll start again then I guess.

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

...R

Robin2:
Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

...R

Okay, thank you. I’ll try that then, thanks.

I have gotten the rf24 to work sending random numbers but when I try to interchange that for the dht22, it just does not work.

Back to the start.

I have gotten the rf24 to work sending random numbers but when I try to interchange that for the dht22, it just does not work.

Please post what you tried

If you started with example code that included incorrectly formed statements like this, you were misled.

    myRadio.openWritingPipe( addresses[0]);

Start instead with Robin2's examples from reply #5 and you should have an easier time of it.

UKHeliBob:
Please post what you tried

This is my code for the dht and oled display, without the rf24, which works

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

//font test
#include <Fonts/FreeMono9pt7b.h>
//#include <Fonts/FreeSans9pt7b.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Wire.begin();
  dht.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C
}

void displayTempHumid(){
  delay(2000);
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
 
{
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont(&FreeMono9pt7b); //added for font test
  //display.setFont(&FreeSans9pt7b); //added for font test
  //display.setTextSize(1);
  display.setCursor(4,13);
  display.print("Temp:"); 
  display.print(t,1);
  display.print(" C"); 
  display.setCursor(4,28);
  display.print("Humid:"); 
  display.print(h,1);
  display.print("%");


//void displaytemp(float temp, char C_F)   // function to display temp, takes temperature and character C or F from calling function void dispTemp(void)
 //{
  display.drawRect(1, 1, display.width()-1, display.height()-1, WHITE);   // draws the outer rectangular boundary on the screen
  display.setTextColor(WHITE);   // i have white OLED display, you can use other colors in case you have multicolored display
  display.setTextSize(1);        // i have used large font to display temperature, it can be varied as per your taste
  display.setFont(); //added for font test
  display.setCursor(107,2);
  display.print("o");            // this prints the "o" symbol to show Degree 
 // display.setTextSize(2);
  //display.setCursor(112,10);    
  //display.print(C_F); 

}
void loop() {
  displayTempHumid();
  display.display();

}

Tx without dht

#include "Arduino.h"
#include <SPI.h>
#include <RF24.h>

// This is just the way the RF24 library works:
// Hardware configuration: Set up nRF24L01 radio on SPI bus (pins 10, 11, 12, 13) plus pins 7 & 8
RF24 radio(7, 8); //7 is CE 8 is CS

byte addresses[][6] = {"1Node", "2Node"};

// -----------------------------------------------------------------------------
// SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP
// -----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println("THIS IS THE TRANSMITTER CODE - YOU NEED THE OTHER ARDIUNO TO SEND BACK A RESPONSE");

  // Initiate the radio object
  radio.begin();

  // Set the transmit power to lowest available to prevent power supply related issues
  radio.setPALevel(RF24_PA_MIN);

  //For further distance power can be set to MAX and data rate at 250KBPS 

  // Set the speed of the transmission to the quickest available
  radio.setDataRate(RF24_2MBPS);

  // Use a channel unlikely to be used by Wifi, Microwave ovens etc
  radio.setChannel(124);

  // Open a writing and reading pipe on each radio, with opposite addresses
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);

  // Random number seeding (we're going to be sending a single random number)
  randomSeed(analogRead(A0));
}

// -----------------------------------------------------------------------------
// LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP
// -----------------------------------------------------------------------------
void loop() {

  // Generate a single random character to transmit
  unsigned char data = random(0, 254);
    
  // Ensure we have stopped listening (even if we're not) or we won't be able to transmit
  radio.stopListening(); 

  // Did we manage to SUCCESSFULLY transmit that (by getting an acknowledgement back from the other Arduino)?
  // Even we didn't we'll continue with the sketch, you never know, the radio fairies may help us
  if (!radio.write( &data, sizeof(unsigned char) )) {
    Serial.println("No acknowledgement of transmission - receiving radio device connected?");    
  }

  // Now listen for a response
  radio.startListening();
  
  // But we won't listen for long, 200 milliseconds is enough
  unsigned long started_waiting_at = millis();

  // Loop here until we get indication that some data is ready for us to read (or we time out)
  while ( ! radio.available() ) {

    // Oh dear, no response received within our timescale
    if (millis() - started_waiting_at > 200 ) {
      Serial.println("No response received - timeout!");
      return;
    }
  }

  // Now read the data that is waiting for us in the nRF24L01's buffer
  unsigned char dataRx;
  radio.read( &dataRx, sizeof(unsigned char) );

  // Show user what we sent and what we got back
  Serial.print("Sent: ");
  Serial.print(data);
  Serial.print(", received: ");
  Serial.println(dataRx);

  // Try again 1s later
  delay(1000);
}

Rx without dht

#include "Arduino.h"
#include <SPI.h>
#include <RF24.h>

// This is just the way the RF24 library works:
// Hardware configuration: Set up nRF24L01 radio on SPI bus (pins 10, 11, 12, 13) plus pins 7 & 8
RF24 radio(7, 8); //7 is CE 8 is CS

byte addresses[][6] = {"1Node","2Node"};

// -----------------------------------------------------------------------------
// SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP   SETUP
// -----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println("THIS IS THE RECEIVER CODE - YOU NEED THE OTHER ARDUINO TO TRANSMIT");

  // Initiate the radio object
  radio.begin();

  // Set the transmit power to lowest available to prevent power supply related issues
  radio.setPALevel(RF24_PA_MIN);

  //For further distance power can be set to MAX and data rate at 250KBPS 

  // Set the speed of the transmission to the quickest available
  radio.setDataRate(RF24_2MBPS);

  // Use a channel unlikely to be used by Wifi, Microwave ovens etc
  radio.setChannel(124);

  // Open a writing and reading pipe on each radio, with opposite addresses
  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);

  // Start the radio listening for data
  radio.startListening();
}

// -----------------------------------------------------------------------------
// We are LISTENING on this device only (although we do transmit a response)
// -----------------------------------------------------------------------------
void loop() {

  // This is what we receive from the other device (the transmitter)
  unsigned char data;

  // Is there any data for us to get?
  if ( radio.available()) {

    // Go and read the data and put it into that variable
    while (radio.available()) {
      radio.read( &data, sizeof(char));
    }

    // No more data to get so send it back but add 1 first just for kicks
    // First, stop listening so we can talk
    radio.stopListening();
    data++;
    radio.write( &data, sizeof(char) );

    // Now, resume listening so we catch the next packets.
    radio.startListening();

    // Tell the user what we sent back (the random numer + 1)
    Serial.print("Sent response ");
    Serial.println(data);
  }
}

Post a link to the RF24 library you downloaded.

jremington:
Post a link to the RF24 library you downloaded.

Its this one, not sure if I got it from here or elsewhere.

In my original post, the code I put up, I’ve changed many times and tried varies things. I started again, again, so I may have removed too much which is why the address is wrong, which you posted before.

Does the example radio code work?

jremington:
Does the example radio code work?

It does. All three codes posted work.

If it works, the library seems to be compatible with the code.

The example you chose is a bit complex, as it waits for acknowledgement of successful reception. Do you need that additional complexity? If not, start with a simpler example that does not require an ACK.

Otherwise, carefully integrate the measurement code with the TX example, replacing the following line with one that sends the actual data:

  if (!radio.write( &data, sizeof(unsigned char) )) {

jremington:
If it works, the library seems to be compatible with the code.

The example you chose is a bit complex, as it waits for acknowledgement of successful reception. Do you need that additional complexity? If not, start with a simpler example that does not require an ACK.

Otherwise, carefully integrate the measurement code with the TX example, replacing the following line with one that sends the actual data:

  if (!radio.write( &data, sizeof(unsigned char) )) {

I don’t need the extra complexity. I was trying to integrate without that but I couldn't get my head around it.

Yes, I thought I needed to remove that but I kept getting errors and saying I’d not defined things. So do I need to replace ‘unsigned char’ for ‘data’ and then define data as the dht reading?

In the program with the DHT and the nRF24 (the one that is causing a problem) I think this

struct package
{
  float temperature ;
  float humidity ;
};


typedef struct package Package;
Package data;

should be

struct package
{
  float temperature ;
  float humidity ;
};

package data;

For my own coding I add the word "struct" to the names of my structs so it is clearer which name is the definition and which is the instance - for example

struct PackageStruct
{
  float temperature ;
  float humidity ;
};

PackageStruct data;

...R

Robin2:
In the program with the DHT and the nRF24 (the one that is causing a problem) I think this

struct package

{
  float temperature ;
  float humidity ;
};

typedef struct package Package;
Package data;




should be


struct package
{
  float temperature ;
  float humidity ;
};

package data;




For my own coding I add the word "struct" to the names of my structs so it is clearer which name is the definition and which is the instance - for example


struct PackageStruct
{
  float temperature ;
  float humidity ;
};

PackageStruct data;




...R

Thank you so much! I thought that was the only right bit ha.

Hello again. Well the NAN is corrected but I'm still unable to get the data to open up.

Can anybody help in this regard? I think I need to use this to open up the package sent, which I got from Robins code, as below. But my code does not like it. Or should it just open the data omce it's read the signal? I've no idea if the data is been received to be honest. I am out of my depth here and should put it on the back burner, but unfortunately I need this working!

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

This is the Tx

#include "DHT.h"
#include <SPI.h>  
#include "RF24.h"

#define DHTPIN 2  
#define DHTTYPE DHT22 
//#define _pin

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};
const int led_pin = 13;

struct PackageStruct
{
  float temperature ;
  float humidity ;
};



PackageStruct data;

DHT dht(DHTPIN, DHTTYPE, 15);

void setup()
{
    Serial.begin(9600);
    pinMode(led_pin, OUTPUT);
    dht.begin();
    myRadio.begin();  
    myRadio.setChannel(115); 
    myRadio.setPALevel(RF24_PA_MAX);
    myRadio.setDataRate( RF24_250KBPS ) ; 
 //   myRadio.openWritingPipe( addresses[0]);

      // Open a writing and reading pipe on each radio, with opposite addresses
  myRadio.openWritingPipe(addresses[1]);
  myRadio.openReadingPipe(1, addresses[0]);
    delay(2000);
}



void loop()
{
 // digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
  readSensor();
  Serial.println(data.humidity);
  Serial.println(data.temperature);
  myRadio.write(&data, sizeof(data)); 
  //digitalWrite(led_pin, LOW);
 // digitalWrite(DHTPIN, HIGH);// added
  //delayMicroseconds(50);// added
 delay(2000);
}

void readSensor()
{
 data.humidity = dht.readHumidity();
 data.temperature = dht.readTemperature();
}

Rx

#include "DHT.h"          //https://github.com/adafruit/DHT-sensor-library
#include "RF24.h"        //https://github.com/TMRh20/RF24
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


struct PackageStruct
{
  float temperature ;
  float humidity ;
};



PackageStruct data;


//#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};

float remoteHumidity = 0.0;
float remoteTemperature = 0.0;

void setup() {

Serial.begin(9600);
    Serial.begin(9600);
    dht.begin();
    myRadio.begin();  
    myRadio.setChannel(115); 
    myRadio.setPALevel(RF24_PA_MAX);
    myRadio.setDataRate( RF24_250KBPS ) ; 
  //  myRadio.openWritingPipe( addresses[0]);

      // Open a writing and reading pipe on each radio, with opposite addresses
  myRadio.openWritingPipe(addresses[0]);
  myRadio.openReadingPipe(1, addresses[1]);

  
  // Start the radio listening for data
  myRadio.startListening();
  
    delay(2000);
  
  Wire.begin();
  dht.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C
}

void displayTempHumid(){
  delay(2000);
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
 
{
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont(&FreeMono9pt7b); //added for font test
  //display.setFont(&FreeSans9pt7b); //added for font test
  //display.setTextSize(1);
  display.setCursor(4,13);
  display.print("Temp:"); 
  display.print(t,1);
  display.print(" C"); 
  display.setCursor(4,28);
  display.print("Humid:"); 
  display.print(h,1);
  display.print("%");


//void displaytemp(float temp, char C_F)   // function to display temp, takes temperature and character C or F from calling function void dispTemp(void)
 //{
  display.drawRect(1, 1, display.width()-1, display.height()-1, WHITE);   // draws the outer rectangular boundary on the screen
  display.setTextColor(WHITE);   // i have white OLED display, you can use other colors in case you have multicolored display
  display.setTextSize(1);        // i have used large font to display temperature, it can be varied as per your taste
  display.setFont(); //added for font test
  display.setCursor(107,2);
  display.print("o");            // this prints the "o" symbol to show Degree 
 // display.setTextSize(2);
  //display.setCursor(112,10);    
  //display.print(C_F); 

}


void loop() {


//radio . read ( & c ,   sizeof ( c ) ) ; 

// Is there any data for us to get?
  if ( myRadio.available()) 

    // Go and read the data and put it into that variable
    while (myRadio.available()) {
      myRadio.read( &data, sizeof(data));
    }



  displayTempHumid();
  display.display();
}

Why have you got all that DHT stuff in the Rx code ?

If the RF24 works and transmits the data struct which contains the remote temperature and humidity values then what you need to do is to output them locally after receiving the data. What you appear to be doing is outputting the local temperature and humidity and ignoring the values received via RF24