virtualwire control with words

hi all,

I am new to arduino and wanted to build my first project a arduino controlling a relai (on pin 11) with a 433mhz wirless signal.
first i have made this program but it only works with one caracter (i need more for secuitity / so that i not control it with a other arduino by accident)

here the code:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    
    vw_setup(2000);	 // Bits per sec
    vw_set_rx_pin(9);
    vw_rx_start();       // Start the receiver PLL running
    

pinMode(11, OUTPUT);
}

void loop()
{
  

  digitalWrite(11, LOW);
  
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
	int i;

        digitalWrite(13, true); // Flash a light to show received good message
	// Message with a good checksum received, dump it.
	Serial.print("Got: ");
	
	for (i = 0; i < buflen; i++)
	{
	    Serial.print(buf[i]);
      
        if(buf[i] == '~'){digitalWrite(11, HIGH);}
        delay(220);
	}
	Serial.println("");
        digitalWrite(13, false);
    }
}

and for the transmitter:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	  // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    
    vw_setup(2000);	 // Bits per sec
    vw_set_tx_pin(2); 

        pinMode(11, INPUT);
       

digitalWrite(11, HIGH);
        
}

void loop()
{
    char *msg;
   
 digitalWrite(6, HIGH); 

     delay(20);
  
  if(digitalRead(11) == LOW){
    char *msg = "~";
      digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
     
     delay(20);
  digitalWrite(13, false);}
 

}

I have found a program om this topic post: RF link transmitter and Receiver pair - Programming Questions - Arduino Forum that works (can read the signal over serial) and have modified it, but i can't control the relai on pin 11 with it...

Here the code:

transmitter

#include <VirtualWire.h>  // include virtualwire libary

void setup()
{
    Serial.begin(9600);	  // Debugging only
    Serial.println("setup"); // print setup op serial
  
  
  pinMode(13, OUTPUT);

  vw_set_ptt_inverted(true);  
  vw_setup(2000);            // Bits per sec
  vw_set_tx_pin(2);          //Tx pin (zend)


        pinMode(11, INPUT);  // pin 11 is input
        
digitalWrite(11, HIGH); // zet pin 11 hoog.
}


void loop()
{
  
  delay(100);               //Send a message every half second

 if(digitalRead(11) == LOW){  
  char *msg = "875987";
  digitalWrite(13, HIGH ); // Flash a light to show transmitting
  vw_send((byte *)msg, strlen(msg));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(13, LOW);
  
 }

}

and receiper;

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    for (i = 0; i < buflen; i++)
    {
      buf[i] = buf[i] -48;
    }
    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
    
    

      
      if(buf[i] == '875987'){digitalWrite(11, HIGH);}
        delay(400);    
     
     delay(10);
    digitalWrite(13, LOW);   
    
  }
 
}

Could you guys have a look at it and find the problem, i could find it in the forum (looked for ohr's :~ ).

[sorry for my bad english]

Thanks!

lordp

if(buf[i] == '875987')

A single character can never be the same as six characters.
Either convert it to a decimal number or a string.

At the point that you test buf[ i ], i points to the first character beyond the end of the array. Really not a good idea.

sorry for my question but how should i grep the receiped caracters and than compare it in a string?

must it be done with: http://arduino.cc/en/Tutorial/StringComparisonOperators ??

or how schould i use a if-statement in this case?

if(buf == '875987')[/quote]
If you want to get this number back, you would need to store it in an array. Then once you have all 6 + Null terminator(Can't remember if null is needed or not anymore), you can do this,
if(buf[ i ] == my_data) // make sure buf[ i ] starts at 0
_{/
do something */}_

how should i make buf start with 0, i dont understand how to do this.
i dont understand the array concept, but i found this http://arduino.cc/en/Tutorial/StringComparisonOperators and that i understand.
so my quetions is how can i grep the send data and set it into a string so that i can compare it?
or would anyone be so kind to give me a working code so that i can figure it out on my one ( with some help from google :wink: ).

so my quetions is how can i grep the send data and set it into a string so that i can compare it?

A string, if you had read that information properly, is a NULL terminated array of chars. The virtual wire library populates the char array for you, and gives you the length. All you need to do is NULL terminate the array, which is easy knowing the number of chars in the array. Then, strcmp() will do the comparison.

Use a for loop.
for(int i = 0; i < 7; i++)
{
if(buf[ i ] != *my_Data)
{
// no good
boolean passGood = false;
}
} // out if for loop

// good
passGood = true;

It's hard to do this on my phone

It's hard to do this on my phone

Especially as you never change the my_Data pointer, and it is not defined anywhere.

thanks for the information, HazardsMind.

i have changed the code like this

// ontvanger versie 3

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    for (i = 0; i < buflen; i++)
    {
      buf[i] = buf[i] -48;
    }
    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
    
    

    for(int i = 0; i < 7; i++)
{
 if(buf[ i ] == 53482)
   {
 digitalWrite(11, HIGH);
    }
} // out if for loop

      

        delay(220);    
     
     delay(10);
    digitalWrite(13, LOW);   
    
  }
 
}

