使用NRF24L01进行故障排除Arduino/PI4通信

发布于 2025-01-18 10:56:42 字数 5582 浏览 2 评论 0原文

我有一个项目需要在没有 WiFi 的情况下进行短距离通信,因此我尝试使用一些 nRF24L01 收发器来实现这一点。

我使用 Arduino Uno 传输数据,使用 Raspberry Pi 4 接收数据,但到目前为止 Pi 还没有收到任何消息。目前我已经浏览了各种教程和包/库,但完全没有成功。

我是一位经验丰富的软件开发人员,但对 Arduino 方面的经验并不丰富。

配置如下:

Arduino:

nrf24arduino
Vin3V3
GNDGND
CEPin 9
CNSPin 10
MOSIPin 11
MISOPin 12
SCKPin 13
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "printf.h"

RF24 radio(9, 10);


void setup() {
  printf_begin();
  Serial.begin(9600);
  radio.begin();
  radio.setChannel(0x76);
  const uint64_t address = 0xfd7dfdfdfd;
  radio.setPALevel(RF24_PA_MIN);
  radio.setCRCLength(RF24_CRC_16);
  radio.enableDynamicPayloads();
  radio.enableAckPayload();
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(address);
  radio.stopListening();
  radio.printDetails();
}

void loop() {
  bool sendResult;

  if (radio.available()){
    Serial.println("Radio is available");
  } else {
    Serial.println("Radio is unavailable");
  }

  char text[32] = "Testeroni";
  sendResult = radio.write(&text, sizeof(text));

  if (sendResult) {
    Serial.println("Message sent");
  } else {
    Serial.println("Message not sent");
  }
  delay(1000);
}

Pi 4:

使用lib_nrf24包。

SPI 使能:

$ stat /dev/spidev0.0
  File: /dev/spidev0.0
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d   Inode: 420         Links: 1     Device type: 99,0
Access: (0660/crw-rw----)  Uid: (    0/    root)   Gid: (  999/     spi)
Access: 2022-04-02 16:16:46.749999997 -0500
Modify: 2022-04-02 16:16:46.749999997 -0500
Change: 2022-04-02 16:16:46.749999997 -0500
 Birth: -
nrf24pi/GPIO
VinPin 17 / 3V3
GNDPin 20 / GND
CEPin 22 / GPIO 25
CNSPin 24 / GPIO 8 / SPI0_CE0_N
MOSIPin 19 / GPIO 10 / SPI0_MOSI
MISOPin 21 / GPIO 9 / SPI0_MISO
SCKPin 23 / GPIO 11 / SPI0_CLK
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time
import spidev
from lib_nrf24 import NRF24


radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 7)
radio.setRetries(15, 15)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)
radio.setCRCLength(NRF24.CRC_8)
radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()
radio.openReadingPipe(0, [0xfd, 0x7d, 0xfd, 0xfd, 0xfd])
radio.startListening()
radio.stopListening()
radio.printDetails()
radio.startListening()

c = 1
while True:
    akpl_buf = [c,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8]

    while not radio.available([0]):
        time.sleep(10000/1000000.0)

    recv_buffer = []
    radio.read(recv_buffer, radio.getDynamicPayloadSize())
    if recv_buffer:
        print(f'Received: {recv_buffer}')

    c += 1
    if c&1 == 0:
        radio.writeAckPayload(1, akpl_buf, len(akpl_buf))

    time.sleep(1)

启动

我首先启动 Raspberry Pi 接收器:

$ sudo python library_listener.py
/home/pokeybill/lib_nrf24.py:377: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  self.GPIO.setup(self.ce_pin, self.GPIO.OUT)
STATUS   = 0x03 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=1 TX_FULL=1
RX_ADDR_P0-1     =
 0xffdfffffff 0xf87878f8f8
RX_ADDR_P2-5     =
0xf8
0xf9
0xf9
0xf9

TX_ADDR          =
 0xfdfdfdfdfd
RX_PW_P0-6       =
0x81
0x80
0x80
0x80
0x80
0xc0

EN_AA            =
0x8f

EN_RXADDR        =
0xc0

RF_CH            =
0x9f

RF_SETUP         =
0xff

