Problem with variable validation using data transmitted via virtual wire

Hi Arduinoers,

I really hope you can help me. My brother and I are trying to implement some simple pairing logic between two arduinos connected via 433mhz modules. One is acting as a wireless throttle and transmitting data using VirtualWire to a second arduino within a control box, which in turn sends the received data onto a third Arduino via a serial connection and is sending the PWM to a pair of motor controllers.

We’ve got the wireless solution working really well, but we’d like to add some simple pairing logic so that more than one system could be used at a time. To get this working I’ve added some code to the wireless throttle so that it first sends a a simple ID and then prefixes a single character to the sent data. The wireless receiver waits for a code, records it and then should only process and use data with a matching prefix.

I’ve got the code in and it’s kind of working, but attempts to validate the prefix against a stored variable simply aren’t working! The code in question is within a function in the receiver code and is a basic if statement. What I’m trying to do is check the prefix is valid and if so pass the data to the third arduino, but the validation never passes. When I check my debug code I can see the two variables and their contents matches!

The function in question is void txSerial() in the receiver code, but the problem is likely to be elsewhere.

I’m only a very basic programmer and haven’t coded for years, so apologies for the bad code I’ve written and bad formatting in advance.

Here’s the code on the receiver:

/* 

S.C.P.M.I Wireless x2 Control System Throttle
By Simon Parke 12-01-2014

*/

//Libraries
#include <VirtualWire.h>
#include <TimedAction.h>
//End Libraries

//Initialisation

//this initializes a TimedAction class that will change the state of an LED every second.
TimedAction CheckRX = TimedAction(500,getRX);
TimedAction SerialSend = TimedAction(500,txSerial);

// LED's
int LEDPin = 17;


// Sensors 
int throttleData;

// RF Transmission container
char throttleDataCharMsg[10];
String throttleDataString;
String NoData = "     ";

// Set pin to receive RF data
int receive_pin = 5;

// debug msg count
//int debugCount = 0;

int SensorTX;
//End Initialisation

boolean InitialiseRX;
boolean RXReceived;
int RXLength;
char ThrottleID[10];
char ThrottleIDPrefix[1];
String RXCheck;
char RXVal[1];

void setup() 
{
 Serial.begin(9600);
 delay(100); 
 Serial1.begin(9600);
 delay(100);
 CheckRX.enable();
 // sets the digital pin as output
 pinMode(LEDPin, OUTPUT);
 // Set pin to receive RF data
 vw_set_rx_pin(receive_pin);
 // VirtualWire 
 // Initialise the IO and ISR
 // Required for DR3100
 vw_set_ptt_inverted(true); 
 // Bits per sec
 vw_setup(2000);     
 // Start the receiver PLL running
 vw_rx_start(); 

 InitialiseRX = true; 
 Serial.print("Initialisation Status ");
 Serial.println(InitialiseRX);
 RXReceived = false;
 delay(1000);
// END setup
}

void loop()
{
 CheckRX.check(); 
 if (InitialiseRX == true)
  {
   //RXCheck = (String)throttleDataCharMsg;
   if (RXReceived == false)
   {
     Serial.print("Throttle not initialised ");
     Serial.println(throttleDataCharMsg);
     delay (1000);     
   }
   else
   {
     strcpy(ThrottleID, throttleDataCharMsg);
     strncpy (ThrottleIDPrefix, throttleDataCharMsg, 1);
     InitialiseRX = false;
     SerialSend.enable();
     Serial.print("String Length: ");
     Serial.println(RXLength);     
     Serial.print("Throttle ID: ");
     Serial.println(ThrottleID); 
     Serial.print("Throttle Prefix: ");
     Serial.println(ThrottleIDPrefix);
     Serial.print("Initialisation Status ");
     Serial.println(InitialiseRX);
     delay (1000);     
   }
 }
 else
 {
   if (RXReceived == true)
   {
    SerialSend.check();
   }
   else
   {
   Serial.println("No serial transmission");
   delay(1000);  
   }
 }
// END Loop  
}

  
void txSerial()
{
  Serial.println("Checking for a valid prefix");
  Serial.println(RXVal);
  Serial.println(ThrottleIDPrefix);
  delay(500);
  //debug code
  if (RXVal == ThrottleIDPrefix)
  {
  throttleData = atoi(throttleDataCharMsg);
  SensorTX = throttleData;
  Serial1.println(SensorTX);
  Serial.print("Throttle TX: ");
  Serial.println(SensorTX); 
  Serial.println("Sent Data");
  SerialSend.reset();
  delay (1000);    
     
  }
 else
  {
     Serial.println("Invalid Throttle Data");
   delay (1000);
 } 
}

void getRX()
{
 uint8_t buf[VW_MAX_MESSAGE_LEN];
 uint8_t buflen = VW_MAX_MESSAGE_LEN;    
 // Non-blocking
 if (vw_get_message(buf, &buflen)) 
  {
   RXReceived = true;
   int i;
   // Turn on a light to show received good message 
   digitalWrite(LEDPin, false); 
   // Message with a good checksum received, dump it. 
   for (i = 0; i < buflen; i++)
   {            
    // Fill throttleDataCharMsg Char array with corresponding 
    // chars from buffer.   
    throttleDataCharMsg[i] = char(buf[i]);
   }
  // Null terminate the char array
  // This needs to be done otherwise problems will occur
  // when the incoming messages has less digits than the
  // one before. 
  throttleDataCharMsg[buflen] = '\0';
  strncpy (RXVal, throttleDataCharMsg, 1);
  Serial.print("Data Received: ");
  Serial.println(throttleDataCharMsg);
  delay(500);   
  digitalWrite(LEDPin, true);  
  CheckRX.reset();
 }
 else
 {
  RXReceived = false;
  Serial.println("No Data Received: ");
 }
}

Thanks in advance, and any improvements to the code would be most welcome!

Best Regards,

Simon

char RXVal[1];

A one element array? Pretty much useless, as it offers no advantages over a scalar variable.

  if (RXVal == ThrottleIDPrefix)

This is comparing the addresses of the two arrays, not the contents of the two arrays. Of course they never match.

I'd suggest strcmp(), except that neither RXVal or ThrottleIDPrefix is a string. A string is a NULL terminated array of chars, which implies a minimum length of two.

You could do:

  if (RXVal[0] == ThrottleIDPrefix[0])

but getting rid of the one element arrays is a better idea.

char RXVal;
RXVal = throttleDataCharMsg[0];

instead of

char RXVal[1];
  strncpy (RXVal, throttleDataCharMsg, 1);

Thanks so much for the guidance.

This depth/level of programming for my novice skill is brain boggling and I really appreciate the clear guidance. This issue had me running around in circles, as when I checked my debug print statements I could see the matching values :)

Hi mates, I’m new and I’d like to know how do you send variables (of numbers) throught 433MHz module ? I have been looking everywhere but they only send text in their tutos. Thanks in advance :slight_smile:

I have been looking everywhere but they only send text in their tutos.

So? Convert your "variables (of numbers)" to text. There are several ways to do that - sprintf(), itoa(), dtostrf(), etc.

Actually, virtual wire does NOT send text. It sends arrays of bytes. Guess what? An int is an array of bytes. So is a float.