Sending a String using VirtualWire

Hi guys,

I'm having trouble getting this code to work. The code is part of a project of mine and transmits two variables, a single character and a long String out to multiple 433Mhz receivers using VirtualWire.

My code for the receiver that processes the single character is working, it's the transmitter code and/or the receiver code for the receiver that processes the long String and outputs it to LCD that I'm stuck on. To simplify the exercise, I've made the string a simple "12345" string so I know what to expect.

My issue is that the LCD display is outputting 5 garbage characters, not "12345" unfortunately.

Any help warmly appreciated.

My transmit code:

#include <VirtualWire.h>

struct DATA{
  char lstate;
  String tstate;
};

DATA DataOut = {0};

String tmsg = "12345";

// constants won't change. They're used here to 
// set pin numbers:
const int dtrPin = 2;
const int rtsPin = 3;         // the number of the pushbutton pin

// variables will change:
int dtrState = 0;         // variable for reading the pushbutton status
int rtsState = 0;
int dtrStateinv = 0;
int rtsStateinv = 0;

void setup() {
DataOut.tstate = tmsg;
pinMode(dtrPin, INPUT);
pinMode(rtsPin, INPUT);  
vw_set_ptt_inverted(true); //
vw_set_tx_pin(12);
vw_setup(4000);// speed of data transfer Kbps
}

void loop(){

  // read the state of the DTR and RTS inputs:
  dtrState = digitalRead(dtrPin);
  rtsState = digitalRead(rtsPin);
  dtrState = !dtrState ;
  rtsState = !rtsState ;

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  
  if (dtrState == HIGH && rtsState == HIGH) {     
    // turn LED on:    
    DataOut.lstate ='2'  ; 
  } else if (dtrState == HIGH && rtsState == LOW) {     
    // turn LED on:    
    DataOut.lstate ='1'  ; 
  }  
  else {
    // turn LED off:
    DataOut.lstate ='0'  ;
  }
  
vw_send((uint8_t *)&DataOut, sizeof(DataOut));
vw_wait_tx(); // Wait until the whole message is gone

}

My receiver code:

#include <VirtualWire.h>

struct DATA{
  char lstate;
  String tstate;
};

struct DATA *DataIn;
String tmsg;

// include the library code for use by the LCD display we're using for testing the program structure
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Setup function runs once and sets the initial state of the board
void setup() {
  // tell the program what type of LCD display we have and then initialize serial port:
  Serial.begin(9600);
  lcd.begin(16, 2);
  
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(8);
    vw_setup(4000);  // Bits per sec
    vw_rx_start();       // Start the receiver PLL running
}

// Loop function runs over and over again
void loop() {
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      DataIn = (struct DATA*)buf;
      tmsg = (DataIn->tstate);
      
    lcd.clear();
    lcd.print(tmsg);
    Serial.println(DataIn->tstate);
    }
}

First of all, 4000 bps is a very high data rate for some TX/RX. Have you tried the default, 2000? Also, are you sure that VW can send a String object? I doubt it. I'm accustomed to seeing it handle char strings.

There is no obvious reason why VirtualWire could not send a String object, but it is pointless to do so.
Just send a character array.

jremington:
There is no obvious reason why VirtualWire could not send a String object, but it is pointless to do so.
Just send a character array.

The lack of a method in the VirtualWire library to do that isn't a reason? You can convert a String to a character array, of course. But that isn't in the posted code.

Like:

vw_send((uint8_t *)DataOut.c_str, sizeof(DataOut));

I'm not sure of the sizeof, I don't use the String class much.