CONFIG           =
0x98

DYNPD/FEATURE    =
0x83
0x81

Data Rate        = 1MBPS
Model            = nRF24L01
CRC Length       = 8 bits
PA Power         = PA_HIGH
Received: [128, 0, 0, 0, 0]

然后启动 Arduino Uno,这是串行输出:

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xfd7dfdfdfd 0x0104030201
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xfd7dfdfdfd
RX_PW_P0-6   = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x76
RF_SETUP     = 0x01
CONFIG       = 0x0a
DYNPD/FEATURE    = 0x3f 0x06
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 8 bits
PA Power     = PA_MIN
Radio is unavailable
Message not sent

我立即注意到警告:

RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  self.GPIO.setup(self.ce_pin, self.GPIO.OUT)

但是,似乎无论我做什么,我总是收到此警告。我尝试多次重新启动 pi 并显式调用 GPIO.cleanup() ,但没有任何乐趣。

另外,似乎无论我在 Raspberry Pi 代码中使用什么管道地址,它们都与我看到的接收器配置不匹配。

arduino radio.available() 调用永远不会返回 true,并且 radio.write 调用永远不会被确认。

Raspberry Pi 偶尔会收到随机噪音,但从未收到来自 arduino 的消息。当我在代码中明确将通道设置为 0x76 时,pi 似乎也有一个 RF_CH=0x1f 。对我来说,感觉好像我错过了 Pi 方面的一些东西,但我真的不知道足够理解我在这里错过了什么。

弄清楚这一点所需的信息可能在无线电详细信息输出中,但我只是不确定在哪里查看。我尝试过改变 CRC 长度、PA 功率和写/读管道地址 - 对这些值的调整没有产生任何差异。

I've got a project which requires short-range communication without WiFi available, so I'm trying to use some nRF24L01 transceivers to make this happen.

I'm using an Arduino Uno to transmit data, and a Raspberry Pi 4 to receive that data, but so far the Pi has not received a single message. I've been through a variety of tutorials and packages/libraries at this point with absolutely no success.

I'm a seasoned software developer, but not as experienced with the Arduino side of things.

Here is the configuration:

Arduino:

nrf24arduino
Vin3V3
GNDGND
CEPin 9
CNSPin 10
MOSIPin 11
MISOPin 12
SCKPin 13
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "printf.h"

RF24 radio(9, 10);


void setup() {
  printf_begin();
  Serial.begin(9600);
  radio.begin();
  radio.setChannel(0x76);
  const uint64_t address = 0xfd7dfdfdfd;
  radio.setPALevel(RF24_PA_MIN);
  radio.setCRCLength(RF24_CRC_16);
  radio.enableDynamicPayloads();
  radio.enableAckPayload();
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(address);
  radio.stopListening();
  radio.printDetails();
}

void loop() {
  bool sendResult;

  if (radio.available()){
    Serial.println("Radio is available");
  } else {
    Serial.println("Radio is unavailable");
  }

  char text[32] = "Testeroni";
  sendResult = radio.write(&text, sizeof(text));

  if (sendResult) {
    Serial.println("Message sent");
  } else {
    Serial.println("Message not sent");
  }
  delay(1000);
}

Pi 4:

Using the lib_nrf24 package.

SPI is enabled:

$ stat /dev/spidev0.0
  File: /dev/spidev0.0
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d   Inode: 420         Links: 1     Device type: 99,0
Access: (0660/crw-rw----)  Uid: (    0/    root)   Gid: (  999/     spi)
Access: 2022-04-02 16:16:46.749999997 -0500
Modify: 2022-04-02 16:16:46.749999997 -0500
Change: 2022-04-02 16:16:46.749999997 -0500
 Birth: -
nrf24pi/GPIO
VinPin 17 / 3V3
GNDPin 20 / GND
CEPin 22 / GPIO 25
CNSPin 24 / GPIO 8 / SPI0_CE0_N
MOSIPin 19 / GPIO 10 / SPI0_MOSI
MISOPin 21 / GPIO 9 / SPI0_MISO
SCKPin 23 / GPIO 11 / SPI0_CLK
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time
import spidev
from lib_nrf24 import NRF24


radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 7)
radio.setRetries(15, 15)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)
radio.setCRCLength(NRF24.CRC_8)
radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()
radio.openReadingPipe(0, [0xfd, 0x7d, 0xfd, 0xfd, 0xfd])
radio.startListening()
radio.stopListening()
radio.printDetails()
radio.startListening()

c = 1
while True:
    akpl_buf = [c,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8]

    while not radio.available([0]):
        time.sleep(10000/1000000.0)

    recv_buffer = []
    radio.read(recv_buffer, radio.getDynamicPayloadSize())
    if recv_buffer:
        print(f'Received: {recv_buffer}')

    c += 1
    if c&1 == 0:
        radio.writeAckPayload(1, akpl_buf, len(akpl_buf))

    time.sleep(1)

Startup

I begin by starting the Raspberry Pi Receiver:

$ sudo python library_listener.py
/home/pokeybill/lib_nrf24.py:377: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  self.GPIO.setup(self.ce_pin, self.GPIO.OUT)
STATUS   = 0x03 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=1 TX_FULL=1
RX_ADDR_P0-1     =
 0xffdfffffff 0xf87878f8f8
RX_ADDR_P2-5     =
0xf8
0xf9
0xf9
0xf9

TX_ADDR          =
 0xfdfdfdfdfd
RX_PW_P0-6       =
0x81
0x80
0x80
0x80
0x80
0xc0

EN_AA            =
0x8f

EN_RXADDR        =
0xc0

RF_CH            =
0x9f

RF_SETUP         =
0xff

CONFIG           =
0x98

DYNPD/FEATURE    =
0x83
0x81

Data Rate        = 1MBPS
Model            = nRF24L01
CRC Length       = 8 bits
PA Power         = PA_HIGH
Received: [128, 0, 0, 0, 0]

Then I fire up the Arduino Uno, here is the serial output:

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xfd7dfdfdfd 0x0104030201
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xfd7dfdfdfd
RX_PW_P0-6   = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x76
RF_SETUP     = 0x01
CONFIG       = 0x0a
DYNPD/FEATURE    = 0x3f 0x06
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 8 bits
PA Power     = PA_MIN
Radio is unavailable
Message not sent

Immediately I notice the warning:

RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  self.GPIO.setup(self.ce_pin, self.GPIO.OUT)

however, it seems like no matter what I do, I always get this warning. I've tried rebooting the pi multiple times and explicitly calling GPIO.cleanup() without any joy.

Also, it seems like no matter what I use for the pipe addresses in the Raspberry Pi code, they do not match up with the receiver configuration I see.

The arduino radio.available() call never returns true, and the radio.write call is never acknowledged.

The pi occasionally receives random noise, but never receives a message from the arduino. The pi also seems to have an RF_CH=0x1f when I explicitly set the channel to 0x76 in the code. To me it feels like I'm missing something with the Pi side of things, but I really don't know enough to understand what I'm missing here.

Its possible the information required to get to the bottom of this is in the radio detail output, but I'm just not sure where to look. I've tried varying CRC length, PA power, and the write/read pipe address - no adjustments to these values have made any difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

上课铃就是安魂曲 2025-01-25 10:56:42

关于日志开头警告的问题,您可以按照以下步骤操作: http://raspi.tv/2013/rpi-gpio-basics-3-how-to-exit-gpio-programs-cleanly-avoid-warnings-and-protect-your-pi 并实施try:、exception: 和finally: 结构。它帮助我摆脱了这个警告。

但是,我担心我的 arduino - 树莓派与 NRF24L01 的链接存在同样的问题。事实上,我没有实现使用相同的库让它工作。我使用 printDetails 方法返回的配置与我之前配置的不对应。

Regarding to your problem with the warning at the beginning of the logs, you can follow this: http://raspi.tv/2013/rpi-gpio-basics-3-how-to-exit-gpio-programs-cleanly-avoid-warnings-and-protect-your-pi and implement the try:, exception: and finally: structures. It helped me getting rid of this warning.

However, I am concerned with the same issue with my arduino - raspberry link with NRF24L01. Indeed, I did not achieve to get it worked using the same library. The configuration that i get back with the printDetails method does not correspond to what I configured previously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文