Comunicação RF

Boa noite,
Estou a trabalhar com dois arduinos uno ambos com um recetor e transmissor 434Mhz.
Utilizo a biblioteca virtualwire.h.
Por vezes não recebo a informação que é transmitida e os modulos estão a uma distancia reduzida.
Alguma ideia do que pode estar a causar este problema?

Muitas coisas podem estar a acontecer.Mostra as ligações e o código

O meu recetor é este:
http://www.inmotion.pt/store/rf-link-4800bps-receiver-434mhz
Transmissor:
http://www.inmotion.pt/store/rf-link-transmitter-434mhz
As ligações:
Os recetores e transmissores estao ligados a uma breadborad separadamente(um recetor e transmissor numa breadboard e outro par em outra)como esta no esquema do datasheet e alimentação é feita pelo arduino uno(Vcc e ground).
Estou a testar comunicação bidirecional.
Código transmissor:

#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]);
    int n2=int(buf[1]);
    Serial.println(n1);
    Serial.println(n2);
   }
}

Código recetor:

#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);
    }
}    
}

qual é o funcionamneto do código? o que espera dele?
sendo os dois pares na frequencia 433, certamente haverá o momento que ambos transmitem e niguem escuta...
tem que analisar que se ambos estao já com antena, eles não funcionam bem a curta distancia(1m).
porque está economizando o buf1 aumenta um pouco ele.

O arduino master é o que esta a receber inputs pela porta serie e envia.O slave é o que recebe a informação e envia de acordo com que é esperado.
Funcionamento esperado é um seguinte:
Envio 1 ou 2 pela porta serie(arduino master).Essa informação é recebida pelo slave e conforme seja 1 ou 2 envia o buffer que é recebida pelo master.
O master e slave(arduinos) estão a uma distancia de mais ou menos um metro.
Funcionamento atual:
Envia 1 ou 2 e nem sempre é recebido pelo slave,quando é recebido(slave) envia mas a informação nem sempre é recebida pelo master.
Penso que não existe o caso de ambos transmitirem e ninguem escuta pois só quando recebe a informação é que a envia mas opininem caso esteja enganado!

Você tem dois problemas aí: o primeiro é a alocação de memória (buf1[1], e você utiliza duas posições).

O segundo é sincronismo. Você esta fazendo muita coisa ao mesmo, o master só envia comando depois que recebe resposta do slave, a cada byte lido ele já envia logo uma mensagem... isso não está legal.

A comunicação master - slave deve ser algo dessa forma:

Master:

Envia solicitação / questionamento

Aguarda para receber respostas

Slave:

Executa seu código normal, até receber solicitação / questionamento

Envia resposta

eu apenas comentei seu codigo, não fiz modificações mas dá pra ter uma idéia dos problemas...

#include <VirtualWire.h>
uint8_t buf[VW_MAX_MESSAGE_LEN]; 
uint8_t buflen = VW_MAX_MESSAGE_LEN; 
char buf1[1]; buffer muito pequeno
int i;
void setup() {
  attachInterrupt(0,receive_RF,CHANGE); // a vw ja se liga automaticamente a este pino pode dar conflito
  Serial.begin(9600);
  vw_set_tx_pin(4);
  vw_set_rx_pin(2);   
  vw_setup(2000); //em testes sempre use baud menor, abaixe para 1000 ou 500...// uma dica para diminuir uma assossiação de problemas, você "conserta" um mas outro não deixa funcionar, como saber que você fez certo no primeiro, retire os modulos rf e interligue tx rx de ambos com fio e tambem os GND, faça o código funcionar redondo, ai sim acrescente o rf que sempre dá problema... 
  vw_rx_start(); 
}

void loop() {

  while (Serial.available() > 0) { // o arduino é muito rapido recebido apenas 1 byte e ja fará o que tem aqui dentro e na proxima interação não verá mais bytes
    long int x = Serial.parseInt(); // aqui  
    Serial.println(x); 
      for(i=0;i>=0;i--){    // converte para array base 10 de novo mas no modo LSB 
        buf1[i]= x % 10; // se você colocar tres digitos aqui ele vai dar buffer overflow na array e sobrescrever outras informações na memoria RAM
        x /= 10;
      }
      vw_send((uint8_t *)buf1,1); você limpou a array antes de colocar novamente dados dentro dela?
    }
  }    

void receiver_RF() acabe com essa função e jogue o conteudo dela no final do loop fazendo polling como no outro sketch...
{
if(vw_get_message(buf, &buflen)) 
  {
    int n1=int(buf[0]);// esta muito economico no debug dos dados seja mais explicativo.
    int n2=int(buf[1]);
    Serial.println(n1);
    Serial.println(n2);
   }
}

