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.
-
Você declarou
vw_set_rx_pin(2);
e tambem atachou uma interrupção por mudança no mesmo pino...
attachInterrupt(0,receive_RF,CHANGE); -
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...
- 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...