1

Good day. I've been learning on how to transfer data from Arduino to Raspberry Pi wirelessly using NRF24L01 based on the following reference: Raspberry Pi 3 Tutorial 14 – Wireless Pi to Arduino Communication with NRF24L01+.

The reason why I want to do this is to log temperature and humidity data wirelessly using DHT22 sensors.

The Arduino code is shown below:

//SendReceive.ino

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

// CE, CSN pins
RF24 radio(9, 10);

void setup(void){
    while(!Serial);
    Serial.begin(9600);

    radio.begin();
    radio.setPALevel(RF24_PA_MAX);
    radio.setChannel(0x76);
    radio.openWritingPipe(0xF0F0F0F0E1LL);
    const uint64_t pipe = (0xE8E8F0F0E1LL);
    radio.openReadingPipe(1, pipe);

    radio.enableDynamicPayloads();
    radio.powerUp();

}

void loop(void){
    radio.startListening();
    Serial.println("Starting loop. Radio on.");
    char receivedMessage[32] = {0};
    if(radio.available()){
        radio.read(receivedMessage, sizeof(receivedMessage));
        Serial.println(receivedMessage);
        Serial.println("Turning off the radio.");
        radio.stopListening();

        String stringMessage(receivedMessage);

        if(stringMessage == "GETSTRING"){
            Serial.println("Looks like they want a string!");
            const char text[] = "Yo wassup, haha";
            radio.write(text, sizeof(text));
            Serial.println("We sent our message.");
        }
    }
    delay(100);

}

Meanwhile, the Raspberry Pi code is shown below:

import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev

GPIO.setmode(GPIO.BCM)

pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 17)

radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)

radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()

radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])
radio.printDetails()
# radio.startListening()

message = list("GETSTRING")
while len(message) &lt; 32:
    message.append(0)

while(1):
    start = time.time()
    radio.write(message)
    print("Sent the message: {}".format(message))
    radio.startListening()

    while not radio.available(0):
        time.sleep(1 / 100)
        if time.time() - start &gt; 2:
            print("Timed out.")
            break

    receivedMessage = []
    radio.read(receivedMessage, radio.getDynamicPayloadSize())
    print("Received: {}".format(receivedMessage))

    print("Translating the receivedMessage into unicode characters")
    string = ""
    for n in receivedMessage:
        # Decode into standard unicode set
        if (n &gt;= 32 and n &lt;= 126):
            string += chr(n)
    print("Out received message decodes to: {}".format(string))

    radio.stopListening()
    time.sleep(1)

Based on the Arduino code above, the code that shows the data that is transmitted is shown below:

const char text[] = "Yo wassup, haha";

Based on the Raspberry code above, the codes that decode the received data from Arduino are shown below:

for n in receivedMessage:
    # Decode into standard unicode set
    if (n &gt;= 32 and n &lt;= 126):
        string += chr(n)

However, these decoding code only works if I transmit string or integer from Arduino to Raspberry Pi. It doesn't work if I transmit float. Since DHT22 records temperature and humidity up until 1 decimal point, it is required for me to transmit float. Can anyone here please teach me how to decode the float values?

Thank you very much.

1

If you say you only need one digit, why not multiplying your value with 10 (with rounding), transmit it as a 4 byte (unsigned?) integer, and divide by 10 after receiving.

You only need to check if you have little or big endian conversion needed (swapping MSB/LSB 2 byte or single byte). But you see this very fast if you print the values in hex format.

  • 2
    Yes, but keep in mind that an Arduino's unsigned int is 16 bits while a pi's is 32 - you want an unsigned long, or better yet a portable type like uint32_t – Chris Stratton Aug 22 '17 at 15:17
  • @ChrisStratton Fully agree, whenever I want to control my type lengths, I always use (u)int8/16/32_t. This mostly is to reduce space (longer arrays) and sending data to other devices. – Michel Keijzers Aug 22 '17 at 15:31
  • But now you used float? – Avamander Aug 22 '17 at 22:02
  • Agree. I was also considering about multiplying the float by 10 in arduino, then transmit the value from arduino to pi, then divide back the value by 10 in raspberry pi. I also need some time to try doing this & will update you guys with my progress later. Thank you very much. – foxfaisal Aug 23 '17 at 4:42
  • Somebody suggested me to convert the float to string in Arduino, then transmit the string from Arduino to Raspberry Pi throught NRF24L01, then convert back the string to float in Raspberry Pi. I think I will also try that. Below are some of my references: Arduino - StringConstructor arduino.cc/en/Reference/StringConstructor Parse String to Float or Int stackoverflow.com/questions/379906/parse-string-to-float-or-int I will inform the result once I tried this. – foxfaisal Aug 23 '17 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.