433 Transmit Receive

Has anyone had any success with 433 communication using Radiohead headers? I had some success transmitting integers but after a minute or two it would eventually print garbage to my lcd display, which leads me to think there is a memory addressing problem. All the examples I've seen use strings... usually "hello world". When I try to copy one of these very simple examples, they simply don't work.
I think this code was copied from the Radiohead Examples web page, as the receive code shows an an attempt to declare "int i;" which raises an error in Arduino IDE.

Transmit code****************

[code]
#include <RadioHead.h>
#include <radio_config_Si4460.h>
#include <RHCRC.h>
#include <RHDatagram.h>
#include <RHGenericDriver.h>
#include <RHGenericSPI.h>
#include <RHHardwareSPI.h>
#include <RHMesh.h>
#include <RHNRFSPIDriver.h>
#include <RHReliableDatagram.h>
#include <RHRouter.h>
#include <RHSoftwareSPI.h>
#include <RHSPIDriver.h>
#include <RHTcpProtocol.h>
#include <RH_ASK.h>
#include <RH_NRF24.h>
#include <RH_NRF905.h>
#include <RH_RF22.h>
#include <RH_RF24.h>
#include <RH_RF69.h>
#include <RH_RF95.h>
#include <RH_Serial.h>
#include <RH_TCP.h>

#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

void setup()
{
    Serial.begin(9600);    // Debugging only
    if (!driver.init())
         Serial.println("init failed");
}

void loop()
{
    const char *msg = "Hello World!";
    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(1000);
}

[/code]

Receive code*****************************

[code]
#include <RadioHead.h>
#include <radio_config_Si4460.h>
#include <RHCRC.h>
#include <RHDatagram.h>
#include <RHGenericDriver.h>
#include <RHGenericSPI.h>
#include <RHHardwareSPI.h>
#include <RHMesh.h>
#include <RHNRFSPIDriver.h>
#include <RHReliableDatagram.h>
#include <RHRouter.h>
#include <RHSoftwareSPI.h>
#include <RHSPIDriver.h>
#include <RHTcpProtocol.h>
#include <RH_ASK.h>
#include <RH_NRF24.h>
#include <RH_NRF905.h>
#include <RH_RF22.h>
#include <RH_RF24.h>
#include <RH_RF69.h>
#include <RH_RF95.h>
#include <RH_Serial.h>
#include <RH_TCP.h>

#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

void setup()
{
    Serial.begin(9600);  // Debugging only
    if (!driver.init())
         Serial.println("init failed");
}

void loop()
{
    uint8_t buf[12];
    uint8_t buflen = sizeof(buf);
    if (driver.recv(buf, &buflen)) // Non-blocking
    {
      //int i;
      // Message with a good checksum received, dump it.
      Serial.print("Message: ");
      Serial.println((char*)buf);         
    }
}

[/code]

This guy...

Thanks. This video proves that the software works, when implemented properly. I copied it exactly and finally got it to work. There is one difference, however. When I receive "Welcome to the Workshop!" there is an extra character at the end of the string. I prepared the buffer for 24 characters as in the video, but I get 25 when I check the length of the received string. Any ideas why this happens to me and not in the video?

Null terminator = "\0" denoting "EOT" >> pipe to bit bucket (ignore) I am incorrect.

The transmit code does not send the terminating zero of the C-string:

    driver.send((uint8_t *)msg, strlen(msg));

The receive code assumes that the terminating zero is there, so you can expect random failures, depending on whatever is in memory following the receive buffer.

    if (driver.recv(buf, &buflen)) // Non-blocking
    {
      //int i;
      // Message with a good checksum received, dump it.
      Serial.print("Message: ");
      Serial.println((char*)buf);  

To fix that, either send the terminating zero, or add one upon receive.

By "terminating 0" you mean a NULL character, right? Or I could add an extra character space to the buffer to accommodate an extra character? I'm thinking that this extra character is being written out of bounds and causing havoc in memory. Adding extra space in buffer should fix it, right?

C-strings, AKA "zero terminated character arrays" are required to end with a byte containing binary zero.

Serial.print() expects that zero byte to be present in a C-string, and there are many valid ways of ensuring that it is.

OK. How can I get it transmit a terminating zero?

Add one.

driver.send((uint8_t *)msg, strlen(msg)+1);

That's exactly what I just tried to do and it worked! Oddly, on the receive side, for a transmission of "Welcome to the Workshop!", if I set the buffer size to 24, I get a string length of 25. But if I set the buffer size to 25, I get a string length of 24. I'll leave it at 25.

"Welcome to the Workshop!" has 24 ASCII characters, thus the buffer, or zero-terminated C-string must be declared as 25 bytes or longer.

Yes, of course. There is also the possibility of using the max buffer length option (I don't remember the name) if you don't mind wasting a bit of memory, or your not sure of the length.

Do you now understand why this did not work as expected?

Actually, no I don't. I know I added +1 to allow for NULL. That would make 25. I may receive 25 characters, however, when I check for string length, the NULL should not be counted, and I should see 24.

But I think if I set the buffer to 24 and I get 25 characters, the 25th character (NULL) infringes on an area outside of it's bounds. If checking the length it will still see the NULL character marking the end of the string, but I don't know why it would count 25 characters.

Exactly. An out of bounds write to memory has unpredictable consequences, including loss of data and program crashes, on any computer. Pay close attention to array sizes, allowed read/write buffer lengths, etc.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.