Questions on RF links and VirtualWire

Hi guys 

First of all I want to say this threat have nothing to do with robotics. Instead its about using some Arduinos to make a weather station. I've seen some of you are using RF links and VirtualWire in your projects so I hope you can help me anyway! :-) 

As written above Im in the middle of making a weather station. Im using an Arduino outside the house with a couple of sensors (At this point temperature and humidity). In side the house an other Arduino will be displaying the data from the sensors on a screen. The communication happens wirelessly using RF links. 

I managed to read the data from the sensors and transmit the data to the receiving Arduino. The receiving Arduino print the data in the serial monitor. It looks about right (22.1 is temperature and 46.0 is humidity):  

 22.1,  46.0,

 22.1,  46.0,

 22.1,  46.0,

 22.1,  46.0,

The problem is that I need to "split" the data apart to print it on a LCD screen. Like, in this case, storing 22.1 in one float and 46.0 in another. 

This is the code I wrote: 

Transmitter: 

#include <VirtualWire.h>

#include <DHT.h>

 

//Defining DHT sensor

#define DHTPIN 2 

#define DHTTYPE DHT11  

DHT dht(DHTPIN, DHTTYPE);

float H = 0;

 

int tempPin = 0;

float calTemp;

 

char tString[24];

char hString[24];

char msg[27];

 

 

void setup()

{

  Serial.begin(9600);

 

  //VirtualWire setup

  vw_set_tx_pin(12);

  vw_setup(2000);

 

 

  dht.begin();

}

 

void loop() {

  H = dht.readHumidity();

  analogReference(INTERNAL);

  temp(analogRead(tempPin)); //Calculating temperature in celcius

  analogReference(DEFAULT);

  sendData();

  delay(100);

}

 

void temp(int value) {

  long temperature = 0;

  //Reading the sensor 20 times and finding the average reading

  int aRead = 0;

  for (int i = 0; i < 20; i++) {

    aRead = aRead+value;

  }

  aRead = aRead / 20;

 

  //Converting the temperature to celsius

  temperature = ((100*1.1*aRead)/1024)*10;

 

  // prints a value of 123 as 12.3

  long hele = temperature / 10;

  float deci = (temperature % 10)/10.0;

  calTemp = hele + deci;

}

 

int sendData (){

  //Converting temperature to a string

  dtostrf(calTemp, 5, 1, tString);

  //Converting humidity to a string

  dtostrf(H, 5, 1,hString);

  //Combining to one string

  sprintf(msg, "%s, %s,", tString, hString);

  Serial.print("message to send: [");

  Serial.print(msg);

  Serial.println("]");

  //Sending the string

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

  vw_wait_tx();

}

 

Receiver: 

#include <VirtualWire.h>

 

void setup()

{

  Serial.begin(9600);

 

  //VirtualWire Setup

  vw_setup(2000);

  vw_set_rx_pin(10);

  vw_rx_start();

}

 

void loop()

{

  uint8_t buflen = VW_MAX_MESSAGE_LEN; //Maximum length of the message

  uint8_t buf[buflen]; // The buffer that holds the message

 

  if (vw_get_message(buf, &buflen)) 

  {       

 

    buf[buflen] = '\0';

    Serial.println((char *)buf);

  }

}


My questions is therefore: Can anyone help me with separating the different variables that the RF links receives? 

 

Thanks a lot!

 

 

Your values are comma separated.

a loop to iterate through the array should suit you well. find the location of the comma. Everything from the beginning to the location before the comma goes in one variable. Everything from after the comma to the end goes in another. I would suggest losing the space in your output though.

Message data

You could try sending the raw data form the external unit and letting the receiver do the formatting. Converting the raw temperature and humidity to ascii hex would allow the message to be sent as 4 characters. This way also allows you to add special  StartOfMessage (SOM) and EndOfMessage (EOM) bytes to encapulsate the data.

