即时通讯工具、arduino 和 NRF24L01

instant messenger, arduino and NRF24L01

我正在尝试使用 arduino、NRF24L01 芯片和 TMRH20 的库 RF24 创建一个即时通讯工具。 它专为 2 个 arduino 板设计。

这是我的 Messenger 的问题:大多数时候,接收者没有收到消息,有时他收到了消息,但一切都搞混了,比如错误的编码错误...

代码如下: http://pastebin.com/TP53VyeH

要尝试它,您需要 2 个 arduino 板,插入 2 个不同的 USB 端口。对于其中一个板,您必须更改第 10 行的数字。

ps:在我的工作站上,如果我尝试 "GettingStarted_HandlingData",一切正常,所以问题不是我的 arduinos...

您正在将数据直接抓取到 String 对象中,而不是它的缓冲区中。

radio.read( &message, sizeof(message) ); 

这很糟糕,因为不仅字符串 class 大约有 6 个字节长,而且您还覆盖了存储指向其缓冲区的指针的字节。因此,当您读取 String 时,它的指针现在位于某个任意位置。您将读取那里的任何内容,这可能是其他变量、寄存器,甚至 GPIO 引脚。 (此时您的应用程序可能非常损坏)。

您需要使用字符缓冲区。

编辑:

it seems that the message get cut after 32 character, and not 50... No idea why. I tried replacing 50 with 200, and the message still get cut after 32 character.

您应该使用radio.getPayloadSize()来确保您的数据能够接收到尽可能大的数据包。此外,如果您需要发送大量数据,或者想要发送较小的数据包,您可以使用 radio.setPayloadSize()。但是,最大 32 字节。

radio.startListening();
char buffer[ radio.getPayloadSize() ];  //Note: an array like this is a GCC extension, not standard C++

if(radio.available()) {       
  radio.read( &buffer, radio.getPayloadSize() ); 
}

message = buffer; //Not really needed, you can just use the buffer.

使用循环似乎不对,radio.available() 是如果接收到整个数据包。在这里循环只会丢弃除最后一个数据包以外的所有数据包。你也许应该循环整个接收端(在 radio.startListening(); 之后),这样你就可以 print/process 每个数据包进来。


您不能真正使用 String 对象,因为它不识别新数据(如果直接使用其内部缓冲区,其长度将不会更新)。我现在 a patch I'm trying to get merged 进入核心,这将允许这样的事情:

message.buffer( radio.getPayloadSize() );
radio.read( message.c_str(), radio.getPayloadSize() );
message.validate(); //Allow String to detect new contents (Not in the core yet).

不过,我会 post 这个问题作为另一个很好补充的原因。

我终于让它工作了。我在传输过程中使用了char而不是String,这解决了所有问题。

这意味着设置最大消息长度限制(我设置了50个字符,这绰绰有余)。

这是工作代码: http://pastebin.com/5Ryjr8sD

(ps :对于串行通信,输出仍然是一个字符串,所以我使用以下方法将其转换为字符:message.toCharArray(messagechar,50);

编辑:消息似乎在 32 个字符后被截断,而不是 50 个...不知道为什么。我尝试用 200 替换 50,但消息在 32 个字符后仍然被截断

edit2: 这是最后的代码,防止用户写超过 32 个字符。 http://pastebin.com/TVgu16zx