Need help !!! (making an RC plane)

Hey, can someone plz guide me what i am doing wrong.
I wanted to send three servo inputs to another arduino using virtual wire.
I know that i am sending the inputs correctly as they appear on the serial print as i want them to but when i receive them, im only getting zeros.

Iv also tried the (for loop) for the array to store the data that i receive but had no luck with that too.
I have very little experience with arduino can someone plz explain me in detail what i can do.

thank you.

//transmitter
#include <VirtualWire.h>

int Rtrig;
char Rstr[5];
int Rtrig1;
char Rstr1[5];
int Rtrig2;
char Rstr2[5];

void setup()
{
  Serial.begin(9600);
vw_setup(2000); // Bits per sec
Serial.begin(9600);
}
void loop()
{
Rtrig = analogRead(0);

Rtrig = map( Rtrig , 0 , 1023,1000 ,2000);
itoa(Rtrig, Rstr, 10);
const char *msg = Rstr;
Serial.println(msg);
vw_send((uint8_t *)msg, strlen(msg));
 vw_wait_tx(); 

Rtrig1 = analogRead(1);

Rtrig1 = map( Rtrig , 0 , 1023,1000 ,3000);
itoa(Rtrig1, Rstr1, 10);
const char *msg1 = Rstr1;
Serial.println(msg1);
vw_send((uint8_t *)msg1, strlen(msg1));
vw_wait_tx(); 

Rtrig2 = analogRead(2);

Rtrig2 = map( Rtrig2 , 0 , 1023,1000 ,2000);
itoa(Rtrig2, Rstr2, 10);
const char *msg2 = Rstr2;
Serial.println(msg2);
vw_send((uint8_t *)msg2, strlen(msg2));
 vw_wait_tx(); 
}
//reciever

#include <ServoTimer2.h>

#include <VirtualWire.h>

ServoTimer2 myservo;
ServoTimer2 myservo1;
ServoTimer2 myservo2;


void setup()
{
Serial.begin(9600);
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
myservo.attach(9);
myservo1.attach(10);
myservo2.attach(6);
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen))
{
int i;

for (i = 0; i < buflen; i++)
{

  
int val1;
int val2;
int val3;
val1 = atoi(buf[0]); 
 val2 = atoi(buf[1]);
 val3 = atoi(buf[2]);
myservo.write(val1);
myservo1.write(val2);
myservo2.write(val3);
Serial.println(val1,DEC);
Serial.println(val2, DEC);
Serial.println(val3, DEC);
}

}

}
  Serial.begin(9600);
vw_setup(2000); // Bits per sec
Serial.begin(9600);

Maybe you need to call Serial.begin() about 8 or 9 more times.

You DEFINITELY need to use your tab key. Your indenting looks like sh*t.

ServoTimer2 myservo;
ServoTimer2 myservo1;
ServoTimer2 myservo2;

Uh-huh, one, two... Is that how you count?

You send three messages. How many values are in each message?

You read one message. How many values are in that message?

Since you put ONE value in each message, how on earth do you think that the ONE message is going to contain THREE values?

val1 = atoi(buf[0]);
 val2 = atoi(buf[1]);
 val3 = atoi(buf[2]);

buf[0] is NOT a string. You should NOT pass something that is not a string to a function that expects a string.
buf[1] is NOT a string. You should NOT pass something that is not a string to a function that expects a string.
buf[2] is NOT a string. You should NOT pass something that is not a string to a function that expects a string.

If you send the data in three messages it would be helpful if each message included an indication of which value it contained. You can do that with a structure:

struct SM {
byte channel;
unsigned int value;
} ServoMessage;

Then for each analog pin:

void sendMessage(byte channel, byte pin)
{
    ServoMessage.channel = channel;
    ServoMessage.value = map(analogRead(pin), 0, 1023, 1000, 2000);
    vw_send((uint8_t *)ServoMessage, sizeof SM);
    vw_wait_tx(); 
}

So your loop() becomes:

void loop()
{
    sendMessage(0, Channel0Pin);
    sendMessage(1, Channel1Pin);
    sendMessage(2, Channel2Pin);
}

In your receiver:

void loop()
{
    if (vw_get_message(buf, &buflen))
    {
        SM * ServoMessage = buf;
        switch (ServoMessage->channel)
        {
        case 0:  // Channel 0
                myServo.writeMicroseconds(ServoMessage->value);
                break;

       case 1:  // Channel 1
                myServo1.writeMicroseconds(ServoMessage->value);
                break;

       case 2:  // Channel 2
                myServo2.writeMicroseconds(ServoMessage->value);
                break;
        }
    }
}

