Go Down

Topic: Comunicação RF (Read 2505 times) previous topic - next topic

vasr

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?

HugoPT

Muitas coisas podem estar a acontecer.Mostra as ligações e o código 
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

vasr

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:
Code: [Select]
#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:
Code: [Select]
#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);
    }
}   
}


fabio_h

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.

vasr

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!

LegendBR

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:

Code: [Select]

Envia solicitação / questionamento

Aguarda para receber respostas


Slave:

Code: [Select]

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

Envia resposta

fabio_h

eu apenas comentei seu codigo, não fiz modificações mas dá pra ter uma idéia dos problemas...
Code: [Select]
#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);
   }
}

vasr

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.

fabio_h

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...

4. 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.

vasr

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.

vasr

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


fabio_h

fiz alguns testes, funciona com fio, teste com os modulos:
master:
Code: [Select]

#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:
Code: [Select]

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


}
}



vasr

Obrigado pela ajuda.Podias-me explicar o funcionamento?

fabio_h

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...

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy