简单的 nRF24L01 2.4GHz 收发器演示
查看原文
参考教程: https://github.com/nRF24/
问题解答:
- nRF24L01 没有通信573
- NRF24L01 PA LNA 不工作(Arduino Nano 和 ELEGOO Mega2560 R3)215
- Nrf24l01 模块不工作145
- NRF24 的问题115
- 5-7m距离简单信号线71
- 其他 90 个
658 | nRF24L01 不 与 arduino通信 |
---|---|
216 | NRF24L01 PA LNA 不工作 (Arduino Nano & ELEGOO Mega2560 R3) arduino.cc |
145 | Nrf24l01 模块不工作 arduino.cc |
115 | NRF24 arduino.cc的问题 |
71 | 超过 5-7m 简单的距离信号线 arduino.cc |
62 | 连接两个 NRF24s arduino.cc |
54 | NRF24L01 接收器与 Arduino Nano arduino.cc的问题 |
26 | 无法让 NRF24L01 工作 - 硬件问题? arduino.cc |
24 | GitHub - nRF24/RF24: Arduino & Raspberry Pi/Linux 上 nRF24L01 的 OSI 第 2 层驱动程序… github.com |
18 | 使用 NRF24 arduino.cc网关或路由操作 |
15 | nRF24L01 PA LNA 连接问题 arduino.cc |
15 | 双向 nrf 通信 arduino.cc |
15 | NRF24L01 的射程 <50 英尺 arduino.cc |
13 | Nrf24l01 arduino 不起作用 arduino.cc |
13 | NRF24L01 COM 问题 arduino.cc |
11 | 双向 nrf 通信 arduino.cc |
9 | 帮助 - NRF24L01 _Multiple Transceivers / Pipes arduino.cc |
8 | 在 nRF24L01 arduino.cc中变值问题 |
7 | 解决 nrf24 和 nano arduino.cc的问题 |
5 | 使用 nrf24 无线电arduino.cc将 8 位 arduino 转换为 32 位 |
5 | Nrf24l01 收发器 arduino.cc |
4 | 基本 NRF24L01 草图 arduino.cc |
4 | RF24 发送/接收基础 arduino.cc |
3 | NRF24 未接收。需要帮助 arduino.cc |
3 | 10PCS/LOT NRF24L01 PA LNA905/C… aliexpress.com |
2 | NRF24 定制 PCB 不工作 arduino.cc |
2 | 不能使用天线 arduino.cc为 NRF24 供电 |
1 | 我不能让我的 NRf24 工作 arduino.cc |
1 | Arduino,nrf24l01,屏幕,RGB arduino.cc |
1 | 带有 nrf24l01 arduino.cc的 Arduino nano |
1 | nRF24L01,收音机工作正常,需要数据类型帮助 arduino.cc |
1 | NRF24 数据发送失败 arduino.cc |
1 | [NRF24L01] 试用和调试 Robin2 的 SimpleRX.ino 和 SimpleTX.ino arduino.cc |
1 | 另一个可以通过方便和远程控制 nrf24l01 arduino.cc 来控制nrf24l01 |
1 | 为 nRF24L01 arduino.cc代码中提供的问题 |
1 | NRF24L数据可以重复发送吗? arduino.cc |
1 | 用 NRF24L01 替换 USB/串行数据传输 - radio.read 问题 arduino.cc |
nRF24L01 2.4GHz 收发器模块既便宜又有效,但我遇到了一些人在使用它们时遇到问题的线程,所以我认为在一个地方集中基本的渐进序列可能很有用。
编辑 2021 年 2 月 3 日 - 安装本教程 RF24 库的 1.1.7 版(可通过 Arduino 获取库管理器)。回复#30中的更多信息。
2016 年 8 月 29 日编辑。我今天下载并成功测试了一切 3 对程序与 Arduino IDE 1.6.3 - SimpleTxAckPayload.ino 需要进行 2 次小修正
编辑2017年 9 月 6 日。修改示例 1 和 2 根据文本 Pipe 1 上监听
编辑 2017 年 3 月 18 每天添加回复#29,包括检查和检查简单程序 Arduino 的连接
本教程使用TMRh20 版本的 RF24 库,它修复了早期阶段 ManiacBug 版本中的一些问题。但不幸的是,TMRh20 不考虑给他的版本起不同的名字,所以很难确定哪个版本在你的版本 PC 上。如果您在阅读本文之前已经下载并安装了它 RF24 库,最简单的方法可能是删除它的所有痕迹,然后下载和安装它 TMrh20 版本。请注意,演示程序不适合 ManiacBug 版本的库。
我使用的 nRF24 模块如下所示。
引脚在最上面,天线在右侧,引脚连接是
因为 nRF24 使用 SPI 与 Arduino 通信,所以它们必须使用 Arduino 引脚 13、12 和 11(SCK、MISO 和 MOSI)。还需要连接 CSN 和 CE 引脚,任何 Arduino I/O 引脚都可以用于它们。然而,出于演示目的,使用引脚 10 和 9 似乎是最简单的,这样所有 5 个连接都在引脚 13 到 9 上相邻。我使用一些母-公跳线连接到 nRF24 以进行测试和开发。跳线是一根带状电缆,如果你用 5 根电线分开一根,并分配电线以适应 Arduino 引脚,则很容易将 nRF24 与 Arduino 连接和断开,而不会混淆连接。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqlEwINc-1657329003472)(https://aws1.discourse-cdn.com/arduino/original/4X/4/8/f/48ff0dc9c5cba648cf0bd7879e8bad7be9bfbe36.png)] 如果您将 10 和 9 以外的引脚用于 CSN 和 CE,您仍必须将引脚 10 设置为 OUTPUT 以确保 Uno 充当 SPI 主机。
nRF24 模块需要 3.3v 电源。小心不要将 VCC 引脚连接到 5v 电源。我发现当连接到我的 Unos 上的 3.3v 引脚时,它们可以令人满意地工作。
建议在 VCC 和 GND 上尽可能靠近模块放置一个 10µF 电容器,当我在面包板上制作一些带有 Atmega328 芯片的单元时,我发现这很重要。电容器稳定模块的电源。但是我还没有发现有必要在我的 Uno(或 Mega)上使用电容器。但是,如果您认为您已正确遵循所有其他说明并且遇到问题,那么安装电容器肯定是个好主意。
在某些情况下,在将新程序上传到 Arduino 后,nRF24 似乎不会重置。这可能会阻止程序正常工作。如果您认为是这种情况,请断开 Arduino 与 USB 电缆的连接并重新连接。
因为 nRF24 是收发器,它们显然可以发送和接收。为了避免混淆,我假设您使用其中一个(我将其称为 TX 或“主”)进行发送,而另一个(RX 或“从”)用于接收。
与许多其他设备(例如 WiFi 和蓝牙)一样,nRF24L01+ 模块在 2.4GHz 频段上广播。精确的频率由选择的频道决定。TX 和 RX 必须使用相同的通道。RF24 库的默认通道是 76。
当 TX 发送消息时,在同一通道上侦听的每个 RX 都会收到该消息。TX 在消息中包含一个“地址”,而 RX 将忽略没有其地址的消息。地址在概念上类似于电话号码,只是您不能轻易更改电话号码。地址是一个 5 字节的数字。
nRF24L01+ 模块可以监听 6 个“管道”中的任何一个或全部。不幸的是,在一些 RF24 演示程序中,用于保存地址的变量被命名为“管道”,即使管道和地址完全不同。出于本教程的目的,我将只使用一个管道(管道 1)进行收听。请注意,管道 0 是唯一的写入管道。可以在管道 0 上收听,但将其专门留作编写更简单。
6 个管道允许 nRF24 监听来自具有 6 个不同地址的 6 个其他设备的消息。但这些设备可能不会同时传输。
请注意,如果 2 个或更多 TX 在同一信道上同时传输,它们将相互干扰,并且无法接收到消息。这就是为什么 NRF24 不能同时在其 6 个管道上接收消息的原因。
如果(例如)附近的 Wifi 系统以完全相同的频率同时传输,消息也会出现乱码。
但是,每个单独的传输都非常短(几毫秒),因此来自您的 TX 的传输不太可能与其他东西重叠。
2016 年 10 月 14 日编辑 - 有人指出这是不准确的。我留下错误的文本,以便可能已经阅读过它的人了解更改 nRF24L01+ 模块以 32 字节数据包传输数据。如果您只想发送几个字节,RF24 库将自动用 \0 字符填充消息。如果您尝试发送超过 32 个字节,它将作为多个数据包传输。对于本教程,我不会发送超过 32 个字节。另外,我不打算介绍允许用户选择较小的数据包大小以减少传输时间的动态有效负载功能。 修订版 nRF24L01+ 模块在一条消息中最多可以传输 32 个字节。如果您需要发送更多信息,则需要将其分成多个单独的消息。对于本教程,我不会发送超过 32 个字节。
有两种操作模式 {A} 一个固定的有效负载大小,默认为 32 字节,可以通过 setPayloadSize() 进行更改,{B} 一个动态有效负载模式,通过 enableDynamicPayloads() 选择。当您选择 ackPayload 功能时,会自动应用动态负载模式(请参阅示例 2)。您可以使用 getDynamicPayloadSize() 检查有效负载大小。
使用动态有效负载时,您必须确保读取所有接收到的字节,否则通信将中断。
nRF24 自动包含复杂的系统,以识别接收到的数据是否与发送的数据匹配。如果数据没有正确接收,RX 将不会显示 data available() 并且不会发送确认。这意味着 TX 将认为传输失败。您将在示例程序中看到 TX 被自动指示在放弃之前重试最多 5 次。(最大值为 15)。
因此,在您的 RX 代码中,您可以假设如果数据可用()它将是正确的。
另请注意,与 Arduino 串行通信不同,当 RF24 库显示数据为 available() 时,这意味着已正确接收到整个消息。
在示例程序中,我尝试使用我在串行输入基础和规划和实施程序 中使用的相同风格。 通过将部分安排成小函数,应该很容易将它们合并到其他程序中。
在下一篇文章中继续
如果要求从设备将数据发送回主设备,则两个设备似乎有必要交换角色。除其他外,这意味着“主”将需要一个地址以及从属。时间的问题也需要考虑——例如,master应该持续多长时间监听slave的回复?而且,如果从机试图写而不是听,它可能会错过来自主机的传输。
可以完全避免交换角色的复杂性。这个想法是,slave 在收到来自 master 的消息之前将数据放入 ackPayload 缓冲区,然后 ackPayload 缓冲区中的数据作为正常确认过程的一部分自动发送,而无需您的代码使设备交换角色。
ackPayload 概念只能在从机到主机传输的数据量为 32 字节或更少时使用。
这也意味着从机发送的数据总是比从机接收的数据落后一步。例如,ackPayoad 不能考虑在消息中接收到的数据,它是对其进行确认。
在这个例子中,slave 将发送一对数字给 master。
// SimpleTxAckPayload - the master or the transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[10] = "Message 0";
char txNum = '0';
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
//===============
void setup() {
Serial.begin(9600);
Serial.println(F("Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino"));
Serial.println("SimpleTxAckPayload Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.enableAckPayload();
radio.setRetries(5,5); // delay, count
// 5 gives a 1500 µsec delay which is needed for a 32 byte ackPayload
radio.openWritingPipe(slaveAddress);
}
//=============
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
}
showData();
}
//================
void send() {
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
if ( radio.isAckPayloadAvailable() ) {
radio.read(&ackData, sizeof(ackData));
newData = true;
}
else {
Serial.println(" Acknowledge but no data ");
}
updateMessage();
}
else {
Serial.println(" Tx failed");
}
prevMillis = millis();
}
//=================
void showData() {
if (newData == true) {
Serial.print(" Acknowledge data ");
Serial.print(ackData[0]);
Serial.print(", ");
Serial.println(ackData[1]);
Serial.println();
newData = false;
}
}
//================
void updateMessage() {
// so you can see that new data is being sent
txNum += 1;
if (txNum > '9') {
txNum = '0';
}
dataToSend[8] = txNum;
}
// SimpleRxAckPayload- the slave or the receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
char dataReceived[10]; // this must match dataToSend in the TX
int ackData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;
//==============
void setup() {
Serial.begin(9600);
Serial.println("SimpleRxAckPayload Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.enableAckPayload();
radio.startListening();
radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
}
//==========
void loop() {
getData();
showData();
}
//============
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
updateReplyData();
newData = true;
}
}
//================
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.println(dataReceived);
Serial.print(" ackPayload sent ");
Serial.print(ackData[0]);
Serial.print(", ");
Serial.println(ackData[1]);
newData = false;
}
}
//================
void updateReplyData() {
ackData[0] -= 1;
ackData[1] -= 1;
if (ackData[0] < 100) {
ackData[0] = 109;
}
if (ackData[1] < -4009) {
ackData[1] = -4000;
}
radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}
编辑 2016 年 12 月 5 日以更正函数 updateReplyData() 中的错误管道引用。对任何混淆表示歉意。
2017 年 3 月 18 日编辑 - 请参阅回复#17,了解适用于多个从站的版本
编辑 2019 年 2 月 21 日以更改 RxAckPayload 中的 setup(),以便在 startListening() 之后上传有效负载
编辑 2020 年 1 月 20 日以增加 setRetries() 的延迟以允许更长的 ackPayload。Nordic nRF24L01+ 数据表第 7.4.2 节中的详细信息
在下一篇文章中继续
我还没有发现需要这种方法,但我会说明它以防它对其他人有用。
在这个例子中,两个 nRF24(主和从)大部分时间都在听,并且只在发送消息所需的最短时间切换到通话。与 ackPayload 示例一样,从站仅发送消息以响应来自主站的消息。
// MasterSwapRoles
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
const byte masterAddress[5] = {'T','X','a','a','a'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[10] = "Message 0";
char txNum = '0';
int dataReceived[2]; // to hold the data from the slave - must match replyData[] in the slave
bool newData = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
//============
void setup() {
Serial.begin(9600);
Serial.println("MasterSwapRoles Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openWritingPipe(slaveAddress);
radio.openReadingPipe(1, masterAddress);
radio.setRetries(3,5); // delay, count
send(); // to get things started
prevMillis = millis(); // set clock
}
//=============
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
prevMillis = millis();
}
getData();
showData();
}
//====================
void send() {
radio.stopListening();
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
radio.startListening();
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
Serial.println(" Acknowledge received");
updateMessage();
}
else {
Serial.println(" Tx failed");
}
}
//================
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
//================
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.print(dataReceived[0]);
Serial.print(", ");
Serial.println(dataReceived[1]);
Serial.println();
newData = false;
}
}
//================
void updateMessage() {
// so you can see that new data is being sent
txNum += 1;
if (txNum > '9') {
txNum = '0';
}
dataToSend[8] = txNum;
}
// SlaveSwapRoles
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
const byte masterAddress[5] = {'T','X','a','a','a'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataReceived[10]; // must match dataToSend in master
int replyData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
void setup() {
Serial.begin(9600);
Serial.println("SlaveSwapRoles Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openWritingPipe(masterAddress); // NB these are swapped compared to the master
radio.openReadingPipe(1, slaveAddress);
radio.setRetries(3,5); // delay, count
radio.startListening();
}
//====================
void loop() {
getData();
showData();
send();
}
//====================
void send() {
if (newData == true) {
radio.stopListening();
bool rslt;
rslt = radio.write( &replyData, sizeof(replyData) );
radio.startListening();
Serial.print("Reply Sent ");
Serial.print(replyData[0]);
Serial.print(", ");
Serial.println(replyData[1]);
if (rslt) {
Serial.println("Acknowledge Received");
updateReplyData();
}
else {
Serial.println("Tx failed");
}
Serial.println();
newData = false;
}
}
//================
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
//================
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.println(dataReceived);
}
}
//================
void updateReplyData() {
replyData[0] -= 1;
replyData[1] -= 1;
if (replyData[0] < 100) {
replyData[0] = 109;
}
if (replyData[1] < -4009) {
replyData[1] = -4000;
}
}
教程结束
…R
编辑 2019 年 9 月 2 日以删除对断开链接的引用
16 年 11 月post #10
你好,
我将电线插入 3.3 和 5V 入口。我没有注意到任何区别。 我重用了这个简单的例子。
这是代码:
// SimpleTx - the master or the transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[10] = "Message 0";
char txNum = '0';
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
void setup() {
Serial.begin(9600);
Serial.println("SimpleTx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.setRetries(3,5); // delay, count
radio.openWritingPipe(slaveAddress);
}
//====================
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
prevMillis = millis();
}
}
//====================
void send() {
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
Serial.println(" Acknowledge received");
updateMessage();
}
else {
Serial.println(" Tx failed");
}
}
//================
void updateMessage() {
// so you can see that new data is being sent
txNum += 1;
if (txNum > '9') {
txNum = '0';
}
dataToSend[8] = txNum;
}
和
// SimpleRx - the slave or the receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;
//===========
void setup() {
Serial.begin(9600);
Serial.println("SimpleRx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
}
//=============
void loop() {
getData();
showData();
}
//==============
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.println(dataReceived);
newData = false;
}
}
我得到: SimpleTx 开始
接收到的数据 接收到的 数据 接收到的 数据
显然,信息不是由发射器发送的。
我还设置了两个带有两个 Uno 的 nRF,并尝试让 simpleTx 和 simpleRx 单向通信工作;它不工作。
我正在使用这个库:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZhSoDXZ-1657329820175)(https://github.githubassets.com/favicons/favicon.svg)]GitHub
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPaF9uC6-1657329820176)(https://aws1.discourse-cdn.com/arduino/original/4X/8/9/4/894631eabe301b4a8c5375dbac076cb67d48c074.png)]
GitHub - nRF24/RF24: Arduino 上 nRF24L01 的 OSI 第 2 层驱动程序 &… 24
Arduino & Raspberry Pi/Linux 设备上 nRF24L01 的 OSI 第 2 层驱动程序 - GitHub - nRF24/RF24:Arduino 和 Raspberry Pi/Linux 设备上 nRF24L01 的 OSI 第 2 层驱动程序
我按照 Robin2 的说明,添加了 10uf 电容器以稳定电源,我的 nRF 模块看起来像他照片中的那些。
仍然没有运气;我从发件人那里得到这个:
SimpleTx 开始 数据发送消息 0 发送失败 数据发送消息 0 发送失败 数据发送消息 0 发送失败 数据发送消息 0 发送失败 …
这在接收器上:
SimpleRx 开始 收到 数据 消息 0 收到数据 消息 0 收到数据 消息 0 收到 数据 消息 0
其他方面没有错误。有没有人使用 Robin2 提供的 SimpleTx 和 SimpleRx 代码成功获得“简单单向传输”?
或者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aANlpn3M-1657329820176)(https://dub2.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/zmeu33/45/616310_2.png)]
21 年 5 月post #53
ifry111920×1032 27.1 KB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JgST2iwW-1657329820177)(https://aws1.discourse-cdn.com/arduino/optimized/4X/8/1/e/81e131f75e8a15649fc6824bd4a44318331e5c0e_2_690x369.png)]ifyr221920×1028 14.9 KB
21 年 5 月post #54
Interestingly, it did not get a timeout so the data may have just been coming too fast. Try these delays on the transmitter side just to check the logic. There should be a 5 second delay between sets of 3 messages. If that doesn’t give repeatable results there is then another problem. After that, you can start playing with the delays and timeouts to get it to run more quickly.
radio.write( &byteArray[ 0 ] , 32 );
delay( 100) ;
radio.write( &byteArray[ 32 ] , 32 );
delay( 100) ;
radio.write( &byteArray[ 64 ] , 32 );
delay( 5000) ;
1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HBDUwT7G-1657329820177)(https://dub2.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/zmeu33/45/616310_2.png)]
1
21 年 5 月post #55
是的,现在进展非常顺利。我尝试了几次停止它并启动它,但数据仍然按应有的方式出现。非常感谢您的帮助。我欠你。我将数据设置为出现在同一行中。明天我将尝试在 Processig 中介绍它们,看看会收到什么。非常感谢您的帮助,很抱歉打扰您并占用您的时间!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVuz5kWi-1657329820178)(https://aws1.discourse-cdn.com/arduino/optimized/4X/1/e/6/1e6b5138270881dc2770be9a10a4d562701feb8b_2_690x388.png)]8765111920×1080 116 KB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Az7t8HKO-1657329820178)(https://dub2.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/6v6gt/45/225488_2.png)]
1
21 年 5 月post #56
好的。我很高兴现在开始看起来不错。 对于测试和微调,请记住传输时间可能会受到接收质量差的影响,因为可能会尝试多次重试。接收器上的超时设置应小于发送 3 组消息之间的间隔,以便在传输失败的情况下进行干净的恢复。也许您可以在测试中模拟失败的传输。 您还可以通过打印出集合的总传输时间来检测接收器部分:(millis() - startTime) 以帮助确定超时的良好值。 您还可以调整结构中的填充。浮点数的总和(每个浮点数为 4 个字节),填充应为 96 个字节。非常重要的是它不能太小,否则数据可能会被覆盖。如果它太大,它只会浪费空间。
罗宾2
21 年 5 月post #57
谢谢,这真的很有帮助而且很清楚。我尝试过转换角色并取得了一些成功,但这要容易得多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hYbVvzpT-1657329820179)(https://avatars.discourse-cdn.com/v4/letter/c/da6949/45.png)]
21 年 5 月post #58
哦,谢谢你,这个例子是我唯一能做的事情…尝试了 3 个不同的库,RF24、NRFLite 和 Radiohead,但无法让他们的任何例子与独特的 CE、CSN 引脚一起工作(可能是我的经验不足,但是,嘿,每个人都是从菜鸟开始的,对吧?)。我正在运行两个 Megas;TX 有 11 个数字和 5 个模拟输入,RX 有 16 个数字和 6 个模拟 (PWM) 输出。
我也努力尝试从一个简单的 Hello World 到更复杂的东西,所以我从 Radiohead 的 DroneBotWorkshops 操纵杆示例开始,但我一生无法弄清楚如何更改 CE 引脚…幸运的是之后盯着足够多的代码,我能够将我的 I/O 应用到这个示例中,并且一切都很好。
我确信还有改进的余地,我仍然需要弄清楚心跳或其他东西,这样我就可以决定如果 TX 出于任何原因下降会发生什么…任何人都有任何指示我全神贯注,但是还想发布我的代码以防它帮助其他人
德克萨斯州:
// SimpleTx - the master or the transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 49
#define CSN_PIN 53
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 100;
// Define map output parameters
const int mapLo = 63; // calibrated to 25% PWM
const int mapMd = 127; // calibrated to 50% PWM
const int mapHi = 191; // calibrated to 75% PWM
// Declare unsigned 8-bit joystick array
// 6 Bytes for joystick proportional axiis
// 6 bytes for digital pins
uint8_t joystickArray[12];
// Define Joystick Connections
#define joy2EXT A0
#define joy3EXT A1
#define joyDIGR A2
#define joyWNCH A3
#define joyROTA A4
#define joyLIFT A5
// Define Joystick Values - Start at 512 (middle position)
int joypos2EXT = 512;
int joypos3EXT = 512;
int joyposDIGR = 512;
int joyposWNCH = 512;
int joyposROTA = 512;
int joyposLIFT = 512;
// Define Digital pin input
const int pinEstop = 22;
// const int pinValves = 23; // placeholder, pin 23 not used
const int pinHiIdle = 24;
const int pinDigWin = 25; // select between digger/winch
const int pinTiltUp = 27;
const int pinTiltDn = 26;
const int pinClawOp = 29;
const int pinClawCl = 28;
const int pinHiLo = 31;
const int pinDigRel = 30;
const int pinStart = 33;
const int pinKill = 32;
void setup() {
Serial.begin(9600);
Serial.println("SimpleTx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.setRetries(3,5); // delay, count
radio.openWritingPipe(slaveAddress);
pinMode(pinEstop, INPUT_PULLUP);
pinMode(pinHiIdle, INPUT_PULLUP);
pinMode(pinDigWin, INPUT_PULLUP);
pinMode(pinTiltUp, INPUT_PULLUP);
pinMode(pinTiltDn, INPUT_PULLUP);
pinMode(pinClawOp, INPUT_PULLUP);
pinMode(pinClawCl, INPUT_PULLUP);
pinMode(pinHiLo, INPUT_PULLUP);
pinMode(pinDigRel, INPUT_PULLUP);
pinMode(pinStart, INPUT_PULLUP);
pinMode(pinKill, INPUT_PULLUP);
digitalWrite(pinEstop, HIGH);
digitalWrite(pinHiIdle, HIGH);
digitalWrite(pinDigWin, HIGH);
digitalWrite(pinTiltUp, HIGH);
digitalWrite(pinTiltDn, HIGH);
digitalWrite(pinClawOp, HIGH);
digitalWrite(pinClawCl, HIGH);
digitalWrite(pinHiLo, HIGH);
digitalWrite(pinDigRel, HIGH);
digitalWrite(pinStart, HIGH);
digitalWrite(pinKill, HIGH);
}
//====================
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
prevMillis = millis();
}
}
//====================
void send() {
bool rslt;
rslt = radio.write( &joystickArray, sizeof(joystickArray) );
Serial.print("Data Sent ");
if (rslt) {
Serial.println(" Acknowledge received");
updateMessage();
}
else {
Serial.println(" Tx failed");
}
}
//================
void updateMessage() {
// Print to Serial Monitor
Serial.println("Reading joystick values ");
// Read the Joystick positions
joypos2EXT = analogRead(joy2EXT);
joypos3EXT = analogRead(joy3EXT);
joyposDIGR = analogRead(joyDIGR);
joyposWNCH = analogRead(joyWNCH);
joyposROTA = analogRead(joyROTA);
joyposLIFT = analogRead(joyLIFT);
joystickArray[0] = map(joypos2EXT, 0, 1023, mapLo, mapHi);
joystickArray[1] = map(joypos3EXT, 1023, 0, mapLo, mapHi);
joystickArray[4] = map(joyposROTA, 1023, 0, mapLo, mapHi);
joystickArray[5] = map(joyposLIFT, 1023, 0, mapLo, mapHi);
if (digitalRead(pinDigWin) == HIGH) {
joystickArray[2] = mapMd;
joystickArray[3] = map(joyposWNCH, 0, 1023, mapLo, mapHi);
}
else { // (digitalRead(pinDigWin) == LOW) // use winch joystick axis to control digger
joystickArray[2] = map(joyposWNCH, 0, 1023, mapLo, mapHi);
joystickArray[3] = mapMd;
}
if (digitalRead(pinEstop) == LOW) joystickArray[6]=0;
if (digitalRead(pinEstop) == HIGH) joystickArray[6]=1;
if (digitalRead(pinTiltUp) == LOW) joystickArray[7]=2;
else if (digitalRead(pinTiltDn) == LOW) joystickArray[7]=3;
else joystickArray[7]=4;
if (digitalRead(pinClawOp) == LOW) joystickArray[8]=2;
else if (digitalRead(pinClawCl) == LOW) joystickArray[8]=3;
else joystickArray[8]=4;
if (digitalRead(pinHiLo) == LOW) joystickArray[9]=2;
else if (digitalRead(pinDigRel) == LOW) joystickArray[9]=3;
else joystickArray[9]=4;
if (digitalRead(pinHiIdle) == LOW) joystickArray[10]=0;
if (digitalRead(pinHiIdle) == HIGH) joystickArray[10]=1;
if (digitalRead(pinStart) == LOW) joystickArray[11]=2;
else if (digitalRead(pinKill) == LOW) joystickArray[11]=3;
else joystickArray[11]=4;
/* sample code for custom map
// joystick customize lower/upper ranges and mid
if (joypos2EXT < 460)
{
joystickArray[0] = map(joypos2EXT, 0, 460, 63, 127);
}
else if (joypos2EXT > 564)
{
joystickArray[0] = map(joyposVert, 564, 1023, 128, 191;
}
else
{
// This is Stopped
joystickArray[0] = 127;
}
//repeat for other axiis and adjust as needed
*/
//Display the Joystick values in the serial monitor.
Serial.print("2nd Extension: ");
Serial.println(joystickArray[0]);
Serial.print("3rd Extension: ");
Serial.println(joystickArray[1]);
Serial.print("Digger: ");
Serial.println(joystickArray[2]);
Serial.print("Winch: ");
Serial.println(joystickArray[3]);
Serial.print("Rotation: ");
Serial.println(joystickArray[4]);
Serial.print("Lift: ");
Serial.println(joystickArray[5]);
}
接收:
// SimpleRx - the slave or the receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 49
#define CSN_PIN 53
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
uint8_t buf[12];
// char buf[12]; // this must match dataToSend in the TX
bool newData = false;
// Define Us signal output pins
#define Us2EXT 5
#define Us3EXT 6
#define UsDIGR 7
#define UsWNCH 8
#define UsROTA 9
#define UsLIFT 10
// set initial Us value on startup
int UsMapInit = 0;
// set output pins
const int pin2EXT = 22;
const int pin3EXT = 23;
const int pinDIGR = 24;
const int pinWNCH = 25;
const int pinROTA = 26;
const int pinLIFT = 27;
const int pinHiIdle = 28;
const int pinStart = 29;
const int pinTiltUp = 30;
const int pinTiltDn = 31;
const int pinClawOp = 32;
const int pinClawCl = 33;
const int pinDigHiLo = 34;
const int pinDigRel = 35;
const int pinEstop = 36;
const int pinKill = 37;
// const int pinHorn = 36;
//===========
void setup() {
Serial.begin(9600);
Serial.println("SimpleRx Starting");
// Set the controller pins to output
// Output PWM freq setup
pinMode(Us2EXT,OUTPUT);
pinMode(Us3EXT,OUTPUT);
pinMode(UsDIGR,OUTPUT);
pinMode(UsWNCH,OUTPUT);
pinMode(UsROTA,OUTPUT);
pinMode(UsLIFT,OUTPUT);
// Output relay variables
pinMode(pin2EXT,OUTPUT);
pinMode(pin3EXT,OUTPUT);
pinMode(pinDIGR,OUTPUT);
pinMode(pinWNCH,OUTPUT);
pinMode(pinROTA,OUTPUT);
pinMode(pinLIFT,OUTPUT);
pinMode(pinHiIdle,OUTPUT);
pinMode(pinStart,OUTPUT);
pinMode(pinTiltUp,OUTPUT);
pinMode(pinTiltDn,OUTPUT);
pinMode(pinClawOp,OUTPUT);
pinMode(pinClawCl,OUTPUT);
pinMode(pinDigHiLo,OUTPUT);
pinMode(pinDigRel,OUTPUT);
pinMode(pinEstop,OUTPUT);
pinMode(pinKill,OUTPUT);
// Output relays set off initial
digitalWrite(pin2EXT,HIGH);
digitalWrite(pin3EXT,HIGH);
digitalWrite(pinDIGR,HIGH);
digitalWrite(pinWNCH,HIGH);
digitalWrite(pinROTA,HIGH);
digitalWrite(pinLIFT,HIGH);
digitalWrite(pinHiIdle,HIGH);
digitalWrite(pinStart,HIGH);
digitalWrite(pinTiltUp,HIGH);
digitalWrite(pinTiltDn,HIGH);
digitalWrite(pinClawOp,HIGH);
digitalWrite(pinClawCl,HIGH);
digitalWrite(pinDigHiLo,HIGH);
digitalWrite(pinDigRel,HIGH);
digitalWrite(pinEstop,HIGH);
digitalWrite(pinKill,HIGH);
analogWrite(Us2EXT, UsMapInit);
analogWrite(Us3EXT, UsMapInit);
analogWrite(UsDIGR, UsMapInit);
analogWrite(UsWNCH, UsMapInit);
analogWrite(UsROTA, UsMapInit);
analogWrite(UsLIFT, UsMapInit);
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
}
//=============
void loop() {
getData();
showData();
}
//==============
void getData() {
if ( radio.available() ) {
radio.read( &buf, sizeof(buf) );
newData = true;
}
}
void showData() {
if (newData == true) {
Serial.println("Data received ");
Serial.println(buf[0]);
Serial.println(buf[1]);
Serial.println(buf[2]);
Serial.println(buf[3]);
Serial.println(buf[4]);
Serial.println(buf[5]);
Serial.println(buf[6]);
Serial.println(buf[7]);
Serial.println(buf[8]);
Serial.println(buf[9]);
Serial.println(buf[10]);
Serial.println(buf[11]);
// output PWM Us signals
analogWrite(Us2EXT, buf[0]);
analogWrite(Us3EXT, buf[1]);
analogWrite(UsDIGR, buf[2]);
analogWrite(UsWNCH, buf[3]);
analogWrite(UsROTA, buf[4]);
analogWrite(UsLIFT, buf[5]);
// output relay
// Low-level relay board initiates relays-ON at LOW
if (buf[6] == 0) { // Valves
digitalWrite(pinEstop, LOW);
digitalWrite(pin2EXT, LOW);
digitalWrite(pin3EXT, LOW);
digitalWrite(pinDIGR, LOW);
digitalWrite(pinWNCH, LOW);
digitalWrite(pinROTA, LOW);
digitalWrite(pinLIFT, LOW);
}
else { // (buf[6] == 1)
digitalWrite(pinEstop, HIGH);
digitalWrite(pin2EXT, HIGH);
digitalWrite(pin3EXT, HIGH);
digitalWrite(pinDIGR, HIGH);
digitalWrite(pinWNCH, HIGH);
digitalWrite(pinROTA, HIGH);
digitalWrite(pinLIFT, HIGH);
}
if (buf[7] == 2) {
digitalWrite(pinTiltUp, LOW);
digitalWrite(pinTiltDn, HIGH);
}
else if (buf[7] == 3) {
digitalWrite(pinTiltUp, HIGH);
digitalWrite(pinTiltDn, LOW);
}
else { // (buf[7] == 4) Both OFF
digitalWrite(pinTiltUp, HIGH);
digitalWrite(pinTiltDn, HIGH);
}
if (buf[8] == 2) {
digitalWrite(pinClawOp, LOW);
digitalWrite(pinClawCl, HIGH);
}
else if (buf[8] == 3) {
digitalWrite(pinClawOp, HIGH);
digitalWrite(pinClawCl, LOW);
}
else { // (buf[8] == 4) Both OFF
digitalWrite(pinClawOp, HIGH);
digitalWrite(pinClawCl, HIGH);
}
if (buf[9] == 2) {
digitalWrite(pinDigHiLo, LOW);
digitalWrite(pinDigRel, HIGH);
}
else if (buf[9] == 3) {
digitalWrite(pinDigHiLo, HIGH);
digitalWrite(pinDigRel, LOW);
}
else { // (buf[9] == 4) Both OFF
digitalWrite(pinDigHiLo, HIGH);
digitalWrite(pinDigRel, HIGH);
}
if (buf[10] == 0) { // HI IDLE
digitalWrite(pinHiIdle, LOW);
}
else { // (buf[10] == 1)
digitalWrite(pinHiIdle, HIGH);
}
if (buf[11] == 2) {
digitalWrite(pinStart, LOW);
digitalWrite(pinKill, HIGH);
}
else if (buf[11] == 3) {
digitalWrite(pinStart, HIGH);
digitalWrite(pinKill, LOW);
}
else { // (buf[11] == 4) Both OFF
digitalWrite(pinStart, HIGH);
digitalWrite(pinKill, HIGH);
}
newData = false;
}
}
26 天后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1pb3VWKz-1657329820179)(https://dub2.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/25/238766_2.png)]
21 年 6 月 22 日拆分了此话题
5 个帖子被拆分到一个新主题:手势控制机器人
13 天后
21 年 7 月 6 日拆分了此话题
一篇文章被拆分到一个新主题:连接两个 NRF24s
21 年 7 月post #61
使用 Robin2 的简单传输和接收代码,我通过收到的消息得到一个奇怪的输出(如图所示)。我有一个 Micro 作为传输和一个 MKR 1010 作为接收器。我已经获得了与 micro 和 Uno 一起使用的相同设置,但我为接收器尝试的任何 wifi 型号都不起作用。我还在两个 nRF 上连接了 10 个 microF 电容器,但仍然没有。任何帮助将非常感激。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTxR2jPV-1657329820180)(https://aws1.discourse-cdn.com/arduino/original/4X/a/9/8/a9885c18d1b06e369729f057909fbb6bd976e5b7.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eYeXZu5B-1657329820180)(https://avatars.discourse-cdn.com/v4/letter/m/919ad9/45.png)]
21 年 7 月post #62
我尝试了使用 ack 的第二个示例,它运行良好,因为它说“数据接收按摩 0”然后“数据接收按摩 1”等等。所以我认为它可以工作,但简单的 rx 和 tx 示例对我不起作用所以这是什么意思 ???? 我想制作手势控制的汽车,所以它不工作并且 nrf24 没有通信所以我应该添加什么到我的代码中以添加 ack,因为 nrf 与 ack 示例一起使用
1 个月后
罗宾2
21 年 8 月post #63
你好, 我试过这个测试,我得到:
20:18:01.573 -> CheckConnection Starting
20:18:01.573 ->
20:18:01.573 -> FIRST WITH THE DEFAULT ADDRESSES after power on
20:18:01.665 -> Note that RF24 does NOT reset when Arduino resets - only when power is removed
20:18:01.711 -> If the numbers are mostly 0x00 or 0xff it means that the Arduino is not
20:18:01.804 -> communicating with the nRF24
20:18:01.849 ->
20:18:01.849 -> STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
20:18:01.942 -> RX_ADDR_P0-1 = 0xe7e7e7e7e7 0x4141417852
20:18:01.942 -> RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
20:18:01.988 -> TX_ADDR = 0xe7e7e7e7e7
20:18:02.034 -> RX_PW_P0-6 = 0x00 0x20 0x00 0x00 0x00 0x00
20:18:02.080 -> EN_AA = 0x3f
20:18:02.080 -> EN_RXADDR = 0x02
20:18:02.126 -> RF_CH = 0x4c
20:18:02.126 -> RF_SETUP = 0x07
20:18:02.172 -> CONFIG = 0x0e
20:18:02.172 -> DYNPD/FEATURE = 0x00 0x00
20:18:02.172 -> Data Rate = 1MBPS
20:18:02.218 -> Model = nRF24L01+
20:18:02.218 -> CRC Length = 16 bits
20:18:02.264 -> PA Power = PA_MAX
20:18:02.310 ->
20:18:02.310 ->
20:18:02.310 -> AND NOW WITH ADDRESS AAAxR 0x41 41 41 78 52 ON P1
20:18:02.356 -> and 250KBPS data rate
20:18:02.356 ->
20:18:02.356 -> STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
20:18:02.403 -> RX_ADDR_P0-1 = 0xe7e7e7e7e7 0x4141417852
20:18:02.494 -> RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
20:18:02.540 -> TX_ADDR = 0xe7e7e7e7e7
20:18:02.540 -> RX_PW_P0-6 = 0x00 0x20 0x00 0x00 0x00 0x00
20:18:02.587 -> EN_AA = 0x3f
20:18:02.633 -> EN_RXADDR = 0x02
20:18:02.633 -> RF_CH = 0x4c
20:18:02.633 -> RF_SETUP = 0x27
20:18:02.633 -> CONFIG = 0x0e
20:18:02.679 -> DYNPD/FEATURE = 0x00 0x00
20:18:02.726 -> Data Rate = 250KBPS
20:18:02.726 -> Model = nRF24L01+
20:18:02.772 -> CRC Length = 16 bits
20:18:02.772 -> PA Power = PA_MAX
20:18:02.772 ->
20:18:02.772 ->
我认为这是正确的,因为它们都不是 0x00 或 0xFF。当我尝试发送任何类型的数据时,它只是无法将其发送到另一个 Arduino。我已经检查并重新检查了我所有的连接,但这种情况一直在发生。我还使用了将 5v 转换为 3.3v 的分线板,以获得更稳定的电压。我的错误可能是什么?我只有一对坏的 nrf24l01 吗? 请告诉我。
- 无法让 NRF24L01+ 工作 - 硬件问题?26
4 个月后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0723H0UV-1657329820185)(https://aws1.discourse-cdn.com/arduino/original/3X/1/f/1f6eb1c9b79d9518d1688c15fe9a4b7cdd5636ae.svg)]
21 年 12 月 18 日关闭
该主题在最后一次回复后 120 天自动关闭。不再允许新的回复。
您好!看起来您很喜欢讨论,但您还没有注册帐户。
当您创建帐户时,我们会准确记住您阅读过的内容,因此您总可以从上次停止的地方返回。每当有人回复您时,您还会在此处和通过电子邮件收到通知。您可以为帖子点赞来分享爱。💗
注册明天提醒我不,谢谢