Arduino gets “NaN” while sending data from DHT22 sensor with the RF24.

Currently I am trying to send data (battery status, humidity, Arduino ID, ...) with the RD24 transceiver to a gateway (Raspberry Pi).
It already works with another temperature sensor.
The problem with the whole thing is that the sensor sends back 'NaN'.
My Hardware:
Arduino pro Mini: https://www.antratek.de/arduino-pro-mini-328-3-3v-8mhz
DHT22: %product-title% kaufen
NRF24L01: https://www.ebay.de/itm/142897030856
Battery case: %product-title% kaufen
Battery: https://www.amazon.de/dp/B07PCDSBZM/
Jumper Wires

My Arduino is wired as follows:
GND – GND (RF24)
2 - out (Humidity Sensor)
7 - CE (RF24)
8 - CS (RF24)
11 – MOSI (RF24)
12 – MISO (RF24)
13 – SCK (RF24)
A0 – Battery (red wire)
VCC – VCC (RF24)
GND - Battery (black wire)
VCC – VCC (Humidity Sensor)
GND – GND (Humidity Sensor)

Here is the code for it:

#include <DHT.h>
#include <DHT_U.h>
#include <OneWire.h>
#include <printf.h>
#include <SPI.h>
#include <RF24.h>

#define DHTPIN 2      
#define DHTTYPE DHT22
#define TIMERSECONDS 30

DHT dht(DHTPIN, DHTTYPE);
RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin

uint8_t address[][6] = {"1Node", "2Node"}; // Let these addresses be used for the pair
float batteryPercent;
int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
float batteryVoltage;
float humidity;
long lastTimestamp = -1;
float payload[4];
bool radioNumber = 2; //to use different addresses on a pair of radios, we need a variable to uniquely identify which address this radio will use to transmit
int valueA0 = 0;

void setup() {
  
  payload[0] = 2; // ID 
  payload[1] = 1234; // API - Key 
  
  Serial.begin(115200);

  // initialize the transceiver on the SPI bus
  if (!radio.begin()) {
    Serial.println(F("radio hardware is not responding!!"));
    while (1) {} // hold in infinite loop
  }
  
  dht.begin();
  delay(2000);

  // Set the PA Level low to try preventing power supply related problems
  // because these examples are likely run with nodes in close proximity to
  // each other.
  radio.setPALevel(RF24_PA_LOW);  // RF24_PA_MAX is default.

  // save on transmission time by setting the radio to only transmit the
  // number of bytes we need to transmit a float
  radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes

  // set the TX address of the RX node into the TX pipe
  radio.openWritingPipe(address[radioNumber]);     // always uses pipe 0

  // set the RX address of the TX node into a RX pipe
  radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
  
  radio.stopListening();  // put radio in TX mode

} // setup

void loop() {  
  //executes the code every TIMERSECONDS
  if (now()/TIMERSECONDS != lastTimestamp)
  {
     lastTimestamp=now()/TIMERSECONDS;
     delay(2000);
     humidity = dht.readHumidity();

     if (isnan(humidity)) {
      humidity = 99.0;
      }
     

    // calculates volts and battery level
    valueA0 = analogRead(A0);
    batteryVoltage = valueA0 * (3.3/1024.0);
    batteryPercent = (batteryVoltage - 1.0) * 100 / (3.3 - 1.0); // map(): (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  
    // battery calculation isnt accurate
    if (batteryPercent > 100.0){
      batteryPercent = 100.0;
    }else if(batteryPercent < 0.0){
      batteryPercent = 0.0;
    }
    
    // data to transfer
    payload[2] = humidity;
    payload[3] = batteryPercent; 
    
    bool report = radio.write(&payload, sizeof(payload));        // transmit & save the report
    
    if (report) {
      Serial.println(F("Transmission successful! "));           // payload was delivered 
    } else {
      Serial.println(F("Transmission failed or timed out"));    // payload was not delivered
    }
    
      // to make this example readable in the serial monitor
      delay(1000);  // slow transmissions down by 1 second

  }
} // loop

unsigned long now(){
  static unsigned long prevMillis;
  static unsigned long sysTime;
  while( millis() - prevMillis >= 1000){     
    sysTime++;
    prevMillis += 1000;  
  }
  return sysTime;
}

I tried the following things:

1:
I connect it to the breadboard and connect the battery cables to the upper VCC and GND, instead of A0 and GND. The problem here is that I don't want my Arduino on the breadboard. If I take it off there, I have one VCC pin too less.

2:
If I connect the Arduino on the breadboard as described above and also connect the PC, the sensor only sends correct data if the battery is also switched on at the same time.

@leonmeirose

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

