micropython-lib icon indicating copy to clipboard operation
micropython-lib copied to clipboard

Can Characteristics have data types?

Open adrianblakey opened this issue 1 year ago • 6 comments

Is there an api (and does BT allow it) to assign a data type to a Characteristic?

I am creating my own service and characteristics using 128bit UUID's. I'd like to in effect say "this characteristic is an integer" - is that possible?

adrianblakey avatar Nov 09 '23 23:11 adrianblakey

You can add a "Characteristic presentation format" descriptor to the characteristic for for that.

dlech avatar Nov 09 '23 23:11 dlech

Please could you point me to the api?

adrianblakey avatar Nov 09 '23 23:11 adrianblakey

It looks like it's another 16 bit uuid hex string - does it get appended to the characteristic uuid?

adrianblakey avatar Nov 10 '23 00:11 adrianblakey

I haven't used the MicroPython Bluetooth API, I just know BLE in general.

I assume it would just be part of https://docs.micropython.org/en/latest/library/bluetooth.html#bluetooth.BLE.gatts_register_services

which says:

Each characteristic is a two-or-three-element tuple containing a UUID, a flags value, and optionally a list of descriptors.

Each descriptor is a two-element tuple containing a UUID and a flags value.

And you would need to look up the Bluetooth specs to figure out the UUID and the required flags for the "Characteristic presentation format" descriptor to know what values to fill in.

dlech avatar Nov 10 '23 00:11 dlech

@dlech You are correct but I think this might be different to what @adrianblakey is asking.

I get the impression that what you want is to be able to say that e.g. this characteristic is a temperature, and therefore (e.g. the temp characteristic on the standard environmental service) should be interpreted as a sint16 deci-degrees. i.e. if I read() it, it should return back a float "degrees" (even though internally it's the sint16).

There's currently no support for this... I haven't given it a lot of thought yet but I think it would be very useful. Maybe having a library of standard converters, and being able to pass it to the Characteristic constructor (on the server, some other mechanism on the client).

jimmo avatar Nov 10 '23 03:11 jimmo

@dlech is right, and here are the specs: (see also https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/)

Descriptor Metadata:
Descriptor: Characteristic Presentation Format

    - NAME: Characteristic Presentation Format
    - ABSTRACT: The Characteristic Presentation Format descriptor defines the format of the Characteristic Value.
    - SUMMARY: One or more Characteristic Presentation Format descriptors may be present. If multiple of these descriptors are present, then a
                   Aggregate Formate descriptor is present. This descriptor is read only and does not require authentication or authorization to
                   read. This descriptor is composed of five parts: format, exponent, unit, name space and description. The Format field determines
                   how a single value contained in the Characteristic Value is formatted. The Exponent field is used with integer data types to
                   determine how the Characteristic Value is further formatted. The actual value = Characteristic Value * 10^Exponent.
    - UUID: 2904
    - INFO TEXT: None
    - Format:
        - Requirement: Mandatory
        - Format: 8bit
        - Ctype: B
        - Minimum: 0
        - Maximum: 27
        - Enumerations:
            - 0: Reserved For Future Use
            - 1: Boolean
            - 2: unsigned 2-bit integer
            - 3: unsigned 4-bit integer
            - 4: unsigned 8-bit integer
            - 5: unsigned 12-bit integer
            - 6: unsigned 16-bit integer
            - 7: unsigned 24-bit integer
            - 8: unsigned 32-bit integer
            - 9: unsigned 48-bit integer
            - 10: unsigned 64-bit integer
            - 11: unsigned 128-bit integer
            - 12: signed 8-bit integer
            - 13: signed 12-bit integer
            - 14: signed 16-bit integer
            - 15: signed 24-bit integer
            - 16: signed 32-bit integer
            - 17: signed 48-bit integer
            - 18: signed 64-bit integer
            - 19: signed 128-bit integer
            - 20: IEEE-754 32-bit floating point
            - 21: IEEE-754 64-bit floating point
            - 22: IEEE-11073 16-bit SFLOAT
            - 23: IEEE-11073 32-bit FLOAT
            - 24: IEEE-20601 format
            - 25: UTF-8 string
            - 26: UTF-16 string
            - 27: Opaque Structure
    - Exponent:
        - Requirement: Mandatory
        - Format: sint8
        - Ctype: b
    - Unit:
        - InformativeText: The Unit is a UUID.
        - Requirement: Mandatory
        - Format: uint16
        - Ctype: H
    - Namespace:
        - InformativeText: The Name Space field is used to identify the organization that is responsible for defining the enumerations for the
         description field.
        - Requirement: Mandatory
        - Format: 8bit
        - Ctype: B
        - Minimum: 0
        - Maximum: 1
        - Enumerations:
            - 1: Bluetooth SIG Assigned Numbers
    - Description:
        - InformativeText: The Description is an enumerated value from the organization identified by the Name Space field.
        - Requirement: Mandatory
        - Format: 16bit
        - Ctype: h
   

@adrianblakey you need to create the characteristic with this descriptor (2904) and then write (using the value handle of this descriptor) the appropriate values in those fields

FORMAT EXPONENT UNIT NAMESPACE DESCRIPTION
B (8bit) b (sint8) H (uint16) B(8bit) h(16bit)

e.g in binary

#                               FORMAT    EXPONENT    UNIT         NAMESPACE    DESCRIPTION
BLE.gatts_write(value_handle, 0b00000110_00000000_0010011100100110_00000000_0000000000000000)

Carglglz avatar Nov 10 '23 04:11 Carglglz