Master and slave RF communication

I have two arduinos,one is the master that i input numbers over serial and send to the slave(other arduino).The slave send to the master a sequence.
This is my testing code:
Master:

#include <VirtualWire.h>
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
char buf1[1];
int i;
void setup() {
  attachInterrupt(0,receive_RF,CHANGE);
  Serial.begin(9600);
  vw_set_tx_pin(4);
  vw_set_rx_pin(2);   
  vw_setup(2000);
  vw_rx_start(); 
}

void loop() {

  while (Serial.available() > 0) {
    long int x = Serial.parseInt();
    Serial.println(x);
      for(i=0;i>=0;i--){ 
        buf1[i]= x % 10;
        x /= 10;
      }
      vw_send((uint8_t *)buf1,1);
    }
  }    

void receiver_RF()
{
if(vw_get_message(buf, &buflen)) 
  {
    int n1=int(buf[0]);//debug
    int n2=int(buf[1]);
    Serial.println(n1);
    Serial.println(n2);
   }
}

Slave:

#include <VirtualWire.h>
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
char buf1[1];
int i;
void setup() {
  Serial.begin(9600);
  vw_set_tx_pin(4);
  vw_set_rx_pin(2);   
  vw_setup(2000);
  vw_rx_start(); 
}

void loop() {
 if(vw_get_message(buf, &buflen)) 
  {
   if(buf[0]==1){
     buf1[0]=1;
     buf1[1]=1;
     vw_send((uint8_t *)buf1,2);
    }
     if(buf[0]==2){
     buf1[0]=2;
     buf1[1]=2;
     vw_send((uint8_t *)buf1,2);
    }
}    
}

Like this I lose data sometimes and i dont know who.Any help?

vasr:   while (Serial.available() > 0) {     long int x = Serial.parseInt();     Serial.println(x);       for(i=0;i>=0;i--){         buf1[i]= x % 10;         x /= 10;       }       vw_send((uint8_t *)buf1,1);     }

What is this for loop supposed to do?

You need to add error checking (at least).

Here is what I do in my current project, which uses Bluetooth serial com between arduino and my PC:

For every message to be sent, I add a “checksum” of this message, a number that is the sum of all characters + the lenght of the message

void serialWrite( HardwareSerial serialport, const char* text )
{
  static char output[512];
  size_t len = strlen( text );
  uint16_t sum = len;
  for ( size_t i = 0; i < len; i++ )
    sum += (byte)text[i];
    
  sprintf( output, "%c%u<%s>%c", 0x02, sum, text, 0x03 );
  serialport.print( output );
}

So the final message looks like “201”. 201 because ‘A’ = 65, ‘B’ = 66, ‘C’ = 67, A+B+C+3 = 201, char 0x02 indicates start of message, char 0x03 indicates end of message.

When a message is received on my PC, I use regular expression to parse this message, making sure it’s valid (starting with 0x02, ending with 0x03, and checksum valid). I don’t post code because it’s C# code for my PC program. You can do it without regular expressions, however there is a regexp library by Nick Gammon, I haven’t tried it yet, here is a link to read: Gammon Forum : Programming : General : Lua regular expression library that does not need Lua

So… that was my simple method of error checking. Handling invalid messages is a part that I won’t discuss because I haven’t found a good solution yet… It becomes complex, needs queueing etc…

PeterH:This loop its when i put the input numbers to the character array.Someting wrong? guix:You send 0x02 indicates start of message and char 0x03 indicates end of message,the sum and the text you want to send. when you receive this you know the start message and the end but who you valid de checksum?

Other question,who sometimes i lose data?I have to send one more time data to be received.

Thank you for the replys.

To check for a valid checksum, just recalculate the checksum the same way I used in the previous code.

You first need to extract from the received message, the checksum and the characters between < and >. Exemple:

Arduino 1 send message “ABC” to Arduino 2, the valid message is “201” ( + start and end characters )
Arduino 2 receive this message, check for start and end characters, extract 201 and “ABC”, calculate checksum of “ABC” (the same calculation that was done by Arduino 1), check if the checksum calculated equals the checksum received, if yes, message is valid.

Thank you guix for the example, know i understand. Do you know why iam losing data?Sometimes i have to send one more time.Synchronism problem between the arduinos? The slave arduino send data when receive from master a number,maybe this is the problem.

Anyone help me why i lose sometimes data?1 of 3 sendings i lose data.I try to change de code and the same thing.Its the code that make the poblem? I use the 434Mhz receiver and transmitter. Receiver datasheet: http://inmotion.pt/documentation/sparkfun/WRL-08950/MO-RX3400.pdf Transmitter datasheet: http://inmotion.pt/documentation/sparkfun/WRL-08946/MO-SAWR.pdf I connect the receiver and tansmitter to a breadboard like the datasheet without the capacitor.I have to put a capacitor?What value? The master(one arduino) and slave are connect to differents computers,and a use the Vcc and the GND of arduinos to source the circuits.

Thank you for the help.

Any help?

Have you taken account of the advice already given? If so and you have modified your code what does it look like now? If not, why was the advice inappropriate?

What tests have you carried out to try to understand the cause of the data loss?

...R

I put the higher voltage on the transmitter to improve signal strength of transmitter. I remove the transmitter/receiver and connect directly with wires. And finally,I change the code.Sending information by the master and see if its received by the slave(without re-send to the master).

I send a sequence of numbers 1 to 10, i receive this:
2 3 5 6 7 9 10 1 2 4 5 7 9 10 2 3 4 5 6 7 8 10 1 2 3 4 5 7 8 9 10

Receive code:

#include <VirtualWire.h>
 
int RF_RX_PIN = 2;
 
void setup()
{
  Serial.begin(9600);
  Serial.println("setup");
  vw_set_rx_pin(RF_RX_PIN);  // Setup receive pin.
  vw_setup(2000); // Transmission speed in bits per second.
  vw_rx_start(); // Start the PLL receiver.
}
 
void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if(vw_get_message(buf, &buflen)) // non-blocking I/O
  {
    int n1=int(buf[0]);
    Serial.println(n1);
  }
}

Transmitter code:

#include <VirtualWire.h>
int i=0;
char msg[1];
int RF_TX_PIN = 2;
 
void setup()
{
  vw_set_tx_pin(RF_TX_PIN); // Setup transmit pin
  vw_setup(2000); // Transmission speed in bits per second.
}
 
void loop()
{
  msg[0]=i;
  i++;
  vw_send((uint8_t *)msg, strlen(msg));  // Send 'hello' every 400ms.
  delay(400);
  if(i==11){
    i=0;
  }
}

I try to power source the transmitter with a external power suply and it stop working.I put the arduino power and it work again.Why?