Is there a cleaner way to convert this data?

Ok, Here is what I am doing.
I have a 433mhz tx and an UNO that will send a tank level (using ping) to my computer.
I have more than 1 sensor out in the field, so I am giving the tx’s simple ID’s (A,B,C…)
my message to be transmitted using virtualwire will be:
(ID,sensor data)
for instance: (A,100) or (B,67.5)
the comma is needed for my code on the rx end.
My code compiles, but I am away from home right now; I can only hope it actually works.
Anyway, I used String class. I know that it is memory heavy, however, my code is small.
I have been running all over the internet tonight, trying to figure out the best way to do this.
So, rip away, and learn me something new! LOL
Seriously, I am constantly trying to get better, so if you have suggestions, let me know!
Ken

 /* modified level transmitter code. Assigns “A,” as the ID of the TX, and adds it to the beginning of the
Package.  The RX will parse data, and display it according to the ID. That’s the idea, anyways! Lol */
#include <VirtualWire.h>
#include<NewPing.h>
#define TRIGGER_PIN  8
#define ECHO_PIN     9 
#define MAX_DISTANCE 30


NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
String id="A,"; //tx address or id
String reading;
String package;
char buf[20];

int level;
int inches;

void setup() {
vw_setup(2000);
vw_set_tx_pin(3);
}
void loop() {
inches=sonar.ping_in();
int level=map(inches,0,30,100,0);


//here is my conversion of different casts
reading=String(level);
package = (id,reading);
package.toCharArray(buf,20);


//and hopefully it sends something intelligent out! 
vw_send((uint8_t *)buf, strlen(buf));
vw_wait_tx();
delay(200);
}

Anyway, I used String class. I know that it is memory heavy, however, my code is small.

you mean your source-code is small?

[IDE1.5.8 produces]
Sketch uses 6,740 bytes (20%) of program storage space. Maximum is 32,256 bytes.
Global variables use 239 bytes (11%) of dynamic memory, leaving 1,809 bytes for local variables. Maximum is 2,048 bytes.

#include <VirtualWire.h>
#include<NewPing.h>
#define TRIGGER_PIN  8
#define ECHO_PIN     9
#define MAX_DISTANCE 30

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

char id[] = "A";     //tx address or id
char buf[20];

int level;
int inches;

void setup() 
{
  vw_setup(2000);
  vw_set_tx_pin(3);
}

void loop() 
{
  inches = sonar.ping_in();
  level = map(inches, 0, 30, 100, 0);

  sprintf(buf, "%s,%d", id, level);  // you can use "<%s,%d>" to have record terminators

  vw_send((uint8_t *)buf, strlen(buf));
  vw_wait_tx();
  delay(200);
}

Sketch uses 6,226 bytes (19%) of program storage space. Maximum is 32,256 bytes.
Global variables use 219 bytes (10%) of dynamic memory, leaving 1,829 bytes for local variables. Maximum is 2,048 bytes.

~500 bytes smaller and 20 bytes less mem by not using Strings

as the string “A,12345” is the max length, buf could be as small as 8 bytes incl \0 terminator.
10 bytes would allow terminators around package “<A,12345>”
20 bytes would allow a millis() timestamp too e.g. “<A, 12345,123456789>”
a timestamp help to sort the measurements and you can interpolate more appropriately between measurements.

Thanks! I have been looking at all sorts of different examples! I have not used sprintf yet. Thanks! I am learning as I go. Now I am off to read up on sprintf!

reading=String(level);

What does this do… Creates a temporary string which converts the value of ‘level’ to a string.
If the constructor can accept an int, you can assume that the assignment operator does as well:
reading= level;

package = (id,reading);

This does nothing with id, and assigns reading to package. What did you intend here?

package.toCharArray(buf,20);

toCharArray is a waste of resources, you can access the internal string without copying any data.

All versions of the IDE:
vw_send((uint8_t *) &package[0], package.length() );

In 1.5.7 and above the c_str method has been added:
vw_send((uint8_t *) package.c_str(), package.length() );

Just for a side note, package.length() does not include the null, if you need it in the count add ‘+1’

%s= text %d= signed int cool. Do all the c++ specifiers work?

pYro_65:
What does this do… Creates a temporary string which converts the value of ‘level’ to a string.
If the constructor can accept an int, you can assume that the assignment operator does as well:
reading= level;

This does nothing with id, and assigns reading to package. What did you intend here?

toCharArray is a waste of resources, you can access the internal string without copying any data.

All versions of the IDE:
vw_send((uint8_t *) &package[0], package.length() );

In 1.5.7 and above the c_str method has been added:
vw_send((uint8_t *) package.c_str(), package.length() );

Just for a side note, package.length() does not include the null, if you need it in the count add ‘+1’

sorry about that!
It is the middle of the night, Iand i have changed the code dozens of times.
That section had been replaced with

int level=map(inches,0,30,100,0);
reading=String(level);
reading.concat(id);
reading.toCharArray(buf,20);
vw_send((uint8_t *)buf, strlen(buf));

until I did to Char Array, i kept getting cast errors from vw_send.
I am reading up on sprintf now.
Thanks for looking at it!
Ken

I can't understand why you would use the String type in the first place if, at the end of the day, you're going to use a char array to do your communication. It's like fitting electric windows to a lawn mower.

blcodemonkey: %s= text %d= signed int cool. Do all the c++ specifiers work?

no float %f is not supported - it uses (too) much memory

check dtostrf() on - http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html -

in general there is a LOT to learn here - http://www.nongnu.org/avr-libc/user-manual/pages.html -

KenF: I can't understand why you would use the String type in the first place if, at the end of the day, you're going to use a char array to do your communication. It's like fitting electric windows to a lawn mower.

Quite simply, I could't figure out any other way at the time. i tried all sorts of things, it kept kicking back errors when i tried to combine text and integers. I am going to use sprintf now.

electric windows on a lawnmower? good idea! I hate handcranks! LOL!