Arduino Duemilanove and VirtualWire

Hi all,

I had this posted in the hardware>interfacing section, but I think it is more of a software issue…

I came across this Hobby Robotics » Cheap Arduino Wireless Communications and thought that it was an awesome idea.
I have been looking at this more however as he uses VirtualWire:
http://www.benjohansen.com/archives/642

I plan to use the VirtualWire library www.open.com.au/mikem/arduino/VirtualWire.pdf.
And these transmitters and receivers:

I am having trouble understanding the example that comes with the library for both transmitter and receiver.
I wish to read a value from an analog input and then send it to the receiver where it will be used for a PWM output.

My transmitter code looks something like this:

#include <VirtualWire.h>

int POTPIN = 0;
int POTVAL = 0;
byte PWMVAL = 0;
// int PWMOUT = 3;

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(2000); // Bits per sec
}

void loop()
{
const char *msg;
POTVAL = analogRead(POTPIN); // read value from potentiometer
PWMVAL = map(POTVAL, 0, 1023, 0, 255); // map the value so that it can be used for PWM signal
msg = “PWMVAL”;
Serial.println(msg);
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait until the whole message is gone

delay(100);
}

One of my problems is that I do not want to send characters and instead just one byte of the value from mapped analog value.
I am unsure of how to adapt the code for my project Sad

If anyone has any advice I would greatly appreciate it.

Thanks in advance.

Without knowing anything about the virtual wire library. If the message doesn't have to be null terminated, this might work?

void loop()
{  
  const size_t POTVAL = analogRead(POTPIN); // read value from potentiometer
  const uint8_t PWMVAL = map(POTVAL, 0, 1023, 0, 255); // map the value so that it can be used for PWM signal
  Serial.println(PWMVAL, INT);
  vw_send(&PWMVAL, 1);
  vw_wait_tx(); // Wait until the whole message is gone

  delay(100);
}

Using your section of code, it complains here “vw_send(&PWMVAL, 1);” with this message “error invalid conversion from ‘const unint8_t*’ to ‘uint8_t*’”
If I remove the ‘const’ infront of the const uint8_t PWMVAL… then it complies fine.
I don’t actually have the modules yet to test but am working on the program so long.
I do however have the potentiometer hooked up.
If I open the serial port monitor I am seeing what appears to be ascii, if I vary the potentiometer fairly quickly I get something like this (ûóúãj
kÚãj
kkjkÚâþJÿJÿjÿJÿKÿkÿKÿj*k)

I am posting the example code from the library files as well. Hopefully it might clear up what I am trying to change.

Transmitter code:

// transmitter.pde
//
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

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

Receiver Code:

// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#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(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
{
int i;

digitalWrite(13, 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*, HEX);*

  • Serial.print(" ");*
  • }*
  • Serial.println("");*
  • digitalWrite(13, false);*
  • }*
    }
    So obviously instead of the message ‘hello’ I wish to send my analog data

I have that RF pair and here is a snippet from my sketch that I know works: char *msg = "012"; msg[0] = x; msg[1] = y; msg[2] = dir; vw_send( (uint8_t *)msg, strlen(msg));

As you can see I am sending three characters, to send just one you can modify it like this: char *msg = "0"; msg[0] = PWMVAL; vw_send( (uint8_t *)msg, strlen(msg));

As far as the garbage characters, make sure that the baud rate selected at the bottom right of the Serial Monitor window matches the one you specify in Serial.begin(9600);

Thanks for the reply.
Is there anyway to show the decimal value in the serialport monitor instead of the ascii.
I put your piece of code in so it looks like this:

char *msg = "0";
  POTVAL = analogRead(POTPIN); // read value from potentiometer
  PWMVAL = map(POTVAL, 0, 1023, 0, 255); // map the value so that it can be used for PWM signal
  msg[0] = PWMVAL;
  test = msg[0];
  Serial.println(test,DEC);
  vw_send((uint8_t *)msg, strlen(msg));
  vw_wait_tx(); // Wait until the whole message is gone

  delay(500);

This seems to work and what I see in the serialport monitor when varying the potentiometer from one end to the other is a decimal number between 0-255.

I only included the ‘test’ variable to make sure that the correct value is being sent.

When I leave the serial print as; Serial.println(msg) then I get a majority or the ascii characters changing in the correct order.
I don’t think the monitor can display all the characters as a couple of squares and blank lines show up.

Now for the receiver side of things I was thinking of something like this:

#include <VirtualWire.h>

byte PWMVAL = 0;
int PWMOUT = 3;

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(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
    {
       PWMVAL = buf[0];
         analogWrite(PWMOUT,PWMVAL);
  
        
    }
}

I am not so sure if this line PWMVAL = buf[0]; is going to work.
It compiles with no errors.

Any ideas? It may work or may not work :-/

Yes, that should work fine. Let me know if you run into other issues.

Ok, if I have any other issues I will be sure to post them.

I am still waiting on the components so when I get them I will let you know how it works when they arrive.

Thanks a million for the help! I would still be stuck if it weren’t for the helpful people here.