Send/receive data from iPhone to Arduino via VirtualWire

I have a set up where Processing reads serial data from my iPhone and send this message to Arduino to actuate motors.
I now want this process to be wireless as the motors are a propulsion system for a helium blimp; am playing around with VirtualWire to do so.
Arduino1 (connected to computer) is the transmitter (receiving data from iPhone/Processing),
Arduino2 receives this message and actuates the motors.

The communication that is working:
iPhone>Processing>Arduino1>transmit
Issue:
Arduino2 is not receiving (code issue; all hardware working fine with other VW codes).

Am a new kid on the block in terms of VirtualWire, I suspect I'm mishandling data/datatypes (?!)
thoughts?
thanks in advance...

//TRANSMITTER CODE
#include <AFMotor.h>
#include <VirtualWire.h>


int msg = 0; //MSG from iphone>processing
void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("wireless setup");
//wireless setup
  vw_setup(2000); // Bits per sec
 

  pinMode (9, OUTPUT);

}

void loop() {

  
  if (Serial.available() > 0) { //  Check if there is a new message

    msg = Serial.read();    //  Put the serial input into the message
    Serial.println(msg);
vw_send((byte *)msg, 2);


delay(200);
  }
}
//RECEIVERCODE
#include <AFMotor.h>
#include <VirtualWire.h>

int message = 0; 
int ledPin = 13;
int dly = 2;

//DIRECTIONAL MOTORS

AF_DCMotor motor(1, MOTOR12_64KHZ); 
AF_DCMotor motor2(1, MOTOR12_64KHZ); 

AF_DCMotor motor3(3, MOTOR12_64KHZ); 
AF_DCMotor motor4(3, MOTOR12_64KHZ); 

// LANDING PROPELLORS

AF_DCMotor motor5(2, MOTOR12_64KHZ); 
AF_DCMotor motor6(2, MOTOR12_64KHZ); 
AF_DCMotor motor7(2, MOTOR12_64KHZ); 
AF_DCMotor motor8(2, MOTOR12_64KHZ); 



void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  Serial.println("wireless setup");
//wireless setup
  vw_setup(2000); // Bits per sec
  vw_rx_start(); // Start the receiver PLL running
//motor setup
  motor.setSpeed(255);
  motor2.setSpeed(255);// set the speed to 200/255
  motor3.setSpeed(255);
  motor4.setSpeed(255);

  motor5.setSpeed(1000);
  motor6.setSpeed(1000);
  motor7.setSpeed(1000);
  motor8.setSpeed(1000);

  pinMode (9, OUTPUT);

}

void loop() {
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received, dump HEX
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println("");
}
 // if (Serial.available() > 0) { //  Check if there is a new message

   
//MOTOR ACTIONS
    //LEFT MOTOR--------------------------------------------------------------
    if(message == 'A'){
      Serial.print("fwd");
      motor.run(FORWARD);      // turn it on going forward
      motor2.run(FORWARD);
      delay(dly);
    }

    if (message == 'C'){
      Serial.print("back");
      motor.run(BACKWARD);     // the other way
      motor2.run(BACKWARD);  
      delay(dly);
    }


    if (message == 'B'){ 

      Serial.print("stop");
      motor.run(RELEASE);      // stopped
      motor2.run(RELEASE);  
      delay(dly);

    }

    //RIGHT MOTOR--------------------------------------------------------------
    if(message == 'F'){
      Serial.print("fwd");
      motor3.run(FORWARD);      // turn it on going forward
      motor4.run(FORWARD); 
      delay(dly);
    }

    if (message == 'D'){
      Serial.print("BAck");
      motor3.run(BACKWARD);     // the other way
      motor4.run(BACKWARD);
      delay(dly);
    }


    if (message == 'E'){ 

      Serial.print("stop");
      motor3.run(RELEASE);      // stopped
      motor4.run(RELEASE); 
      delay(dly);
    }

    //LANDING MOTOR--------------------------------------------------------------
    if(message == 'X'){
      Serial.print("land");
      motor5.run(BACKWARD);      // turn it on going forward
      motor6.run(BACKWARD); 
      motor7.run(BACKWARD);      // turn it on going forward
      motor8.run(BACKWARD); 
      delay(dly);
    }

    if(message == 'Y'){

      Serial.print("stopLand");
      motor5.run(RELEASE);      // stopped
      motor6.run(RELEASE); 
      motor7.run(RELEASE);      // stopped
      motor8.run(RELEASE);
      delay(dly);
    }


