nRF24L01+与Arduino Nano通信异常:代码调试求助
nRF24L01收发代码适配性验证
已确认两块nRF24L01模块及两块Arduino Nano均正常工作,且使用简单测试代码可实现通信。目前尝试所有可行方案仍无法解决问题,恳请帮忙验证以下收发代码是否适配nRF24L01模块。
接收代码
#include "SPI.h" #include "RF24.h" #include "nRF24L01.h" #define CE_PIN 9 #define CSN_PIN 10 #define INTERVAL_MS_SIGNAL_LOST 1000 #define INTERVAL_MS_SIGNAL_RETRY 250 RF24 radio(CE_PIN, CSN_PIN); const byte address[6] = "00001"; //NRF24L01 buffer limit is 32 bytes (max struct size) struct payload { byte data1; char data2; //byte pot_value; }; payload payload; unsigned long lastSignalMillis = 0; void setup() { Serial.begin(115200); radio.begin(); //Append ACK packet from the receiving radio back to the transmitting radio radio.setAutoAck(false); //(true|false) //Set the transmission datarate radio.setDataRate(RF24_250KBPS); //(RF24_250KBPS|RF24_1MBPS|RF24_2MBPS) radio.setPALevel(RF24_PA_HIGH); //(RF24_PA_MIN|RF24_PA_LOW|RF24_PA_HIGH|RF24_PA_MAX) //Default value is the maximum 32 bytes radio.setPayloadSize(sizeof(payload)); radio.openReadingPipe(0, address); radio.startListening(); } void loop() { unsigned long currentMillis = millis(); if (radio.available()) { radio.read(&payload, sizeof(payload)); Serial.println("Received"); Serial.print("Data1:"); Serial.println(payload.data1); Serial.print("Data2:"); Serial.println(payload.data2); //Serial.print("Data3:"); //Serial.println(payload.pot_value); lastSignalMillis = currentMillis; } if (currentMillis - lastSignalMillis > INTERVAL_MS_SIGNAL_LOST) { lostConnection(); } delay(INTERVAL_MS_SIGNAL_RETRY); } void lostConnection() { Serial.println("We have lost connection, preventing unwanted behavior"); }
发送代码
#include "SPI.h" #include "RF24.h" //#include <printf.h>-- #define CE_PIN 9 #define CSN_PIN 10 //#define POT_PIN #define INTERVAL_MS_TRANSMISSION 250 RF24 radio(CE_PIN, CSN_PIN); const byte address[6] = "00001"; //NRF24L01 buffer limit is 32 bytes (max struct size) struct payload { byte data1; char data2; //byte pot_value; }; payload payload; void setup() { Serial.begin(115200); if (radio.isChipConnected()) { radio.begin(); Serial.println("nRF24L01 Intialiazed!"); //Append ACK packet from the receiving radio back to the transmitting radio radio.setAutoAck(false); //(true|false) //Set the transmission datarate radio.setDataRate(RF24_250KBPS); //(RF24_250KBPS|RF24_1MBPS|RF24_2MBPS) radio.setPALevel(RF24_PA_HIGH); //(RF24_PA_MIN|RF24_PA_LOW|RF24_PA_HIGH|RF24_PA_MAX) //Default value is the maximum 32 bytes radio.setPayloadSize(sizeof(payload)); radio.openWritingPipe(address); radio.stopListening(); }else{ Serial.println("No connection between nRF24L01 and Arduino! "); } } void loop() { payload.data1 = 123; payload.data2 = 'x'; //payload.pot_value = analogRead(POT_PIN); if(radio.write(&payload, sizeof(payload))) { Serial.print("Data1:"); Serial.println(payload.data1); Serial.print("Data2:"); Serial.println(payload.data2); //Serial.print("Data3:"); //Serial.println(payload.pot_value); Serial.println("Sent"); }else { Serial.println("Error! Payload not sent"); } delay(INTERVAL_MS_TRANSMISSION); }
代码适配性分析及问题点
这套代码基于RF24库开发,整体框架适配nRF24L01模块,但存在几个可能导致通信失败的细节问题:
地址长度不匹配:
nRF24L01默认地址宽度为5字节,但代码中定义了6字节的地址数组const byte address[6] = "00001"(字符串包含5个字符加终止符\0,共6字节)。收发双方未通过radio.setAddressWidth(6)明确设置地址宽度,模块会默认按5字节解析地址,导致实际通信时地址不匹配。自动ACK关闭的影响:
代码中双方都关闭了自动ACK(radio.setAutoAck(false)),取消了nRF24L01的重传机制,信号环境不佳时极易丢包。同时,RF24库的write()方法在关闭ACK时,仅返回“是否完成发送动作”,而非“是否被接收方成功接收”,代码中基于该返回值判断发送成功的逻辑会失去准确性。发送方初始化逻辑瑕疵:
发送方中radio.isChipConnected()的调用顺序有误,正确流程应先调用radio.begin()初始化模块,再检测芯片连接状态。当前先检测再初始化的逻辑,会导致isChipConnected()的结果不准确。
修复建议
- 将地址改为5字节,或在收发双方的
setup()中添加radio.setAddressWidth(6),确保地址宽度一致; - 开启自动ACK(将
radio.setAutoAck(false)改为radio.setAutoAck(true)),利用模块自带的重传机制提升通信可靠性; - 调整发送方初始化顺序:先调用
radio.begin(),再执行radio.isChipConnected()检测。
内容的提问来源于stack exchange,提问作者HSRibeiro
相关产品推荐
相关产品推荐