If you put your servo objects into an array you would not even need the 'switch' statement.

Thank you so much for explaining what i was doing wrong.

johnwasser:
If you send the data in three messages it would be helpful if each message included an indication of which value it contained. You can do that with a structure:

really liked ur idea on sending an indicator…i tried ur code … i think i am missing something not so sure its giving me this error:

invalid cast from type ‘SM’ to type 'uint8_t* {aka unsigned char*}

I tried adding ‘&’ in " vw_send((uint8_t *)&ServoMessage, sizeof(SM));" which did the trick but i dont know whyit did. I remembered someone doing it in another forum. heres the code:

#include <VirtualWire.h>
struct SM {
byte channel;
unsigned int value;
} ServoMessage;

void sendMessage(byte channel, byte pin)
{
    ServoMessage.channel = channel;
    ServoMessage.value = map(analogRead(pin), 0, 1023, 1000, 2000);
    vw_send((uint8_t *)ServoMessage, sizeof(SM));
    vw_wait_tx(); 
}


 void setup()
{
vw_setup(2000); 

}
void loop()
{
    sendMessage(0, Channel0Pin);
    sendMessage(1, Channel1Pin);
    sendMessage(2, Channel2Pin);
}

In the receiver im getting this error as well. Although i have found a code that helped me… i would still like to know about what this error means. I really appreciate the help.

I started this project with almost no knowledge about arduino to learning a little about all the examples and the programming language itself. After spending a weeks only doing this iv manage to learn quite a bit…especially from the forums.

Heres the code for the plane if anyone wants ive have altered it to my need but the actual code was for a temperature sensor. All credits go to HazardsMind.

// Transmitter
#include <VirtualWire.h>

char Array[20]; // store data 
int X,Y; // for the joystick
int Z; // potentiometer
void setup()
{
  Serial.begin(9600);    
  Serial.println("Sending");

  vw_setup(2000);  
  vw_set_tx_pin(12); 
  
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(5, OUTPUT);
  
  digitalWrite(7, LOW); // joystick ground
  digitalWrite(8,HIGH); // joystick Vcc
  digitalWrite(5,HIGH); // potentiometer Vcc

  pinMode(13, INPUT); //accel Z
  pinMode(14, INPUT); //accel Y
  pinMode(15, INPUT); //accel X
}

void loop()
{ 
  X = analogRead(3) ; // X axis
  Y = analogRead(4) ; // Y axis
  Z = analogRead(2) ; // potentiometer

  
  sprintf(Array, "%d,%d,%d ",X,Y,Z); 


  vw_send((uint8_t*)Array, strlen(Array)); 
  vw_wait_tx();  
}
//receiver

#include <ServoTimer2.h>
ServoTimer2 myservo1;
ServoTimer2 myservo2;

#include <VirtualWire.h>

//#define DEBUG_MODE

void setup()
{
  Serial.begin(9600); 
  
  pinMode(13,OUTPUT); 
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
 
  myservo1.attach(6);
  myservo2.attach(9);
  
  vw_setup(2000);      
  vw_set_rx_pin(11);   
  vw_rx_start();       

}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN]; 
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  digitalWrite(2, HIGH);// Vcc for servo
  digitalWrite(3, HIGH);// Vcc for servo  
  if (vw_get_message(buf, &buflen))
  {
    
    digitalWrite(13, HIGH); 
    
    int X = atoi(strtok(buf, ",")); 
    int Y = atoi(strtok(NULL,","));
    int esc = atoi(strtok(NULL," "));


X = map (X,  900, 0, 1000,3000 ); // Aleron
Y = map (Y , 900, 0, 1000,3000 ); // Rudder
 esc = map (esc , 0, 1023, 1000,2000 ); 
 #ifdef DEBUG_MODE 
  Serial.print(X); // x axis
    Serial.print(", ");
    Serial.print(Y); // Y axis
    Serial.print(", ");
    Serial.print(esc); // for the ESC
    Serial.println();
  #endif
  
  
  
  myservo1.write(X); // Aleron
  myservo2.write(Y); // Rudder
  
  }
  else digitalWrite(13, LOW); // No data received
}

I tried adding '&' in " vw_send((uint8_t *)&ServoMessage, sizeof(SM));" which did the trick but i dont know whyit did.

It is the address of the array that you want to be treated as though it was of type uint_8, so casting the address is the proper thing to do.