//  }
}

updated- Arduino2 receives a message
Arduino1's message (currently) sends a series of letters whilst Arduino2 receives a series of digits.
help?

    msg = Serial.read();    //  Put the serial input into the message
    Serial.println(msg);
vw_send((byte *)msg, 2);

Read one byte from the serial port, and send both of them. Why?

Arduino1's message (currently) sends a series of letters whilst Arduino2 receives a series of digits.
help?

This doesn't make sense. Print, on the sender, the byte(s) being sent, in the same way that you are printing them on the receiver.

Show some examples of what you are sending, and what you are receiving. If you are (trying to) send an A, and you are receiving a 65, then everything is working.

Hey PaulS, thanks so much for your reply.

Arduino1's message (currently) sends a series of letters whilst Arduino2 receives a series of digits.
help?

A sample of what I'm sending/receiving at the moment

SAMPLE FROM TRANSMITTER

wireless setup
8
899
8

9
899
9

8
89
9
9
9
9
99
9
9
8
SAMPLE FROM RECEIVER

Got: 0 4 0 0 0 C0 0 0 0 5 28 5 28 0 5 28 0  0 C0 FF C8 0 A 0 A 5 
Got: 0 4 0 0 0 C0 0 0 0 5 5 25 28 0 5 28 0 C6 0C0 FF C8 0 A 0 A 0 5
Got: 0 4 0 0 0 00 0 0 0 5 5 28 5  0 5 28 0 C6 0 C0 FC8 0 A 0 A 0 5 
t: 0 4 0 0 0 0 C0  0 0 5 5 28 5 28 0 28 0 C6 0 C0 FF C8 A 0 A 0 5 
G 0 5 C A 
Got: 0 4 0 0 0 0 C0 0 0 0  2 28 0 5 28 0 C6 0 CFC0A A5 
Got: 0 4 0 0 0 C0 0 0 0 5 5 28 58 0 5 28 0 C     A  Go 00  C:  0280 0 0  0 0 5 C6 00  5 C 5 C28FF
G0  5C8:0 8  A 4 50  0 0 26 A  08 C05 0 2 F
 00  Ct: 0280 0   0A 4 5 C6A 0 28 0 5 0 20 
G0  0 ot0  2 0 00 8  A 4 5C A 0 26 0  05 C05 0 2F Go 00  Ct: 0280 0 0  00 0 5 C6A0  5 C 5 0 20  
0  0 ot0  5C8 00 8  A 4 5 C A 0 20 0  5 C05 C08 F Go 00 8   0280 0 5  A04 5 0 0 0 5 0 0  05 C00  0 2C0  08 0  2 8 FF 20  5FFE 0  2F E0 8 C8 
 C8 C8 
0  08

The Transmitter should be sending single characters A,B,C,D,E,X or Y.

Read one byte from the serial port, and send both of them. Why?

Yikes, I'm not sure I understand sorry-

 msg = Serial.read();//  Put the serial input into the message
    Serial.println(msg); //print to the serial monitor

this prints the msg to the serial and also the serial monitor (for debugging) no?

 vw_send((byte *)msg, 2); //send msg to receiver

and, I thought to send an interger you had to send it as 2bytes- super novice understanding of this data transmission ordeal...

thanks again for responding.

after a lot more research and progress, I have developed the code quite some bit and it is almost working...I'm one step away from it functioning properly... calling on any VirtualWire gurus out there...

And the iPhone data is feeding into the transmitter perfectly.
The transmitter and receiver communicate nicely. Sometimes. See following:

This all works except the character fails to transmit to the VWire

//TRANSMITTER CODE

#include <VirtualWire.h>

 

int  serIn;             // var that will hold the bytes-in read from the serialBuffer

char serInString[25];  // array that will hold the different bytes  100=100characters;

// -> you must state how long the array will be else it won't work.

int  serInIndx  = 0;    // index of serInString[] in which to insert the next incoming byte

