433 Mhz RF Transmitter And Receiver Modules

Hello Geeks! :grinning:

I thought I would make an Arduino controlled Bait Boat using a 433Mhz RF Transmitter and Receiver Module pair. It's going well but I have two questions that I would like to ask if I may, one regarding the Transmitter sketch and one on the Receiver.

The RF driver is part of the RadioHead Library and the example I based the sketch on is from the excellent DroneBot Workshop (https://www.youtube.com/watch?v=b5C9SPVlU4U)

My version uses two joysticks with the intention of controlling two 9V DC motors on a model boat. The Arduino takes the output of the Joysticks and converts the readings to strings. An Output string concatenates the two with a comma separator and the RF Driver transmits the Output string using the 433 Mhz RF Transmitter.

The receiver code needs the received string to be a fixed length but the string varies from 2 x single character to 2 x four character as the Joysticks are moved.

So I added this code to include leading Xs where required:

 JoyStick1Val = analogRead (JoyStick1Pin);
  
  str_Zero = X;

  if (JoyStick1Val < 10)
  {
    str_JoyStick1Val = str_Zero + str_Zero + str_Zero + JoyStick1Val;  
  }

The code works ok, in fact really well, it adds leading 0s instead of Xs and with the comma separator, I get a fixed 9 character Output string irrespective of the JoyStick read values. But I don't understand why it changes the X to a 0!

I'm guessing that the str_Zero = X; sees the word zero as a numerical string for some reason.

Does anyone have an explanation please?

Regards

Graeme

Code:

/*
 *
 *  The Bait Boat 
 *  Rev 02.04 _Transmitter 
 *  14/04/24
 *  
 *  Description
 *  Prototype to test the Transmitter/Receiver Pair
 *
 *  Rev History
 *  Rev 02.01_Transmitter with text message string
 *  Rev 02.02_Transmitter - Transmitter with text message string
 *  Rev 02.02_Receiver - Receiver
 *  Rev 02.03_Transmitter - Transmitter with Joystick position string
 *  Rev 02.03_Receiver - Receiver
 *  Rev 02.04_Transmitter - Transmitter with Dual Joysticks and 2 x 4 character string
 *  Rev 02.04_Receiver - Receiver
 *
*/
  
//  Libraries

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

//  Create RH Driver
RH_ASK rf_driver;

//  Variables
int DelayTime = 200;
int JoyStick1Pin = A1;
int JoyStick1Val;
int JoyStick2Pin = A2;
int JoyStick2Val;
int X;
String str_Zero;
String str_JoyStick1Val;
String str_JoyStick2Val;
String str_Output;

void setup() 
{
  rf_driver.init();   //  Arduino Pin 12
  Serial.begin (9600);
  pinMode(JoyStick1Pin, INPUT);
  pinMode(JoyStick2Pin, INPUT);

}

void loop() 
{

  //  Read Joystick 1 value

  JoyStick1Val = analogRead (JoyStick1Pin);
  
  str_Zero = X;

  //  Add 3 leading zeros to 1 character reading

  if (JoyStick1Val < 10)
  {
    str_JoyStick1Val = str_Zero + str_Zero + str_Zero + JoyStick1Val;  
  }

  //  Add 2 leading zeros to 2 character reading

  if (JoyStick1Val >= 10 && JoyStick1Val < 100)
  {
    str_JoyStick1Val = str_Zero + str_Zero + JoyStick1Val;  
  }

  //  Add 1 leading zero to 3 character reading

  if (JoyStick1Val >= 100 && JoyStick1Val < 1000)
  {
    str_JoyStick1Val = str_Zero + JoyStick1Val;  
  }

    if (JoyStick1Val >= 1000)
  {
    str_JoyStick1Val = JoyStick1Val;  
  }

  //  Read Joystick 2 value

  JoyStick2Val = analogRead (JoyStick2Pin);

  //  Add 3 leading zeros to 1 character reading

   if (JoyStick2Val < 10)
  {
    str_JoyStick2Val = str_Zero + str_Zero + str_Zero + JoyStick2Val;  
  }
  
  //  Add 2 leading zeros to 2 character reading

  if (JoyStick2Val >= 10 && JoyStick2Val < 100)
  {
    str_JoyStick2Val = str_Zero + str_Zero + JoyStick2Val;  
  }
  
  //  Add 1 leading zero to 3 character reading
  
  if (JoyStick2Val >= 100 && JoyStick2Val < 1000)
  {
    str_JoyStick2Val = str_Zero + JoyStick2Val;  
  }

    if (JoyStick2Val >= 1000)
  {
    str_JoyStick2Val = JoyStick2Val;  
  }

  //  Compose Output string

  str_Output = str_JoyStick1Val + "," + str_JoyStick2Val;

  //  Send 9 character string

  static char *msg = str_Output.c_str();
  rf_driver.send((uint8_t *)msg, strlen(msg));
  rf_driver.waitPacketSent();

  delay(DelayTime);

  Serial.println (str_Output);

}


//  EoF

A much simpler option is to send the variable(s) in binary, rather than a clumsy character string, or worse a String object that leads to program crashes.

For two joystick values something like this will work:

int joystick[2];
joystick[0] = analogRead(JoyStick1Pin);
joystick[1] = analogRead(JoyStick2Pin);
  rf_driver.send((uint8_t *)joystick, sizeof(joystick));
  rf_driver.waitPacketSent();

The receiver code is no more complex than that.

X is a global variable and is initialized to zero.

Cheers for the swift reply.

My second question was going to be about the receiver code crashing!

So I'll try your suggestion and see if the problem goes away and report back.

Thanks

Graeme

Understood.

Thanks.

Graeme

Well the Transmitter code works lovely, Serial.prints of both Joystick readings return a full range of 0 to 1023.

I'm struggling to get the Receiver code to work though. A Serial.print displays 248 for Joystick[0] and 1 for Joystick[1]. When I move the Joysticks I get non linear numbers displayed.

The maximum number displayed is 255 on Joystick 1. My guess is that it's because the results displayed for the Receiver array are 8 bit so unable to deal with the Joystick analogue 10 bit values.

The rf_driver library (Radiohead) needs to see a uint8_t variable to transmit a value. Is there an alternative way of transmitting 10 bit numbers using a uint8_t variable?

Thanks

Graeme

Post the code.

Integers of more than 8 bits are sent z using multiple 8 bit bytes. The receiver code should be easy if you examine how the r]tran sitter is sending.

