virtual wire multiple values

Hi,

I used a sketch from the internet to send by RFLink one sensor value to another arduino board. It works well.
But my purpose is to send multiple values, such as light, temperature, CO2-concentration, humidity etc.
So I try to change the sketch for two sensorvalues, but now there are (for me) not-understandable things.

At the recievers side comes the serial data as follow:

983 983
1023 0

2 lines every time.
983 and 1023 (first numbers in the row) are good values.
The other 2 values (983 and 0) are not known. 983 looks like a mirror of the first value.
But were in the code is it going wrong.
Refers it to the char [4]?

Also I don't understand the code at the end of the reciever about buflen.
The int i was in the original sketch.
The int j was invented by myself, because i thought there are two sensors so there must be two charMsg's.

Correct me, please, if I'm wrong.

Gr.
Johan

Here's the code from the transmitter (some words are in dutch...):

#include <VirtualWire.h>

// LED's
const int ledPin = 13;

// Sensors 
const int licht = A0;
const int co2 = A1; 

int lichtData;
int co2Data;
char lichtCharMsg[4]; 
char co2CharMsg[4];

void setup() {

  // PinModes 
  // LED 
  pinMode(ledPin,OUTPUT);

  // for debugging
  Serial.begin(9600); 

  // VirtualWire setup
  vw_setup(2000);     // Bits per sec


}

void loop() {

  // Read and store Sensor data
  lichtData = analogRead(licht);
  co2Data = analogRead(co2);

  // Convert integer data to Char array directly 
  itoa(lichtData,lichtCharMsg,10);
  itoa(co2Data,co2CharMsg,10);

  // DEBUG
  Serial.print("licht Integer: ");
  Serial.print(lichtData);
  Serial.print(" licht CharMsg: ");
  Serial.print(lichtCharMsg);
  Serial.print("co2 Integer: ");
  Serial.print(co2Data);

  Serial.print(" co2 CharMsg: ");
  Serial.print(co2CharMsg);
  Serial.println(" ");
  delay(1000);

  // END DEBUG

  digitalWrite(13, true); // Turn on a light to show transmitting
  vw_send((uint8_t *)lichtCharMsg, strlen(lichtCharMsg));
  vw_wait_tx(); // Wait until the whole message is gone
  vw_send((uint8_t *)co2CharMsg, strlen(co2CharMsg));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(13, false); // Turn off a light after transmission
  delay(200); 

} // END void loop...

And this is the code from the reciever.

#include <VirtualWire.h>

// LED's
int ledPin = 13;

// Sensors 
int lichtData;
int co2Data;

// RF Transmission container
char lichtCharMsg[4]; 
char co2CharMsg[4];

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

  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);      

  // VirtualWire 
  // Initialise the IO and ISR
  // Required for DR3100
  vw_set_ptt_inverted(true); 
  // Bits per sec
  vw_setup(2000);     

  // Start the receiver PLL running
  vw_rx_start();       

} // END void setup

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

  // Non-blocking
  if (vw_get_message(buf, &buflen)) 
  {
    int i;
    // Turn on a light to show received good message 
    digitalWrite(13, true); 

    // Message with a good checksum received, dump it. 
    for (i = 0; i < buflen; i++)
    {            
      // Fill Sensor1CharMsg Char array with corresponding 
      // chars from buffer.   
      lichtCharMsg[i] = char(buf[i]);


    }

    int j;
    for (j = 0; j < buflen; j++)
    {
      co2CharMsg[j] = char(buf[j]);
    }

    // Null terminate the char array
    // This needs to be done otherwise problems will occur
    // when the incoming messages has less digits than the
    // one before. 
    lichtCharMsg[buflen] = '\0';
    co2CharMsg[buflen] = '\0';

    // Convert Sensor1CharMsg Char array to integer
    lichtData = atoi(lichtCharMsg);
    co2Data = atoi(co2CharMsg);


    // DEBUG 
    Serial.print("Licht: ");
    Serial.print(lichtData);
    Serial.print("\t");
    Serial.print("CO2: ");
    Serial.println(co2Data);

    // END DEBUG

    // Turn off light to and await next message 
    digitalWrite(13, false);
  }
}

The value read from the analog pins can be as high as 1023. To convert that to a string requires FIVE places in the array, because strings are character arrays that are NULL terminated. Your NULL, in some cases, if being written past the end of the array.

Thanks. It's better.
But now the Serial Monitor from the reciever shows:

985 985
1023 1023

Every loop it gives two lines.
The first row is twice the lightsensor.
The second row is twice a 5V signal.

I want to see:

985 1023

What's wrong with the Serial.print commands in the code?

Gr.
Johan

What's wrong with the Serial.print commands in the code?

In the code that you changed? Beats me.

Beats you? Sorry, Seattle is to far from Holland.
Means 'Beats me' the same as 'I don't know' or means it like 'stupid! Don't you see this?'
Indeed i'm still a newbie. But i don't work the whole day with arduino.

Why comes in one loop two lines of serial data at the recievers side?
Anyone another less painfull answer?

Johan

Means 'Beats me' the same as 'I don't know'

Yes, it does.

It means that you modified your code, and you didn't post the new code, so we have no way of knowing what your problem is now.

Ah, so.
But the code isn't changed from the one in my starterpost, only your suggestion to make an array from 5 instead of 4, and i've changed the serial.print commands a little bit:

Transmitter:

  Serial.print(lichtCharMsg);
  Serial.print("\t);
  Serial.println(co2CharMsg);
  delay(1000);

Gives in the serial monitor: 0 1023 (i've put them in GND and 5V)

Reciever:

    Serial.print(lichtCharMsg);
    Serial.print("\t");
    Serial.println(co2CharMsg);

Gives in the serial monitor
0 0
1023 1023

Twice the lightvalue and twice the co2value.

Could it be a delay problem? That the transmitter sends faster than the reciever could handle?

The code you initially posted prints something in front of every number you print. You either changed the code or your "sample output" does not match your real output.

I don't want to keep track of the code changes you make/have made. Post the current code for sender and receiver and REAL output from sender and receiver.

Ok, i'll try:

Sender code:

#include <VirtualWire.h>

// LED's
const int ledPin = 13;

// Sensors 
const int licht = A0;
const int co2 = A5; 

int lichtData;
int co2Data;
char lichtCharMsg[5]; 
char co2CharMsg[5];

void setup() {

  // PinModes 
  // LED 
  pinMode(ledPin,OUTPUT);

  // for debugging
  Serial.begin(9600); 

  // VirtualWire setup
  vw_setup(2000);     // Bits per sec


}

void loop() {

  // Read and store Sensor data
  lichtData = analogRead(licht);
  co2Data = analogRead(co2);

  // Convert integer data to Char array directly 
  itoa(lichtData,lichtCharMsg,10);
  itoa(co2Data,co2CharMsg,10);

  // DEBUG
  //  Serial.print("licht Integer: ");
  //  Serial.print(lichtData);
  //  Serial.print(" licht CharMsg: ");
  Serial.print(lichtCharMsg);
  //  Serial.print("co2 Integer: ");
  //  Serial.print(co2Data);
  Serial.print("\t");
  //  Serial.print(" co2 CharMsg: ");
  Serial.println(co2CharMsg);
  //  Serial.println(" ");
  delay(1000);

  // END DEBUG

  digitalWrite(13, true); // Turn on a light to show transmitting
  vw_send((uint8_t *)lichtCharMsg, strlen(lichtCharMsg));
  vw_wait_tx(); // Wait until the whole message is gone
  vw_send((uint8_t *)co2CharMsg, strlen(co2CharMsg));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(13, false); // Turn off a light after transmission
  delay(200); 

} // END void loop...

With output:

01023
01023
01023
etc... every second

Reciever's code:

#include <VirtualWire.h>

// LED's
int ledPin = 13;

// Sensors 
int lichtData;
int co2Data;

// RF Transmission container
char lichtCharMsg[5]; 
char co2CharMsg[5];

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

  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);      

  // VirtualWire 
  // Initialise the IO and ISR
  // Required for DR3100
  vw_set_ptt_inverted(true); 
  // Bits per sec
  vw_setup(2000);     

  // Start the receiver PLL running
  vw_rx_start();       

} // END void setup

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

  // Non-blocking
  if (vw_get_message(buf, &buflen)) 
  {
    int i;
    // Turn on a light to show received good message 
    digitalWrite(13, true); 

    // Message with a good checksum received, dump it. 
    for (i = 0; i < buflen; i++)
    {            
      // Fill Sensor1CharMsg Char array with corresponding 
      // chars from buffer.   
      lichtCharMsg[i] = char(buf[i]);


    }

    int j;
    for (j = 0; j < buflen; j++)
    {
      co2CharMsg[j] = char(buf[j]);
    }

    // Null terminate the char array
    // This needs to be done otherwise problems will occur
    // when the incoming messages has less digits than the
    // one before. 
    lichtCharMsg[buflen] = '\0';
    co2CharMsg[buflen] = '\0';

    // Convert Sensor1CharMsg Char array to integer
    lichtData = atoi(lichtCharMsg);
    co2Data = atoi(co2CharMsg);


    // DEBUG 
    //    Serial.print("Licht: ");
    Serial.print(lichtCharMsg);
    Serial.print("\t");
    //    Serial.print("CO2: ");
    Serial.println(co2CharMsg);

    // END DEBUG

    // Turn off light to and await next message 
    digitalWrite(13, false);
  }
}

With output:

0 0
1023 1023
0 0
1023 1023
0 0
1023 1023
etc. every second two lines.

Is this what you want to see? Or is there another way to post the real output? A printscreen from the serialmonitor?

If you actually printed identifiers in front of what you are printing, it would be more obvious what your problem is.

Look at the sender. How are you sending data?
Send a single value:

  vw_send((uint8_t *)lichtCharMsg, strlen(lichtCharMsg));
  vw_wait_tx(); // Wait until the whole message is gone

Send another single value:

  vw_send((uint8_t *)co2CharMsg, strlen(co2CharMsg));
  vw_wait_tx(); // Wait until the whole message is gone

On the receiver side, you are assuming that both values are in the same packet. And, in the same place in that packet.

With tips & trucks from all of you at least i have a code which is working (completed with a DHT11 sensor):

Sender:

#include <VirtualWire.h>
#include <DHT.h>

#define DHTPIN 2

#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup()
{
  Serial.begin(9600);
  Serial.println("setup");
  vw_set_tx_pin(12);
  vw_setup(2000);
  pinMode(13,OUTPUT);
  dht.begin();
}
void loop()
{
  int h = dht.readHumidity();
  int t = dht.readTemperature();

  String messageString = String();
  for(int i=0;i<6;i++){
    messageString.concat(analogRead(i));
    messageString.concat(",");
  }
  messageString.concat(t);
  messageString.concat(",");
  messageString.concat(h);
  messageString.concat(",");

  char msg[messageString.length()+1];
  messageString.toCharArray(msg,messageString.length()+1);
  digitalWrite(13, true);
  vw_send((uint8_t *)msg, strlen(msg));
  vw_wait_tx();
  digitalWrite(13, false);
  delay(1000);
}

Reciever:

#include <VirtualWire.h>
void setup()
{
     Serial.begin(9600);
    Serial.println("setup");
    Serial.println("CLEARDATA");
    vw_setup(2000);
    vw_set_rx_pin(11);
    vw_rx_start();
    pinMode(13,OUTPUT);
}
void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    if (vw_get_message(buf, &buflen)) 
    {
int i;
digitalWrite(13, true); 
//Serial.print("Got:   ");
Serial.println("CLEARDATA");
Serial.print("DATA, ,");
for (i = 0; i < buflen; i++)
{
  
    Serial.write(buf[i]);
    Serial.print(" ");
}
Serial.println(" ");

     digitalWrite(13, false);
    }
}

The concat-function works fine for me.
The CLEARDATA and DATA prints are necessary for the transport to Excel.

Thanks so far...

Gr.
Johan

A char array, large enough to hold what you are sending, and sprintf() will use far fewer resources on the sender.

On the receiver, you can use strtok() to extract the two values from the string, and atoi() to convert them to numbers, if you want to.