Go Down

Topic: Shorten Messages sent via serial link (Read 497 times) previous topic - next topic

robvoi

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


PaulS

Quote
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.

Quote
1.523434

Are 6 decimal places reasonable?

robvoi


Quote
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.


Quote
1.523434

Are 6 decimal places reasonable?

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

PaulS

Quote
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.


robvoi

Well, validation is done implicitly and not completely.

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

Processing:
Code: [Select]
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.

robtillaart

Code: [Select]
#1.523434;100;-150;15;20;
you can make fields fixed length (can also cause all kinds of trouble)
Code: [Select]
#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.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robvoi

Thanks robtillaart.

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

Robert

robvoi

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.

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up