Go Down

Topic: RF Link Kit problem / Virtual Wire (Read 2436 times) previous topic - next topic

Borb

This is the RF Link Kit in question:
http://www.seeedstudio.com/depot/2km-long-range-rf-link-kits-w-encoder-and-decoder-p-321.html
(2KM Long Range RF link kits w/ encoder and decoder)

------------------

I am building a wireless link to be able to remotely monitor a greenhouse temperature. The temperature will be represented by an analogue voltage derived from a thermistor, say in range 0-3V.

I am using an Arduino Mega to convert the analogue input to a digital output and plan to feed this into a wireless board. I then have a matching wireless receiver which feeds a Arduino Duemilanove which is connected to the PC via USB.

The wireless transmitter and receiver work OK over the required distance - I can transmit a binary signal to flash an LED on the receiver, using the following code

Code: [Select]

// RECEIVER - DUEMILANOVE
void setup()
{
  pinMode(A1, INPUT);  // Receiver (using analog as digital for convenience)
  pinMode(13, OUTPUT);
}

void loop()
{
  int sig = digitalRead(A1);
 
  if (sig) {
    digitalWrite(13, HIGH);
  }
    else{
    digitalWrite(13, LOW);
  }
}

// TRANSMITTER - MEGA

void setup()
{
  Serial.begin(9600);
 
  pinMode(13, OUTPUT);
  pinMode(50, OUTPUT); // transmitter, digital pin
}

void loop()
{
    digitalWrite(50, HIGH);
    digitalWrite(13,HIGH);
    delay(200);
    digitalWrite(50, LOW);
    digitalWrite(13,LOW);
    delay(200);
}


However I can't figure out how to get it to send a data message representing the analogue signal from the thermistor. My plan was to use virtual wire, but I haven't got the following code to work...

Code: [Select]

// RECEIVER

#include <VirtualWire.h>

void setup()
{
  pinMode(13, OUTPUT);
  vw_set_ptt_inverted(true);
  Serial.begin(9600);
  vw_set_rx_pin(A1);
  vw_setup(500);
  vw_rx_start();
}

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

  if (vw_get_message(buf, &buflen))
  {
    Serial.print("Got: ");
    Serial.print(buf[0]);
    digitalWrite(13, HIGH);
    delay(100);
  }
}

// TRANSMITTER

#include <VirtualWire.h>
void setup()
{
  pinMode(13, OUTPUT);
  vw_set_ptt_inverted(true);
  vw_set_tx_pin(50);
  vw_setup(500);
}

void loop()
{
    char message = 'test';
    vw_send((uint8_t *)&message, strlen(&message));
    vw_wait_tx();
    digitalWrite(13,HIGH);
    delay(400);
    digitalWrite(13,LOW);
    delay(400);
}


I have read something about soldering the pads on the tx and rx boards but I don't see how this would help transmit a message that will vary according to the analogue input to the Arduino....and then pass this on to the PC to decode and translate into a temperature reading.

Can anyone help ? Thanks in advance

CrossRoads

The pads on the back are just for setting the 'address' of the Tx & Rx units. If you only have this one set, you can leave them as is.

Take out this line, your part does not need it.
vw_set_ptt_inverted(true);

For your transmitter, you can load up an array and send it like this:

Code: [Select]

     msg[0]=key;                               // load the array with the key character  --> fill this as needed

    digitalWrite(ledPin, true);               // Flash a light to show transmitting

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

//    Serial.println(key);                // for debugging only

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

    delay (50);                               // need some delay or seem to miss key presses

    digitalWrite(ledPin, false);              // turn off the flash of LED


The receive side will get the data as a string of character
Code: [Select]

// **********************************************************************************************
// look for wireless input

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(ledPin, LOW); // Turn on LED to show working a message

  // Message with a good checksum received, dump it.
  //Serial.println("Got: ");  // Show on PC for debugging

  //    for (i = 0; i < buflen; i++)
  //    {
  //Serial.print(byte(buf[i]));
  //    }
  //Serial.println(""); // spaces it out for the monitor


So I think you're pretty close.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Borb

Hi, Thanks for your reply.

I have tried that code but to no avail. Below is the precise code I used.
Does anyone else have any other ideas, perhaps alternative to virtualwire or pointers on how I could implement my own software to achieve my goal?

Thanks

Code: [Select]

// TRANSMITTER
#include <VirtualWire.h>

const int ledPin = 13;
const int txPin = 50;

void setup()
{
  pinMode(ledPin, OUTPUT);
  vw_set_tx_pin(txPin);
  vw_setup(100);
}

void loop()
{   
    char msg[0];
    msg[0]='a';   
    digitalWrite(ledPin, true);               // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));     // send the character out
    Serial.println(msg[0]);                // for debugging only
    vw_wait_tx();                             // Wait until the whole message is gone
    delay (500);                               // need some delay or seem to miss key presses
    digitalWrite(ledPin, false);              // turn off the flash of LED
    delay(500);
   
}


Code: [Select]

// RECEIVER
#include <VirtualWire.h>

const int ledPin = 13;

