Virtual wire-conversion of analog read values.

Hi all,

I am new to arduino programming.

In my project,I use the virtual wire library.

My need is to transmit the analog read values of A0 and A1 pins to another arduino via the RF.

Can someone suggest me how it can be done.

I tried to convert the analog read value to const char. I got an error,constants must not change,i guess.

I tried Internet to learn more about virtual wire,unfortunately that was too not successful.

Pls help.

Thanks in advance.

Change this part of the message transmit:

{
const char *msg = "hello";
vw_send((uint8_t *)msg, strlen(msg));
delay(400);
}

to this

    msg[0]=key;                               // load the array with your data, as many bytes as you need

    vw_send((uint8_t *)msg, strlen(msg));     // send the character out

    vw_wait_tx();                             // Wait until the whole message is gone

Analog reads are 2 bytes (10 digits),
int analogValue = analogRead(A0); // returns a 16 bit number
which you have to split into 2.
byte lowerByte = (analogValue && 0x0F); // gives you the right hand 8 bits
byte upperByte = (analogValue >>8); // gives the left hand 8 bits
then for the transmit:
msg[0]= lowerByte
msg[1]= upperByte

on the other end, it back together
analogValue = upperByte<<8 + lowerByte;

Dear crossroads,
I coded like this.

Rx

#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()
{
  byte temp[VW_MAX_MESSAGE_LEN];
  byte templen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(temp, &templen)) // Non-blocking
  {
    int i,lowerByte,upperByte,tempread;
    digitalWrite(13, true); // Flash a light to show received good message
    // Message with a good checksum received, dump it.
    temp[0]= lowerByte;
      temp[1]= upperByte;
      tempread= upperByte<<8 + lowerByte;
      Serial.print("Got: ");

    for (i = 0; i < templen; i++)
    {
      Serial.print(temp[i], BYTE);
      Serial.print(" ");
    }
    Serial.println("");
    Serial.println(tempread);
    digitalWrite(13, false);


  }
}

Tx

#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()
{


  char temp[2];
  int tempread=analogRead(A0);
  byte lowerByte = (tempread && 0x0F);  // gives you the right hand 8 bits
  byte upperByte = (tempread);  // gives the left hand 8 bits


  vw_send((uint8_t *)temp, strlen(temp));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(13, false);
  delay(200);
}

It gets compiled perfectly,but never comes in working.
I cant receive anything.

pls help.

Okay, take this out of both:

vw_set_ptt_inverted(true); // Required for DR3100

unless you have a transmitter that actually needs that, most of the simple 433 MHz types don't.

Tx, you have to put the data into the array:

char temp[2];
int tempread=analogRead(A0);
// put the temperature bytes into the array for sending:
temp[0] = (tempread && 0x0F); // gives you the right hand 8 bits
temp[1] = (tempread>> 8 ); // gives the left hand 8 bits

vw_send((uint8_t *)temp, strlen(temp));

  byte lowerByte = (tempread && 0x0F);  // gives you the right hand 8 bits

Well, & would. && does something completely different.

Well, if one & is good, two && must be really good!
Knew I should have checked that before hitting post ...

  vw_send((uint8_t *)temp, strlen(temp));

Ah, no. Try:

  vw_send((uint8_t *)temp, sizeof(temp));

strlen does something completely different, and is wrong in this case.

In any case, for sending you could do:

int tempread=analogRead(A0);
vw_send((byte *) &tempread, sizeof (tempread));

Anyway, all this mucking around with copying bytes hither and thither makes me nervous. How about a union?

I'll illustrate with the Wire library as I don't have the VirtualWire installed:

#include <Wire.h>

// union of int and bytes
typedef union 
{
  int i;
  byte c [2];
} t_int;

void setup ()
{
  Wire.begin ();
}

void loop () 
  {
 // make a union variable
  t_int reading;
  // get the reading
  reading.i = analogRead (0);
  // send it
  Wire.send (reading.c, sizeof reading.c);
  }

The union lets you look at a variable in two ways - one way is an int (for the analogRead) and the other way is two bytes (for sending).

The receiving end would be similar.

Nick,
strlen is what I use in my RF remote control and its been working for 10 months nows.
1 character at a time, that's all I send.

OK, well looking at this code:

char temp[2];
int tempread=analogRead(A0);
// put the temperature bytes into the array for sending:
temp[0] = tempread & 0x0F;  // gives you the low-order bits
temp[1] = tempread >> 8 ;  // gives the high-order bits
vw_send((uint8_t *)temp, strlen(temp));

The low-order byte goes into the first byte of temp, and if the high-order bits are zero you are lucky. It will send one byte. This is because strlen calculates how many bytes there are, until it hits a zero.

But if the reading was, say 0x114 (decimal 276) then you will have to hope that there is a zero beyond temp. If not, strlen (temp) might be 100 or something.

