nRF24L01管道问题


9

我正在浏览这里找到的示例代码。我知道nRF24L01模块可以使用6条管道,但是我一直在互联网上搜索地址名称,却一无所获。更具体地说,在第37行上,有关于作者在哪里获得0xF0F0F0F0E1LL,0xF0F0F0F0D2LL的参考吗?

谢谢。


1
您是否看过无线电IC的数据表?那当然有关于管道地址的更多信息。

1
openReadingPipe()此处检查RF24 API文档:maniacbug.github.io/RF24/…它提到您可以在最后一个地址字节中使用任何值。
jfpoilpret 2014年

因此,我浏览了文档,但没有提到如何选择管道地址。它只是说他们应该共享前32位。例如0xF0F0F0F0(XX),0x是否计为字节?还是F0F0F0F0是重要的32位?另外,只要管道共享这32位,是否不是F0F0F0F0也有关系吗?最后两个有效字节(XX)怎么样?这些也是任意的吗?
2014年

0x...前缀只是告诉值为十六进制。这是因为即使它们看起来相同,十进制的99与十六进制的99也有所不同。因此,我们改用0x99。
Gerben 2014年

2
您使用的代码仅支持1个管道。nRF24L01具有2个唯一的管道(0和1)。它还具有4个其他管道(2、3、4和5),您只能在其中设置最低有效字节。其他字节将与第二个管道(1)相同。
Gerben 2014年

Answers:


5

正如大多数人所发布的那样,管道的值是任意的,但必须遵循API的规则:

管道1-5应该共享前32位。只有最低有效字节应该是唯一的,例如

在回答您的问题之前,我认为需要对十六进制和十进制值进行解释。

40位十六进制表示以16为底的数字。十进制表示以10为底。因此,您可以将十六进制值转换为十进制。由于这超出了该问题的范围,您可以在Google上搜索如何从一种转换为另一种。有一些在线转换器:

十六进制到十进制转换器

将十六进制值转换为十进制时,您会看到它只是一个数字表示形式。转换时,将0x和放下LL。如前所述,0x指示值是十六进制值,LL表示类型Long Long

因此,要回答您的问题,请使用转换器来查找十六进制数字,例如:

F0F0F0F0A1
F0F0F0F0A2
F0F0F0F0B4
F0F0F0F0E9

只需更改最后两位数字(最低有效位)即可:

Pipes 1-5 should share the first 32 bits. Only the least significant byte should be unique, e.g.
   openReadingPipe(1,0xF0F0F0F0AA);
   openReadingPipe(2,0xF0F0F0F066);

添加0xLL

0xF0F0F0F0A1LL
0xF0F0F0F0A2LL
0xF0F0F0F0B4LL
0xF0F0F0F0E9LL

所有人都应该工作。

根据我的学习,我不是十六进制专家,所以如果我不正确,请有人纠正我。

最后,nRF24L01数据表指出以下几点,地址的选择并非完全任意:

注意:经常仅在噪声中检测到电平仅移动一次(即000FFFFFFF)的地址,并且可能提供错误的检测,这可能会提高包错误率。作为前同步码的继续(高低切换)的地址也提高了分组错误率。


您能否也请提一下,这些管道仅指“ 6个数据多接收器”功能(s。Nordic数据表p39-40)。默认情况下,仅启用数据管道0和1。

@bersch-有关系吗?OP正在询问如何选择管道值,例如where the author is getting 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL?,而不是如何使用管道。
PhillyNJ 2014年

为了选择值,您需要知道默认情况下有一个写入管道和一个读取管道。在多接收器模式下,有一个写入和多达5个读取管道。您仅描述了阅读管道。到目前为止,我还没有检查过,但是我相信,如果选择共享前32位的读写管道,它将失败。

根据我的测试,只要您的管道0和1在发送器和接收器上都相同,则值是任意的
PhillyNJ 2014年

我知道了。对于我自己,我没有检查多接收器功能。我使用每个芯片进行发送和接收。

2

这些值0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL是任意值,并且定义要与之交谈的发送者和接收者的地址。

如果您使用Mirf库

Mirf.setRADDR((byte *)"serv1");

它们也可以是字符串serv1

RF24 用途

write_register(RX_ADDR_P0, &value, 5);
write_register(TX_ADDR, &value, 5);

1

每个人都会忘记告诉您的一些事情:

第一个接收器后应缩短接收器处的管道

const uint64_t pipe01 = 0xE8E8F0F0A1LL;
const uint64_t pipe02 = 0xA2LL;  
const uint64_t pipe03 = 0xA3LL;
const uint64_t pipe04 = 0xA4LL;
const uint64_t pipe05 = 0xA5LL;
const uint64_t pipe06 = 0xA6LL;

radio.openReadingPipe(1, pipe01);  
radio.openReadingPipe(2, pipe02);
radio.openReadingPipe(3, pipe03);
radio.openReadingPipe(4, pipe04);
radio.openReadingPipe(5, pipe05);

变送器处的管道应

const uint64_t pipe01 = 0xE8E8F0F0A1LL;
const uint64_t pipe02 = 0xE8E8F0F0A2LL;  
const uint64_t pipe03 = 0xE8E8F0F0A3LL;
const uint64_t pipe04 = 0xE8E8F0F0A4LL;
const uint64_t pipe05 = 0xE8E8F0F0A5LL;
const uint64_t pipe06 = 0xE8E8F0F0A6LL;

uint64_t setPipeToSend = pipe01; // or pipe02 or pipe03 or pipe04 or pipe05
radio.openWritingPipe(setPipeToSend );

如果您想知道哪个管道的消息来了,请使用

  uint8_t someVariable;
    if (radio.available(&someVariable))
    {
       Serial.print("pipe number ");
       Serial.printLn(someVariable);
    }

同样,管道编号6也用于接收确认消息。

此外,初始化代码必须具有以下内容:radio.enableDynamicPayloads(); 这对我来说效果很好:

    radio.begin();
    //radio.setChannel(0x57); //if set should be the same at the both sides
    radio.setPALevel(RF24_PA_LOW);  // "LOW" is more stable mode
    radio.enableAckPayload(); //for autoanswers
    radio.openWritingPipe(pipe01); //for sending
    //link pipe numbers to the pipe addresses
    //radio.openReadingPipe(1, pipe01); // I use pipe01 for sending
    radio.openReadingPipe(2, pipe02);
    radio.openReadingPipe(3, pipe03);
    radio.openReadingPipe(4, pipe04);
    radio.openReadingPipe(5, pipe05);
    radio.enableDynamicPayloads(); //must have for multi pipe receiving
    radio.startListening();  //start listening

祝好运...


pipe在您的示例中定义了什么?
x29a

1
我已经编辑了代码。您可以使用这些“管道”中的任何一个进行发送,但不要忘记(像我一样)将其从读取中排除。
Faig
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.