nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.2k stars 1.01k forks source link

[Question] Why i'm getting Different Writing-Reading Rates and Noise? #619

Closed rbp9802 closed 3 years ago

rbp9802 commented 3 years ago

Hi,

I'm trying to read aceleration data in real time send from an Arduino to a Rpi usin NRF24L01P (+) modules. I´m sending data at 200Hz (Serial printed) but receiving it only at 90 Hz. How can i improve the reading rate?

On the other hand, my goal is to communicate at 250KBPS data rate but i'm getting to much noise with this rate. the noise is acceptable only at 2MBPS. Why does this happen?

Thanks!!

i'll leave my codes here:

Arduino Transmitter Code:

#include "Arduino.h"
#include "Wire.h"
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define I2Caddress 0x48

RF24 radio(7, 8); // CE, CSN

typedef struct{
  int16_t AY;        // Y Acceleration
  int16_t AZ;        // Z Acceleration
  unsigned long t1;  // time in microseconds
  }
myData;
myData data;

unsigned long t2; // Reference time

void setup()
{
  Serial.begin(115200);
  RadioSetUp();
  Wire.begin();
  data.t1 = micros();
}

void loop()
{ t2 = micros();
  if (t2 - data.t1 > 4990) {   // Sample every 5ms (200Hz)
    Read();
    SerialPrint();
    Send(); 
  }
}

void Read(){
  data.t1 = micros();
  data.AY = yRead();
  data.AZ = zRead();  
  }

void SerialPrint(){
  Serial.print(data.AY);Serial.print("\t");
  Serial.println(data.AZ);//Serial.println("\t");
  }

void Send(){
  radio.writeFast(&data, sizeof(data));
  }

void RadioSetUp(){
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(0x76);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.enableDynamicPayloads();
  radio.setPayloadSize(32);
  radio.setCRCLength(RF24_CRC_8);
  radio.setDataRate(RF24_2MBPS);
  radio.setAutoAck(1);
  radio.setRetries(1, 3); 
  radio.powerUp();
  }

RPi Python Script:

import RPi.GPIO as GPIO
from lib_nrf24 import NRF24

import os
import numpy as np

from numpy import asarray
from numpy import save
from numpy import load

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.setCRCLength(NRF24.CRC_8)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_2MBPS)
radio.setPALevel(NRF24.PA_MAX)

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

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

message = 1

radio.startListening()

a = np.array([0,0,0], dtype = 'int16')

try:
    while True:

##        start = time.time()
##        while not radio.available(0):
##            time.sleep(1/10000.0)
##            if time.time() - start > 0.01:
##                print("Timed out")
##                break

        if radio.available() == True:
            r = [] #received in 8-bit list
            radio.read(r, 8) #tamaño del mensaje (N° de bytes)
            ##            AY            AZ            t
            b = np.array([r[0]+r[1]*256,r[2]+r[3]*256,r[4]+r[5]*256+r[6]*65536+r[7]*16777216])    
            a = np.vstack([a,b])
            print("Recieved: {} at {}".format(b,time.ctime()))
        #time.sleep(5/1000.0)

finally:
    radio.stopListening()
    GPIO.cleanup()
    a = np.delete(a,0,0)
    save('data.npy', a)
    x = np.load('/home/pi/Desktop/RF24/data.npy')
TMRh20 commented 3 years ago

Hrrmm, where to start?

"I'm trying to read aceleration data in real time send from an Arduino to a Rpi usin NRF24L01P (+) modules. I´m sending data at 200Hz (Serial printed) but receiving it only at 90 Hz. How can i improve the reading rate?"

That seems pretty unlikely. You have auto-ack enabled with 3 retries, so the transmitter will wait for the receiver to acknowledge before sending again.

Unless there is simply an issue with packets being missed at a very high rate, in that case it would be a hardware issue and/or problems communicating at the physical layer. Verify proper behaviour with known examples, gettingstarted gettingstarted call response. Try modifying the intervals in the examples. Increase retries, change radio channel etc to mitigate.