int  serOutIndx = 0;    // index of the outgoing serInString[] array;

 

void setup() {

  Serial.begin(9600);   // set up Serial library at 9600 bps

  vw_setup(2000);       // Bits per sec

//  pinMode (9, OUTPUT);

}

 

void loop() {

  /// - First lines read anything that has been received into the serial buffer

  ///    into an array called "serInString"

  int sb;  

  if(Serial.available()) {

    while (Serial.available()){

      sb = Serial.read();            

      serInString[serInIndx] = sb;

      serInIndx++;

    }

  }   

  /// - Now 'replay' the string one character at a time from "serInString"

  ///   out to the print function (with hex version in Sq Brackets) and to the VWire

  ///   eg 'hello' is h[68] e[65] l[6c] l[6c] o[6f]  

  ///   eg '789' is 7[37] 8[38] 9[39]

  if( serInIndx > 0) {

    //loop through all bytes in the array and print them out/send

    for(serOutIndx=0; serOutIndx < serInIndx; serOutIndx++) {

      if(serInIndx>15){  // if the buffer is heading towards an overflow then ignore everything in it and start again

        break;

      } 

      Serial.print(serInString[serOutIndx]); //print to the serial monitor

   char *msg=serInString[serOutIndx];

      vw_send((uint8_t *)serInString[serOutIndx], strlen(msg));//send one character message msg to receiver

      vw_send((uint8_t *)serInString[serOutIndx], 1);

      vw_wait_tx();

 

    }       

    //reset all the functions to be able to fill the string back with content

    serOutIndx = 0;

    serInIndx  = 0;

    Serial.println();

 

  }

 

}

However, transmitting a simple “h” at the very bottom of the loop does send the ‘h’ successfully through VWire. There seems to be some scope issue and vw_send only works when at the root level of loop().

//TRANSMITTER CODE

#include <VirtualWire.h>

 

int  serIn;             // var that will hold the bytes-in read from the serialBuffer

char serInString[25];  // array that will hold the different bytes  100=100characters;

// -> you must state how long the array will be else it won't work.

int  serInIndx  = 0;    // index of serInString[] in which to insert the next incoming byte

int  serOutIndx = 0;    // index of the outgoing serInString[] array;

 

void setup() {

  Serial.begin(9600);   // set up Serial library at 9600 bps

  vw_setup(2000);       // Bits per sec

//  pinMode (9, OUTPUT);

}

 

void loop() {

  /// - First lines read anything that has been received into the serial buffer

  ///    into an array called "serInString"

  int sb;  

  if(Serial.available()) {

    while (Serial.available()){

      sb = Serial.read();            

      serInString[serInIndx] = sb;

      serInIndx++;

    }

  }   

  /// - Now 'replay' the string one character at a time from "serInString"

  ///   out to the print function (with hex version in Sq Brackets) and to the VWire

  ///   eg 'hello' is h[68] e[65] l[6c] l[6c] o[6f]  

  ///   eg '789' is 7[37] 8[38] 9[39]

  if( serInIndx > 0) {

    //loop through all bytes in the array and print them out/send

    for(serOutIndx=0; serOutIndx < serInIndx; serOutIndx++) {

      if(serInIndx>15){  // if the buffer is heading towards an overflow then ignore everything in it and start again

        break;

      } 

      Serial.print(serInString[serOutIndx]); //print to the serial monitor

//   char *msg=serInString[serOutIndx];

//      vw_send((uint8_t *)serInString[serOutIndx], strlen(msg));//send one character message msg to receiver

//      vw_send((uint8_t *)serInString[serOutIndx], 2);

//      vw_wait_tx();

 

    }       

    //reset all the functions to be able to fill the string back with content

    serOutIndx = 0;

    serInIndx  = 0;

    Serial.println();

 

  }

const char *msg = "h";

vw_send((uint8_t *)msg, strlen(msg));

delay(400);

 

}

I have tried using the sendString() function right after the loop:

void sendString(String s){

              uint8_t Mybuf[VW_MAX_MESSAGE_LEN];

              for(int i=0;i<s.length();i++) {Mybuf[i]=(uint8_t)s.charAt(i);}

              vw_send(Mybuf,s.length());

              vw_wait_tx();

           

}

