0

I'm working on a product which sends data over Bluetooth to a custom app.
While I got the communication link working, I can't seem to find a solution for converting the raw data to a struct.

I'm sending data from an ESP32 over bluetooth, which sends a struct that looks like :

struct dataStruct {
  float value = 0.45;
  int temp = 23;
  byte filler[250];
} dataRCV;

, puts it in a BLE characteristic and notifies the "client" (phone connected to it).
(The filler is a placeholder for future values)

The data is retrieved with characteristic.value!, and gives me a 256 byte array I would like to convert back to a swift struct that would look like :

struct dataStruct {
    var value: Float
    var temp: UInt16
    var filler: [UInt8]
}

I found some code snippets for converting structs to raw bytes, and some obscure ones to convert raw byte arrays of integers back to structs consisting only of UInt8's, but not for mixed types of data...
Is there any way to do that ? Or is there any way to do it any other way ?

EDIT :

The "256 byte array" comes directly from the data that is being sent from the ESP32 with pCharacteristic->setValue((byte*)&dataRCV, sizeof(dataRCV)); , and sizeof(dataRCV)is equal to 256 (because I defined the struct that way).

When, in my swift code, I print(characteristic.value!), it just prints 256 bytes in the console; and this data is what I want to convert back to a struct.
In C/C++ it's possible with memcpy as explained here, but I couldn't find any information on how it would be done in Swift, so I haven't really tried anything that got me closer to what I want to do yet.

6
  • 256 byte array is too vague. You need to post details of what those bytes mean. Float need only 4 bytes, UInt16 needs 2 bytes and [UInt8] can be any size. Btw int temp = 1.70 doesn't make any sense. Commented Feb 1, 2021 at 0:20
  • Welcome to SO but note also that this is not a code writing service. You are suppose to post what you have tried and the issues you are facing. Commented Feb 1, 2021 at 0:26
  • @LeoDabus Thanks !; I know, I'll add that right now. Commented Feb 1, 2021 at 0:27
  • edit your post and clarify your question Commented Feb 1, 2021 at 0:28
  • @LeoDabus Is it better ? Commented Feb 1, 2021 at 0:40

1 Answer 1

1

I got it working !

The struct in the swift code is defined with :

struct dataStruct {
    var value = Float(0.0)
    var temp = UInt16(0)
    var filler = [UInt8](repeating: 0, count: 248)
}

, and I created a function that converts the received Data from the characteristic to a suitable struct and returns it : (based on code found here)

func dataToStruct(data: Data) -> dataStruct {
    let _data = data
    let converted:dataStruct = _data.withUnsafeBytes { $0.load(as: dataStruct.self) }
    return converted
  }
}

I can now call this function to convert the raw data I receive into something usable ! :

  var receivedParsed = dataToStruct(data: characteristic.value!)
  print(receivedParsed.value)
Sign up to request clarification or add additional context in comments.

2 Comments

That's not going to work for the filler though. load only populates value types, not dynamically allocated data such as the buffer that backs an Array
@RobertCrabtree Is there a way that will work ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.