but still it wont work, i understand that a string is a array with a null terminated but dont get how i should get that array and test it so i can controll pins with it.(am a beginner in programming so everthing is new for me).

i didnt understand the 'pointer' so i changed it to a value, is that the problem that it didnt works??? and how should i make a pointer (dont understand the infomation on arduino platground).

but dont get how i should get that array

This does that:

  if (vw_get_message(buf, &buflen)) // Non-blocking

and test it so i can controll pins with it.(am a beginner in programming so everthing is new for me).

NULL terminate the array:

buf[buflen] = '\0';

Then, do the compare:

if(strcmp(buf, "53482") == 0)
{
   // They match...
}

90% of what you are doing is useless.

thanks for the information, understand it al little bit more i think.... :cold_sweat:

here is the code with your changes:

// ontvanger versie 3

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    for (i = 0; i < buflen; i++)
    {
      buf[i] = buf[i] -48;
    }
    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
   
   buf[buflen] = '\0'; // here the array is terminated, if i understand it correctly?
    
    if(strcmp(buf, "53482") == 0)
{
 digitalWrite(11, HIGH);
}
    

        delay(220);    
     
     delay(10);
    digitalWrite(13, LOW);   
    
  }
 
}

only can't compile it because of error 'invalid conversion from BYTE* to 'const char* ' so i need to concert it (am i correct in thinking that the error relates to the "53482" in the if(strcmp(buf, "53482") == 0) ?
how should i solve it? looked on the web but dont understand it... :frowning:

and what is useless about this code that i found?

"53482" => '53482'

that didn't fix it, get the same error...

  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

byte and char are the same size, but one is signed and one is not. When you have a byte array that you know only contains char values, and a function that expects a char array, you can lie to the function, and tell it that the array you have is a char array, using a cast:
if(strcmp((char *)buf,"53482") == 0)

oke i have changed the code to this, but it didnt work:

// ontvanger versie 3

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    for (i = 0; i < buflen; i++)
    {
      buf[i] = buf[i] -48;
    }
    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
   
   buf[buflen] = '\0'; // here the array is terminated, if i understand it correctly?
    

 if(strcmp((char *)buf,"53482") == 0)
{
 digitalWrite(11, HIGH);
}  

        delay(220);    
     
     delay(10);
    digitalWrite(13, LOW);   
    
  }
 
}

but if i understand correctly the char can only hold one character and not the string "53482", wont that be a problem (sorry beforehand if i hav it wrong,i find it quite complicated)?

(does anyone has a fully working code, so that i can fix my code/ learn to understand it...)

kind regards,

lordp

I told you that 90% of what you were doing was not needed. Get rid of:

    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    for (i = 0; i < buflen; i++)
    {
      buf[i] = buf[i] -48;
    }
    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }

After NULL terminating buf, print it, using ONE Serial.print() statement.

Show us the serial output.

If you're comparing it to a string, then you need to lose the "-48" trick.

thank you very mutch thank did the job!!! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

only the code is a little slow, even with delay of 20ms the relai gets high and low in 2sec time!!!

i try to make it a little bit faster...

here the working reciever code, (maybe someone else can used it if he/she gets the same problem).

// ontvanger versie 3

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    

    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
   
   buf[buflen] = '\0'; // here the array is terminated, if i understand it correctly?
    

 if(strcmp((char *)buf,"53482") == 0)
{
 digitalWrite(11, HIGH);
}  

        delay(20);    
     

    digitalWrite(13, LOW);   
    
  }
  
  


 
}

i was looking for a other solution to the problem, and found this thread on the forum: VirtualWire controlling Outputs - #3 by system - Interfacing - Arduino Forum

especialy the if(buf[0] == 'A){ // buf[0] is the first byte received, buf[1] is second, etc is interresting......

i could make a long if statement like: if(buf[0] == '5')&&(buf[1] == '3')(buf[2] == '4') enz. but dont know if this works....

for now thanks for everyone that helped me.

kind regards,

lordp

my fould found the problem, i forgot to set pin 11 low in the end of the loop :roll_eyes:

here the code with the fix:

// ontvanger versie 3

#include <VirtualWire.h>


int i =0;
int msg_received = 0;

void setup()
{

  Serial.begin(9600);
  Serial.println("Started");
  

  vw_setup(2000);	         // Bits per sec
  vw_set_rx_pin(9);              //Rx pin
  vw_rx_start();               

  pinMode(13, OUTPUT);  
  pinMode(11, OUTPUT);

}

void loop()
{


  byte buf[VW_MAX_MESSAGE_LEN];
  byte buflen = VW_MAX_MESSAGE_LEN;

 
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    
    digitalWrite(13, HIGH);
    
    Serial.print('\n');
    Serial.println("Receiving data");
    Serial.print('\n');
    
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    

    Serial.print('\n');
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    
    Serial.print('\n');
    Serial.print("------------------------");
   
   buf[buflen] = '\0'; // here the array is terminated, if i understand it correctly?
    

 if(strcmp((char *)buf,"53482") == 0)
{
 digitalWrite(11, HIGH);
}  

        delay(200);    
     

    digitalWrite(11, LOW);   
          delay(10);
     digitalWrite(13, LOW);    
  }
  
  


 
}