Go Down

Topic: Arduino Duemilanove and VirtualWire (Read 1 time) previous topic - next topic

reflexsa

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 http://www.glacialwanderer.com/hobbyrobotics/?p=291 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:
http://www.sparkfun.com/commerce/product_info.php?products_id=8945
http://www.sparkfun.com/commerce/product_info.php?products_id=8948

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.

ulrichard

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

Code: [Select]

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);
}

reflexsa

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 (ûóúãjkÚã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

hari

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

reflexsa

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:

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

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





hari

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

reflexsa

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.

Go Up