433Mhz modules, RadioHead problems, problem with library?

Hello

I wanted to make a project using some 433MHz recievers and transmittors. But i have ran into some problems i cant solve, and i need some help with.

The context and me testing my modules:

Everywhere i look they say i should use teh RadioHead library.

I downloaded it for here:
http://www.airspayce.com/mikem/arduino/RadioHead/

I wired both of my breadboards with sender and reciever. I used some battery's in serie to get 9V battery's. I made 5V using a lm7805. The 9V was supplied to my arduino's and the 5V was used to supply my modules. All grounds are connected. I placed some 22µF (25V) capacitors over the voltage supply of my senders and recievers because it realy increased my range. Also i added some antenna's.

I went ahead and tried the examples named:

  • ask_reciever
  • ask_transmitter

I made arduino 1 sender and arduino 2 reciever, that worked. I then switched the programs so arduino 1 was reciever and arduino 2 was sender. That worked also.

So at this point i know i hooked up my arduino's correctly. And my modules work correctly.

The problem:

When trying out the examples named:

  • ask_reliable_datagram_client
  • ask_reliable_datagram_server

I noticed it didnt work correctly. I went ahead and put some Serial.println ("") in my code and the library to detect what was going wrong. This is what i think is going on: the ack gets send but isnt picked up. I do not know why.

The question:

Could someone try this out for themselves and let me kow if they have the same problem? And if you have the same problem, do you know what goes wrong?
I really think something is wrong with the library

My code:

This is my client code:

// ask_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RHReliableDatagram class, using the RH_ASK driver to control a ASK radio.
// It is designed to work with the other example ask_reliable_datagram_server
// Tested on Arduino Mega, Duemilanova, Uno, Due, Teensy, ESP-12

#include <RHReliableDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2


RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

void setup() 
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];

void loop()
{
  Serial.println("Sending to ask_reliable_datagram_server");
    
  // Send a message to manager_server
  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is ask_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

This is the original client code:

// ask_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RHReliableDatagram class, using the RH_ASK driver to control a ASK radio.
// It is designed to work with the other example ask_reliable_datagram_server
// Tested on Arduino Mega, Duemilanova, Uno, Due, Teensy, ESP-12

#include <RHReliableDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_ASK driver;
// RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

void setup() 
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];

void loop()
{
  Serial.println("Sending to ask_reliable_datagram_server");
    
  // Send a message to manager_server
  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is ask_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

As you can see i only deleted 2 lines of code and uncommented 1 line. This is the code im talking about:

// Singleton instance of the radio driver
RH_ASK driver;
// RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

This is my server code:

// ask_reliable_datagram_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging server
// with the RHReliableDatagram class, using the RH_ASK driver to control a ASK radio.
// It is designed to work with the other example ask_reliable_datagram_client
// Tested on Arduino Mega, Duemilanova, Uno, Due, Teensy, ESP-12

#include <RHReliableDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

void setup() 
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
}

uint8_t data[] = "And hello back to you";
// Dont put this on the stack:
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];

void loop()
{
  if (manager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAck(buf, &len, &from))
    {
      Serial.print("got request from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);

      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");
    }
  }
}

This is the original server code:

// ask_reliable_datagram_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging server
// with the RHReliableDatagram class, using the RH_ASK driver to control a ASK radio.
// It is designed to work with the other example ask_reliable_datagram_client
// Tested on Arduino Mega, Duemilanova, Uno, Due, Teensy, ESP-12

#include <RHReliableDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_ASK driver;
// RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

void setup() 
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
}

uint8_t data[] = "And hello back to you";
// Dont put this on the stack:
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];

void loop()
{
  if (manager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAck(buf, &len, &from))
    {
      Serial.print("got request from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);

      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");
    }
  }
}

Again, i only deleted 2 lines of code and uncommented 1 line. This is the code im talking about:

// Singleton instance of the radio driver
RH_ASK driver;
// RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2

I hope everything is well explained.
Thanks in advance for helping.

How long does it wait to send the ACK? The AGC of the receiver on the one that initially sends data would get cranked way down, since it's right next to a transmitter that was just transmitting. The behavior here varies depending on the receiver module(also, those crappy green receivers - which are really terrible, the range is awful compared to others such as RXB12, which is like $1/ea on ebay and gets >10x the range and works on 3.3v - I have seen the green ones get into a bad state when used at very short range where the sensitivity gets cranked all the way down and stays there)

Can you make it wait longer to send the ack? Or repeat the ack more times?

What about if you move transmitter and receiver modules for each arduino further apart from eachother?

That's what I suspect at least. Though it could also be something silly like having the transmitter on a different pin than your code thinks it is or something. Does RH library manage pinMode on the transmitter pin for you? I assume it must, since I see no indication of it being set anywhere.

I dont know how long exactly but when i vieuw the code that handles the recieving of data end sending of the ACK i think its richt after the message is recieved. This is that part of the code:

bool RHReliableDatagram::recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* from, uint8_t* to, uint8_t* id, uint8_t* flags)
{  
    uint8_t _from;
    uint8_t _to;
    uint8_t _id;
    uint8_t _flags;
    // Get the message before its clobbered by the ACK (shared rx and tx buffer in some drivers
    if (available() && recvfrom(buf, len, &_from, &_to, &_id, &_flags))
    {
	// Never ACK an ACK
	if (!(_flags & RH_FLAGS_ACK))
	{
	    // Its a normal message not an ACK
	    if (_to ==_thisAddress)
	    {
	        // Its for this node and
		// Its not a broadcast, so ACK it
		// Acknowledge message with ACK set in flags and ID set to received ID
		acknowledge(_id, _from);
	    }
            // Filter out retried messages that we have seen before. This explicitly
            // only filters out messages that are marked as retries to protect against
            // the scenario where a transmitting device sends just one message and
            // shuts down between transmissions. Devices that do this will report the
            // the same ID each time since their internal sequence number will reset
            // to zero each time the device starts up.
	    if ((RH_ENABLE_EXPLICIT_RETRY_DEDUP && !(_flags & RH_FLAGS_RETRY)) || _id != _seenIds[_from])
	    {
		if (from)  *from =  _from;
		if (to)    *to =    _to;
		if (id)    *id =    _id;
		if (flags) *flags = _flags;
		_seenIds[_from] = _id;
		return true;
	    }
	    // Else just re-ack it and wait for a new one
	}
    }
    // No message for us available
    return false;
}

These look like the ones i bought (probably are these excact ones):

I could probably just put a delay before sending the ack, but i would be guesing for even what sort of range i would need to put it in.

Tomorow i will try to move the sender and reciever from the same arduino further away, if it works i will let you know. Right now they are about 5cm apart from each other.

I do not think its something with wrong pins. The code that is used to send data in the "reliable datagram" part of the library is the code that is being used to send data in these example codes:

  • ask_reciever
  • ask_transmitter

Today i got it working with ur tips.

I tried putting delays in but i did not realy get any good results.
However when i put my sender and reciever from the same arduino further away from each other i did get the code to work. :smiley: :smiley: :smiley:

There's still 1 problem, the sender and reciever cant be closer than 30cm or something like that. And i want my devices to be a circle with a diameter of 15cm.

I think i will try to buy those RXB12 recievers. Can i still use my old transmittors if i switch to those recievers?