【问题标题】:instant messenger, arduino and NRF24L01即时通讯工具,arduino 和 NRF24L01
【发布时间】:2016-04-14 13:40:16
【问题描述】:

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

这是我的信使的问题:大多数时候,接收者没有收到消息,有时他收到了,但一切都搞混了,就像一个糟糕的编码错误......

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

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

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

【问题讨论】:

    标签: arduino wireless


    【解决方案1】:

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

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

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

    您需要使用字符缓冲区。

    编辑:

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

    您应该使用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(); 之后),这样您就可以在每个数据包进入时打印/处理它们。


    你不能真正使用 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).
    

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

    【讨论】:

    • 感谢您的建议,我已经尝试了您的解决方案,但接收者会收到空消息。我终于让它使用 char 而不是 String。 (见我的另一条消息)。我希望你的补丁被合并;)
    • @n0tis,更新或添加编辑到您的帖子末尾。你很可能做错了什么。正如我所提到的,您的原始代码根本不起作用!
    • @n0tis 我发布的数组是本地的,不是静态大小的,如果你这样做了,你不能在它上面使用 sizeof。我改用radio.getPayloadSize()
    【解决方案2】:

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

    这意味着设置了最大消息长度限制(我设置了 50 个字符,这已经足够了)。

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

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

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

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

    【讨论】:

    • 我添加了一个编辑来解决您的下一个问题。如果使用 char 数组,并且其他信息对您有所帮助,或者将帮助您解决问题,您是否可以考虑接受答案。干杯
    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多