how to send data from one arduino to another

hey guys i’m making a rc boat and i am using a cheap 433mhz rf module for the transmission.i dont know how to send the data and recieve it. i am trying to use the radiohead ask library to send and recieve the data. i am realatively new to this. in the code below i want to send ‘Valc’.

//Define the input pins for the joystick and the variables to keep track of its state

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
int Vala = 0;
int Valb = 0;
int potpin = 0;
const int buttonPinf = 7;
const int buttonPinb = 6;
int Valc = 0;
int buttonStatef = 0;
int buttonStateb = 0;
const int transmit_pin = 12;
const int receive_pin = 11;
void setup()

{
Serial.begin(9600);
  
pinMode(buttonPinf, INPUT);
pinMode(buttonPinb, INPUT);
}

void loop()

{ //This will happen over and over and over and over again......
  
Valb = analogRead(potpin);
 Valb = map(Valb, 0, 1023, 0, 180);
 
buttonStatef = digitalRead(buttonPinf);
buttonStateb = digitalRead(buttonPinb);

if(buttonStatef == HIGH && buttonStateb == HIGH)
{
  Vala = 1000;
}
else if( buttonStatef == HIGH)
{
   Vala = 2000;
}
  else if ( buttonStateb == HIGH)
{
 Vala = 3000;
}
else { Vala = 1000;}
  
{
Valc = Vala + Valb;

const char *msg = Valc;
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
Serial.println(Valc);
}
}

and recieve the value(Valc) in the reciever.

#include<Servo.h>

Servo myservo;
int val = 0;
int servoval = 0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myservo.attach(9);
myservo.write(90);
}

void loop() {
  // put your main code here, to run repeatedly:
if(Serial.available() > 0)
{

  val = Serial.read();
  
  if(val >= 1000 && val < 4000)
  {
   Serial.write(val);
    if(val >= 1000 && val < 2000)
    { 
      servoval = val - 1000; 
        
    }
  else if(val >= 2000 && val < 3000)
  {
    pinMode(7, HIGH);
    servoval = val - 2000;
    
  }
  else if(val >= 3000 && val < 4000)
  {
    pinMode(6, HIGH);
    servoval = val - 3000;
  }
 
 }
myservo.write(servoval);
}
}

i dont mind if you tell me to use a different library. i have to finish the for my science fair project fast. any help is appreciated. thnx in advance

I've not checked your library for using RF, assume you got that code from somewhere and it works in general but I noticed you are building the msg to send in the wrong way

you have

int Valc = 0;

then you do a few things to come up with the value of Valc as an int

and then you use code to send a string and to build that string to be sent you do

const char *msg = Valc;
driver.send((uint8_t *)msg, strlen(msg));

I would suggest you try to understand what the first line really does

that's probably your bug or at least one - I'm just assuming that this is the correct way to send data with your library and RF chip.

(and then you will understand also that you don't want to do strlen(msg) in the next line)

of course then you have a similar problem on the receiving end when you do

val = Serial.read();

because that only reads 1 byte of data and what you want is an int (2 bytes).

if you can't figure it out, answer here and we'll help

The code that i posted was made entirely by me except for the part which sends Valc throgh rf using the radiohead library.

i think that the first lineconst char *msg = Valc; assigns the value of 'Valc' to 'msg'. The second linedriver.send((uint8_t *)msg, strlen(msg)); sends the data(driver.send((uint8_t *)msg) along with the value for the length of the data, strlen(msg));

When i compiled it its is saying error:"invalid conversion from 'int' to 'const char*' [-fpermissive]" on this lineconst char *msg = Valc;.

so i changed it toconst char *msg = const char(Valc); but it is telling error:"expected primary-expression before 'const' " and it is marking the same line. what should i do? Thnx in advance :slight_smile:

thnx a lot. the transmitter code compiled now. only have the reciever code to go :slight_smile:

transmit:

uint8_t *msg = (uint8_t)Valc;
driver.send(msg, 1);

assuming you just want to send one byte

i changed the reciever to this:

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
#include<Servo.h>
Servo myservo;
int val = 0;
int servoval = 0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myservo.attach(9);
myservo.write(90);
}