a7

Here's the Receiver code I'm using:





/*
 *
 *  The Bait Boat 
 *  Rev 02.05_Receiver - jremington
 *  21/04/24
 *  Graeme Durden
 *  
 *  Description
 *  Prototype to test the Transmitter/Receiver Pair
 *  
 *  Rev History
 *  Rev 02.01_Transmitter with text message string
 *  Rev 02.02_Transmitter - Transmitter with text message string
 *  Rev 02.02_Receiver - Receiver
 *  Rev 02.03_Transmitter - Transmitter with Joystick position string
 *  Rev 02.03_Receiver - Receiver
 *  Rev 02.04_Transmitter - Transmitter with Dual Joysticks and 2 x 4 character string
 *  Rev 02.04_Receiver - Receiver       
 *  Rev 02.05_Transmitter - jremington
 *  Rev 02.05_Receiver - jremington
 */
 
//  Libraries
#include <RadioHead.h>
#include <RH_ASK.h>
#include <SPI.h>

//  Create RH Driver

RH_ASK rf_driver;

//  Variables

int JoyStick1Val;
int JoyStick2Val;
int JoyStick[2];  
int DelayTime = 200;


void setup() 
{

  Serial.begin (9600);
  rf_driver.init(); //  Arduino Pin 11
  
}

void loop() 
{

  uint8_t JoyStick[2];
  uint8_t JoySticklen = sizeof (JoyStick);

  if (rf_driver.recv(JoyStick, &JoySticklen))
  {

    JoyStick1Val = JoyStick[0];
    JoyStick2Val = JoyStick[1];

  }
  
  Serial.print (JoyStick[0]);
  Serial.print (" + ");
  Serial.println (JoyStick[1]);  
  Serial.print(JoyStick1Val);
  Serial.print(" - ");
  Serial.println(JoyStick2Val);
  
  delay(DelayTime);

}



//  EoF

This in the sender

int joystick[2];
joystick[0] = analogRead(JoyStick1Pin);
joystick[1] = analogRead(JoyStick2Pin);

  rf_driver.send((uint8_t *)joystick, sizeof(joystick));
  rf_driver.waitPacketSent();

doesn't match what you say you want to receive

  uint8_t JoyStick[2];
  uint8_t JoySticklen = sizeof (JoyStick);

  if (rf_driver.recv(JoyStick, &JoySticklen))
  {

I'm just bluffing here, it's gonna be something more like

  int JoyStick[2];
  size_t JoySticklen = sizeof JoyStick / sizeof *JoyStick;

  if (rf_driver.recv((uint8_t *) JoyStick, &JoySticklen))

You send 4 bytes because you send 2 16 bit integers. You receive the same numbers and put them where they will mean the same thing.

a7

Looks like the RH_ASK doesn't have a function for that.

I got this when trying to compile:

g:\Arduino\Sketches\libraries\RadioHead/RH_ASK.h:305:39: note: candidate: virtual bool RH_ASK::recv(uint8_t*, uint8_t*)
RH_INTERRUPT_ATTR virtual bool recv(uint8_t* buf, uint8_t* len);
^~~~
g:\Arduino\Sketches\libraries\RadioHead/RH_ASK.h:305:39: note: no known conversion for argument 2 from 'size_t* {aka unsigned int*}' to 'uint8_t* {aka unsigned char*}'

exit status 1

Compilation error: no matching function for call to 'RH_ASK::recv(uint8_t*, size_t*)'

Graeme

Fix that as follows:

  uint8_t JoySticklen = sizeof JoyStick;

  if (rf_driver.recv((uint8_t *) JoyStick, &JoySticklen))
2 Likes

You are the Man!

Thank you very much.

I'll post a picture of the first carp I catch!

Graeme

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