Shorten Messages sent via serial link

Hi,

I send sensor data from my robot via a wireless link to my PC. There Processing is used to process the data.
At the moment I use Stings to send the messages.

Is there a way to submit the data in a more compressed form?

Example message:

#1.523434;100;-150;15;20;

content:
message type;theta;x-coordinates,y-coordinates;sensor1;sensor2

Thanks
Robert

Is there a way to submit the data in a more compressed form?

Yes, but you loose the ability to sync messages. If a byte get lost, and that DOES happen, ASCII messages are easy to re-sync. Binary messages are MUCH harder to re-sync.

1.523434

Are 6 decimal places reasonable?

PaulS:

Is there a way to submit the data in a more compressed form?

Yes, but you loose the ability to sync messages. If a byte get lost, and that DOES happen, ASCII messages are easy to re-sync. Binary messages are MUCH harder to re-sync.

Do you have some sample code for resyncing. At the moment I do only fire the messages. If they are unvalid I drop them But it might still happen that the message is valid but the sensor reading got changed.
I also still need to implement kind of a handover procedure so that not both sides try to send messages at the same time.

PaulS:

1.523434

Are 6 decimal places reasonable?

I can certainly cut on this one. Done. I cut it down to 4 decimal places.

If they are unvalid I drop them

How do you determine that a packet is invalid? It's rather hard to answer generic questions. Seeing your code would make it much more specific, and easier to answer.

Well, validation is done implicitly and not completely.

Arduino:

Serial1 << "#" << _FLOAT(theta,4) << ";" << X_pos << ";" << Y_pos << ";" << PING2cm(PingCM[0]) << ";" << PING2cm(PingCM[1]) << ";" << endl;

Processing:

if (myString.substring(0, 1).equals ("#")) {
        float[] nums = float(splitTokens(new String(myString.substring(1)), ";"));
          theta=nums[0];
          x_pos=nums[1]; x_pos_MAP = round(Size/2 + x_pos);
          y_pos=nums[2]; y_pos_MAP = round(Size/2 - y_pos);
          lastPingL = nums[3];
          lastPingR = nums[4];
          drawSonar(int(lastPingL), 10, -5, 8); 
          drawSonar(int(lastPingR), -10, 5,8);
      }

So if the # ist lost or any number is no longe a falid float - the message will cause an exception and will be droped. But as long as the basic structure isn't changed the message is still valid.

So far I didn't notice bad effects from altered messages. There is a non valid one once in a while. But more often my commands sent from the PC to the robot are dropped because hte robot is currently sending. So I need to implement a kind of "allowance to talk" whcih gets handed over between the two. Some true message validation wouldn't hurt either.

#1.523434;100;-150;15;20;

you can make fields fixed length (can also cause all kinds of trouble)

#1.5234100-1501520

better use a binary format { # float int int uint8_t uint8_t uint8_t }

is a record synchronizer

float is the 1.5...
2 ints 100, -150
2 bytes = 15, 20
last byte is a checksum to check for errors,

==> 12 bytes per transmission 50% size reduction + added error checking.
should be not too difficult to implement.

Thanks robtillaart.

Great answer as usual. I'll give this a try.

Robert

I gave it a short try. Works great for positive integers.
I struggle with reconstructing negative integers and floats on the processing side. I will need to spend some more time on it.