Em resposta ao LegendBR:
Não podes dar um exemplo?Poderá estar acontecer um problema de sincronismo e pode ser a causa do meu problema mas não sei como fazer a sincronização devida.
Em resposta ao fabiohbm007:
Podes-me explicar os seguintes comentários?
1-// a vw ja se liga automaticamente a este pino pode dar conflito.Terei que ligar a outro?
2-// o arduino é muito rapido recebido apenas 1 byte e ja fará o que tem aqui dentro e na proxima interação não verá mais bytes
3-//// converte para array base 10 de novo mas no modo LSB .
4-//você limpou a array antes de colocar novamente dados dentro dela?-Terei de limpar o array sempre?Com zeros?

Obrigado pela ajuda e respostas.

  1. Você declarou
    vw_set_rx_pin(2);
    e tambem atachou uma interrupção por mudança no mesmo pino...
    attachInterrupt(0,receive_RF,CHANGE);

  2. Se você mandar 10 pelo serial monitor, primeiro chega o 1, o 0 chegará após 11 bauds de 9600 por segundo, que dá 1.15 ms, que são 18400 clocks do arduino... ele entra no while verifica,acrscenta, e chaga ao fim do while, volta a verificar o serial available e sai do while porque não encontra mais nada

3.O parseint converte de array decimal para numero binario de 16bits, que você converter de novo em array usando o modulo e a divisão...

  1. Se por um milagre aquele while processasse 2 char, e transforma-se em dois digitos a serem transmitidos, no proximo uso da array que tiver um só um ficará a variavel preenchida com aquele valor porque você não limpou, zerou.

Para usar a rotina de interrupção tive que utilizar o INT0 que corresponde ao pino 2.A biblioteca liga ao pino 2 por default?
No ponto 3, que sugeres?Faço um Serial.read?
Posso estar a ter um problema de sincronismo como disse o usuario LegendBR?Estou a perder informação com a comunicação bidirecional descrita no código.

Obrigado pelas respostas.
Alguém me pode ajudar nas dúvidas que descrevi no tópico anterior e no problema de sincronismo?

Alguém?

fiz alguns testes, funciona com fio, teste com os modulos:
master:

#include <VirtualWire.h>
char buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
uint8_t enviar=0;
uint8_t i=0;
const int transmitter = 13;
const int receiver = 8;

void setup() {
  Serial.begin(9600);
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_set_tx_pin(13);
  vw_set_rx_pin(2);   
  vw_setup(2000);
  vw_rx_start(); 
}

void loop() {
  if (Serial.available()&&!enviar){
    byte temp=Serial.read();
      if (temp=='\n'){
        buf[i]='\0';
        enviar=1;
      }
    else{
    if((i<80)&&(temp!='\r')){
        buf[i++]=temp;
    }
    }
  }


  if (enviar){
    vw_send((uint8_t *)buf,i);
    Serial.print("Mensagem enviada com "); 
    Serial.print(i);
    Serial.print(" bytes [");
    Serial.print(buf);
    Serial.println("]");
    vw_wait_tx();
    //vw_rx_start();
    if (vw_wait_rx_max(1000))
      for (byte z=0;z<80;z++){buf[z]=0;}
      vw_get_message((uint8_t *)buf,&buflen);
        if (buf[0]=='o' && buf[1]=='k'){
          i=0;
          enviar=0;
//          Serial.print(buflen);
          Serial.print("Mensagem recebida com ");
          Serial.print(buflen);
          Serial.print(" bytes [");
          Serial.print(buf);
          Serial.println("]");
        }
  }

}

slave:

#include <VirtualWire.h>

char buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int i;
void setup() {
  Serial.begin(9600);
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_set_tx_pin(13);
  vw_set_rx_pin(2);   
  vw_setup(2000);
  vw_rx_start(); 
}

void loop() {
 if(vw_have_message()) 
  {
	vw_get_message((uint8_t *)buf,&buflen);
	char resposta []= "ok-obrigado";	
	vw_rx_stop();
	vw_send((uint8_t *)resposta,11);
	Serial.print("Mensagem enviada [");
	Serial.print(buf);
	Serial.println("]");
	vw_wait_tx();
	vw_rx_start();

				
}
}

Obrigado pela ajuda.Podias-me explicar o funcionamento?

o master fica escutando pela serial, você digita qualquer coisa, assim que detectar o fim de linha que no caso é \n ele
envia e espera a confirmação que no caso testa se ok, se não escutar nada em 1000 ms repete o processo até dar certo...