However you really should use sizeof (temp) because you have two bytes you want to send, and sizeof (temp) is 2, regardless of the contents.

Maybe your remote control shield uses different code to the above, that might explain why it works.

Maybe I just got lucky in ignorance then as I only needed to send 1 byte with the remote and it worked.

I am really glad to see you all helping me.

well,I made the following changes to the code.

TX

#include <VirtualWire.h>

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

  vw_setup(2000);	
}

void loop()
{


  char temp[2];
  int tempread=analogRead(A0);
  temp[0] = (tempread & 0x0F);
  temp[1] = (tempread >> 8  ); 
  vw_send((uint8_t *)temp, sizeof(temp));
  vw_wait_tx(); 
  digitalWrite(13, false);
  delay(200);
}

I have avoided the ptt funcion,I am here using the sizeof keyword.I guess the & (bit wise and) is needed here.

RX

#include <VirtualWire.h>

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

  vw_setup(2000);	

  vw_rx_start();      
}

void loop()
{
  byte temp[VW_MAX_MESSAGE_LEN];
  byte templen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(temp, &templen))
  {
    int i,lowerByte,upperByte,tempread;
    digitalWrite(13, true);
    temp[0]= lowerByte;
      temp[1]= upperByte;
      tempread= (upperByte<<8) + lowerByte;
      Serial.print("Got: ");

    for (i = 0; i < templen; i++)
    {
      Serial.print(temp[i], BYTE);
      Serial.print(" ");
    }
    Serial.println("");
    Serial.println(tempread);
    digitalWrite(13, false);


  }
}

Is the codes correct now ?

Moderator edit: [code] [/code] tags added.

You tell us...

  • Do they compile OK?
  • Do they work?

Yes,

well it does gets compiled.

But what I get through the 433 MHz channel is '0'.

I guess there is a problem in conversion of the analog read,but I don't know how to correct it.

pls help.

 byte templen = VW_MAX_MESSAGE_LEN;

if (vw_get_message(temp, &templen))

I am puzzled by this. I don't have the VirtualWire library, and you haven't told me where to find it. But why pass the address of the length?

And just run by me what this is doing ...

if (vw_get_message(temp, &templen))
  {
    int i,lowerByte,upperByte,tempread;
    digitalWrite(13, true);
    temp[0]= lowerByte;
      temp[1]= upperByte;
      tempread= (upperByte<<8) + lowerByte;

I am guessing that vw_get_message reads into "temp". Then you discard temp by replacing both bytes with bytes that are undefined. Then you combine those into tempread.

You've chosen to ignore my advice to use a union.

Closer to what you want is probably:

if (vw_get_message(temp, &templen))
  {
    int i, tempread;
    digitalWrite(13, true);
    tempread = (temp[0] << 8) | temp[1];

Nick,

OK thanks. Looks like the address of the length is OK then. :slight_smile:

Oh, I am sorry.

please see.

http://www.open.com.au/mikem/arduino/

Dear nick,

I am not ignoring the concept of union,but I could not understand the concept.

See,I am getting thing over air now.

but In both ends,the splitting to msb and lsb and the reconstruction are the problem.

I think the problem is with the splitting,which will make everything else error prone.

well, this is where i stand.

TX

#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()
{
  char temp[2];
  int tempread= 101;
    Serial.println("_________________________");
  Serial.println(tempread,BIN);
  Serial.println("................................");
  byte lowerByte = (tempread & 000000001111111);  // gives you the right hand 8 bits
  byte upperByte = (tempread<< 8 );  // gives the left hand 8 bits
delay(1000);
Serial.println(lowerByte,BIN);
Serial.println("L");
delay(1000);
Serial.println(upperByte,BIN);
Serial.println("U");
delay(1000);
temp[0]=lowerByte;
temp[1]=upperByte;
  vw_send((uint8_t *)temp, sizeof(temp));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(13, false);
  delay(200);
}

RX

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);	// Debugging only
  Serial.println("setup");
  // Initialise the IO and ISR
  vw_setup(2000);	 // Bits per sec

  vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
  byte temp[VW_MAX_MESSAGE_LEN];
  byte templen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(temp, &templen)) // Non-blocking
  {
    int i,tempread;
    byte lowerByte,upperByte;
    
    digitalWrite(13, true); // Flash a light to show received good message
    // Message with a good checksum received, dump it.
    for (i = 0; i < templen; i++)
    {
      Serial.println(temp[i],BIN);
    
    }
    Serial.println("");
      Serial.println(VW_MAX_MESSAGE_LEN);
      tempread = (temp[0] << 8 ) | temp[1];
    Serial.println(tempread,BIN);
    digitalWrite(13, false);


  }
}

Please help me.