I don’t think your averaging scheme is correct. It appears that you add the same value 20 times and then divide by 20. You probably want to make the data storage array and summation global and initialize it in the setup. Then remove the oldest and add the newest. BDK6 posted a tutorial last week on filtering.

 

Just summing up what ggallant and birdmun have said

Nice Project there! I have tried out RF modules in a  couple of my projects, most recently in a keyboard controlled wireless robot where the RX module had to read different characters to execute a specific movement routine.

I am totally with ggallant’s idea on message data by converting the raw sensor readings to ascii hex. 

Then, as birdmun said, you could just create an array of incoming values, and iterate it, as I had done with my robot :

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

    if (vw_get_message(buf, &buflen)) // if RX-pair receives a character
    {
int i;

        digitalWrite(13, true); // Flash a light to show received good message

<span style="color: #cc6600;">for</span> (i = 0; i &lt; buflen; i++)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #cc6600;"><strong>Serial</strong></span>.<span style="color: #cc6600;">print</span>(buf[i]);

        if(buf[i] == ‘w’)
        {
          forward();//go forward when w is pressed
        }
        if(buf[i] == ‘s’)
      {
        backward();//go backward when s is pressed
      }
        if(buf[i] == ‘e’)
      {
        stop();//stop/brake when e is pressed
      }
        if(buf[i] == ‘a’)
      {
        left();//go left when a is presed
      }
        if(buf[i] == ‘d’)
        {
          right();//go right when d is pressed
        }   
}//close for loop
}
}

I am not sure if my code entirely applies to what you are trying to do. I don’t think you will even require the conditional statements  as only the format of the incoming ascii values needs to be changed accordingly. Good luck!

How?

Thanks for reply. 

It sounds good but how to do it? Could you try with some code example please? 

Thanks for reply! "You

Thanks for reply! 

 

You could try sending the raw data form the external unit and letting the receiver do the formatting. Converting the raw temperature and humidity to ascii hex would allow the message to be sent as 4 characters. This way also allows you to add special  StartOfMessage (SOM) and EndOfMessage (EOM) bytes to encapulsate the data.” 

So you see this as a problem: 

dtostrf(calTemp, 5, 1, tString);

  //Converting humidity to a string

  dtostrf(H, 5, 1,hString);

  //Combining to one string

  sprintf(msg, “%s, %s,”, tString, hString);

Isen’t it needed to convert the data in to a string as the Virtual Wire Library only supports sending strings? Or is there something I have misunderstood? :-) 


 

Thanks. My problem is that I

Thanks. My problem is that I guess I cant be making if-statements for every possible number I could receive. Well I could but it would take a lot of time! :smiley:

(How did you manage to keep the layout of the code? It looks way more awesome than what i postet?)

You can select a portion of

You can select code in Arduino and copy it in a special manner with the “Copy as HTML” feature under the edit menu. Then, while trying to add code, simply press the HTML button, and paste the copied HTML version of the code in its relevant area. Give it a try, and you’ll also have an awesome layout like 6677 and me. haha.

If Copy as HTML, doesn’t work.

Some versions of arduino ide don’t work for some reason.

You can use various websites that will generate HTML versions of fancy code. I personally use http://hilite.me/ with C++, copy the HTML and paste it like Enig suggested.

ASCII Hex

ascii hex is a string. 255 deciminal == 0xFF. If you know the radix is hex and you are doing both ends of the transmission you can skip the “0x”. As others have suggested, this is only one of many possible solutions. The receiver must have enough information, either explicit or implicit, to decode the incomming message.

I don’t have your hardware but am also transmitting temperature data over a radio link. Low cost / low power radios are prone to errors during transmission. I prefer a protocol that contains start and end markers, message ids, data, and check code. Message ids are particulary useful because they change the check code and the receiver can detect missing packets.

 

TCP/IP
Have you looked at the IP protocol and the TCP protocol above it?

You probably don’t want all of the fields, but it is designed for buggy networks.

The NKM2401 chip might be a better match for your needs because it does much of what you want transparently and handless some conditions that IP doesn’t.