Best structure to use for sending multiple variables between a phone and ESP32 via Bluetooth

Hey everyone, I am looking to send multiple variables between an Android phone and an ESP32 via classic Bluetooth. I am looking for two-way communication since both devices will be sending one another different data. After following some tutorials I have a basic version going where I'm sending a text string between the two devices.

My initial thought was to combine all the variables into a string, send this string to the receiving device, and then have the receiver parse the data to assign them to individual variables. Would this be the best approach for what I'm trying to achieve or would you guys suggest something else?

Thanks for the help!

You started a topic in the Uncategorised category of the forum when its description explicitly tells you not to

Your topic has been moved to a relevant category. Please be careful in future when deciding where to start new topics

A structure is the normal way. Place the most strict alignment first like UL, the loosest last like char

Sending the character data may be easier to develop and debug than sending the data in a struct. You may lose some efficiency, but how much data are you sending/exchanging and how fast do you need to do this?

I would recommend a review of Robin2's excellent tutorial on how to send the Serial data as a character string with start and stop markers.

What are you running on the Android side. Is it a custom app? Did you use app inventor? Do you know how to handle a struct on the Android side if you chose to go that route?

If your variables can be organized into groups, use different structure for each group, plus an identifier for the group.
Be aware that there may be some size difference for variables that are used in each device.

It sounds very much like a lot of work for no purpose. Why do you think you need to do this?

Easier to debug.

We don't know the effort it takes to receive multiple bytes as binary values on the smartphone-app-side.

But maybe you can throw in a smartphone-demo-app within 5 minutes that demonstrates receiving binary data?

certainly for a purpose

no need to "parse", try using sccanf() with comma separated values

you should really know what you are doing if you use scanf and its variants

A beginners' guide away from scanf()

back to the main problem "best structure to use for sending mutliple bytes"

what the "best" structure will be depends on the details of your application.

post the most complicated example of multiple "datas" that can occur in your application.

post at what frequency are you sending the variables values back and forth?

post what the maximum time is that you find acceptable between sending the data and the receiver reacts on the received data

post what exact type of microcontrollers you are using.

If you have clarified these details a good suggestion can be made

scanf(), one 's', is intended for processing standard input. So it needs to handle all possible input and can get out of sync

sscanf() extracts values from a string. later parts of the string can be ignored.

It may be more common, less troublesome to read complete lines of input using Serial.readBytesUntil() or gets() (unix) and then use sscanf() to process the input after some quick analysis.

for example, you could do a simple comparision of the beginning of a string that can identify the type of data and then use various sscanf() formats to read one or more addition values of various types (e.g. int, float, char*).

I don´t think the way I did it is better than what everyone has suggested above because I know them all are more experienced than I am. But what I did is to send unpacked 3 bytes of info, being the first byte an identifier of the variable and the other two their values (useful for x and y coordinates for example). In the other side I simply wait for 3 bytes, read them and assign them to their respective variables in order.

It has its limitations (each value cannot be higher than 255, there´s a risk of loosing bytes, etc...), but it´s been working fine and it´s easy to implement at APP Inventor.

doubt that you'd loose bytes, but how do you insure that you're in sync, always reading the 1st byte. Will there ever be a need to restart the receiver in the middle of receiving data?

this isn't a serious problem when sending an ascii string because the end of the string can always be terminated with a unique char, linefeed. corrupted or missing data could simply be discarded, knowing that the next message will start with the 1st byte following the linefeed.

of course you can do the same with binary data, in fact it's by far the most common. other mechanisims are used to recognize the start of a message/packet/frame, check for errors and even have error correction.

but i agree with @StefanL38, that sending data as ascii is easier to test and debug. it can be manually generated as well

That´s the point of "losing bytes", I cannot ensure that I´m in sync. But reading the buffer of 3 bytes looks faster than bluetoothing them. I believe that´s why it has been working fine.

you can be out-of-sync without loosing bytes because the receiver was started after transmission started. yes, this is technically loosing bytes, but it's really a startup issues.

another way to avoid this is to only send data when requested or acknowledged, ACK. send an ACK to indicate when ready to receive data.