Transmitting a string of fixed lengh

I am fairly new to arudino. I have written/put together from existing code a program that grabs data from several sensors. It then does math, conversions etc to this data, and then using Serial1.print I output via TX1 to NI LabVIEW. The problem is, for example one of the sensors gives heading, so sometimes this may be 56 and sometimes it might be 234. The receiving program needs to know how long to expect the string to be, otherwise it cuts some off. If I tell it to expect a string too long, stuff gets cut off on the next loop. After trial and error, Ive come to the conclusion the problem is on the arudnio side. At first I thought of converting the data to binary, that way, each piece of data will always be the same length, however this will not work for two reason 1) Some values, such as heading, are larger then the the largest binary value I can get. 2) Many of these values have decimal components.

Any suggestions would be greatly appreciated

Why can't you send the value as ASCII, followed by some non-numeric character, like a comma, or carriage-return?

from what I understood, doesnt serial.print convert to ASCII?
This is print function I am currently using, some of the values are floats, some ints,

void printData(){



//   compass data
     Serial1.print("DOF");
     Serial1.print(",");
     Serial1.print(angles[0]);
     Serial1.print(",");
     Serial1.print(angles[1]);
     Serial1.print(",");
     Serial1.print(angles[2]);
     Serial1.print(",");
     Serial1.print(heading);
     Serial1.print(",");
     Serial1.print(tempDOF);
     Serial1.print(",");
     Serial1.print(internalPressure);
     Serial1.print(",");
    //internal pressure and humidty from Phidget
     Serial1.print("INT");
     Serial1.print(",");
     Serial1.print(tempPhidget);
     Serial1.print(",");
     Serial1.print(relativeHumidity);
     Serial1.print(",");
     Serial1.print(deltaHumidity);
     Serial1.print(",");
     // Sonar data
     Serial1.print("SONAR"); 
     Serial1.print(","); 
     Serial1.print(range); 
     Serial1.print(","); 
     //External temperautre and pressure
     Serial1.print("PRESS");
     Serial1.print(",");
     Serial1.print(tempReal);
     Serial1.print(",");
     Serial1.print(externalPressure);
     Serial1.print(",");
     Serial1.print(tempComp); 
     Serial1.print(",");
}

from what I understood, doesnt serial.print convert to ASCII?

It does.

I'm sorry, you already seem to be sending commas as delimiters, so I'm puzzled as to why you're having problems here.

KatherineJean:
I am fairly new to arudino. I have written/put together from existing code a program that grabs data from several sensors. It then does math, conversions etc to this data, and then using Serial1.print I output via TX1 to NI LabVIEW. The problem is, for example one of the sensors gives heading, so sometimes this may be 56 and sometimes it might be 234. The receiving program needs to know how long to expect the string to be, otherwise it cuts some off. If I tell it to expect a string too long, stuff gets cut off on the next loop. After trial and error, Ive come to the conclusion the problem is on the arudnio side. At first I thought of converting the data to binary, that way, each piece of data will always be the same length, however this will not work for two reason 1) Some values, such as heading, are larger then the the largest binary value I can get. 2) Many of these values have decimal components.

Any suggestions would be greatly appreciated

How about this: Example, you want every value to be exactly 4 digits with leading zeros if necessary:

    char buffer [32]; // must be large enough to hold the entire string

    int rpm; // example rpm can range from 0 to over 3000

    // function to send string to serial port
    void sendData (int dat)
    {
        sprintf (buffer, "RPM: %04d\n", dat);
        Serial.print (buffer);
    }


    // this part of your program reads the RPM
    rpm = sensorRead (num); // example get data from your code
    sendData (rpm); // send data to serial port

This example will do the following:

If RPM is 0, it prints:

[b]RPM: 0000[/b]

If RPM is 100:

[b]RPM: 0100[/b]

If RPM is 2500:

[b]RPM: 2500[/b]

If RPM is 30000 (note string got longer)

[b]RPM: 30000[/b]

Notice the "%04d" formatting. The format code "%d" means "print an int".
The 4 means print 4 characters regardless
The 0 means fill unprinted spaces with "0"

So, "%d" would just print like this:

[b]0
100
2500
30000[/b]

If you used "%4d" it would do this:

[b]   0
 100
2500
30000[/b]

Finally the "0" in "%04d" means fill the spaces with zero:

[b]0000
0100
2500
30000[/b]

For other kinds of data types, different formatting codes are used. Google "printf formatting" for more info.

Lastly, the stupid Arduino IDE setup doesn't support floating point numbers by default. If you try to print a float value by using something like "%5.2f", all it will do is print a question mark.

This can be fixed by editing and recompiling the IDE to send the proper GCC command line or else you can use the "dtostrf()" function (see here): dtostrf() alternative for concatenating a float and a string - Programming Questions - Arduino Forum

Hope this helps!

It does.

I'm sorry, you already seem to be sending commas as delimiters, so I'm puzzled as to why you're having problems here.

The receiving program needs to be told how long the string of data is. Otherwise it cuts some off (if too short) or starts to fill up with the data from the next loop. (to long). It isnt always a problem, but if it cuts off say, in the middle of "SONAR", then it doesn't match match any of the set conditions and if takes a few iterations before it sorts itself back out, which sometimes can take over a minute

How about this: Example, you want every value to be exactly 4 digits with leading zeros if necessary:

That looks just like what I need, thank you

KatherineJean:
The receiving program needs to be told how long the string of data is.

How do you tell it? Can the first byte of your data be the length of the data?

What is the receiving program?
Did you write it?
Can you change it?

...R

Robin2:
How do you tell it? Can the first byte of your data be the length of the data?

What is the receiving program?
Did you write it?
Can you change it?

...R

I spoke too soon, seems that was not what I needed

The receiving program in NI Labview. There is a vi for serial read and it must be told the byet count.
I wrote it

sprintf returns the number of characters in its output buffer.
Use sprintf instead of the individual Serial.prints, and note the number it returns.

KatherineJean:
I wrote it

Then I suggest you change it so it detects a special character to mark the end of the data.

This demo may give you some ideas.

...R

Thank you all for your help.
I got it working, all I needed to do was send a new line at the end of the prints.
I can't believe I didnt think of that

KatherineJean:
I can't believe I didnt think of that

Happens to all of us.

These trivial problems are often the hardest to figure because everyone here probably assumed you already had a newline.

...R