"On the other hand, my goal is to communicate at 250KBPS data rate but i'm getting to much noise with this rate. the noise is acceptable only at 2MBPS. Why does this happen?"

Radios use SPI for communication and the radios generate signals as well. SPI operates at 8Mhz on AVRs by default. You can modify the frequency in the constructor to see if it helps:

RF24 radio(7,8,8000000);

Hard to say exactly, caps on the PWR-GND of radios may help too.

In your code:

radio.writeFast(&data, sizeof(data));

Typically want to get the return value of this and call radio.txStandBy() if getting failures.

Also should technically call txStandBy at some point to put the radio into standby mode, out of active TX.

This addressing is not the best, see http://maniacalbits.blogspot.com/2013/04/rf24-addressing-nrf24l01-radios-require.html

radio.openWritingPipe(0xF0F0F0F0E1LL);

I've seen people doing this a lot in code samples. No need to set the payload size, you're using dynamic payloads. radio.enableDynamicPayloads(); radio.setPayloadSize(32);

On Wed, Aug 26, 2020 at 11:36 PM rbp9802 notifications@github.com wrote:

Hi,

I'm trying to read aceleration data in real time send from an Arduino to a Rpi usin NRF24L01P (+) modules. I´m sending data at 200Hz (Serial printed) but receiving it only at 90 Hz. How can i improve the reading rate?

On the other hand, my goal is to communicate at 250KBPS data rate but i'm getting to much noise with this rate. the noise is acceptable only at 2MBPS. Why does this happen?

Thanks!!

i'll leave my codes here:

Arduino Transmitter Code:

include "Arduino.h"

include "Wire.h"

include

include

include

define I2Caddress 0x48

RF24 radio(7, 8); // CE, CSN

typedef struct{

int16_t AY; // Y Acceleration

int16_t AZ; // Z Acceleration

unsigned long t1; // time in microseconds

}

myData;

myData data;

unsigned long t2; // Reference time

void setup()

{

Serial.begin(115200);

RadioSetUp();

Wire.begin();

data.t1 = micros();

}

void loop()

{ t2 = micros();

if (t2 - data.t1 > 4990) { // Sample every 5ms (200Hz)

Read();

SerialPrint();

Send();

}

}

void Read(){

data.t1 = micros();

data.AY = yRead();

data.AZ = zRead();

}

void SerialPrint(){

Serial.print(data.AY);Serial.print("\t");

Serial.println(data.AZ);//Serial.println("\t");

}

void Send(){

radio.writeFast(&data, sizeof(data));

}

void RadioSetUp(){

radio.begin();

radio.setPALevel(RF24_PA_MAX);

radio.setChannel(0x76);

radio.openWritingPipe(0xF0F0F0F0E1LL);

radio.enableDynamicPayloads();

radio.setPayloadSize(32);

radio.setCRCLength(RF24_CRC_8);

radio.setDataRate(RF24_2MBPS);

radio.setAutoAck(1);

radio.setRetries(1, 3);

radio.powerUp();

}

RPi Python Script:

import RPi.GPIO as GPIO

from lib_nrf24 import NRF24

import os

import numpy as np

from numpy import asarray

from numpy import save

from numpy import load

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.setCRCLength(NRF24.CRC_8)

radio.setChannel(0x76)

radio.setDataRate(NRF24.BR_2MBPS)

radio.setPALevel(NRF24.PA_MAX)

radio.setAutoAck(True)

radio.enableDynamicPayloads()

radio.enableAckPayload()

radio.openWritingPipe(pipes[0])

radio.openReadingPipe(1, pipes[1])

radio.printDetails()

message = 1

radio.startListening()

a = np.array([0,0,0], dtype = 'int16')

try:

while True:

start = time.time()

while not radio.available(0):

time.sleep(1/10000.0)

if time.time() - start > 0.01:

print("Timed out")

break

    if radio.available() == True:

        r = [] #received in 8-bit list

        radio.read(r, 8) #tamaño del mensaje (N° de bytes)

        ##            AY            AZ            t

        b = np.array([r[0]+r[1]*256,r[2]+r[3]*256,r[4]+r[5]*256+r[6]*65536+r[7]*16777216])

        a = np.vstack([a,b])

        print("Recieved: {} at {}".format(b,time.ctime()))

    #time.sleep(5/1000.0)

