Can't get VirtualWire to work send correct data.

I'm not entirely sure if this is a hardware problem, or the way I have things set up.

I'm using the Sparkfun a315 transmitter and receiver.

I'm trying to get the receiver to output the hex into serial, which isnt happening.

I uploaded the transmitter example code to my Duem. and the receiver code to my mega.

I can tell that the transmitter is transmitting because when I bridge an LED between the receiver's DATA and ground, it blinks.

My best guess is that there is interference in the whole 6" between transmitter and receiver, because

if (vw_get_message(buf, &buflen))

isn't evaluating TRUE, or else all would (I presume) be working properly.

Can anyone suggest ideas? I've tried everything I can think of.

If this is a software problem, we need to see some code.

If it's a hardware problem, we need to see some schematics, pictures, and links to data sheets.

You have provided neither.

Here's the code I'm running

Transmitter code:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);        // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    //vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2400);       // Bits per sec
}

void loop()
{
    const char *msg = "hello";

    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(200);
}

and receiver code:

// receiver.pde

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);      // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    //vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2400);       // 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
    //vw_get_message(buf, &buflen);
    {
      int i;

        digitalWrite(10, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.
      Serial.print("Got: ");
      
      for (i = 0; i < buflen; i++)
      {
          Serial.print(buf[i], HEX);
          Serial.print("a ");
      }
      Serial.println("");
        digitalWrite(10, false);
    }
}

Here are the TX and RX units I'm using:

I am using these without antennas, but I read that that was fine for short distances.

I have those same units. I got them to transmit and receive, but I wasn't using virtual wire.

If connected to TX and RX, appropriately, you should be able to just do a serial print on the sender and a serial read on the receiver.

In my case, there was a huge amount of noise associated with them, and an antenna was most definitely required, even for short distances.

They were more trouble to set up than the XBees, and are far less reliable.

The virtualwire library attepts to balance the 1's and 0's (ons and offs) to compensate for the primitive AGC on the receivers. It does have a somewhat bizarre way of coding though. You could try slowing it down with the vw_setup() construct....

PaulS, can you show me an example of the simplified code you used? How do you separate the noise from the signal without encoding like VW uses?

Looking at the spec sheet, I assumed the antennas only worked at 2400 and 4800, but apparently not.

All I'm really trying to do is pass a quick byte from arduino to arduino, to move a servo at this point.

What about Xbee makes it easier to use? Does it handle all the encoding discreetly?

Sorry for all the newbie questions, I spent a good 10 hours researching this on my own, some answers just weren't made clear :stuck_out_tongue:

PaulS, can you show me an example of the simplified code you used?

This is the sender code:

/*
  RF Transmitter
  Language: Wiring/Arduino

  This program reads an analog input on pin 0
  and sends the result out as an ASCII-encoded string.
  The TX line of the microcontroller is connected to
  an RF transmitter that is capable of reading at 2400 bps.
*/

void setup()
{
  // open the serial port at 2400 bps:
  Serial.begin(2400);
}

void loop()
{
  // read the analog input:
  int analogValue = analogRead(0);
  // send the value out via the transmitter:
  Serial.println(analogValue, DEC);
  // delay 10ms to allow the analog-to-digital receiver to settle:
  delay(100);
}

The receiver code was equally simple. It simply used Serial.read to read the data.

How do you separate the noise from the signal without encoding like VW uses?

Encoding doesn't help with noise. The noise comes from other components near the sending and receiving antennas.

Looking at the spec sheet, I assumed the antennas only worked at 2400 and 4800, but apparently not.

The RF modules only work up to 2400 baud. Regardless of the speed that the sender is trying to send data, the radio itself is designed to have an antenna - on both the transmitter and receiver. A simple coil of wire of the correct length works.

What about Xbee makes it easier to use? Does it handle all the encoding discreetly?

The XBee operates at much higher frequency, and is not as affected by noise. They are bi-directional, so if the receiver fails to receive data correctly, it can ask the sender to send it again. The XBee wraps the data you want to send with some additional data - the number of characters and a checksum, so that the receiver can tell that it received a complete packet, and that the packet was received correctly.

Sorry for all the newbie questions, I spent a good 10 hours researching this on my own, some answers just weren't made clear

No problem. At least you are trying to learn, and make use of the answers you are getting.

Ok so I measured out the antennas, coiled them up, and implemented them on the transmitter and receiver.

Here is the code I'm running on the transmitter now:

void setup(){
Serial.begin(2400);
}

void loop(){
int sendValue = 9;
Serial.println(sendValue, DEC);
delay(100);
}

And my receiver:

void setup()
{
  //open the serial port at 2400 bps:
  Serial.begin(2400);
}

void loop()
{
  if (Serial.available() > 0) {
  int received = Serial.read();
  Serial.println(received,DEC);
  }
  
}

When I monitor the serial of the transmitter, it correctly spams
9
9
9
ten times a second.

When I read the receiver I get random values between 0 and 255,
with a steady pattern of 6 0's and one non-zero number.

I understand the 0s are because of the delay in the transmitter program, but what of these random values?

Thanks again for all your help guys. Figuring this out is my goal for this weekend lol ;D

I changed the receiver's Serial.print() to type BYTE and I'm starting to see quite a few 9's in the serial monitor.

The problem now is how many I'm getting that aren't 9.

Here's a cut and paste:

9
H

9


À

á



ü



~
9
H
ø
9



9
á
j

Just noise? Timing mismatch? Either way, how can I possibly filter my message out of that?

Well I found a sample for VirtualWire that works 100% perfectly. Thanks for all your help guys, I appreciate it muchly!

For any other newbies who find themselves in this predicament, here's the code to run.

Receiver:

#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder

void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(23);           // We will be receiving on pin 23 (Mega) ie the RX pin from the module connects to this pin.
    vw_rx_start();                      // Start the receiver
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
    int i;
     // Message with a good checksum received.
        
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }
}

And transmitter:

#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder

void setup()
{
     // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for RF Link module
    vw_setup(2000);                 // Bits per sec
    vw_set_tx_pin(12);                // pin 3 is used as the transmit data out into the TX Link module, change this to suit your needs.
}

void loop()
{
    const char *msg = "Hello, World of wireless!";       // this is your message to send

   vw_send((uint8_t *)msg, strlen(msg));
   vw_wait_tx();                                          // Wait for message to finish
   delay(200);
}

Only other problem I had is getting VirtualWire to work with Servo.h. It seems both of them call "SIGNAL(TIMER1_COMPA_vect)" which causes a compilation error. I made a duplicate of Servo and just commented out the offending line, didn't seem to make a difference, although I'd really like to know how to resolve that problem.

You'll find, having done that, that your servos may now not behave properly. The servo software relies on the timer interrupt (that you no longer allow to be called) to send a signal to the servo often enough for the servo to hold still.

There is a servo2 library that does not use the timer interrupt, but it limits servos to specific pins.