to no avail.

Thoughts?
Would appreciate any...

   char *msg=serInString[serOutIndx];
      vw_send((uint8_t *)serInString[serOutIndx], strlen(msg));//send one character message msg to receiver

You define a pointer, and point it at one character. You do this so you can determine the length of the one character string.

A string (what strlen expects as input) must be a NULL terminated array of characters, not a single character. Why you need to measure the length of a character is a mystery. Will it ever be other than 1?

  if(Serial.available()) {

    while (Serial.available()){

      sb = Serial.read();            

      serInString[serInIndx] = sb;

      serInIndx++;

    }

  }

What is going to happen if there are 60 characters available on the serial port?

      vw_send((uint8_t *)serInString[serOutIndx], strlen(msg));//send one character message msg to receiver

      vw_send((uint8_t *)serInString[serOutIndx], 1);

Why are you sending the character twice? Why are you not sending the whole thing in one call?

You know its length (that is in serInIndx). Send the data in one call.

I see what you are saying about the string thing - it ended that way through some trial and error to address issues and was ugly as you pointed out. I have re-written the code to focus on the issue at hand. It sends a complete string through the function now.

The code is below.

The issue is that the receiver is receiving scrambled output.
If LINES AA are commented out and LINE B uncommented the receiving end gets "Hello" successfully.
Got: 68(h) 65(e) 6C(l) 6C(l) 6F(o)

If both sets are uncommented then Hello is mangled up with random characters (not a mix of the incoming characters and hello).

Most weirdly, if LINES AA are commented out and LINE B uncommented and the iPhone transmition comes into the serial in, it actually corrupts the "Hello"! The incoming data rate can be at 9600 which is of course higher than the outgoing of 2000. Can that incoming stream swamp the device?

Got: 68(h) 65(e) 6C( 6C(l) 6F(o)
G: 68(h) 65(e) 6C( 6C(l) 6F(o)
Gth6()Cl6C(l) 6F(o)
Gt: 68(h) 65(e) 6Cl6C(l) 6F(o)
G: 68(h) 65(e) 6C( 6C(l) 6F(o)
G: 68(h) 65(e) 6C(l6C(l) 6F(o)
Go 68(h) 65(e) 6C(l6C(l) 6F(o)
G ) 65(e) 6C(l) 6C(l) 6F(o)

As a side comment - if LINES AA are replaced with just a string eg
sendString("hello"), it still scrambles.

Essentially, somehow the incoming Serial data stream is interfering with the VWire TX stream.

I hope that provides focus for the problem issue - quite a challenge...

//TRANSMITTER CODE
#include <VirtualWire.h>

int TXpin=12;        //Sets pit to VWtransmit on - 13 for LED; 12 for real transmitter
int  serIn;             // var that will hold the bytes-in read from the serialBuffer
char serInString[25];  // array that will hold the different bytes  100=100characters;
// -> you must state how long the array will be else it won't work.
int  serInIndx  = 0;    // index of serInString[] in which to insert the next incoming byte
int  serOutIndx = 0;    // index of the outgoing serInString[] array;

void setup() {
  Serial.begin(9600);   // set up Serial library at 9600 bps
  vw_setup(2000);       // Bits per sec
  vw_set_tx_pin(TXpin);
}

void loop() {
  /// - First lines read anything that has been received into the serial buffer 
  ///    into an array called "serInString"
  int sb;   
  if(Serial.available()) { 
    while (Serial.available()){ 
      sb = Serial.read();             
      serInString[serInIndx] = sb;
      serInIndx++;
      if(serInIndx>5){break;}  // If the serial input is getting too ahead just send & drop it
    }
  }    
if(serInIndx>0){   //If there is a string to send then send it
  sendString(serInString);  // LINES AA
  Serial.print(serInString);// LINES AA

}
    //reset the index to strat again
    serInIndx  = 0;
  // sendString("hello");  // LINE BB
}

void sendString(String s){
	  uint8_t Mybuf[VW_MAX_MESSAGE_LEN];
	  for(int i=0;i<s.length();i++) {Mybuf[i]=(uint8_t)s.charAt(i);}
	  vw_send(Mybuf,s.length());
	  vw_wait_tx();
}