finally:

radio.stopListening()

GPIO.cleanup()

a = np.delete(a,0,0)

save('data.npy', a)

x = np.load('/home/pi/Desktop/RF24/data.npy')

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nRF24/RF24/issues/619, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAT5KHFP3KLHUAXINK3DUQLSCXWFDANCNFSM4QMSQRXQ .

rbp9802 commented 3 years ago

thanks for your reply, i really apprecieate it!

I've been trying you suggestions without success. I try the "RF24 radio(7,8,8000000);" command and get a compiling Error on the arduino and an error on rpi.

On the other hand, i realise that my python3 runs very low on my Raspberry Pi 4 (2GB Ram). I have cofigurate to 512 MB CPU (max.) I run the following script and get 100 Hz prints.

import time

while True
    print(time.ctime())

How can i improve python3 speed?? I don't know C Language

Avamander commented 3 years ago

How can i improve python3 speed??

Use faster functions. time.ctime() is like 10x slower than time.time(). Alternatively use pypy or cython, but more often than not with small projects, the needed improvement comes from a better algorithm or architecture than switching the interpreter.

rbp9802 commented 3 years ago

Thanks Avamander. The problem was much simpler than i thought. I solved the speed problem. printing in the while loop is slow. instead i stack it on an array and print the array at the end of the process.

I'm still getting errors using "RF24 radio(7,8,8000000);" on the Arduino and Raspberry pi, and noise using 250KBPS. How can i solve this??

TMRh20 commented 3 years ago

The most current version of RF24 should have no problem with the new constructor, so probably you just need to update your libraries.

rbp9802 commented 3 years ago

Thanks again TMRh20, I have updated the libaries and still getting noise at 250KBPS rate. Also i need to run the arduino with external power supply (batteries or adapter) and when connected to the external power only sends the data when rate is 2MBPS and failed to send at 1MBPS and 250KBPS. I need to have PA_LEVEL at MAX.

rbp9802 commented 3 years ago

Update: I have just run using radio.setPALevel(RF24_PA_LOW); and run without problems at all 3 rates and minimal noise. This is not usefull to me because i need to cover us much range as possible. In summary: RF24_PA_MAX: failed to send at 250KBPS and 1MBPS rates with external power RF24_PA_MIN: run successfully at all rates RF24_PA_HIGH: send successfully, accelerometer data decrease from 31300 to 29700 (16bit values)

I'm using breadboard power supply module (link below) and 12V battery / Adapter https://www.amazon.com/HiLetgo-Supply-Module-Prototype-Breadboard/dp/B00HJ6AE72/ref=sr_1_1_sspa?dchild=1&keywords=breadboard+power+supply+module&qid=1599544524&sr=8-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFVWjNZTlRQSUhGVzImZW5jcnlwdGVkSWQ9QTA4NTMxMzQzRzNKOE5DQ0FCR0FFJmVuY3J5cHRlZEFkSWQ9QTA4NjU5MDEySzIxNFhDSkxFMlRTJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==

TMRh20 commented 3 years ago

Unfortunately this is looking like a hardware issue, so from a software perspective, not much we can help with.

It seems pretty likely the problem is power supply related or at least that is a part of it, since you can operate at low pa levels. Standard troubleshooting applies. Testing with a pure DC source like some 3v batteries should clear up some problems if that is the case etc..

rbp9802 commented 3 years ago

I have 5V output of the breadboard power supply coneccted to VIN pin in the arduino nano. i try using 5V pin in the arduino and run correctly with RF24_PA_HIGH, also i change 200Hz to 100Hz (which is not ideal for my porpose but usefull) reading rate of the accelerometer. Now i have the same issue i have with PA level high but with PA leve max, I assume its a lack of power. Now its time to program a mesh. Thank you very much for your support!

2bndy5 commented 3 years ago

Closing this as it seems like it's been solved