void loop() {
  // put your main code here, to run repeatedly:
uint8_t val[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(val);
  
  if(val >= 1000 && val < 4000)
{
   Serial.write(val);
    if(val >= 1000 && val < 2000)
{ 
      servoval = val - 1000;       
}
  else if(val >= 2000 && val < 3000)
{
    pinMode(7, HIGH);
    servoval = val - 2000;
}
  else if(val >= 3000 && val < 4000)
{
    pinMode(6, HIGH);
    servoval = val - 3000;
}
}
myservo.write(servoval);
}

when i compile it i am getting an error saying:“ISO C++ forbids comparison between pointer and integer [-fpermissive]” and it is marking this lineelse if(val >= 3000 && val < 4000). so basically all the lines which checks if ‘val’ is between the range of the specified numbers.What do i need to do to make it work? And are there any other problems with the code?Thnx in advance :slight_smile:

hum - not quite.

The library you use for sending and receiving has 2 key functions defined like this.

virtual bool recv (uint8_t *buf, uint8_t *len);
virtual bool send (const uint8_t *data, uint8_t len);

so you need to give a pointer in memory to the start of the bytes flow you want to send and on the other side a pointer to the byte flow you want to receive.

what you want to send is an int, which is stored on 2 bytes in your arduino, in the Valc variable.

so you need to simply say

driver.send((uint8_t *) &Valc, (uint8_t ) 2);

this means I want to send 2 bytes, starting at the address where the Valc variable is stored in memory.

on the receiver side

I suppose you have an associated 433mhz rf module for the reception, so you need to configure it the same way and when something is available for reception do (with your val you declared as an int)

if (driver.recv((uint8_t *) &val, (uint8_t ) 2)) {
    // worked out fine, I got 2 bytes
    // do your stuff here
};

because you know you expect an int on 2 bytes (if you don't want to deal with transmission error detection). So you pass the address in memory where you want the 2bytes to be stored (which is the address of the val variable, which you represent as &val) and the number of bytes you want to read:2

PS: most of AVR microcontrollers are little endian. Little-endian format stores the least significant byte at the first location with the most significant byte being stored last. This is important to know if you have 2 different architectures for the sender and receiver because you will send bytes in one order and they will be perceived as the other way around on the other side of the "wire" (airwaves)

I suppose you have a 433Mhz RF transmitter and receiver kit for Arduino which looks like this

or

it is similar to the second one. when i compiled the reciever code after i made the changes i got an error saying:" invalid conversion from ‘uint8_t {aka unsigned char}’ to ‘uint8_t* {aka unsigned char*}’ [-fpermissive]". here is the code:

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
#include<Servo.h>
Servo myservo;
int val = 0;
int servoval = 0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myservo.attach(9);
myservo.write(90);
}

void loop() {
  // put your main code here, to run repeatedly:
uint8_t val[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(val);
  if (driver.recv((uint8_t *) &val, (uint8_t ) 2)) {

   if(val >= 1000 && val < 4000)
{
   Serial.write(val);
    if(val >= 1000 && val < 2000)
{ 
      servoval = val - 1000;       
}
  else if(val >= 2000 && val < 3000)
{
    pinMode(7, HIGH);
    servoval = val - 2000;
}
  else if(val >= 3000 && val < 4000)
{
    pinMode(6, HIGH);
    servoval = val - 3000;
}
}
myservo.write(servoval);
};  
}

what should i do?sorry that i am asking you a question for each and evrything :frowning: but this is my first arduino project.thnx in advance :slight_smile:

I downloaded the library and found out that the defition of the receive function is

virtual bool    recv(uint8_t* buf, uint8_t[b]*[/b] len);

as written above but I did not take into account the *

extract from RH_ASK.h

    /// Turns the receiver on if it not already on.
    /// If there is a valid message available, copy it to buf and return true
    /// else return false.
    /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
    /// You should be sure to call this function frequently enough to not miss any messages
    /// It is recommended that you call it in your main loop.
    /// \param[in] buf Location to copy the received message
    /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
    /// \return true if a valid message was copied to buf
    virtual bool    recv(uint8_t* buf, uint8_t* len);

So on the receiver side you actually need to pass the address of the variable holding the length you expect and the function will modify that variable to tell you how many it actually received and returns true or false.

You no longer need

uint8_t val[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(val);

so your code should look like this

#include<RH_ASK.h>
RH_ASK driver;


int val = 0;
uint8_t nbBytesReceived=2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (driver.recv((uint8_t *) (&val), &nbBytesReceived)) {

    if (val >= 1000 && val < 4000)
    {
      Serial.write(val);
      if (val >= 1000 && val < 2000)
      {

      } else if (val >= 2000 && val < 3000)
      {

      } else if (val >= 3000 && val < 4000)
      {

      }
    }
  }
}

I removed all the extra code to deal with your servo, so you need to add back that in. (the SPI.h include etc)

Note also that I’ve seen you do:

 pinMode(7, HIGH);

→ are you sure this is correct? parameter should be: INPUT, OUTPUT, or INPUT_PULLUP
→ don’t you want to actually turn on something and do digitalWrite(7, HIGH); ?

I have copied the code you posted and added the parts for servo and pinMode. When i compiled it it read error:"
libraries\Servo\avr\Servo.cpp.o: In function `__vector_11’:

C:\Program Files\Arduino\libraries\Servo\src\avr/Servo.cpp:81: multiple definition of `__vector_11’

libraries\RadioHead\RH_ASK.cpp.o:C:\Users\Pranav\Documents\Arduino\libraries\RadioHead/RH_ASK.cpp:609: first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling." I thought that something was wrong with my pc/ide so i compilied the both the codes in https://codebender.cc and it said error:" Looks like your project uses header files or libraries that do not exist in our system, in your personal libraries or in your sketch. More info

(sketch file) rc boat reciever.ino:1:9: fatal error: ‘RH_ASK.h’ file not found
#include<RH_ASK.h>
^
1 error generated. ". But when i compiled the transmitter code for the rc boat and the example codes included with the library in my pc it copiled it sucessfully. I tried the example code and the rc boat transmitter code on https://codebender.cc but it read the same error as the previous ones. Why did the example code and rc boat transmitter code compile in the ide in my pc but not in https://codebender.cc? Is something wrong with my pc?

Here are the codes for the transmitter and reciever for the rc boat:
Transmitter:

//Define the input pins for the joystick and the variables to keep track of its state

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
int Vala = 0;
int Valb = 0;
int potpin = 0;
const int buttonPinf = 7;
const int buttonPinb = 6;
int Valc = 0;
int buttonStatef = 0;
int buttonStateb = 0;
const int transmit_pin = 12;
const int receive_pin = 11;
void setup()

{
Serial.begin(9600);
  
pinMode(buttonPinf, INPUT);
pinMode(buttonPinb, INPUT);
}

void loop()

{ //This will happen over and over and over and over again......
  
Valb = analogRead(potpin);
 Valb = map(Valb, 0, 1023, 0, 180);
 
buttonStatef = digitalRead(buttonPinf);
buttonStateb = digitalRead(buttonPinb);

if(buttonStatef == HIGH && buttonStateb == HIGH)
{
  Vala = 1000;
}
else if( buttonStatef == HIGH)
{
   Vala = 2000;
}
  else if ( buttonStateb == HIGH)
{
 Vala = 3000;
}
else { Vala = 1000;}
  
{
Valc = Vala + Valb;


driver.send((uint8_t *)&Valc, (uint8_t)2);
driver.waitPacketSent();
Serial.println(Valc);
}
}

Reciever:

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
#include<Servo.h>
Servo myservo;
int val = 0;
int servoval = 0;
uint8_t nbBytesReceived=2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(90);
}

void loop() {
  // put your main code here, to run repeatedly:
if (driver.recv((uint8_t *) (&val), &nbBytesReceived)) {

 if (val >= 1000 && val < 4000)
 {
  if (val >= 1000 && val < 2000)
   {
    servoval = val - 1000;
   } 
  else if (val >= 2000 && val < 3000)
   {
    pinMode(7, HIGH);
    servoval = val - 2000;
   } 
  else if (val >= 3000 && val < 4000)
   {
    pinMode(6, HIGH);
    servoval = val - 3000;
   }
 myservo.write(servoval);  
 }
}
}

Thhnx in advance :slight_smile:

I don't know, depends if you got the same RH_ASK.h library that I have

I would suggest that to debug you get rid of the servo piece and just print what you receive. Once you have the communication working then you can worry about adding more complexity to your code.

I've noticed a bug when you do in the receiver

if (driver.recv((uint8_t *) (&val), &nbBytesReceived)) {

you are actually modifying the value of nbBytesReceived. so if there is nothing for you the first time, then nbBytesReceived is set to zero and next time you come to that function in the loop you are going to tell the driver that you want to receive zero byte. So you should always reset that value to 2 before calling it.

As mentionned above you still have the

pinMode(7, HIGH);

--> are you sure this is correct? in which case parameters should be: INPUT, OUTPUT, or INPUT_PULLUP
--> don't you want to actually turn on something and do digitalWrite(7, HIGH); ?

i used the original code that you posted and it compiled sucessfully! But then when i added the servo library and compiled it, it read error. When i uploded the transmitter code to the arduino and checked serial monitor for the values it was sending it was blank

driver.send((uint8_t *)&Valc, (uint8_t)2);
driver.waitPacketSent();
Serial.println(Valc);

but then when i changed the positio of the serial.print

Serial.println(Valc);
driver.send((uint8_t *)&Valc, (uint8_t)2);
driver.waitPacketSent();

it displayed the value once and after that it didnt display anything.
From this i can find that there is an error in sending the value through rf as the program is getting stoped here and not proceeding forward.

When i uploded both the codes and checked the serial monitor in the reciever i got a blank page. What am i doing wrong :confused:

reciever

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


int val = 0;
uint8_t nbBytesReceived=2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (driver.recv((uint8_t *) (&val), &nbBytesReceived)) {
Serial.println(val);
      }
    }

transmitter

//Define the input pins for the joystick and the variables to keep track of its state

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
int Vala = 0;
int Valb = 0;
int potpin = 0;
const int buttonPinf = 7;
const int buttonPinb = 6;
int Valc = 0;
int buttonStatef = 0;
int buttonStateb = 0;
const int transmit_pin = 12;
const int receive_pin = 11;
void setup()

{
Serial.begin(9600);
  
pinMode(buttonPinf, INPUT);
pinMode(buttonPinb, INPUT);
}

void loop()

{ //This will happen over and over and over and over again......
  
Valb = analogRead(potpin);
 Valb = map(Valb, 0, 1023, 0, 180);
 
buttonStatef = digitalRead(buttonPinf);
buttonStateb = digitalRead(buttonPinb);

if(buttonStatef == HIGH && buttonStateb == HIGH)
{
  Vala = 1000;
}
else if( buttonStatef == HIGH)
{
   Vala = 2000;
}
  else if ( buttonStateb == HIGH)
{
 Vala = 3000;
}
else { Vala = 1000;}
  
{
Valc = Vala + Valb;


driver.send((uint8_t *)&Valc, (uint8_t)2);
driver.waitPacketSent();
Serial.println(Valc);
}
}

And im using an l293d to control the motors so the output pins (pinmode(HIGH)) connect to the input pins of the l293d to move the motors accordingly.
Thnx in advance

I fixed the transmitter code

//Define the input pins for the joystick and the variables to keep track of its state

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
int Vala = 0;
int Valb = 0;
int potpin = 0;
const int buttonPinf = 7;
const int buttonPinb = 6;
int Valc = 0;
int buttonStatef = 0;
int buttonStateb = 0;
const int transmit_pin = 12;
const int receive_pin = 11;
void setup()

{
Serial.begin(9600);
 if (!driver.init())
 Serial.println("init failed"); 
pinMode(buttonPinf, INPUT);
pinMode(buttonPinb, INPUT);
}

void loop()

{ //This will happen over and over and over and over again......
  
Valb = analogRead(potpin);
 Valb = map(Valb, 0, 1023, 0, 180);
 
buttonStatef = digitalRead(buttonPinf);
buttonStateb = digitalRead(buttonPinb);

if(buttonStatef == HIGH && buttonStateb == HIGH)
{
  Vala = 1000;
}
else if( buttonStatef == HIGH)
{
   Vala = 2000;
}
  else if ( buttonStateb == HIGH)
{
 Vala = 3000;
}
else { Vala = 1000;}
  
{
Valc = Vala + Valb;


driver.send((uint8_t *)&Valc, (uint8_t)2);
driver.waitPacketSent();
Serial.println(Valc);
}
}

but how do i fix the bug you mentioned in the reciever code

#include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;
#include<Servo.h>
Servo myservo;
int val = 0;
int servoval = 0;
uint8_t nbBytesReceived=2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(90);
}

void loop() {
  // put your main code here, to run repeatedly:
if (driver.recv((uint8_t *) (&val), &nbBytesReceived)) {

 if (val >= 1000 && val < 4000)
 {
  if (val >= 1000 && val < 2000)
   {
    servoval = val - 1000;
   } 
  else if (val >= 2000 && val < 3000)
   {
    pinMode(7, HIGH);
    servoval = val - 2000;
   } 
  else if (val >= 3000 && val < 4000)
   {
    pinMode(6, HIGH);
    servoval = val - 3000;
   }
 myservo.write(servoval);  
 }
}
}

without the servo part
[/code] #include<RH_ASK.h>
#include<SPI.h>
RH_ASK driver;

int val = 0;
uint8_t nbBytesReceived=2;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:

if (driver.recv((uint8_t *) (&val), (uint8_t)(2))) {
Serial.println(val);
}
}

[/code]
Thnx in advance :slight_smile: