Sending Weather Data (Multiple Values) between 2 Arduinos (433Mhz)

Hey guys,

I am kind of the to the whole thing. Had C and some basic µC programming back in the university.

At the moment I am “learning” the basics and want to transfer Data between 2 Arduinos. The first step was some kind of tutorial from instructables, which worked perfectly fine.
Today I wanted to take the next step in sending 2 Values from a DHT22 to the 16x2 LCD. I somehow got it to work, altough I dont understand all the code.
Next step would be to add commas.

I understand I have to use floats instead of ints? But if I change the programm to float (sprintf(string1, “%f,%f”, temp, hum); even the string1 shows just ?,?

I added my code, so maybe you understand my problem.

regards from germany
Bastian

RX_MehrereDaten.ino (713 Bytes)

TX_MehrereDaten.ino (436 Bytes)

By default, sprintf doesn't support floats on the Arduino.
Try dtostrf

Thanks! Tried that but I get:

"exit status 1
cannot convert 'char*' to 'double' for argument '1' to 'char* dtostrf(double, signed char, unsigned char, char*)'
"

I think I am missing some library? Could anyone give me an example on how my dtostrf would look like? The temp value has 4 digits, 2 after the decimal point)

Posting an error message without the code it relates to is kind of pointless, don't you think?
Use code tags

Cant tell sorry. I cant even use the dtostrf function (it does not get displayed orange.)
I changed the ints to floats and tfrom that on forward I dont know how to use the dtostrf function.

If you don't tell us what you've tried, it's very hard to help you.

it does not get displayed orange

That means nothing at all - syntax highlighting is simply eye-candy.

I've tried nothing so far and would like to get advice on how to transform a float to string.

But after I reloaded the programm again I get totally messed up results for the 2nd channel (hum). I get values around +-25000

man1ac:
I've tried nothing so far and would like to get advice on how to transform a float to string.

You could try using this

Thanks!
Do I need some kind of special library for this?

What does the compiler say?

This function is part of the standard library. Try running the following.

char fBuff[20];        // buffer for converted float
float val = 3.39457f;  // float to convert 

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

  // print with precision from 2 to 5
  for(int precision = 2; precision < 6; precision++)
  {
    // print float with given precision, padded to 7 characters
    Serial.println();
    Serial.print("Precision = ");
    Serial.print(precision);
    Serial.print("  value = ");
    Serial.println(dtostrf(val,7,precision,fBuff));

  }

}

void loop()
{


}

Thanks!
@AWOL: Hadnt had the chance of working on the project again. Will do so today!

@BLue Eyes: Thanks, this looks nice. Will test it!

For my example the output I sent (whats written into string) I want my 2 values in there.
My DHT22 sends 2 floats:

temp = 24.45°C (example)
hum = 45.60%

To convert temp into a string using dtostrf it would look like:

char string1[21]; //the one I want to send
char tempstring[10]
char humstring[10]

dtostrf(temp,6,1,tempstring); // The temp could have -10.04 (so 6 characters) and 1 character after the decimal point would be enough
dtostrf(hum, 5, 1, humstring);
sprintf(string1, “%s,%s,” , tempstring, humstring)

This should produce a string that contains both values?!

On the receiving side I would need to seperate the 2 strings again and then convert them into floats?

sscanf(StringReceived, “%s,%s”,&tempstring, &humstring);
sscanf(tempstring, “%f”, &temp);
sscanf(humstring, “%f”, &hum);

(Is it a correct use of sscanf? Or wrong in general?

dtostrf(temp,6,1,tempstring); // The temp could have -10.04 (so 6 characters) and 1 character after the decimal point would be enough
dtostrf(hum, 5, 1, humstring);
sprintf(string1, "%s,%s," , tempstring, humstring)

strcat instead of sprintf would be simpler, but I don't see why you need everything in one string.

"atof" or "strtod" are simpler than "sscanf"

Thanks.
I dont know if I need everything in one string. I Simply dont know on how to send the values after one another. I think I could copy the sending line. But how do I receive them and save the first in "value1" and the 2nd in value two.

I thought having them in the same string would make things easier.
If can show me a neat way on how to send 2 values and display them simultaneously at my LCD - very much appreciated :slight_smile:

Hello why send floats at all???
use the working code you have and just multiply the values with 100 on the transmitter side and then divide by 100.0 on the receiver side. much simpler :slight_smile:

I'm assuming that for testing, you're using actual wires in place of the radio devices, and that you've already proved that you can copy a simple string like "Hello world" from one board to the other.

Nope, even for testing I set up the wireless connection. Submitting one value works flawless (for and int).
Is it really that simple and multiply by 100? I tried something smiliar and hat vales like 2300 (temp) and 4000(hum) but on the receiving end I just got weird numbers >10000...

Please post your code, in code tags.

Will do that later on when I am home!

Thats the TX

#include <VirtualWire.h>
#include <DHT.h>
int temp = 0;
int hum = 0;
DHT dht;
char string1[21];
char string2[21];

void setup() {
Serial.begin(9600);
vw_set_tx_pin(12);
vw_setup(2000);
dht.setup(13);
}

void loop() {
  delay(dht.getMinimumSamplingPeriod());
  temp = dht.getTemperature();
  hum = dht.getHumidity();
  
  sprintf(string1, "%d,%d", temp, hum);

  vw_send((uint8_t *)string1, strlen(string1));
  vw_wait_tx();
  Serial.println(string1);
}

Thats the RX

#include <VirtualWire.h>
#include<Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
int i;
int temp;
int hum;

void setup() {
Serial.begin(9600);
lcd.begin (16,2);
vw_set_rx_pin(12);
vw_setup(2000);
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) )
{
sscanf ((char*)buf, "%d%*c%d%", &temp, &hum);
Serial.println(temp);
Serial.println(hum);
lcd.setCursor(0, 0);
lcd.print("Temp:");    
lcd.setCursor(7,0);   
lcd.print(temp);
lcd.setCursor(9,0);    
lcd.print((char)223);
lcd.print("C");  
lcd.setCursor(0, 1);
lcd.print("Humidity:");    
lcd.setCursor(10,1);   
lcd.print(hum);
lcd.print("%");  

}
}

consider TX using markers like this:

sprintf(string1, "T%dH%d;", temp, hum);

and in RX check for a 'T' or an 'H' and parse the integer:

Using parseInt() for demonstration only (easy)

int temp, humidity;

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

}

void loop() 
{
  if(Serial.available())
  {
    if (Serial.peek() =='T')
    {
      Serial.read();
      temp = Serial.parseInt();
    }
    if(Serial.peek() == 'H')
    {
      Serial.read();
      humidity = Serial.parseInt();
    }
    else
    {
      Serial.read();
    }
    Serial.print("Temperature:");
    Serial.println(temp);
    Serial.print("Humidity:");
    Serial.println(humidity);
    
  }
}