I'm buffering data when my device is not connected so I need to implement timestamps so I can tell what was measured when.
fortunately the weight measurement characteristic includes a timestamp.
unfortunately it's not clear how to write this data to the package since it's not a normal data type, and it's surely not just a single byte.
I'm using Adafruit's bluefruit arduino library, so I've tried just ignoring the schema and writing a unix timestamp after the SI weight but unsurprisingly it seems like the schema is not allowing that so I'm not seeing the timestamp when I receive the notifications (but i'm still seeing the correct weight readings)
Here's the link for the date_time characteristic, which is apparently the format it expects https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.date_time.xml
I tried looking a bit in the nRF52 SDK so see if this is perhaps handled better through their API but the learning curve is a bit steep and I just need to finish this last bit to make my device work.
Update:
For anyone else with this issue the solution turned out to be that I was using the notify method the same way as it's written in the adafruit example
wmc.notify(notification, sizeof(notification))
because I was indexing through an N x 7 array of buffered data however notification
is a pointer to the first element in the 1 x 7 array i was going to feed, so sizeof was always returning 4 (the size of the address I assume) instead of the length of the array originally written which was 7
The weight_scale service has two manadatory characteristics:
<Characteristic type="org.bluetooth.characteristic.weight_scale_feature" name="Weight Scale Feature">
<Requirement>Mandatory</Requirement>
<Characteristic type="org.bluetooth.characteristic.weight_measurement" name="Weight Measurement">
<Requirement>Mandatory</Requirement>
In the weight_measurement characteristic (uuid="2A9D"), the first byte is flags. Where <Bit index="1" size="1" name="Time stamp present">
needs to be 1
to say there will be a "Time Stamp" field. That "Time Stamp" field will be:
<Field name="Year"> <Format>uint16</Format> = 2 bytes
<Field name="Month"> <Format>uint8</Format> = 1 byte
<Field name="Day"> <Format>uint8</Format> = 1 byte
<Field name="Hours"> <Format>uint8</Format> = 1 byte
<Field name="Minutes"> <Format>uint8</Format> = 1 byte
<Field name="Seconds"> <Format>uint8</Format> = 1 byte
This makes the "Time Stamp" field 7 bytes wide.
To give a worked example of how to create the full packet if you wanted weight (in Kg) and a time stamp it will need to 10 bytes long:
<Field name="Flags"> <Format>8bit</Format> = 1 byte
<Field name="Weight - SI "> <Format>uint16</Format> = 2 bytes
<Field name="Time Stamp"> = 7 bytes
I've used Python to calculate the value of a packet:
import struct
flags = 0b00000010 # Include time. SI units
weight_raw = 38.1 # Weight of 38.1 Kg
weight = int((weight_raw/5)*1000) # Formula from XML
year = 1972
month = 12
day = 11
hour = 23
minute = 22
second = 8
packet = struct.pack('<BHHBBBBB', flags, weight, year, month, day, hour, minute, second)
print(packet)
Which would give a packet of 10 bytes long:
b'\x02\xc4\x1d\xb4\x07\x0c\x0b\x17\x16\x08'