void setup(){
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  vw_set_rx_pin(A1);
  vw_setup(500);
  vw_rx_start();
}

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(ledPin, LOW); // Turn on LED to show working a message

  // Message with a good checksum received, dump it.
  Serial.println("Got: ");  // Show on PC for debugging

  for (i = 0; i < buflen; i++){
    Serial.print(byte(buf[i]));
  }
  Serial.println(""); // spaces it out for the monitor
}

}



CrossRoads

Post your wiring.

This needs to go before setup()

    char msg[0];  << and how can you have an array of size 0? Make this bigger, at least 1. Then msg[0] = 'a' should give vald result

why do you transmit at 100
vw_setup(100);

and receive at 500?
  vw_setup(500);

That's not gonna work.

May not make a difference, but use a digital pin here, even if same pin but called by digital name.
  vw_set_rx_pin(A1);
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Borb

#4
Mar 12, 2011, 10:31 pm Last Edit: Mar 12, 2011, 10:34 pm by Borb Reason: 1
Thanks, I'm now using
Code: [Select]
const char msg[] = "a"; and have equalized the tx/rx speeds (tried 1,100,500,2000). Wasn't sure what you meant by "even if same pin but called by digital name".

Here is my wiring. Note that I am not using the variable resistor analog signal in my test code, but will be eventually.
Also note that it looks like I am TXing on a pin that should be RXed at A0. In my testing where I was just sending a high/low pulse (which worked), it was in fact RXed at the A1 pin (not sure why). I've tried both A0 and A1 in the code to no avail



CrossRoads

>>const char msg[] = "a";<<

Try it like this, just to make it simple and more clear what is happening.

char msg[1];   // creates an array of size 1 byte  << put this at top of the sketch before void setup()

msg[0] = "a";  // loads the array with data

>> vw_set_rx_pin(A1); <<
do this as
vw_set_rx_pin(15);  // this is definitely a digital pin now. I don't know how virtualwire and/or compiler react with an analog pin called out.

same for A0 - call it out as
vw_set_tx_pin(14);  // or pin 50 if that is what you are using.







Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

jumpering

#6
Aug 22, 2014, 12:37 am Last Edit: Aug 22, 2014, 12:44 am by jumpering Reason: 1
Hi there,
I write because I want to return to the subject of the message.
I have the kit of 2 km Seeedstudio RF (transmitter and receiver) connected to my Arduino as follows:


http://www.seeedstudio.com/depot/2KM-Long-Range-RF-link-kit-w-encoder-decoder-and-p-321.html

Code: [Select]

///HARDWARE CONECTION
TX:
D0 -> pin4;
D1 -> pin5;
D2 -> pin6;
D3 -> pin7;
GND -> GND;
VDD -> 5v.


and ...

Code: [Select]

///HARDWARE CONECTIONS
RX:
VT -> pin3;
D0 -> pin4;
D1 -> pin5;
D2 -> pin6;
D3 -> pin7;
GND -> GND;
VDD -> 5v.


The Virtual Wire library and these RF devices, ¿I can send and receive one (or more than one, better) data type "char" from sender to receiver?
I managed to send and receive up to 4 bits (one for each pin transmitter / receiver) but WITHOUT Virtual Wire; I use this code (get from Seeeduino forum (!thanks!)):

Code: [Select]

//RECIVER
int data=0;

void setup()
{
 pinMode(3,INPUT);
 pinMode(4,INPUT);
 pinMode(5,INPUT);
 pinMode(6,INPUT);
 pinMode(7,INPUT);
 attachInterrupt(1,RF_VT,RISING);
 Serial.begin(9600);
}
void loop()
{
}
//=======================================
void RF_VT() // interrupt service function
{
 data=(digitalRead(4)<<3)+(digitalRead(5)<<2)+(digitalRead(6)<<1)+(digitalRead(7)<<0);
 Serial.print("data=");
 Serial.println(data,DEC);
}


and....

Code: [Select]

//TRANSMITER
void setup()
{
 pinMode(4,OUTPUT);
 pinMode(5,OUTPUT);
 pinMode(6,OUTPUT);
 pinMode(7,OUTPUT);
 Serial.begin(9600);
}
void loop()
{
 unsigned char i=0;
 for(i=0;i<16;i++)
 {
   send_data(i);
   Serial.print("i=");
   Serial.println(i,DEC);
   delay(500);
   send_data(0);
   delay(500);
 }
}
//====================================
void send_data(unsigned char data)
{
 digitalWrite(4,(data&0x01));
 digitalWrite(5,(data&0x02));
 digitalWrite(6,(data&0x04));
 digitalWrite(7,(data&0x08));
}

This works but I not how do you send a "char" (8 bits) or more of 1 "char". Sorry for my english, I use googleTranslator...
Thank you very much for your help!

mauried

You have bought the wrong RF link kit.
That kit has a encoder and a decoder on the board with the transmitter and receiver.
Its most likley based on the SC 2262 / SC 2272 4 bit data encoders, which can send a 4 bit value from one to the other.
You dont need Virtual Wire.
To send an 8 bit value , you will have to break it into 2 , 4 bit values , and then send the 4 bit values one after the other.

Go Up