Ich versuche, eine Verbindung zu einem Bluetooth LE-/Bluetooth Smart-/BLE-Gerät mit Gesundheitsthermometer (0x1809) herzustellen, wie hier offiziell beschrieben: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml. Insbesondere ersuche ich um Benachrichtigungen vom Gesundheitsthermometer-Merkmal (0x2A1C) mit der folgenden Beschreibung: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml.So lesen Sie einen BLE-Merkmalsschwimmer in Swift
Ich habe einen anständigen Swift 2 Hintergrund, aber ich habe noch nie so eng mit NSData, Bytes oder bitweise Operatoren gearbeitet und ich bin komplett neu bei Little Endian vs. Big Endian, also ist das ziemlich neu für mich und Ich könnte etwas Hilfe gebrauchen. Das Merkmal enthält eine Logik, die festlegt, welche Daten Sie erhalten. Ich habe Daten in der Reihenfolge von Flags, Temperaturmesswert und Zeitstempel bisher in 100% der Zeit erhalten, aber leider bekomme ich immer die Steuerlogik von "010", was bedeutet, dass ich die Flags falsch lese. In Wahrheit denke ich, dass ich alles, was vom Timestamp schief ist, falsch einbringe. Ich schließe ein, welche Daten ich in den Code-Kommentaren sehe.
Ich habe mehrere Möglichkeiten versucht, diese Binärdaten zu erhalten. Die Flags sind ein einzelnes Byte mit Bitoperatoren. Die Temperaturmessung selbst ist ein Float, und es dauerte einige Zeit, bis ich erkannte, dass es kein Swift Float ist, sondern ein ISO/IEEE-Standard "IEEE-11073 32-Bit FLOAT" mit der Angabe "EXPONENT VALUE" "hier: https://www.bluetooth.com/specifications/assigned-numbers/format-types. Ich weiß nicht einmal, was das bedeutet. Hier ist mein Code aus dem didUpdateValueForCharacteristic() Funktion, wo man meine mehrere Versuche anzeigen können, die ich bemerkte, wie ich ein neues ausprobiert:
// Parse Characteristic Response
let stream = NSInputStream(data: characteristic.value!)
stream.open() // IMPORTANT
// Retrieve Flags
var readBuffer = Array<UInt8>(count: 1, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
var flags = String(readBuffer[ 0 ], radix: 2)
flags = String(count: 8 - flags.characters.count, repeatedValue: Character("0")) + flags
flags = String(flags.characters.reverse())
print("FLAGS: \(flags)")
// Example data:
// ["01000000"]
//
// This appears to be wrong. I should be getting "10000000" according to spec
// Bluetooth FLOAT-TYPE is defined in ISO/IEEE Std. 11073
// FLOATs are 32 bit
// Format [8bit exponent][24bit mantissa]
/* Attempt 1 - Read in a Float - Doesn't work since it's an IEEE Float
readBuffer = Array<UInt8>(count: 4, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
var tempData = UnsafePointer<Float>(readBuffer).memory
// Attempt 2 - Inverted bytes- Doesn't work since it's wrong and it's an IEEE Float
let readBuffer2 = [ readBuffer[ 3 ], readBuffer[ 2 ], readBuffer[ 1 ], readBuffer[ 0 ] ]
var tempValue = UnsafePointer<Float>(readBuffer2).memory
print("TEMP: \(tempValue)")
// Attempt 3 - Doesn't work for 1 or 2 since it's an IEEE Float
var f:Float = 0.0
memccpy(&f, readBuffer, 4, 4)
print("TEMP: \(f)")
var f2:Float = 0.0
memccpy(&f2, readBuffer2, 4, 4)
print("TEMP: \(f2)")
// Attempt 4 - Trying to Read an Exponent and a Mantissa - Didn't work
readBuffer = Array<UInt8>(count: 1, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let exponent = UnsafePointer<Int8>(readBuffer).memory
readBuffer = Array<UInt8>(count: 3, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let mantissa = UnsafePointer<Int16>(readBuffer).memory
let temp = NSDecimalNumber(mantissa: mantissa, exponent: exponent, isNegative: false)
print("TEMP: \(temp)")
// Attempt 5 - Invert bytes - Doesn't work
readBuffer = Array<UInt8>(count: 4, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let exponentBuffer = [ readBuffer[ 3 ] ]
let mantissaBuffer = [ readBuffer[ 2 ], readBuffer[ 1 ], readBuffer[ 0 ] ]
let exponent = UnsafePointer<Int16>(exponentBuffer).memory
let mantissa = UnsafePointer<UInt64>(mantissaBuffer).memory
let temp = NSDecimalNumber(mantissa: mantissa, exponent: exponent, isNegative: false)
print("TEMP: \(temp)")
// Attempt 6 - Tried a bitstream frontwards and backwards - Doesn't work
readBuffer = Array<UInt8>(count: 4, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
var bitBuffer: [String] = Array<String>(count:4, repeatedValue: "")
for var i = 0; i < bitBuffer.count; i++ {
bitBuffer[ i ] = String(readBuffer[ i ], radix: 2)
bitBuffer[ i ] = String(count: 8 - bitBuffer[ i ].characters.count, repeatedValue: Character("0")) + bitBuffer[ i ]
//bitBuffer[ i ] = String(bitBuffer[ i ].characters.reverse())
}
print("TEMP: \(bitBuffer)")
// Attempt 7 - More like the Obj. C code - Doesn't work
readBuffer = Array<UInt8>(count: 4, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let value = UnsafePointer<UInt32>(readBuffer).memory
let tempData = CFSwapInt32LittleToHost(value)
let exponent = tempData >> 24
let mantissa = tempData & 0x00FFFFFF
if (tempData == 0x007FFFFF) {
print(" *** INVALID *** ")
return
}
let tempValue = Double(mantissa) * pow(10.0, Double(exponent))
print("TEMP: \(tempValue)")
// Attempt 8 - Saw that BLE spec says "NO Exponent" - Doesnt' work
readBuffer = Array<UInt8>(count: 1, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
readBuffer = Array<UInt8>(count: 3, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let tempValue = UnsafePointer<Float>(readBuffer).memory
print("TEMP: \(tempValue)")
// Example data:
// ["00110110", "00000001", "00000000", "11111111"]
//
// Only the first byte appears to ever change.
*/
// Timestamp - Year - works
readBuffer = Array<UInt8>(count: 2, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let year = UnsafePointer<UInt16>(readBuffer).memory
// Timestamp Remainder - works
readBuffer = Array<UInt8>(count: 5, repeatedValue: 0)
stream.read(&readBuffer, maxLength: readBuffer.count)
let month = readBuffer[ 0 ]
let day = readBuffer[ 1 ]
let hour = readBuffer[ 2 ]
let minute = readBuffer[ 3 ]
let second = readBuffer[ 4 ]
print("TIMESTAMP: \(month)/\(day)/\(year) \(hour):\(minute):\(second)")
ich dieses Beispiel in Objective C gefunden habe, die ich nicht weiß (https://github.com/AngelSensor/angel-sdk/blob/b7459d9c86c6a5c72d8e58b696345b642286b876/iOS/SDK/Services/HealthThermometer/ANHTTemperatureMeasurmentCharacteristic.m), und ich habe versucht, von ihm zu arbeiten, aber es ist mir nicht klar, was genau vor sich geht:
// flags
uint8_t flags = dataPointer[0];
dataPointer++;
// temperature
uint32_t tempData = (uint32_t)CFSwapInt32LittleToHost(*(uint32_t *)dataPointer);
dataPointer += 4;
int8_t exponent = (int8_t)(tempData >> 24);
int32_t mantissa = (int32_t)(tempData & 0x00FFFFFF);
if (tempData == 0x007FFFFF) {
return;
}
float tempValue = (float)(mantissa*pow(10, exponent));
Wenn mir jemand helfen könnte aus mit, wie die Flaggen und Thermometer Messungen ziehen aus Diese BLE-Eigenschaft würde ich sehr dankbar sein. Vielen Dank.
Ich wurde gebeten, Beispieldaten unten zu geben. Hier ist mein Beispieldaten ist (12 Bytes gesamt):
["00000010", "00110011", "00000001", "00000000", "11111111", "11100000", "00000111", "00000100", "00001111", "00000001", "00000101", "00101100"]
-OR-
<025e0100 ffe00704 0f11150f>
Können Sie ein Beispiel für Ihre Eingangsdaten veröffentlichen? – pbush25
Enthalten oben. Lass es mich wissen, wenn du etwas anderes meintest. Vielen Dank. – pennstump
Sie erstellen also ein Array von Strings aus den Bits, die Sie von BLE erhalten? Ich bin verwirrt, was der Zweck der letzten Funktion ist, die Sie gerade gepostet haben. – pbush25