I'd start by getting the DHT22 examples working without anything else just to verify that part, then add in the rest.
Also, you code comments seem to indicate you are sending a single float when in fact you are sending 4 floats (16 bytes). I hope the receiver is expecting that. There is a good tutorial: Simple nRF24L01+ 2.4GHz transceiver demo

blh64:
I'd start by getting the DHT22 examples working without anything else just to verify that part, then add in the rest.
Also, you code comments seem to indicate you are sending a single float when in fact you are sending 4 floats (16 bytes). I hope the receiver is expecting that. There is a good tutorial: Simple nRF24L01+ 2.4GHz transceiver demo

Hello, thank you for your answer!
If I only connect the DHT22 to the Arduino and use an example sketch, the measurement of the sensor works fine.
If I comment out everything in my code that has to do with the radio and add serialprints to read the DHT, the code also works.

As soon as the radio is added, nothing works.
In the following I would like to show you my gateway code.
It is written in Python and runs on my Raspberry Pi:

"""
 RF24  documentation at https://nRF24.github.io/RF24
 radio communication: https://github.com/nRF24/RF24/tree/master/examples_linux
"""
import socket
import sys
import argparse
import time
import struct
from RF24 import RF24, RF24_PA_LOW


parser = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
    "-n",
    "--node",
    type=int,
    choices=range(2),
    help="the identifying radio number (or node ID number)"
)
parser.add_argument(
    "-r",
    "--role",
    type=int,
    choices=range(2),
    help="'1' specifies the TX role. '0' specifies the RX role."
)

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 10000)

radio = RF24(22, 0)
payload = [0.0, 0.0, 0.0, 0.0] # Instead we'll use a 1 item list to store our float number for the payloads sent/received


"""
Listen for any payloads and print the transaction
"""
def slave():
    radio.startListening()  # put radio in RX mode

    start_timer = time.monotonic()
    while (time.monotonic() - start_timer):
        has_payload, pipe_number = radio.available_pipe()

        if has_payload:
            try:
                sock.connect(server_address)
                sock.sendall(payload)
            except: 
                print("An exception occurred") 
            finally:
                sock.close()

            # fetch 1 payload from RX FIFO
            buffer = radio.read(radio.payloadSize)
            # use struct.unpack() to convert the buffer into usable data
            # expecting a little endian float, thus the format string "<f"
            # buffer[:4] truncates padded 0s in case payloadSize was not set
            payload[0], payload[1], payload[2], payload[3] = struct.unpack("ffff", buffer)
            # print details about the received packet
            print(
                "Received {} bytes on pipe {}: ID: {} APIKey: {} SensorData: {} BatteryLife: {}".format(
                    radio.payloadSize,
                    pipe_number,
                    payload[0],
                    payload[1],
                    payload[2],
                    payload[3]
                )
            )
            start_timer = time.monotonic()  # reset the timeout timer

if __name__ == "__main__":

    args = parser.parse_args()  # parse any CLI args

    # initialize the nRF24L01 on the spi bus
    if not radio.begin():
        raise RuntimeError("radio hardware is not responding")

    # For this example, we will use different addresses
    # An address need to be a buffer protocol object (bytearray)
    address = [b"1Node", b"2Node"]
    # It is very helpful to think of an address as a path instead of as
    # an identifying device destination

    print(sys.argv[0])  # print example name

    # to use different addresses on a pair of radios, we need a variable to
    # uniquely identify which address this radio will use to transmit
    # 0 uses address[0] to transmit, 1 uses address[1] to transmit
    radio_number = 0  # uses default value from `parser`

    # set the Power Amplifier level to -12 dBm since this test example is
    # usually run with nRF24L01 transceivers in close proximity of each other
    radio.setPALevel(RF24_PA_LOW)  # RF24_PA_MAX is default

    # set the TX address of the RX node into the TX pipe
    radio.openWritingPipe(address[radio_number])  # always uses pipe 0

    # set the RX address of the TX node into a RX pipe
    radio.openReadingPipe(1, address[not radio_number])  # using pipe 1

    # To save time during transmission, we'll set the payload size to be only
    # what we need. A float value occupies 4 bytes in memory using
    # struct.pack(); "<f" means a little endian unsigned float
    radio.payloadSize = len(struct.pack("ffff", payload[0], payload[1], payload[2], payload[3]))
    #rint("radio Payload " + str(radio.payloadSize))
    
    try:
        slave()
    except KeyboardInterrupt:
        print(" Keyboard Interrupt detected. Exiting...")
        radio.powerDown()
        sys.exit()

NaN=Not a Number

This is obvious and unfortunately does not help me.

I have not looked into the radio library but I am guessing it may be using interrupts and that may be interfering with the DHT reading. I don't think the DHT library uses interrupts, but I have not checked. For you application, would it be acceptable to turn the radio off/disable it, do the readings and then turn it back on?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.