Hi all,
I'm trying to make 2 arduinos communicate through 433MHz RF. The idea is to make the 1st one an "RF card" plugged in a PC (USB) to send data to the distant arduino. And to make the overall goal clearer I use both arduinos to send infra red signals to 2 air conditionners, one being in my living room, the other in the bedroom. I use a "full duplex" communication as I want to send orders as well as to receive an acknoledgement (RF is not that reliable) and sensors information (temperature).
My problem is that at some point the message received becomes incorrect, only 1, 2 or 4 bytes (depending on the test) are received instead of 9, and from this point on the communication never comes back to normal unless I reset the arduinos (and the final "distant" device is actually the microcontroler only, not the full arduino, no reset button has been added, I need it to be reliable).
Starting from the examples transmitter and receiver with a Seeduino (<=> Arduino duemilanove) and an arduino Uno, I launch the following codes :
Transmitter:
#include <VirtualWire.h>
const int LEDPin = 13;
uint8_t message[] = {0x09, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
void setup()
{
Serial.begin(9600);
pinMode(LEDPin,OUTPUT);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
sendRadioMessage();
Serial.println();
delay(250);
}
void sendRadioMessage(){
boolean timeoutOK;
vw_send((uint8_t *)message, message[0]);
vw_wait_tx(); // Wait until the whole message is gone
}
Receiver:
#include <VirtualWire.h>
const int LEDPin = 5;
void setup()
{
Serial.begin(9600); // Debugging only
Serial.println("setup");
pinMode(LEDPin, OUTPUT);
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
flashLED (buf[0] == buflen);
Serial.print("messageSize= ");
Serial.println(buf[0]);
for (int i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
void flashLED(boolean messageOK){
if (messageOK){
digitalWrite(LEDPin, HIGH);
delay(10);
digitalWrite(LEDPin, LOW);
}
else{
for(int i = 0 ; i < 10 ; i++){
digitalWrite(LEDPin, HIGH);
delay(30);
digitalWrite(LEDPin, LOW);
delay(30);
}
}
}
The first byte of the buffer sent indicates the message length.
This test is OK, it prints (on the receiver side) for hours:
[...]
messageSize= 9
9 DE AD BE EF DE AD BE EF
messageSize= 9
9 DE AD BE EF DE AD BE EF
[...]
I then modify the code to include a response. The receiver sends back the message to the emitter.
Emitter:
#include <VirtualWire.h>
const int LEDPin = 13;
uint8_t message[] = {0x09,0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
long timeoutMs = 1000;
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
void setup()
{
Serial.begin(9600);
pinMode(LEDPin,OUTPUT);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
sendRadioMessage();
Serial.println();
delay(250);
}
void sendRadioMessage(){
boolean timeoutOK;
vw_send((uint8_t *)message, message[0]);
vw_wait_tx(); // Wait until the whole message is gone
long timerStart = millis();
timeoutOK = true;
while (!vw_get_message(buf, &buflen) && timeoutOK){
timeoutOK = (millis() - timerStart < timeoutMs);
}
boolean messageOK = true;
if (!timeoutOK){
Serial.print("No Ack!");
messageOK = false;
}
else{
//Serial.print(" => ");
for (int i = 0 ; i < buflen ; i++){
Serial.print(buf[i],HEX);
Serial.print(" ");
if (buf[i] != message[i]){
messageOK = false;
}
}
Serial.println();
}
flashLED(messageOK);
}
void flashLED(boolean messageOK){
if (messageOK){
digitalWrite(LEDPin, HIGH);
delay(30);
digitalWrite(LEDPin, LOW);
}
else{
for(int i = 0 ; i < 10 ; i++){
digitalWrite(LEDPin, HIGH);
delay(30);
digitalWrite(LEDPin, LOW);
delay(30);
}
}
}
Receiver: only add a response at the end of the loop
[...]
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
flashLED (buf[0] == buflen);
Serial.print("messageSize= ");
Serial.println(buf[0]);
for (int i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println("");
vw_send((uint8_t *)buf, buflen);
vw_wait_tx(); // Wait until the whole message is gone
}
}
[...]
The first thing that annoys me is that if I don't connect the Serial monitor to the emitter it doesn't receive the response 1 time out of 3... I suppose it's a delay problem but I am unable to determine where it lies. Anyway the use case in my project is to communicate with it through the Serial interface so it should work. When connected I really seldom have a timeout.
This works for some time then the message received back from the initial emitter is only 2 bytes.
I read the Serial.prints from the emitter but the receiver still flashes the LED one time if the message is ok (at least if buf[0] == message length) so I can see if the problem comes from the initial message or the response.
Output (after a few dozains of minutes):
[...]
9 DE AD BE EF DE AD BE EF
9 DE AD BE EF DE AD BE EF
9 DE AD BE EF DE AD BE EF
9 DE AD BE EF DE AD BE EF
No Ack!
9
9
9
9
9
I don't know why at a time the problem occurs, but it never comes back to a normal operation. This problem seems to be on the emitter's side (the receiver flashes normally, and a reset of the emitter makes the behaviour normal again).
My initial project had a similar problem but on the receiver side, which made the distant arduino useless once the problem occured (which was almost immediate). I was trying to target the problem starting from a simple sketch but I wasn't expecting the problem to occur on a code that simple.
Does someone know where it comes from ? Is the problem in my code or in the library ? By the way I use $Id: VirtualWire.h,v 1.6 2013/02/14 22:02:11
Thanks in advance (and sorry for the message length ).