From a05b2722b34122baa89ca0a0c087b07934fed819 Mon Sep 17 00:00:00 2001 From: JongChern Date: Thu, 10 Apr 2025 14:19:42 +0800 Subject: [PATCH 01/21] UUID for 3R --- .../ShimmerBluetooth/BleByteRadio.swift | 15 +++++++++++++-- .../ShimmerBluetooth/Shimmer3Protocol.swift | 7 ++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift b/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift index 5d3b413..91f2a70 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift @@ -8,7 +8,8 @@ public class BleByteRadio : NSObject, ByteCommunication { var RBL_CHAR_TX_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" private var bluetoothManager: BluetoothManager? public static let VERISENSE = "Verisense" - public static let SHIMMER = "Shimmer" + public static let SHIMMER3 = "Shimmer3" + public static let SHIMMER3R = "Shimmer3r" private var continuation: CheckedContinuation? public static let VERISENSE_RBL_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" public static let VERISENSE_RBL_CHAR_RX_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" @@ -17,6 +18,12 @@ public class BleByteRadio : NSObject, ByteCommunication { public static let SHIMMER3_RBL_SERVICE_UUID = "49535343-FE7D-4AE5-8FA9-9FAFD205E455" public static let SHIMMER3_RBL_CHAR_RX_UUID = "49535343-1E4D-4BD9-BA61-23C647249616" public static let SHIMMER3_RBL_CHAR_TX_UUID = "49535343-8841-43F4-A8D4-ECBE34729BB3" + + public static let SHIMMER3R_RBL_SERVICE_UUID = "65333333-A115-11E2-9E9A-0800200CA100" + public static let SHIMMER3R_RBL_CHAR_RX_UUID = "65333333-A115-11E2-9E9A-0800200CA102" + public static let SHIMMER3R_RBL_CHAR_TX_UUID = "65333333-A115-11E2-9E9A-0800200CA101" + + public var deviceName: String? public var delegate: ByteCommunicationDelegate? @@ -38,7 +45,11 @@ public class BleByteRadio : NSObject, ByteCommunication { RBL_SERVICE_UUID = BleByteRadio.VERISENSE_RBL_SERVICE_UUID RBL_CHAR_RX_UUID = BleByteRadio.VERISENSE_RBL_CHAR_RX_UUID RBL_CHAR_TX_UUID = BleByteRadio.VERISENSE_RBL_CHAR_TX_UUID - } else if let isActive = self.activePeripheral?.name?.contains(BleByteRadio.SHIMMER), isActive { + } else if let isActive = self.activePeripheral?.name?.contains(BleByteRadio.SHIMMER3R), isActive { + RBL_SERVICE_UUID = BleByteRadio.SHIMMER3R_RBL_SERVICE_UUID + RBL_CHAR_RX_UUID = BleByteRadio.SHIMMER3R_RBL_CHAR_RX_UUID + RBL_CHAR_TX_UUID = BleByteRadio.SHIMMER3R_RBL_CHAR_TX_UUID + } else if let isActive = self.activePeripheral?.name?.contains(BleByteRadio.SHIMMER3), isActive { RBL_SERVICE_UUID = BleByteRadio.SHIMMER3_RBL_SERVICE_UUID RBL_CHAR_RX_UUID = BleByteRadio.SHIMMER3_RBL_CHAR_RX_UUID RBL_CHAR_TX_UUID = BleByteRadio.SHIMMER3_RBL_CHAR_TX_UUID diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index ae3c1d5..db72910 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -11,11 +11,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { enum HardwareType: Int { case Shimmer3 = 3 - + case Shimmer3R = 10 var description: String { switch self { case .Shimmer3: return "Shimmer3" + case .Shimmer3R: + return "Shimmer3R" } } } @@ -564,6 +566,9 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { if (self.receivedBytes[1] == PacketTypeShimmer.inquiryResponse.rawValue) { var length = 1 + 1 + 8 //ack + response byte + 8 + if (self.REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + length = length + 3; + } var received = Array(self.receivedBytes.prefix(length)) self.receivedBytes.removeFirst(length) for index in 0..<(received[2+6]+self.CRCMode.rawValue){ From ff86b99f0f44bd991f24c1d87943e7cf9bbc026a Mon Sep 17 00:00:00 2001 From: JongChern Date: Fri, 11 Apr 2025 13:55:16 +0800 Subject: [PATCH 02/21] Update Shimmer3Protocol.swift minor update to support 3r --- ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index db72910..9261473 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -565,13 +565,17 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } else if (self.commandSent==PacketTypeShimmer.inquiryCommand){ if (self.receivedBytes[1] == PacketTypeShimmer.inquiryResponse.rawValue) { + print(self.receivedBytes.map { String($0) }.joined(separator: " ")) var length = 1 + 1 + 8 //ack + response byte + 8 + var xlength = 0 if (self.REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ - length = length + 3; + xlength = 3 + length = length + xlength } var received = Array(self.receivedBytes.prefix(length)) self.receivedBytes.removeFirst(length) - for index in 0..<(received[2+6]+self.CRCMode.rawValue){ + + for index in 0..<(received[2+6+xlength]+self.CRCMode.rawValue){ received.append(self.receivedBytes.removeFirst()) } var crcresult = true From 4b7ac2ce18268dd88f74c82c9a82da27cd9cc052 Mon Sep 17 00:00:00 2001 From: JongChern Date: Fri, 18 Apr 2025 16:21:44 +0800 Subject: [PATCH 03/21] Update BleByteRadio.swift --- ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift b/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift index 91f2a70..3584a4f 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/BleByteRadio.swift @@ -9,7 +9,7 @@ public class BleByteRadio : NSObject, ByteCommunication { private var bluetoothManager: BluetoothManager? public static let VERISENSE = "Verisense" public static let SHIMMER3 = "Shimmer3" - public static let SHIMMER3R = "Shimmer3r" + public static let SHIMMER3R = "Shimmer3R" private var continuation: CheckedContinuation? public static let VERISENSE_RBL_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" public static let VERISENSE_RBL_CHAR_RX_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" From 1224362e3bf605d7f1bd7ec3e9474fd12fa1e6c9 Mon Sep 17 00:00:00 2001 From: JongChern Date: Mon, 21 Apr 2025 14:50:53 +0800 Subject: [PATCH 04/21] Update Shimmer3Protocol.swift --- .../ShimmerBluetooth/Shimmer3Protocol.swift | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 9261473..0d2fa82 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -266,7 +266,12 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } shimmer3InfoMem.configByteParse(configBytes: infoMem) initializeSensors() - await sendPressureCalibCoefficientsCommand() + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + await sendBMP280PressureCalibCoefficientsCommand() + } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + await sendPressureCalibCoefficientsCommand() + } + await sendInquiryCommand() changeState(btState:Shimmer3BTState.CONNECTED) print("Current State: \(BTState)") @@ -1292,7 +1297,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } } - private func sendPressureCalibCoefficientsCommand() async -> Bool?{ + private func sendBMP280PressureCalibCoefficientsCommand() async -> Bool?{ let bytes:[UInt8] = [PacketTypeShimmer.getBmp280CalibrationCoefficientsCommand.rawValue] commandSent = PacketTypeShimmer.getBmp280CalibrationCoefficientsCommand @@ -1307,6 +1312,10 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } } + private func sendPressureCalibCoefficientsCommand() async -> Bool?{ + + } + public func sendSetSamplingRateCommand(samplingRate: Double) async -> Bool?{ var samplingByteValue = (Int)(32768/samplingRate) var bytes = [UInt8]() @@ -1771,6 +1780,8 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case bmp180CalibrationCoefficientsResponse = 0x58 case getBmp280CalibrationCoefficientsCommand = 0xA0 case bmp280CalibrationCoefficientsResponse = 0x9F + case getpressureCalibrationCoefficientsCommand = 0xA7 + case pressureCalibrationCoefficientsResponse = 0xA6 case setExgRegsCommand = 0x61 case exgRegsResponse = 0x62 case getExgRegsCommand = 0x63 From f3d05cddab67353fce9eef74a12cb99ce7573dc2 Mon Sep 17 00:00:00 2001 From: JongChern Date: Tue, 22 Apr 2025 11:15:05 +0800 Subject: [PATCH 05/21] Update Shimmer3Protocol.swift --- .../ShimmerBluetooth/Shimmer3Protocol.swift | 73 +++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 0d2fa82..b012314 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -594,7 +594,11 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { self.removeACKandCRCForResponse(bytes: &received) print(received) self.inquiry = received - self.interpretInquiryResponseShimmer3(packet: received) + if (self.REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + self.interpretInquiryResponseShimmer3R(packet: received) + } else if (self.REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + self.interpretInquiryResponseShimmer3(packet: received) + } print("Command ACK Received and Processed: \(self.commandSent!)") self.continuation?.resume(returning: true) self.continuation = nil @@ -853,7 +857,11 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.XLNAccel.rawValue: //if HardwareVersion == ShimmerVersion.SHIMMER3 { signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_X) - signalDataTypeArray.append(SensorDataType.u12) + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + signalDataTypeArray.append(SensorDataType.u12) + } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + signalDataTypeArray.append(SensorDataType.i16) + } lnAccelSensor.packetIndexAccelX = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) @@ -866,7 +874,11 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.YLNAccel.rawValue: //if HardwareVersion == ShimmerVersion.SHIMMER3 { signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_Y) - signalDataTypeArray.append(SensorDataType.u12) + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + signalDataTypeArray.append(SensorDataType.u12) + } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + signalDataTypeArray.append(SensorDataType.i16) + } lnAccelSensor.packetIndexAccelY = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) @@ -879,7 +891,11 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.ZLNAccel.rawValue: //if HardwareVersion == ShimmerVersion.SHIMMER3 { signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_Z) - signalDataTypeArray.append(SensorDataType.u12) + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + signalDataTypeArray.append(SensorDataType.u12) + } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + signalDataTypeArray.append(SensorDataType.i16) + } lnAccelSensor.packetIndexAccelZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) @@ -1144,6 +1160,53 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } } + func interpretInquiryResponseShimmer3R(packet: [UInt8]) { + // Check if this packet is sane and not just random + if packet.count >= 4 { // Max number of channels currently allowable + let ADCRawSamplingRateValue = Int(packet[0]) + (Int(packet[1]) << 8 & 0xFF00) + CurrentSamplingRate = Double(32768) / Double(ADCRawSamplingRateValue) + + let ConfigSetupByte0 = Int64(packet[2]) + (Int64(packet[3]) << 8) + (Int64(packet[4]) << 16) + (Int64(packet[5]) << 24) + let AccelHRBit = Int((ConfigSetupByte0 >> 0) & 0x01) + let AccelLPBit = Int((ConfigSetupByte0 >> 1) & 0x01) + let AccelRange = Int((ConfigSetupByte0 >> 2) & 0x03) + let GyroRange = Int((ConfigSetupByte0 >> 16) & 0x03) + let MagGain = Int((ConfigSetupByte0 >> 21) & 0x07) + let AccelSamplingRate = Int((ConfigSetupByte0 >> 4) & 0xF) + let Mpu9150SamplingRate = Int((ConfigSetupByte0 >> 8) & 0xFF) + let magSamplingRate = Int((ConfigSetupByte0 >> 18) & 0x07) + let PressureResolution = Int((ConfigSetupByte0 >> 28) & 0x03) + let GSRRange = Int((ConfigSetupByte0 >> 25) & 0x07) + let InternalExpPower = Int((ConfigSetupByte0 >> 24) & 0x01) + let Mpu9150AccelRange = Int((ConfigSetupByte0 >> 30) & 0x03) + + if magSamplingRate == 4 && ADCRawSamplingRateValue < 3200 { + // 3200 is the raw ADC value and not in HZ + let LowPowerMagEnabled = true + } + + if AccelSamplingRate == 2 && ADCRawSamplingRateValue < 3200 { + let LowPowerAccelEnabled = true + } + + if Mpu9150SamplingRate == 0xFF && ADCRawSamplingRateValue < 3200 { + let LowPowerGyroEnabled = true + } + + let NumberofChannels = Int(packet[6+3]) + let BufferSize = Int(packet[7+3]) + var ListofSensorChannels: [UInt8] = [] + + for i in 0.. Bool?{ - + return true; } public func sendSetSamplingRateCommand(samplingRate: Double) async -> Bool?{ From 26a4a5427d257f6ad9e47316fb1807af38b3a282 Mon Sep 17 00:00:00 2001 From: JongChern Date: Tue, 22 Apr 2025 15:12:54 +0800 Subject: [PATCH 06/21] ln accel streaming now --- .../ShimmerBluetooth/IMUSensor.swift | 5 + .../ShimmerBluetooth/LNAccelSensor.swift | 24 ++- .../ShimmerBluetooth/Shimmer3Protocol.swift | 158 ++---------------- .../ShimmerExamplePlot/ViewModel.swift | 88 +++++----- 4 files changed, 85 insertions(+), 190 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/IMUSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/IMUSensor.swift index 4156329..9669845 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/IMUSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/IMUSensor.swift @@ -8,6 +8,11 @@ import Foundation public class IMUSensor: Sensor, IMUProcessing { + let HardwareVersion: Int + required init(hwid: Int) { + self.HardwareVersion = hwid + super.init() + } public static func calibrateInertialSensorData(_ data: [Double], _ AM: [[Double]], _ SM: [[Double]], _ OV: [Double]) -> [Double]? { /* Based on the theory outlined by Ferraris F, Grimaldi U, and Parvis M. diff --git a/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift index b427f2a..6f4055a 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift @@ -17,16 +17,25 @@ public class LNAccelSensor : IMUSensor , SensorProcessing{ var AlignmentMatrix:[[Double]] = [[]] var SensitivityMatrix:[[Double]] = [[]] var OffsetVector:[Double]=[] - let CALIBRATION_ID = 2 + var CalibrationID = 2 public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { let x = Array(sensorPacket[packetIndexAccelX..= 6 { - signalDataTypeArray.append(SensorDataType.u24) packetSize = TimeStampPacketByteSize // Time stamp timeSensor.packetIndexTimeStamp = 0 timeSensor.sensorEnabled = true @@ -855,242 +859,119 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { switch signalIdByte { case ChannelContentsShimmer3.XLNAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_X) - if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ - signalDataTypeArray.append(SensorDataType.u12) - } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ - signalDataTypeArray.append(SensorDataType.i16) - } lnAccelSensor.packetIndexAccelX = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) - /*} else if HardwareVersion == ShimmerVersion.SHIMMER2R { - signalNameArray.append(Shimmer2Configuration.SignalNames.ACCELEROMETER_X) - signalDataTypeArray.append("u12") - packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer2.SENSOR_ACCEL) - }*/ case ChannelContentsShimmer3.YLNAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_Y) - if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ - signalDataTypeArray.append(SensorDataType.u12) - } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ - signalDataTypeArray.append(SensorDataType.i16) - } lnAccelSensor.packetIndexAccelY = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) - /*} else if HardwareVersion == ShimmerVersion.SHIMMER2R { - signalNameArray.append(Shimmer2Configuration.SignalNames.ACCELEROMETER_Y) - signalDataTypeArray.append("u12") - packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer2.SENSOR_ACCEL) - }*/ case ChannelContentsShimmer3.ZLNAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(LNAccelSensor.LOW_NOISE_ACCELEROMETER_Z) - if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ - signalDataTypeArray.append(SensorDataType.u12) - } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ - signalDataTypeArray.append(SensorDataType.i16) - } lnAccelSensor.packetIndexAccelZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) - /*} else if HardwareVersion == ShimmerVersion.SHIMMER2R { - signalNameArray.append(Shimmer2Configuration.SignalNames.ACCELEROMETER_Z) - signalDataTypeArray.append("u12") - packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer2.SENSOR_ACCEL) - }*/ case ChannelContentsShimmer3.VBatt.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(Shimmer3Configuration.SignalNames.V_SENSE_BATT) - signalDataTypeArray.append(SensorDataType.i16) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_VBATT.rawValue) - /*} else if HardwareVersion == ShimmerVersion.SHIMMER2R { - signalNameArray.append(Shimmer2Configuration.SignalNames.GYROSCOPE_X) - signalDataTypeArray.append("u12") - packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer2.SENSOR_GYRO) - }*/ - // Add more cases for other signal IDs... case ChannelContentsShimmer3.XWRAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(WRAccelSensor.WIDE_RANGE_ACCELEROMETER_X) - signalDataTypeArray.append(SensorDataType.i16) wrAccelSensor.packetIndexAccelX = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) - case ChannelContentsShimmer3.YWRAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(WRAccelSensor.WIDE_RANGE_ACCELEROMETER_Y) - signalDataTypeArray.append(SensorDataType.i16) wrAccelSensor.packetIndexAccelY = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) - case ChannelContentsShimmer3.ZWRAccel.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(WRAccelSensor.WIDE_RANGE_ACCELEROMETER_Z) - signalDataTypeArray.append(SensorDataType.i16) wrAccelSensor.packetIndexAccelZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) case ChannelContentsShimmer3.XMag.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(Shimmer3Configuration.SignalNames.MAGNETOMETER_X) - signalDataTypeArray.append(SensorDataType.i16) magSensor.packetIndexMagX = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) - case ChannelContentsShimmer3.YMag.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(Shimmer3Configuration.SignalNames.MAGNETOMETER_Y) - signalDataTypeArray.append(SensorDataType.i16) magSensor.packetIndexMagY = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) - case ChannelContentsShimmer3.ZMag.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(Shimmer3Configuration.SignalNames.MAGNETOMETER_Z) - signalDataTypeArray.append(SensorDataType.i16) magSensor.packetIndexMagZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) case ChannelContentsShimmer3.XGyro.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(GyroSensor.GYROSCOPE_X) - signalDataTypeArray.append(SensorDataType.i16MSB) gyroSensor.packetIndexGyroX = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) - case ChannelContentsShimmer3.YGyro.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(GyroSensor.GYROSCOPE_Y) - signalDataTypeArray.append(SensorDataType.i16MSB) gyroSensor.packetIndexGyroY = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) - case ChannelContentsShimmer3.ZGyro.rawValue: - //if HardwareVersion == ShimmerVersion.SHIMMER3 { - signalNameArray.append(GyroSensor.GYROSCOPE_Z) - signalDataTypeArray.append(SensorDataType.i16MSB) gyroSensor.packetIndexGyroZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) case ChannelContentsShimmer3.GsrRaw.rawValue: - signalNameArray.append(GSRSensor.GSR) - signalDataTypeArray.append(SensorDataType.u16) gsrSensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_GSR.rawValue) case ChannelContentsShimmer3.Exg1_Status.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG1_STATUS) - signalDataTypeArray.append(SensorDataType.u8) packetSize += 1 case ChannelContentsShimmer3.Exg1_CH1.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG1_CH1_24BIT) - signalDataTypeArray.append(SensorDataType.i24MSB) packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue) case ChannelContentsShimmer3.Exg1_CH2.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG1_CH2_24BIT) - signalDataTypeArray.append(SensorDataType.i24MSB) packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue) case ChannelContentsShimmer3.Exg2_Status.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG2_STATUS) - signalDataTypeArray.append(SensorDataType.u8) packetSize += 1 case ChannelContentsShimmer3.Exg2_CH1.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG2_CH1_24BIT) - signalDataTypeArray.append(SensorDataType.i24MSB) packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue) case ChannelContentsShimmer3.Exg2_CH2.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG2_CH2_24BIT) - signalDataTypeArray.append(SensorDataType.i24MSB) packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue) case ChannelContentsShimmer3.Exg1_CH1_16Bit.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG1_CH1_16BIT) - signalDataTypeArray.append(SensorDataType.i16MSB) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG1_16BIT.rawValue) case ChannelContentsShimmer3.Exg1_CH2_16Bit.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG1_CH2_16BIT) - signalDataTypeArray.append(SensorDataType.i16MSB) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG1_16BIT.rawValue) case ChannelContentsShimmer3.Exg2_CH1_16Bit.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG2_CH1_16BIT) - signalDataTypeArray.append(SensorDataType.i16MSB) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_16BIT.rawValue) case ChannelContentsShimmer3.Exg2_CH2_16Bit.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.EXG2_CH2_16BIT) - signalDataTypeArray.append(SensorDataType.i16MSB) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_16BIT.rawValue) case ChannelContentsShimmer3.InternalAdc13.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A13.description) - signalDataTypeArray.append(SensorDataType.u12) adcA13Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A13.rawValue) case ChannelContentsShimmer3.ExternalAdc15.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A15.description) - signalDataTypeArray.append(SensorDataType.u12) adcA15Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A15.rawValue) case ChannelContentsShimmer3.InternalAdc12.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A12.description) - signalDataTypeArray.append(SensorDataType.u12) adcA12Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A12.rawValue) case ChannelContentsShimmer3.InternalAdc1.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A1.description) - signalDataTypeArray.append(SensorDataType.u12) adcA1Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A1.rawValue) case ChannelContentsShimmer3.ExternalAdc6.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A6.description) - signalDataTypeArray.append(SensorDataType.u12) adcA6Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A6.rawValue) case ChannelContentsShimmer3.ExternalAdc7.rawValue: - signalNameArray.append(ADCSensor.ADCType.Shimmer3_A7.description) - signalDataTypeArray.append(SensorDataType.u12) adcA7Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A7.rawValue) case ChannelContentsShimmer3.Temperature.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.TEMPERATURE) - signalDataTypeArray.append(SensorDataType.u16MSB) packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) case ChannelContentsShimmer3.Pressure.rawValue: - signalNameArray.append(Shimmer3Configuration.SignalNames.PRESSURE) - signalDataTypeArray.append(SensorDataType.u24MSB) packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) - default: - signalNameArray.append("") - signalDataTypeArray.append(SensorDataType.u12) packetSize += 2 } @@ -1098,12 +979,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } EnabledSensors = enabledSensors - SignalNameArray = signalNameArray - SignalDataTypeArray = signalDataTypeArray PacketSize = packetSize + Int(CRCMode.rawValue) - - print(SignalNameArray) - print(SignalDataTypeArray) print(PacketSize) //print("Packet Size : \(PacketSize) CRC Mode and starting byte not included") } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index 9913b8d..5a06999 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift @@ -118,11 +118,11 @@ class ViewModel: NSObject, ObservableObject { func sendInfoMemConfigUpdate() async { var infomem = shimmer3Protocol?.getInfoMemByteArray() - var wrAccel = WRAccelSensor() - infomem = wrAccel.updateInfoMemAccelRange(infomem: infomem!, range: WRAccelSensor.Range.fromValue(UInt8(wrRangeIndex))!) + var wrAccel = shimmer3Protocol?.wrAccelSensor + infomem = wrAccel?.updateInfoMemAccelRange(infomem: infomem!, range: WRAccelSensor.Range.fromValue(UInt8(wrRangeIndex))!) - var gyro = GyroSensor() - infomem = gyro.updateInfoMemGyroRange(infomem: infomem!, range: GyroSensor.Range.fromValue(UInt8(gyroRangeIndex))!) + var gyro = shimmer3Protocol?.gyroSensor + infomem = gyro?.updateInfoMemGyroRange(infomem: infomem!, range: GyroSensor.Range.fromValue(UInt8(gyroRangeIndex))!) var press = PressureTempSensor() infomem = press.updateInfoMemPressureResolution(infomem: infomem!, res: PressureTempSensor.Resolution.fromValue(UInt8(pressResIndex))!) @@ -140,14 +140,14 @@ class ViewModel: NSObject, ObservableObject { infomem = shimmer3Protocol?.updateInfoMemSamplingRate(infomem: infomem!,samplingRateFreq: samplingRate!) infomem = shimmer3Protocol?.exgSensor.updateInfoMemExgRate(infomem: infomem!,samplingRateFreq: samplingRate!) let updatedSensors = shimmer3Protocol?.isShimmer3withUpdatedSensors() - var mag = MagSensor() - infomem = mag.setLowPowerMag(enable:false, isShimmer3withUpdatedSensors: updatedSensors!, isShimmer3Sensor: (shimmer3Protocol?.isShimmer3Sensor())!, samplingRate: samplingRate!, infomem: infomem!) + var mag = shimmer3Protocol?.magSensor + infomem = mag?.setLowPowerMag(enable:false, isShimmer3withUpdatedSensors: updatedSensors!, isShimmer3Sensor: (shimmer3Protocol?.isShimmer3Sensor())!, samplingRate: samplingRate!, infomem: infomem!) - var wrAccel = WRAccelSensor() - infomem = wrAccel.setLowPowerWRAccel(enable:false, isShimmer3withUpdatedSensors: updatedSensors!, samplingRate: samplingRate!, infomem: infomem!) + var wrAccel = shimmer3Protocol?.wrAccelSensor + infomem = wrAccel?.setLowPowerWRAccel(enable:false, isShimmer3withUpdatedSensors: updatedSensors!, samplingRate: samplingRate!, infomem: infomem!) - var gyro = GyroSensor() - infomem = gyro.setLowPowerGyro(enable:false, samplingRate: samplingRate!, infomem: infomem!) + var gyro = shimmer3Protocol?.gyroSensor + infomem = gyro?.setLowPowerGyro(enable:false, samplingRate: samplingRate!, infomem: infomem!) await shimmer3Protocol?.writeShimmer3InfoMem(infoMem: infomem!) } @@ -303,43 +303,45 @@ extension ViewModel : ShimmerProtocolDelegate { } func shimmerProtocolNewObjectCluster(message: ShimmerBluetooth.ObjectCluster) { - print(message) - - if (!updatedPicker){ - pickerData = message.SignalNames; - updatedPicker = true; - } - - if (message.SignalData.count>=1){ - if (message.SignalData.count0){ - self.signal1.append(message.SignalData[startIndex+0]) + + if (message.SignalData.count >= 1) { + if (message.SignalData.count < self.startIndex + self.numberOfSignals) { + self.startIndex = 0 + } + if (self.numberOfSignals > 0) { + self.signal1.append(message.SignalData[self.startIndex + 0]) + } } - } - if (message.SignalData.count>=2){ - if (numberOfSignals>1){ - self.signal2.append(message.SignalData[startIndex+1]) + if (message.SignalData.count >= 2) { + if (self.numberOfSignals > 1) { + self.signal2.append(message.SignalData[self.startIndex + 1]) + } } - } - if (message.SignalData.count>=3){ - if (numberOfSignals>2){ - self.signal3.append(message.SignalData[startIndex+2]) + if (message.SignalData.count >= 3) { + if (self.numberOfSignals > 2) { + self.signal3.append(message.SignalData[self.startIndex + 2]) + } + } + if (self.signal1.count == 500) { + self.signal1.removeFirst() + } + if (self.signal2.count == 500) { + self.signal2.removeFirst() + } + if (self.signal3.count == 500) { + self.signal3.removeFirst() + } + self.count += 1 + if (self.count % 10 == 0) { + self.delegate?.plotEvent(message: "") } - } - if (signal1.count==500){ - signal1.removeFirst() - } - if (signal2.count==500){ - signal2.removeFirst() - } - if (signal3.count==500){ - signal3.removeFirst() - } - self.count+=1 - if (self.count%10 == 0){ - self.delegate?.plotEvent(message: "") } } From ffa19977834be7765ab9f778e85fe912a27d65c4 Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Tue, 29 Apr 2025 14:23:32 +0800 Subject: [PATCH 07/21] more fixes, 3r support, updates --- .../ConfigByteLayoutShimmer3.swift | 10 +- .../ShimmerBluetooth/GyroSensor.swift | 43 +-- .../ShimmerBluetooth/IMUSensor.swift | 2 +- .../ShimmerBluetooth/LNAccelSensor.swift | 134 +++++++- .../ShimmerBluetooth/PressureTempSensor.swift | 52 +-- .../ShimmerBluetooth/Shimmer3Protocol.swift | 8 +- .../ShimmerBluetooth/WRAccelSensor.swift | 53 ++- .../ShimmerExamplePlot/ContentView.swift | 322 ++++++++++-------- .../ShimmerExamplePlot/ViewModel.swift | 54 ++- 9 files changed, 453 insertions(+), 225 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift index 8711694..0a6c76f 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift @@ -41,7 +41,7 @@ public class ConfigByteLayoutShimmer3{ static let idxAnalogAccelCalibration = 31 static let idxMPU9150GyroCalibration = 52 static let idxLSM303DLHCMagCalibration = 73 - static let idxLSM303DLHCAccelCalibration = 94 //94->114 + //static let idxLSM303DLHCAccelCalibration = 94 //94->114 static let idxSDExperimentConfig0 = 128+89; static let idxSDExperimentConfig1 = 128+90; @@ -63,12 +63,20 @@ public class ConfigByteLayoutShimmer3{ static let bitShiftLSM303DLHCMagRange = 5; static let maskLSM303DLHCMagRange = 0x07; + static let bitShiftMPU9150AccelRange = 6; + static let maskMPU9150AccelRange = 0x03; + static let bitShiftLSM303DLHCMagSamplingRate = 2; static let maskLSM303DLHCMagSamplingRate = 0x07; static let bitShiftLSM303DLHCAccelSamplingRate = 4; static let maskLSM303DLHCAccelSamplingRate = 0x0F; + static let idxLSM6DSVAccelCalibration = 34; + static let idxLSM303DLHCAccelCalibration = 97; + + static let lengthGeneralCalibrationBytes = 21; + static let bitShiftRTCError = 4; static let maskRTCError = 1; } diff --git a/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift index 72196bb..31a1f96 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift @@ -109,28 +109,29 @@ public class GyroSensor : IMUSensor , SensorProcessing{ public func updateInfoMemGyroRange(infomem: [UInt8],range: Range) -> [UInt8]{ var infomemtoupdate = infomem print("oriinfomem: \(infomemtoupdate)") - - var gyroRange = 0 - if (range == Range.RANGE_250DPS){ - gyroRange = 0 - } else if (range == Range.RANGE_500DPS){ - gyroRange = 1 - } else if (range == Range.RANGE_1000DPS){ - gyroRange = 2 - } else if (range == Range.RANGE_2000DPS){ - gyroRange = 3 - } - let orivalue = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] - let value = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] & ~UInt8(ConfigByteLayoutShimmer3.maskMPU9150GyroRange< Range? { + switch value { + case 0: + return .RANGE_2G + case 1: + return .RANGE_4G + case 2: + return .RANGE_8G + case 3: + return .RANGE_16G + default: + return nil + } + } + + } + + var CurrentRange = Range.RANGE_2G public static let LOW_NOISE_ACCELEROMETER_X = "Low Noise Accelerometer X" public static let LOW_NOISE_ACCELEROMETER_Y = "Low Noise Accelerometer Y" public static let LOW_NOISE_ACCELEROMETER_Z = "Low Noise Accelerometer Z" @@ -18,6 +43,24 @@ public class LNAccelSensor : IMUSensor , SensorProcessing{ var SensitivityMatrix:[[Double]] = [[]] var OffsetVector:[Double]=[] var CalibrationID = 2 + var AlignmentMatrix_2G:[[Double]] = [[]] + var SensitivityMatrix_2G:[[Double]] = [[]] + var OffsetVector_2G:[Double]=[] + var AlignmentMatrix_4G:[[Double]] = [[]] + var SensitivityMatrix_4G:[[Double]] = [[]] + var OffsetVector_4G:[Double]=[] + var AlignmentMatrix_8G:[[Double]] = [[]] + var SensitivityMatrix_8G:[[Double]] = [[]] + var OffsetVector_8G:[Double]=[] + var AlignmentMatrix_16G:[[Double]] = [[]] + var SensitivityMatrix_16G:[[Double]] = [[]] + var OffsetVector_16G:[Double]=[] + var lnAccelRange = 1 + + var calibBytes_2G: [UInt8] = [] + var calibBytes_4G: [UInt8] = [] + var calibBytes_8G: [UInt8] = [] + var calibBytes_16G: [UInt8] = [] public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { let x = Array(sensorPacket[packetIndexAccelX.. [UInt8]{ + var infomemtoupdate = infomem + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + var lnAccelRange = 0 + var calibBytes = calibBytes_2G + if (range == Range.RANGE_2G){ + lnAccelRange = 0 + calibBytes = calibBytes_2G + } else if (range == Range.RANGE_4G){ + lnAccelRange = 1 + calibBytes = calibBytes_4G + } else if (range == Range.RANGE_8G){ + lnAccelRange = 2 + calibBytes = calibBytes_8G + } else if (range == Range.RANGE_16G){ + lnAccelRange = 3 + calibBytes = calibBytes_16G + } + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxLSM6DSVAccelCalibration..Range{ + return CurrentRange + } + public func setInfoMem(infomem: [UInt8]) { var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>7) & 1 if (enabled == 1){ @@ -74,6 +173,35 @@ public class LNAccelSensor : IMUSensor , SensorProcessing{ } else { sensorEnabled = false } + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + lnAccelRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte3]>>ConfigByteLayoutShimmer3.bitShiftMPU9150AccelRange) & ConfigByteLayoutShimmer3.maskMPU9150AccelRange) + if (lnAccelRange == 0){ + CurrentRange = Range.RANGE_2G + AlignmentMatrix = AlignmentMatrix_2G + SensitivityMatrix = SensitivityMatrix_2G + OffsetVector = OffsetVector_2G + } + if (lnAccelRange == 1){ + CurrentRange = Range.RANGE_4G + AlignmentMatrix = AlignmentMatrix_4G + SensitivityMatrix = SensitivityMatrix_4G + OffsetVector = OffsetVector_4G + } + if (lnAccelRange == 2){ + CurrentRange = Range.RANGE_8G + AlignmentMatrix = AlignmentMatrix_8G + SensitivityMatrix = SensitivityMatrix_8G + OffsetVector = OffsetVector_8G + } + if (lnAccelRange == 3){ + CurrentRange = Range.RANGE_16G + AlignmentMatrix = AlignmentMatrix_16G + SensitivityMatrix = SensitivityMatrix_16G + OffsetVector = OffsetVector_16G + } + } + + } diff --git a/ShimmerBluetooth/ShimmerBluetooth/PressureTempSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/PressureTempSensor.swift index 2598a45..8beea06 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/PressureTempSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/PressureTempSensor.swift @@ -8,6 +8,11 @@ import Foundation public class PressureTempSensor: Sensor , SensorProcessing{ + public let HardwareVersion: Int + required init(hwid: Int) { + self.HardwareVersion = hwid + super.init() + } public enum Resolution: UInt8 { case RES_LOW = 0x0 case RES_STANDARD = 0x1 @@ -113,31 +118,32 @@ public class PressureTempSensor: Sensor , SensorProcessing{ } public func updateInfoMemPressureResolution(infomem: [UInt8],res: Resolution) -> [UInt8]{ - var infomemtoupdate = infomem - print("oriinfomem: \(infomemtoupdate)") - - var pressReso = 0 - if (res == Resolution.RES_LOW){ - pressReso = 0 - } else if (res == Resolution.RES_STANDARD){ - pressReso = 1 - } else if (res == Resolution.RES_HIGH){ - pressReso = 2 - } else if (res == Resolution.RES_ULTRAHIGH){ - pressReso = 3 - } - let orivalue = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte3] - let value = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte3] & ~UInt8(ConfigByteLayoutShimmer3.maskBMPX80PressureResolution< ObjectCluster { let x = Array(sensorPacket[packetIndexAccelX.. [UInt8]{ var infomemtoupdate = infomem - var wrAccelRange = 0 - if (range == Range.RANGE_2G){ - wrAccelRange = 0 - } else if (range == Range.RANGE_4G){ - wrAccelRange = 2 - } else if (range == Range.RANGE_8G){ - wrAccelRange = 3 - } else if (range == Range.RANGE_16G){ - wrAccelRange = 1 + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ + var wrAccelRange = 0 + var calibBytes = calibBytes_2G + if (range == Range.RANGE_2G){ + wrAccelRange = 0 + calibBytes = calibBytes_2G + } else if (range == Range.RANGE_4G){ + wrAccelRange = 2 + calibBytes = calibBytes_4G + } else if (range == Range.RANGE_8G){ + wrAccelRange = 3 + calibBytes = calibBytes_8G + } else if (range == Range.RANGE_16G){ + wrAccelRange = 1 + calibBytes = calibBytes_16G + } + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxLSM303DLHCAccelCalibration..Range{ @@ -162,7 +184,6 @@ public class WRAccelSensor : IMUSensor , SensorProcessing{ SensitivityMatrix = SensitivityMatrix_16G OffsetVector = OffsetVector_16G } - } public func setLowPowerWRAccel(enable: Bool, isShimmer3withUpdatedSensors: Bool, samplingRate: Double, infomem: [UInt8])-> [UInt8]{ diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index 89df7d2..a687a36 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -7,6 +7,7 @@ import SwiftUI import Charts +import ShimmerBluetooth struct ToyShape: Identifiable { var type: String @@ -61,7 +62,7 @@ struct ContentView: View { @State private var rangeSelection = 0 @State private var protocolSelection = 0 @State private var deviceSelection = 0 - + var body: some View { ScrollView { Picker(selection: $selectionS, label: Text("Number Of Signals (Max 3)")) { @@ -134,7 +135,7 @@ struct ContentView: View { print(protocolSelection) viewModel.protocolShimmer3 = protocolSelection } - + Text("BT State: \(viewModel.stateText)") Button("Connect Shimmer3",action: {Task { do { @@ -155,162 +156,193 @@ struct ContentView: View { } }) - Button("StartStreaming Shimmer3",action:{ Task { - do { - await viewModel.sendStartStreamingCommandDev2() - } catch { - print("Error: \(error)") - } - } - }) - Button("StopStreaming Shimmer3",action:{ Task { - do { - await viewModel.sendStopStreamingCommandDev2() - } catch { - print("Error: \(error)") - } - } - }) - Button("WriteInfoMem WRAccel Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemAccel() - } catch { - print("Error: \(error)") - } - } - }) - Button("WriteInfoMem IMU Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemIMU() - } catch { - print("Error: \(error)") + Button("StartStreaming Shimmer3",action:{ Task { + do { + await viewModel.sendStartStreamingCommandDev2() + } catch { + print("Error: \(error)") + } } - } - }) - Button("WriteInfoMem PPG+GSR Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemPPGGSR() - } catch { - print("Error: \(error)") + }) + Button("StopStreaming Shimmer3",action:{ Task { + do { + await viewModel.sendStopStreamingCommandDev2() + } catch { + print("Error: \(error)") + } } - } - }) + }) + if (viewModel.shimmer3Protocol?.REV_HW_MAJOR==Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ + Button("WriteInfoMem WRAccel Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemWRAccel() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem IMU Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemIMU() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem Pressure Temperature Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemPressureAndTemperature() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem PPG+GSR Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemPPGGSR() + } catch { + print("Error: \(error)") + } + } + }) - Button("WriteInfoMem ECG 24-bit Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemECG24Bit() - } catch { - print("Error: \(error)") - } - } - }) - Button("WriteInfoMem ECG 16-bit Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemECG16Bit() - } catch { - print("Error: \(error)") - } - } - }) - Button("WriteInfoMem EMG Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemEMG() - } catch { - print("Error: \(error)") + Button("WriteInfoMem ECG 24-bit Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemECG24Bit() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem ECG 16-bit Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemECG16Bit() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem EMG Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemEMG() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem EXG Test Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemEXGTest() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem Respiration Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemRespiration() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem Battery Voltage Shimmer3",action:{ Task { + do { + await viewModel.sendInfoMemBattery() + } catch { + print("Error: \(error)") + } + } + }) + } else if (viewModel.shimmer3Protocol?.REV_HW_MAJOR==Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + Button("WriteInfoMem LNAccel Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RLNAccel() + } catch { + print("Error: \(error)") + } + } + }) } - } - }) - Button("WriteInfoMem EXG Test Shimmer3",action:{ Task { - do { - await viewModel.sendInfoMemEXGTest() - } catch { - print("Error: \(error)") + Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { + ForEach(0.. Date: Tue, 29 Apr 2025 14:53:23 +0800 Subject: [PATCH 08/21] tidy up --- ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift index 5195e70..edc94ed 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/LNAccelSensor.swift @@ -70,11 +70,9 @@ public class LNAccelSensor : IMUSensor , SensorProcessing{ var rawDataY: Double = 0 var rawDataZ: Double = 0 if (HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ - print("sensorData X : \(x) , sensorData Y : \(y), sensorData Z : \(z)") rawDataX = Double(ShimmerUtilities.parseSensorData(sensorData: x, dataType: SensorDataType.u12)!) rawDataY = Double(ShimmerUtilities.parseSensorData(sensorData: y, dataType: SensorDataType.u12)!) rawDataZ = Double(ShimmerUtilities.parseSensorData(sensorData: z, dataType: SensorDataType.u12)!) - print("raw LN X : \(rawDataX) , raw LN Y : \(rawDataY), raw LN Z : \(rawDataZ)") } else if (HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ rawDataX = Double(ShimmerUtilities.parseSensorData(sensorData: x, dataType: SensorDataType.i16)!) rawDataY = Double(ShimmerUtilities.parseSensorData(sensorData: y, dataType: SensorDataType.i16)!) From 18761e89d55657198496a904d51e278d98aab15f Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Wed, 7 May 2025 17:23:50 +0800 Subject: [PATCH 09/21] add s3r wr accel sensor support --- .../ShimmerBluetooth/Shimmer3Protocol.swift | 2 + .../ShimmerBluetooth/WRAccelSensor.swift | 153 +++++++++++++----- .../ShimmerExamplePlot/ContentView.swift | 27 ++-- .../ShimmerExamplePlot/ViewModel.swift | 15 ++ 4 files changed, 145 insertions(+), 52 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index e1f81b1..4b53e5d 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -324,6 +324,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { battVoltageSensor = BattVoltageSensor() } else if(REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ lnAccelSensor = LNAccelSensor(hwid: REV_HW_MAJOR) + wrAccelSensor = WRAccelSensor(hwid: REV_HW_MAJOR) timeSensor = TimeSensor() } } @@ -349,6 +350,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ timeSensor.setInfoMem(infomem: infoMem) lnAccelSensor.setInfoMem(infomem: infoMem) + wrAccelSensor.setInfoMem(infomem: infoMem) } } diff --git a/ShimmerBluetooth/ShimmerBluetooth/WRAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/WRAccelSensor.swift index 7b4fd56..26e5273 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/WRAccelSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/WRAccelSensor.swift @@ -41,7 +41,7 @@ public class WRAccelSensor : IMUSensor , SensorProcessing{ public static let WIDE_RANGE_ACCELEROMETER_Y = "Wide Range Accelerometer Y" public static let WIDE_RANGE_ACCELEROMETER_Z = "Wide Range Accelerometer Z" - let CALIBRATION_ID = 31 + var CalibrationID = 31 var AlignmentMatrix_2G:[[Double]] = [[]] var SensitivityMatrix_2G:[[Double]] = [[]] var OffsetVector_2G:[Double]=[] @@ -88,27 +88,51 @@ public class WRAccelSensor : IMUSensor , SensorProcessing{ } public override func parseSensorCalibrationDump(bytes: [UInt8]){ + if(HardwareVersion==Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + CalibrationID = 39 + } var sensorID = Int(bytes[0]) + (Int(bytes[1])<<8) - if bytes[0] == CALIBRATION_ID { + if bytes[0] == CalibrationID { var range = bytes[2] var calbytes = bytes calbytes.removeFirst(12) - if range==0{ - calibBytes_2G = calbytes - (AlignmentMatrix_2G,SensitivityMatrix_2G,OffsetVector_2G) = parseIMUCalibrationParameters(bytes: calbytes) - } - if range==2{ - calibBytes_4G = calbytes - (AlignmentMatrix_4G,SensitivityMatrix_4G,OffsetVector_4G) = parseIMUCalibrationParameters(bytes: calbytes) - } - if range==3{ - calibBytes_8G = calbytes - (AlignmentMatrix_8G,SensitivityMatrix_8G,OffsetVector_8G) = parseIMUCalibrationParameters(bytes: calbytes) - } - if range==1{ - calibBytes_16G = calbytes - (AlignmentMatrix_16G,SensitivityMatrix_16G,OffsetVector_16G) = parseIMUCalibrationParameters(bytes: calbytes) + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ + + if range==0{ + calibBytes_2G = calbytes + (AlignmentMatrix_2G,SensitivityMatrix_2G,OffsetVector_2G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==2{ + calibBytes_4G = calbytes + (AlignmentMatrix_4G,SensitivityMatrix_4G,OffsetVector_4G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==3{ + calibBytes_8G = calbytes + (AlignmentMatrix_8G,SensitivityMatrix_8G,OffsetVector_8G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==1{ + calibBytes_16G = calbytes + (AlignmentMatrix_16G,SensitivityMatrix_16G,OffsetVector_16G) = parseIMUCalibrationParameters(bytes: calbytes) + } + }else if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + + if range==0{ + calibBytes_2G = calbytes + (AlignmentMatrix_2G,SensitivityMatrix_2G,OffsetVector_2G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==1{ + calibBytes_4G = calbytes + (AlignmentMatrix_4G,SensitivityMatrix_4G,OffsetVector_4G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==2{ + calibBytes_8G = calbytes + (AlignmentMatrix_8G,SensitivityMatrix_8G,OffsetVector_8G) = parseIMUCalibrationParameters(bytes: calbytes) + } + if range==3{ + calibBytes_16G = calbytes + (AlignmentMatrix_16G,SensitivityMatrix_16G,OffsetVector_16G) = parseIMUCalibrationParameters(bytes: calbytes) + } } } @@ -116,9 +140,9 @@ public class WRAccelSensor : IMUSensor , SensorProcessing{ public func updateInfoMemAccelRange(infomem: [UInt8],range: Range) -> [UInt8]{ var infomemtoupdate = infomem + var wrAccelRange = 0 + var calibBytes = calibBytes_2G if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ - var wrAccelRange = 0 - var calibBytes = calibBytes_2G if (range == Range.RANGE_2G){ wrAccelRange = 0 calibBytes = calibBytes_2G @@ -132,6 +156,21 @@ public class WRAccelSensor : IMUSensor , SensorProcessing{ wrAccelRange = 1 calibBytes = calibBytes_16G } + }else if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + if (range == Range.RANGE_2G){ + wrAccelRange = 0 + calibBytes = calibBytes_2G + } else if (range == Range.RANGE_4G){ + wrAccelRange = 1 + calibBytes = calibBytes_4G + } else if (range == Range.RANGE_8G){ + wrAccelRange = 2 + calibBytes = calibBytes_8G + } else if (range == Range.RANGE_16G){ + wrAccelRange = 3 + calibBytes = calibBytes_16G + } + } infomemtoupdate.replaceSubrange( ConfigByteLayoutShimmer3.idxLSM303DLHCAccelCalibration..>ConfigByteLayoutShimmer3.bitShiftLSM303DLHCAccelRange) & ConfigByteLayoutShimmer3.maskLSM303DLHCAccelRange) - if (wrAccelRange == 0){ - CurrentRange = Range.RANGE_2G - AlignmentMatrix = AlignmentMatrix_2G - SensitivityMatrix = SensitivityMatrix_2G - OffsetVector = OffsetVector_2G - } - if (wrAccelRange == 2){ - CurrentRange = Range.RANGE_4G - AlignmentMatrix = AlignmentMatrix_4G - SensitivityMatrix = SensitivityMatrix_4G - OffsetVector = OffsetVector_4G - } - if (wrAccelRange == 3){ - CurrentRange = Range.RANGE_8G - AlignmentMatrix = AlignmentMatrix_8G - SensitivityMatrix = SensitivityMatrix_8G - OffsetVector = OffsetVector_8G - } - if (wrAccelRange == 1){ - CurrentRange = Range.RANGE_16G - AlignmentMatrix = AlignmentMatrix_16G - SensitivityMatrix = SensitivityMatrix_16G - OffsetVector = OffsetVector_16G + + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ + if (wrAccelRange == 0){ + CurrentRange = Range.RANGE_2G + AlignmentMatrix = AlignmentMatrix_2G + SensitivityMatrix = SensitivityMatrix_2G + OffsetVector = OffsetVector_2G + } + if (wrAccelRange == 2){ + CurrentRange = Range.RANGE_4G + AlignmentMatrix = AlignmentMatrix_4G + SensitivityMatrix = SensitivityMatrix_4G + OffsetVector = OffsetVector_4G + } + if (wrAccelRange == 3){ + CurrentRange = Range.RANGE_8G + AlignmentMatrix = AlignmentMatrix_8G + SensitivityMatrix = SensitivityMatrix_8G + OffsetVector = OffsetVector_8G + } + if (wrAccelRange == 1){ + CurrentRange = Range.RANGE_16G + AlignmentMatrix = AlignmentMatrix_16G + SensitivityMatrix = SensitivityMatrix_16G + OffsetVector = OffsetVector_16G + } + }else if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + if (wrAccelRange == 0){ + CurrentRange = Range.RANGE_2G + AlignmentMatrix = AlignmentMatrix_2G + SensitivityMatrix = SensitivityMatrix_2G + OffsetVector = OffsetVector_2G + } + if (wrAccelRange == 1){ + CurrentRange = Range.RANGE_4G + AlignmentMatrix = AlignmentMatrix_4G + SensitivityMatrix = SensitivityMatrix_4G + OffsetVector = OffsetVector_4G + } + if (wrAccelRange == 2){ + CurrentRange = Range.RANGE_8G + AlignmentMatrix = AlignmentMatrix_8G + SensitivityMatrix = SensitivityMatrix_8G + OffsetVector = OffsetVector_8G + } + if (wrAccelRange == 3){ + CurrentRange = Range.RANGE_16G + AlignmentMatrix = AlignmentMatrix_16G + SensitivityMatrix = SensitivityMatrix_16G + OffsetVector = OffsetVector_16G + } } } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index a687a36..1ebcdff 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -263,6 +263,14 @@ struct ContentView: View { } } }) + Button("WriteInfoMem WRAccel Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RWRAccel() + } catch { + print("Error: \(error)") + } + } + }) } Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { ForEach(0.. Date: Fri, 9 May 2025 19:42:17 +0800 Subject: [PATCH 10/21] add 3r gyro sensor support --- .../ConfigByteLayoutShimmer3.swift | 6 + .../ShimmerBluetooth/GyroSensor.swift | 307 +++++++++++++++--- .../ShimmerBluetooth/Shimmer3Protocol.swift | 2 + .../ShimmerExamplePlot/ContentView.swift | 17 + .../ShimmerExamplePlot/ViewModel.swift | 18 + 5 files changed, 303 insertions(+), 47 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift index 0a6c76f..bf91fe5 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift @@ -42,6 +42,8 @@ public class ConfigByteLayoutShimmer3{ static let idxMPU9150GyroCalibration = 52 static let idxLSM303DLHCMagCalibration = 73 //static let idxLSM303DLHCAccelCalibration = 94 //94->114 + static let idxConfigSetupByte4 = 128+2; + static let idxSDExperimentConfig0 = 128+89; static let idxSDExperimentConfig1 = 128+90; @@ -51,6 +53,9 @@ public class ConfigByteLayoutShimmer3{ static let bitShiftMPU9150GyroRange = 0; static let maskMPU9150GyroRange = 0x03; + static let bitShiftLSM6DSVyroRangeMSB = 2; + static let maskLSM6DSVyroRangeMSB = 0x01; + static let bitShiftMPU9150AccelGyroSamplingRate = 0; static let maskMPU9150AccelGyroSamplingRate = 0xFF; @@ -73,6 +78,7 @@ public class ConfigByteLayoutShimmer3{ static let maskLSM303DLHCAccelSamplingRate = 0x0F; static let idxLSM6DSVAccelCalibration = 34; + static let idxGyroCalibration = 55; static let idxLSM303DLHCAccelCalibration = 97; static let lengthGeneralCalibrationBytes = 21; diff --git a/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift index 31a1f96..be77749 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/GyroSensor.swift @@ -31,15 +31,49 @@ public class GyroSensor : IMUSensor , SensorProcessing{ } } - var CurrentRange = Range.RANGE_250DPS + public enum Range3R: UInt8 { + case RANGE_125DPS = 0x0 + case RANGE_250DPS = 0x1 + case RANGE_500DPS = 0x2 + case RANGE_1000DPS = 0x3 + case RANGE_2000DPS = 0x4 + case RANGE_4000DPS = 0x5 + + public static func fromValue(_ value : UInt8) -> Range3R? { + switch value{ + case 0: + return .RANGE_125DPS + case 1: + return .RANGE_250DPS + case 2: + return .RANGE_500DPS + case 3: + return .RANGE_1000DPS + case 4: + return .RANGE_2000DPS + case 5: + return .RANGE_4000DPS + default: + return nil + } + } + } + + var CurrentRange = Range.RANGE_250DPS + var Current3RRange = Range3R.RANGE_250DPS + + public var packetIndexGyroX:Int = -1 public var packetIndexGyroY:Int = -1 public var packetIndexGyroZ:Int = -1 public static let GYROSCOPE_X = "Gyroscope X" public static let GYROSCOPE_Y = "Gyroscope Y" public static let GYROSCOPE_Z = "Gyroscope Z" - let CALIBRATION_ID = 30 + var CALIBRATION_ID = 30 + var AlignmentMatrix_125DPS:[[Double]] = [[]] + var SensitivityMatrix_125DPS:[[Double]] = [[]] + var OffsetVector_125DPS:[Double]=[] var AlignmentMatrix_250DPS:[[Double]] = [[]] var SensitivityMatrix_250DPS:[[Double]] = [[]] var OffsetVector_250DPS:[Double]=[] @@ -52,18 +86,40 @@ public class GyroSensor : IMUSensor , SensorProcessing{ var AlignmentMatrix_2000DPS:[[Double]] = [[]] var SensitivityMatrix_2000DPS:[[Double]] = [[]] var OffsetVector_2000DPS:[Double]=[] + var AlignmentMatrix_4000DPS:[[Double]] = [[]] + var SensitivityMatrix_4000DPS:[[Double]] = [[]] + var OffsetVector_4000DPS:[Double]=[] + var gyroRange = 1 var AlignmentMatrix : [[Double]] = [[]] var SensitivityMatrix : [[Double]] = [[]] var OffsetVector : [Double] = [] + var calibBytes_125DPS: [UInt8] = [] + var calibBytes_250DPS: [UInt8] = [] + var calibBytes_500DPS: [UInt8] = [] + var calibBytes_1000DPS: [UInt8] = [] + var calibBytes_2000DPS: [UInt8] = [] + var calibBytes_4000DPS: [UInt8] = [] + public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { let x = Array(sensorPacket[packetIndexGyroX.. [UInt8]{ var infomemtoupdate = infomem print("oriinfomem: \(infomemtoupdate)") - if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ - var gyroRange = 0 + var gyroRange = 0 + var calibBytes = calibBytes_250DPS if (range == Range.RANGE_250DPS){ gyroRange = 0 + calibBytes = calibBytes_250DPS } else if (range == Range.RANGE_500DPS){ gyroRange = 1 + calibBytes = calibBytes_500DPS } else if (range == Range.RANGE_1000DPS){ gyroRange = 2 + calibBytes = calibBytes_1000DPS } else if (range == Range.RANGE_2000DPS){ gyroRange = 3 + calibBytes = calibBytes_2000DPS } + + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxGyroCalibration.. [UInt8]{ + var infomemtoupdate = infomem + print("oriinfomem: \(infomemtoupdate)") + var gyroRange = 0 + var calibBytes = calibBytes_125DPS + if (range == Range3R.RANGE_125DPS){ + gyroRange = 0 + calibBytes = calibBytes_125DPS + }else if (range == Range3R.RANGE_250DPS){ + gyroRange = 1 + calibBytes = calibBytes_250DPS + } else if (range == Range3R.RANGE_500DPS){ + gyroRange = 2 + calibBytes = calibBytes_500DPS + } else if (range == Range3R.RANGE_1000DPS){ + gyroRange = 3 + calibBytes = calibBytes_1000DPS + } else if (range == Range3R.RANGE_2000DPS){ + gyroRange = 4 + calibBytes = calibBytes_2000DPS + }else if (range == Range3R.RANGE_4000DPS){ + gyroRange = 5 + calibBytes = calibBytes_4000DPS + } + + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxGyroCalibration..>2)<Range{ return CurrentRange } + public func get3RRange()->Range3R{ + return Current3RRange + } + public func setInfoMem(infomem: [UInt8]) { var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>6) & 1 @@ -149,30 +319,73 @@ public class GyroSensor : IMUSensor , SensorProcessing{ sensorEnabled = false } - gyroRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftMPU9150GyroRange) & ConfigByteLayoutShimmer3.maskMPU9150GyroRange) - if (gyroRange == 0){ - CurrentRange = Range.RANGE_250DPS - AlignmentMatrix = AlignmentMatrix_250DPS - SensitivityMatrix = SensitivityMatrix_250DPS - OffsetVector = OffsetVector_250DPS - } - if (gyroRange == 1){ - CurrentRange = Range.RANGE_500DPS - AlignmentMatrix = AlignmentMatrix_500DPS - SensitivityMatrix = SensitivityMatrix_500DPS - OffsetVector = OffsetVector_500DPS - } - if (gyroRange == 2){ - CurrentRange = Range.RANGE_1000DPS - AlignmentMatrix = AlignmentMatrix_1000DPS - SensitivityMatrix = SensitivityMatrix_1000DPS - OffsetVector = OffsetVector_1000DPS - } - if (gyroRange == 3){ - CurrentRange = Range.RANGE_2000DPS - AlignmentMatrix = AlignmentMatrix_2000DPS - SensitivityMatrix = SensitivityMatrix_2000DPS - OffsetVector = OffsetVector_2000DPS + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3.rawValue){ + gyroRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftMPU9150GyroRange) & ConfigByteLayoutShimmer3.maskMPU9150GyroRange) + if (gyroRange == 0){ + CurrentRange = Range.RANGE_250DPS + AlignmentMatrix = AlignmentMatrix_250DPS + SensitivityMatrix = SensitivityMatrix_250DPS + OffsetVector = OffsetVector_250DPS + } + if (gyroRange == 1){ + CurrentRange = Range.RANGE_500DPS + AlignmentMatrix = AlignmentMatrix_500DPS + SensitivityMatrix = SensitivityMatrix_500DPS + OffsetVector = OffsetVector_500DPS + } + if (gyroRange == 2){ + CurrentRange = Range.RANGE_1000DPS + AlignmentMatrix = AlignmentMatrix_1000DPS + SensitivityMatrix = SensitivityMatrix_1000DPS + OffsetVector = OffsetVector_1000DPS + } + if (gyroRange == 3){ + CurrentRange = Range.RANGE_2000DPS + AlignmentMatrix = AlignmentMatrix_2000DPS + SensitivityMatrix = SensitivityMatrix_2000DPS + OffsetVector = OffsetVector_2000DPS + } + }else if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + let gyroRangeLSB = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftMPU9150GyroRange) & ConfigByteLayoutShimmer3.maskMPU9150GyroRange) + let gyroRangeMSB = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte4] >> ConfigByteLayoutShimmer3.bitShiftLSM6DSVyroRangeMSB) & ConfigByteLayoutShimmer3.maskLSM6DSVyroRangeMSB) + + gyroRange = ((gyroRangeMSB<<2) | gyroRangeLSB) + if (gyroRange == 0){ + Current3RRange = Range3R.RANGE_125DPS + AlignmentMatrix = AlignmentMatrix_125DPS + SensitivityMatrix = SensitivityMatrix_125DPS + OffsetVector = OffsetVector_125DPS + } + if (gyroRange == 1){ + Current3RRange = Range3R.RANGE_250DPS + AlignmentMatrix = AlignmentMatrix_250DPS + SensitivityMatrix = SensitivityMatrix_250DPS + OffsetVector = OffsetVector_250DPS + } + if (gyroRange == 2){ + Current3RRange = Range3R.RANGE_500DPS + AlignmentMatrix = AlignmentMatrix_500DPS + SensitivityMatrix = SensitivityMatrix_500DPS + OffsetVector = OffsetVector_500DPS + } + if (gyroRange == 3){ + Current3RRange = Range3R.RANGE_1000DPS + AlignmentMatrix = AlignmentMatrix_1000DPS + SensitivityMatrix = SensitivityMatrix_1000DPS + OffsetVector = OffsetVector_1000DPS + } + if (gyroRange == 4){ + Current3RRange = Range3R.RANGE_2000DPS + AlignmentMatrix = AlignmentMatrix_2000DPS + SensitivityMatrix = SensitivityMatrix_2000DPS + OffsetVector = OffsetVector_2000DPS + } + if (gyroRange == 5){ + Current3RRange = Range3R.RANGE_4000DPS + AlignmentMatrix = AlignmentMatrix_4000DPS + SensitivityMatrix = SensitivityMatrix_4000DPS + OffsetVector = OffsetVector_4000DPS + } } } diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index e1f81b1..5dfaadf 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -324,6 +324,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { battVoltageSensor = BattVoltageSensor() } else if(REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ lnAccelSensor = LNAccelSensor(hwid: REV_HW_MAJOR) + gyroSensor = GyroSensor(hwid: REV_HW_MAJOR) timeSensor = TimeSensor() } } @@ -349,6 +350,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ timeSensor.setInfoMem(infomem: infoMem) lnAccelSensor.setInfoMem(infomem: infoMem) + gyroSensor.setInfoMem(infomem: infoMem) } } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index a687a36..0bb4a48 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -263,6 +263,14 @@ struct ContentView: View { } } }) + Button("WriteInfoMem Gyro Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RGyro() + } catch { + print("Error: \(error)") + } + } + }) } Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { ForEach(0.. Date: Tue, 13 May 2025 17:23:59 +0800 Subject: [PATCH 11/21] add 3r mag sensor support --- .../ConfigByteLayoutShimmer3.swift | 2 +- .../ShimmerBluetooth/MagSensor.swift | 145 +++++++++++++++++- .../ShimmerBluetooth/Shimmer3Protocol.swift | 2 + .../ShimmerExamplePlot/ContentView.swift | 17 ++ .../ShimmerExamplePlot/ViewModel.swift | 16 ++ 5 files changed, 174 insertions(+), 8 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift index 0a6c76f..309813c 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/ConfigByteLayoutShimmer3.swift @@ -40,7 +40,7 @@ public class ConfigByteLayoutShimmer3{ static let idxBtCommBaudRate = 30 static let idxAnalogAccelCalibration = 31 static let idxMPU9150GyroCalibration = 52 - static let idxLSM303DLHCMagCalibration = 73 + static let idxLSM303DLHCMagCalibration = 76 //static let idxLSM303DLHCAccelCalibration = 94 //94->114 static let idxSDExperimentConfig0 = 128+89; static let idxSDExperimentConfig1 = 128+90; diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index 520ac08..9a4503c 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -8,17 +8,61 @@ import Foundation public class MagSensor : IMUSensor , SensorProcessing{ + public enum Range3R: UInt8 { + case RANGE_4Ga = 0x0 + case RANGE_8Ga = 0x1 + case RANGE_12Ga = 0x2 + case RANGE_16Ga = 0x3 + + public static func fromValue(_ value : UInt8) -> Range3R? { + switch value{ + case 0: + return .RANGE_4Ga + case 1: + return .RANGE_8Ga + case 2: + return .RANGE_12Ga + case 3: + return .RANGE_16Ga + default: + return nil + } + } + } + + var Current3RRange = Range3R.RANGE_4Ga + public var packetIndexMagX:Int = -1 public var packetIndexMagY:Int = -1 public var packetIndexMagZ:Int = -1 public static let MAGNETOMETER_X = "Magnetometer X" public static let MAGNETOMETER_Y = "Magnetometer Y" public static let MAGNETOMETER_Z = "Magnetometer Z" + var calibBytes_4Ga: [UInt8] = [] + var calibBytes_8Ga: [UInt8] = [] + var calibBytes_12Ga: [UInt8] = [] + var calibBytes_16Ga: [UInt8] = [] var magRange = 0 - let CALIBRATION_ID = 32 + var CALIBRATION_ID = 32 var AlignmentMatrix : [[Double]] = [[]] var SensitivityMatrix : [[Double]] = [[]] var OffsetVector : [Double] = [] + var AlignmentMatrix_4Ga:[[Double]] = [[]] + var SensitivityMatrix_4Ga:[[Double]] = [[]] + var OffsetVector_4Ga:[Double]=[] + var AlignmentMatrix_8Ga:[[Double]] = [[]] + var SensitivityMatrix_8Ga:[[Double]] = [[]] + var OffsetVector_8Ga:[Double]=[] + var AlignmentMatrix_12Ga:[[Double]] = [[]] + var SensitivityMatrix_12Ga:[[Double]] = [[]] + var OffsetVector_12Ga:[Double]=[] + var AlignmentMatrix_16Ga:[[Double]] = [[]] + var SensitivityMatrix_16Ga:[[Double]] = [[]] + var OffsetVector_16Ga:[Double]=[] + + public func get3RRange()->Range3R{ + return Current3RRange + } public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { let x = Array(sensorPacket[packetIndexMagX..>5) & 1 + var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & 1 if (enabled == 1){ sensorEnabled = true } else { sensorEnabled = false } + magRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & ConfigByteLayoutShimmer3.maskLSM303DLHCMagRange) - magRange = Int((infomem[8]>>5) & 7) - + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + if (magRange == 0){ + Current3RRange = Range3R.RANGE_4Ga + AlignmentMatrix = AlignmentMatrix_4Ga + SensitivityMatrix = SensitivityMatrix_4Ga + OffsetVector = OffsetVector_4Ga + } + if (magRange == 1){ + Current3RRange = Range3R.RANGE_8Ga + AlignmentMatrix = AlignmentMatrix_8Ga + SensitivityMatrix = SensitivityMatrix_8Ga + OffsetVector = OffsetVector_8Ga + } + if (magRange == 2){ + Current3RRange = Range3R.RANGE_12Ga + AlignmentMatrix = AlignmentMatrix_12Ga + SensitivityMatrix = SensitivityMatrix_12Ga + OffsetVector = OffsetVector_12Ga + } + if (magRange == 3){ + Current3RRange = Range3R.RANGE_16Ga + AlignmentMatrix = AlignmentMatrix_16Ga + SensitivityMatrix = SensitivityMatrix_16Ga + OffsetVector = OffsetVector_16Ga + } + } } - + public func setLowPowerMag(enable: Bool, isShimmer3withUpdatedSensors: Bool, isShimmer3Sensor: Bool, samplingRate: Double, infomem: [UInt8])-> [UInt8]{ let LowPowerMagEnabled = enable var infomemtoupdate = infomem @@ -149,5 +244,41 @@ public class MagSensor : IMUSensor , SensorProcessing{ return infomemtoupdate } - + public func updateInfoMem3RMagRange(infomem: [UInt8],range: Range3R) -> [UInt8]{ + var infomemtoupdate = infomem + print("oriinfomem: \(infomemtoupdate)") + var magRange = 0 + var calibBytes = calibBytes_4Ga + if (range == Range3R.RANGE_4Ga){ + magRange = 0 + calibBytes = calibBytes_4Ga + }else if (range == Range3R.RANGE_8Ga){ + magRange = 1 + calibBytes = calibBytes_8Ga + } else if (range == Range3R.RANGE_12Ga){ + magRange = 2 + calibBytes = calibBytes_12Ga + } else if (range == Range3R.RANGE_16Ga){ + magRange = 3 + calibBytes = calibBytes_16Ga + } + + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxLSM303DLHCMagCalibration.. Date: Wed, 14 May 2025 12:39:03 +0800 Subject: [PATCH 12/21] add 3r mag low power mode --- .../ShimmerBluetooth/MagSensor.swift | 119 +++++++++++------- 1 file changed, 73 insertions(+), 46 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index 9a4503c..43d37a8 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -165,63 +165,90 @@ public class MagSensor : IMUSensor , SensorProcessing{ public func setLowPowerMag(enable: Bool, isShimmer3withUpdatedSensors: Bool, isShimmer3Sensor: Bool, samplingRate: Double, infomem: [UInt8])-> [UInt8]{ let LowPowerMagEnabled = enable var infomemtoupdate = infomem - if(isShimmer3Sensor){ + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ if(!LowPowerMagEnabled){ - if(isShimmer3withUpdatedSensors){ - if(samplingRate >= 100){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) - }else if(samplingRate >= 50){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:2) - }else if(samplingRate >= 20){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) - }else if(samplingRate >= 10){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) + if(samplingRate > 560){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x01) + }else if(samplingRate > 300){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x11) + }else if(samplingRate > 155){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x21) + }else if(samplingRate > 100){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x31) + }else if(samplingRate > 50){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x31) + }else if(samplingRate > 20){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x3E) + }else if(samplingRate > 10){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x3A) + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x08) + } + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x08) + } + }else { + if(isShimmer3Sensor){ + if(!LowPowerMagEnabled){ + if(isShimmer3withUpdatedSensors){ + if(samplingRate >= 100){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) + }else if(samplingRate >= 50){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:2) + }else if(samplingRate >= 20){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) + }else if(samplingRate >= 10){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) + } }else{ + if(samplingRate >= 50){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:6) + }else if(samplingRate >= 20){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:5) + }else if(samplingRate >= 10){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) + } + } + }else //low power mag for shimmer3 enabled + { + if(isShimmer3withUpdatedSensors){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) } - }else{ - if(samplingRate >= 50){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:6) - }else if(samplingRate >= 20){ + } + }else //Shimmer2 + { + if(!LowPowerMagEnabled){ + if(samplingRate <= 1){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) + }else if(samplingRate <= 15){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) + }else if(samplingRate <= 30){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:5) - }else if(samplingRate >= 10){ + }else if(samplingRate <= 75){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:6) + }else{ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:7) + } + + }else + { + if(samplingRate >= 10){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) } } - }else //low power mag for shimmer3 enabled - { - if(isShimmer3withUpdatedSensors){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) - }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) - } - } - }else //Shimmer2 - { - if(!LowPowerMagEnabled){ - if(samplingRate <= 1){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) - }else if(samplingRate <= 15){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) - }else if(samplingRate <= 30){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:5) - }else if(samplingRate <= 75){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:6) - }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:7) - } - - }else - { - if(samplingRate >= 10){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:4) - }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) - } } } + + + return infomemtoupdate } From 34d2c23af7fe31ac61ce139bb954f2ba0052d163 Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Wed, 14 May 2025 14:00:24 +0800 Subject: [PATCH 13/21] fix --- ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index 43d37a8..16b45ce 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -103,22 +103,18 @@ public class MagSensor : IMUSensor , SensorProcessing{ if range==0{ calibBytes_4Ga = calbytes (AlignmentMatrix_4Ga,SensitivityMatrix_4Ga,OffsetVector_4Ga) = parseIMUCalibrationParameters(bytes: calbytes) - SensitivityMatrix_4Ga = ShimmerUtilities.divideMatrixElements(SensitivityMatrix_4Ga, 100) } if range==1{ calibBytes_8Ga = calbytes (AlignmentMatrix_8Ga,SensitivityMatrix_8Ga,OffsetVector_8Ga) = parseIMUCalibrationParameters(bytes: calbytes) - SensitivityMatrix_8Ga = ShimmerUtilities.divideMatrixElements(SensitivityMatrix_8Ga, 100) } if range==2{ calibBytes_12Ga = calbytes (AlignmentMatrix_12Ga,SensitivityMatrix_12Ga,OffsetVector_12Ga) = parseIMUCalibrationParameters(bytes: calbytes) - SensitivityMatrix_12Ga = ShimmerUtilities.divideMatrixElements(SensitivityMatrix_12Ga, 100) } if range==3{ calibBytes_16Ga = calbytes (AlignmentMatrix_16Ga,SensitivityMatrix_16Ga,OffsetVector_16Ga) = parseIMUCalibrationParameters(bytes: calbytes) - SensitivityMatrix_16Ga = ShimmerUtilities.divideMatrixElements(SensitivityMatrix_16Ga, 100) } } } From 16c2ce6a78329dfba1aa4a681eae8e8699222a8e Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Mon, 26 May 2025 16:32:11 +0800 Subject: [PATCH 14/21] add alt mag 3r sensor support --- .../ShimmerBluetooth/AltMagSensor.swift | 245 ++++++++++++++++++ .../ConfigByteLayoutShimmer3.swift | 2 + .../ShimmerBluetooth/Shimmer3Protocol.swift | 20 ++ .../ShimmerExamplePlot/ContentView.swift | 22 +- .../ShimmerExamplePlot/ViewModel.swift | 22 +- 5 files changed, 308 insertions(+), 3 deletions(-) create mode 100644 ShimmerBluetooth/ShimmerBluetooth/AltMagSensor.swift diff --git a/ShimmerBluetooth/ShimmerBluetooth/AltMagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/AltMagSensor.swift new file mode 100644 index 0000000..326e51e --- /dev/null +++ b/ShimmerBluetooth/ShimmerBluetooth/AltMagSensor.swift @@ -0,0 +1,245 @@ +// +// AltMagSensor.swift +// ShimmerBluetooth +// +// Created by Shimmer Engineering on 26/05/2025. +// + +import Foundation + +public class AltMagSensor : IMUSensor , SensorProcessing{ + + public enum Range3R: UInt8 { + case RANGE_4Ga = 0x0 + case RANGE_8Ga = 0x1 + case RANGE_12Ga = 0x2 + case RANGE_16Ga = 0x3 + + public static func fromValue(_ value : UInt8) -> Range3R? { + switch value{ + case 0: + return .RANGE_4Ga + case 1: + return .RANGE_8Ga + case 2: + return .RANGE_12Ga + case 3: + return .RANGE_16Ga + default: + return nil + } + } + } + var Current3RRange = Range3R.RANGE_4Ga + + public var packetIndexAltMagX:Int = -1 + public var packetIndexAltMagY:Int = -1 + public var packetIndexAltMagZ:Int = -1 + public static let ALT_MAGNETOMETER_X = "Alt Magnetometer X" + public static let ALT_MAGNETOMETER_Y = "Alt Magnetometer Y" + public static let ALT_MAGNETOMETER_Z = "Alt Magnetometer Z" + var calibBytes_4Ga: [UInt8] = [] + var calibBytes_8Ga: [UInt8] = [] + var calibBytes_12Ga: [UInt8] = [] + var calibBytes_16Ga: [UInt8] = [] + var altMagRange = 0 + var CALIBRATION_ID = 41 + var AlignmentMatrix : [[Double]] = [[]] + var SensitivityMatrix : [[Double]] = [[]] + var OffsetVector : [Double] = [] + var AlignmentMatrix_4Ga:[[Double]] = [[]] + var SensitivityMatrix_4Ga:[[Double]] = [[]] + var OffsetVector_4Ga:[Double]=[] + var AlignmentMatrix_8Ga:[[Double]] = [[]] + var SensitivityMatrix_8Ga:[[Double]] = [[]] + var OffsetVector_8Ga:[Double]=[] + var AlignmentMatrix_12Ga:[[Double]] = [[]] + var SensitivityMatrix_12Ga:[[Double]] = [[]] + var OffsetVector_12Ga:[Double]=[] + var AlignmentMatrix_16Ga:[[Double]] = [[]] + var SensitivityMatrix_16Ga:[[Double]] = [[]] + var OffsetVector_16Ga:[Double]=[] + + public func get3RRange()->Range3R{ + return Current3RRange + } + + public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { + let x = Array(sensorPacket[packetIndexAltMagX..>ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & 1 + if (enabled == 1){ + sensorEnabled = true + } else { + sensorEnabled = false + } + altMagRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & ConfigByteLayoutShimmer3.maskLSM303DLHCMagRange) + + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + if (altMagRange == 0){ + Current3RRange = Range3R.RANGE_4Ga + AlignmentMatrix = AlignmentMatrix_4Ga + SensitivityMatrix = SensitivityMatrix_4Ga + OffsetVector = OffsetVector_4Ga + } + if (altMagRange == 1){ + Current3RRange = Range3R.RANGE_8Ga + AlignmentMatrix = AlignmentMatrix_8Ga + SensitivityMatrix = SensitivityMatrix_8Ga + OffsetVector = OffsetVector_8Ga + } + if (altMagRange == 2){ + Current3RRange = Range3R.RANGE_12Ga + AlignmentMatrix = AlignmentMatrix_12Ga + SensitivityMatrix = SensitivityMatrix_12Ga + OffsetVector = OffsetVector_12Ga + } + if (altMagRange == 3){ + Current3RRange = Range3R.RANGE_16Ga + AlignmentMatrix = AlignmentMatrix_16Ga + SensitivityMatrix = SensitivityMatrix_16Ga + OffsetVector = OffsetVector_16Ga + } + } + } + + public func setLowPowerAltMag(enable: Bool, isShimmer3withUpdatedSensors: Bool, isShimmer3Sensor: Bool, samplingRate: Double, infomem: [UInt8])-> [UInt8]{ + let LowPowerMagEnabled = enable + var infomemtoupdate = infomem + if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ + if(!LowPowerMagEnabled){ + if(samplingRate > 560){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x01) + }else if(samplingRate > 300){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x11) + }else if(samplingRate > 155){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x21) + }else if(samplingRate > 100){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x31) + }else if(samplingRate > 50){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x31) + }else if(samplingRate > 20){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x3E) + }else if(samplingRate > 10){ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x3A) + }else{ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x08) + } + }else{ + infomemtoupdate = updateInfoMemAltMagRate(infomem: infomem, magRate:0x08) + } + } + return infomemtoupdate + + } + + public func updateInfoMem3RAltMagRange(infomem: [UInt8],range: Range3R) -> [UInt8]{ + var infomemtoupdate = infomem + print("oriinfomem: \(infomemtoupdate)") + var altMagRange = 0 + var calibBytes = calibBytes_4Ga + if (range == Range3R.RANGE_4Ga){ + altMagRange = 0 + calibBytes = calibBytes_4Ga + }else if (range == Range3R.RANGE_8Ga){ + altMagRange = 1 + calibBytes = calibBytes_8Ga + } else if (range == Range3R.RANGE_12Ga){ + altMagRange = 2 + calibBytes = calibBytes_12Ga + } else if (range == Range3R.RANGE_16Ga){ + altMagRange = 3 + calibBytes = calibBytes_16Ga + } + + infomemtoupdate.replaceSubrange( + ConfigByteLayoutShimmer3.idxLIS3MDLAltMagCalibration.. [UInt8]{ + var infomemtoupdate = infomem + + print("oriinfomem : \(infomemtoupdate)") + + let orivalue = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] + let value = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] & ~UInt8(ConfigByteLayoutShimmer3.maskLSM303DLHCMagSamplingRate<114 static let idxSDExperimentConfig0 = 128+89; static let idxSDExperimentConfig1 = 128+90; diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index e1f81b1..2969b2b 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -50,6 +50,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { var timeSensor: TimeSensor = TimeSensor() public var magSensor: MagSensor = MagSensor(hwid: HardwareType.UNKNOWN.rawValue) public var gyroSensor: GyroSensor = GyroSensor(hwid: HardwareType.UNKNOWN.rawValue) + public var altMagSensor: AltMagSensor = AltMagSensor(hwid: HardwareType.UNKNOWN.rawValue) var adcA13Sensor: ADCSensor = ADCSensor() var adcA12Sensor: ADCSensor = ADCSensor() var adcA1Sensor: ADCSensor = ADCSensor() @@ -302,6 +303,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { gyroSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) wrAccelSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) magSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) + altMagSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) } } @@ -325,6 +327,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } else if(REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ lnAccelSensor = LNAccelSensor(hwid: REV_HW_MAJOR) timeSensor = TimeSensor() + altMagSensor = AltMagSensor(hwid: REV_HW_MAJOR) } } @@ -349,6 +352,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ timeSensor.setInfoMem(infomem: infoMem) lnAccelSensor.setInfoMem(infomem: infoMem) + altMagSensor.setInfoMem(infomem: infoMem) } } @@ -383,6 +387,9 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { if magSensor.sensorEnabled { ojc = magSensor.processData(sensorPacket: bytes, objectCluster: ojc) } + if altMagSensor.sensorEnabled { + ojc = altMagSensor.processData(sensorPacket: bytes, objectCluster: ojc) + } if gyroSensor.sensorEnabled { ojc = gyroSensor.processData(sensorPacket: bytes, objectCluster: ojc) } @@ -897,6 +904,18 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { magSensor.packetIndexMagZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) + case ChannelContentsShimmer3.AlternativeXMag.rawValue: //AlternativeXMag + altMagSensor.packetIndexAltMagX = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) + case ChannelContentsShimmer3.AlternativeYMag.rawValue: + altMagSensor.packetIndexAltMagY = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) + case ChannelContentsShimmer3.AlternativeZMag.rawValue: + altMagSensor.packetIndexAltMagZ = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) case ChannelContentsShimmer3.XGyro.rawValue: gyroSensor.packetIndexGyroX = packetSize packetSize += 2 @@ -1601,6 +1620,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case SENSOR_EXG1_16BIT = 0x100000 case SENSOR_EXG2_16BIT = 0x080000 case SENSOR_BRIDGE_AMP = 0x8000 + case SENSOR_LIS3MDL_ALT_MAG = 0x200000 } enum ChannelContentsShimmer3: UInt8 { diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index a687a36..2d702d1 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -263,6 +263,15 @@ struct ContentView: View { } } }) + Button("WriteInfoMem Alt Mag Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RAltMag() + } catch { + print("Error: \(error)") + } + } + }) + } } Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { ForEach(0.. Date: Mon, 26 May 2025 16:47:28 +0800 Subject: [PATCH 15/21] project update --- ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj b/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj index e480098..15f0edf 100644 --- a/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj +++ b/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 3AED206D2B0B10960066A0F8 /* ShimmerUtilitiesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AED206C2B0B10960066A0F8 /* ShimmerUtilitiesTest.swift */; }; 3AED20712B0C4BA60066A0F8 /* MagSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AED20702B0C4BA60066A0F8 /* MagSensor.swift */; }; 3AED20732B0C587B0066A0F8 /* GyroSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AED20722B0C587B0066A0F8 /* GyroSensor.swift */; }; + 92150EF52DE461CE00FEA53B /* AltMagSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92150EF42DE461CE00FEA53B /* AltMagSensor.swift */; }; 9299E50E2B85054E001EEFE0 /* PressureTempSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9299E50D2B85054E001EEFE0 /* PressureTempSensor.swift */; }; 9299E5102B850571001EEFE0 /* BattVoltageSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9299E50F2B850571001EEFE0 /* BattVoltageSensor.swift */; }; 92B1067A2B7DAFBC00AB9952 /* EXGSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B106792B7DAFBC00AB9952 /* EXGSensor.swift */; }; @@ -84,6 +85,7 @@ 3AED206C2B0B10960066A0F8 /* ShimmerUtilitiesTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShimmerUtilitiesTest.swift; sourceTree = ""; }; 3AED20702B0C4BA60066A0F8 /* MagSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagSensor.swift; sourceTree = ""; }; 3AED20722B0C587B0066A0F8 /* GyroSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GyroSensor.swift; sourceTree = ""; }; + 92150EF42DE461CE00FEA53B /* AltMagSensor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AltMagSensor.swift; sourceTree = ""; }; 9299E50D2B85054E001EEFE0 /* PressureTempSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PressureTempSensor.swift; sourceTree = ""; }; 9299E50F2B850571001EEFE0 /* BattVoltageSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BattVoltageSensor.swift; sourceTree = ""; }; 92B106792B7DAFBC00AB9952 /* EXGSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXGSensor.swift; sourceTree = ""; }; @@ -131,6 +133,7 @@ 3A780C872AE12BEB00EAF050 /* ShimmerBluetooth */ = { isa = PBXGroup; children = ( + 92150EF42DE461CE00FEA53B /* AltMagSensor.swift */, 3AEB12F82BCE6F7E00B5F6F1 /* Shimmer3SpeedTestProtocol.swift */, 3A780C882AE12BEB00EAF050 /* ShimmerBluetooth.h */, 3A780C892AE12BEB00EAF050 /* ShimmerBluetooth.docc */, @@ -299,6 +302,7 @@ 3AB320E62B070830003D94F8 /* Sensor.swift in Sources */, 3A0B4B672B0EE42700786295 /* IMUSensor.swift in Sources */, 3A1CBAD32AE2DD1C00BC1E54 /* BleByteRadio.swift in Sources */, + 92150EF52DE461CE00FEA53B /* AltMagSensor.swift in Sources */, 3A7712912AE26805006213A8 /* BLEByteRadioold.swift in Sources */, 3A77128D2AE177A4006213A8 /* ShimmerDevice.swift in Sources */, 3AA359152AF37943008AD334 /* ConfigByteLayoutShimmer3.swift in Sources */, From c273fca059547f6a9437136fa1d8a2d15d9d9616 Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Tue, 27 May 2025 12:03:23 +0800 Subject: [PATCH 16/21] swapped mag update --- .../ShimmerBluetooth/MagSensor.swift | 160 ++---------------- .../ShimmerExamplePlot/ContentView.swift | 10 +- .../ShimmerExamplePlot/ViewModel.swift | 13 +- 3 files changed, 16 insertions(+), 167 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index 16b45ce..a64f06e 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -8,29 +8,6 @@ import Foundation public class MagSensor : IMUSensor , SensorProcessing{ - public enum Range3R: UInt8 { - case RANGE_4Ga = 0x0 - case RANGE_8Ga = 0x1 - case RANGE_12Ga = 0x2 - case RANGE_16Ga = 0x3 - - public static func fromValue(_ value : UInt8) -> Range3R? { - switch value{ - case 0: - return .RANGE_4Ga - case 1: - return .RANGE_8Ga - case 2: - return .RANGE_12Ga - case 3: - return .RANGE_16Ga - default: - return nil - } - } - } - - var Current3RRange = Range3R.RANGE_4Ga public var packetIndexMagX:Int = -1 public var packetIndexMagY:Int = -1 @@ -38,32 +15,12 @@ public class MagSensor : IMUSensor , SensorProcessing{ public static let MAGNETOMETER_X = "Magnetometer X" public static let MAGNETOMETER_Y = "Magnetometer Y" public static let MAGNETOMETER_Z = "Magnetometer Z" - var calibBytes_4Ga: [UInt8] = [] - var calibBytes_8Ga: [UInt8] = [] - var calibBytes_12Ga: [UInt8] = [] - var calibBytes_16Ga: [UInt8] = [] var magRange = 0 var CALIBRATION_ID = 32 var AlignmentMatrix : [[Double]] = [[]] var SensitivityMatrix : [[Double]] = [[]] var OffsetVector : [Double] = [] - var AlignmentMatrix_4Ga:[[Double]] = [[]] - var SensitivityMatrix_4Ga:[[Double]] = [[]] - var OffsetVector_4Ga:[Double]=[] - var AlignmentMatrix_8Ga:[[Double]] = [[]] - var SensitivityMatrix_8Ga:[[Double]] = [[]] - var OffsetVector_8Ga:[Double]=[] - var AlignmentMatrix_12Ga:[[Double]] = [[]] - var SensitivityMatrix_12Ga:[[Double]] = [[]] - var OffsetVector_12Ga:[Double]=[] - var AlignmentMatrix_16Ga:[[Double]] = [[]] - var SensitivityMatrix_16Ga:[[Double]] = [[]] - var OffsetVector_16Ga:[Double]=[] - - public func get3RRange()->Range3R{ - return Current3RRange - } - + public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { let x = Array(sensorPacket[packetIndexMagX..>ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & 1 if (enabled == 1){ sensorEnabled = true - } else { + } else { sensorEnabled = false } - magRange = (Int(infomem[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftLSM303DLHCMagRange) & ConfigByteLayoutShimmer3.maskLSM303DLHCMagRange) - - if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ - if (magRange == 0){ - Current3RRange = Range3R.RANGE_4Ga - AlignmentMatrix = AlignmentMatrix_4Ga - SensitivityMatrix = SensitivityMatrix_4Ga - OffsetVector = OffsetVector_4Ga - } - if (magRange == 1){ - Current3RRange = Range3R.RANGE_8Ga - AlignmentMatrix = AlignmentMatrix_8Ga - SensitivityMatrix = SensitivityMatrix_8Ga - OffsetVector = OffsetVector_8Ga - } - if (magRange == 2){ - Current3RRange = Range3R.RANGE_12Ga - AlignmentMatrix = AlignmentMatrix_12Ga - SensitivityMatrix = SensitivityMatrix_12Ga - OffsetVector = OffsetVector_12Ga - } - if (magRange == 3){ - Current3RRange = Range3R.RANGE_16Ga - AlignmentMatrix = AlignmentMatrix_16Ga - SensitivityMatrix = SensitivityMatrix_16Ga - OffsetVector = OffsetVector_16Ga - } - } } public func setLowPowerMag(enable: Bool, isShimmer3withUpdatedSensors: Bool, isShimmer3Sensor: Bool, samplingRate: Double, infomem: [UInt8])-> [UInt8]{ @@ -163,25 +73,17 @@ public class MagSensor : IMUSensor , SensorProcessing{ var infomemtoupdate = infomem if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ if(!LowPowerMagEnabled){ - if(samplingRate > 560){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x01) - }else if(samplingRate > 300){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x11) - }else if(samplingRate > 155){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x21) - }else if(samplingRate > 100){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x31) - }else if(samplingRate > 50){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x31) - }else if(samplingRate > 20){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x3E) - }else if(samplingRate > 10){ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x3A) + if(samplingRate < 10){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) + }else if(samplingRate < 20){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) + }else if(samplingRate < 50){ + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:2) }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x08) + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) } }else{ - infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0x08) + infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) } }else { if(isShimmer3Sensor){ @@ -266,42 +168,4 @@ public class MagSensor : IMUSensor , SensorProcessing{ return infomemtoupdate } - - public func updateInfoMem3RMagRange(infomem: [UInt8],range: Range3R) -> [UInt8]{ - var infomemtoupdate = infomem - print("oriinfomem: \(infomemtoupdate)") - var magRange = 0 - var calibBytes = calibBytes_4Ga - if (range == Range3R.RANGE_4Ga){ - magRange = 0 - calibBytes = calibBytes_4Ga - }else if (range == Range3R.RANGE_8Ga){ - magRange = 1 - calibBytes = calibBytes_8Ga - } else if (range == Range3R.RANGE_12Ga){ - magRange = 2 - calibBytes = calibBytes_12Ga - } else if (range == Range3R.RANGE_16Ga){ - magRange = 3 - calibBytes = calibBytes_16Ga - } - - - infomemtoupdate.replaceSubrange( - ConfigByteLayoutShimmer3.idxLSM303DLHCMagCalibration.. Date: Tue, 27 May 2025 12:13:48 +0800 Subject: [PATCH 17/21] minor update --- ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index 524e09c..0ef15ea 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift @@ -201,13 +201,13 @@ class ViewModel: NSObject, ObservableObject { } func sendInfoMemS3RAltMag() async{ - let infomlnacc:[UInt8] = [ + let infomaltmag:[UInt8] = [ 0x80, 0x02, 0x01, 0x00, 0x00, 0x20, 0x02, 0x00, 0x01, 0x08, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x88, 0x06, 0x88, 0x06, 0x88, 0x9C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x88, 0x2C, 0x88, 0x2C, 0x88, 0x9C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9B, 0x02, 0x9B, 0x02, 0x9B, 0x9C, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9B, 0x02, 0x9B, 0x02, 0x9B, 0x9C, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x69, 0x6D, 0x6D, 0x65, 0x72, 0x5F, 0x44, 0x37, 0x45, 0x30, 0x33, 0x52, 0x5F, 0x31, 0x37, 0x35, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x33, 0xF5, 0xF5, 0x01, 0x01, 0x31, 0x01, 0x00, 0x36, 0x01, 0x00, 0x00, 0xE8, 0xDD, 0x50, 0xBB, 0xD7, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xBA, 0x1A, 0xBA, 0x1A, 0xBA, 0x64, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00] - await shimmer3Protocol?.writeShimmer3InfoMem(infoMem: infomlnacc) + await shimmer3Protocol?.writeShimmer3InfoMem(infoMem: infomaltmag) refreshUISettings() } From 0820119e39841f30786cd6993f3f6445536fa168 Mon Sep 17 00:00:00 2001 From: jyong15 Date: Tue, 27 May 2025 13:51:57 +0800 Subject: [PATCH 18/21] DEV-227 fix tests --- ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift b/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift index 059ebdc..bbf8a97 100644 --- a/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift +++ b/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift @@ -13,7 +13,7 @@ import CoreBluetooth class SensorTest: XCTestCase { func testSensorWRAccel(){ - var wrAccelSensor: WRAccelSensor = WRAccelSensor() + var wrAccelSensor: WRAccelSensor = WRAccelSensor(hwid: Shimmer3Protocol.HardwareType.Shimmer3.rawValue) var infomwracc:[UInt8] = [ 0x80,0x02,0x01,0xE0,0x20,0x00,0x01,0x9B,0x0D,0x08,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x09,0x00,0x00,0x00,0x08,0xCD,0x08,0xCD,0x08,0xCD,0x00,0x5C,0x00,0x5C,0x00,0x5C,0x00,0x9C,0x00,0x9C,0x00,0x00,0x00,0x00,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x96,0x19,0x96,0x19,0x96,0x00,0x9C,0x00,0x9C,0x00,0x00,0x00,0x00,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x9B,0x02,0x9B,0x02,0x9B,0x00,0x9C,0x00,0x64,0x00,0x00,0x00,0x00,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x87,0x06,0x87,0x06,0x87,0x00,0x9C,0x00,0x64,0x00,0x00,0x00,0x00,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x68,0x69,0x6D,0x6D,0x65,0x72,0x5F,0x36,0x38,0x44,0x44,0x44,0x65,0x66,0x61,0x75,0x6C,0x74,0x54,0x72,0x69,0x61,0x6C,0x65,0x54,0x7E,0x40,0x00,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ] @@ -37,7 +37,7 @@ class SensorTest: XCTestCase { } func testSensorGyroRange(){ - var gyroSensor: GyroSensor = GyroSensor() + var gyroSensor: GyroSensor = GyroSensor(hwid: Shimmer3Protocol.HardwareType.Shimmer3.rawValue) var infomgyro:[UInt8] = [ 0x20, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x06, 0x01, 0x08, 0x04, 0x88, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x04, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x08, 0xCD, 0x08, 0xCD, 0x08, 0xCD, 0x00, 0x5C, 0x00, 0x5C, 0x00, 0x5C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19, 0x96, 0x19, 0x96, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9B, 0x02, 0x9B, 0x02, 0x9B, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x69, 0x6D, 0x6D, 0x65, 0x72, 0x5F, 0x36, 0x38, 0x44, 0x44, 0x74, 0x72, 0x74, 0x72, 0x74, 0x72, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x4C, 0x45, 0xA6, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x47, 0x8F, 0x04, 0xBD, 0xA2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ] @@ -60,7 +60,7 @@ class SensorTest: XCTestCase { XCTAssertEqual(gyroRange, 3, "Failed to set gyro range") } func testSensorPressureResolution(){ - var pressTempSensor: PressureTempSensor = PressureTempSensor() + var pressTempSensor: PressureTempSensor = PressureTempSensor(hwid: Shimmer3Protocol.HardwareType.Shimmer3.rawValue) var infompressuretemp:[UInt8] = [0x80, 0x02, 0x01, 0x00, 0x00, 0x04, 0x01, 0xFF, 0x01, 0x08, 0x00, 0x88, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x09, 0x00, 0x00, 0x00, 0x08, 0xCD, 0x08, 0xCD, 0x08, 0xCD, 0x00, 0x5C, 0x00, 0x5C, 0x00, 0x5C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19, 0x96, 0x19, 0x96, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9B, 0x02, 0x9B, 0x02, 0x9B, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x69, 0x6D, 0x6D, 0x65, 0x72, 0x5F, 0x36, 0x38, 0x44, 0x44, 0x74, 0x72, 0x74, 0x72, 0x74, 0x72, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x65, 0xD4, 0xBD, 0x5F, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xEB, 0x1B, 0x97, 0x67, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, From 2e857ab1d4e44c4f5c58148229f831e2b9196fbd Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Tue, 27 May 2025 15:41:33 +0800 Subject: [PATCH 19/21] minor update --- ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift | 6 +++--- ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index a64f06e..af8770c 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -158,13 +158,13 @@ public class MagSensor : IMUSensor , SensorProcessing{ let orivalue = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] let value = infomemtoupdate[ConfigByteLayoutShimmer3.idxConfigSetupByte2] & ~UInt8(ConfigByteLayoutShimmer3.maskLSM303DLHCMagSamplingRate< Date: Wed, 28 May 2025 14:31:45 +0800 Subject: [PATCH 20/21] DEV-245 update mag sampling rate logic 3R --- ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift index af8770c..ea3ab28 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/MagSensor.swift @@ -73,11 +73,11 @@ public class MagSensor : IMUSensor , SensorProcessing{ var infomemtoupdate = infomem if(HardwareVersion == Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ if(!LowPowerMagEnabled){ - if(samplingRate < 10){ + if(samplingRate <= 10){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:0) - }else if(samplingRate < 20){ + }else if(samplingRate <= 20){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:1) - }else if(samplingRate < 50){ + }else if(samplingRate <= 50){ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:2) }else{ infomemtoupdate = updateInfoMemMagRate(infomem: infomem, magRate:3) From 8d7510580a4853558dae68b5cc97e36e2c7c44bb Mon Sep 17 00:00:00 2001 From: jyong15 Date: Fri, 6 Jun 2025 14:38:08 +0800 Subject: [PATCH 21/21] DEV-227 fix unit test --- .../ShimmerBluetoothTests/SensorTest.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift b/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift index bbf8a97..4846cf6 100644 --- a/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift +++ b/ShimmerBluetooth/ShimmerBluetoothTests/SensorTest.swift @@ -18,6 +18,12 @@ class SensorTest: XCTestCase { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x68,0x69,0x6D,0x6D,0x65,0x72,0x5F,0x36,0x38,0x44,0x44,0x44,0x65,0x66,0x61,0x75,0x6C,0x74,0x54,0x72,0x69,0x61,0x6C,0x65,0x54,0x7E,0x40,0x00,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ] + //parse calib bytes for all accel ranges + wrAccelSensor.parseSensorCalibrationDump(bytes: [0x1F, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C]) + wrAccelSensor.parseSensorCalibrationDump(bytes: [0x1F, 0x00, 0x01, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x00, 0xD1, 0x00, 0xD1, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C]) + wrAccelSensor.parseSensorCalibrationDump(bytes: [0x1F, 0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x44, 0x03, 0x44, 0x03, 0x44, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C]) + wrAccelSensor.parseSensorCalibrationDump(bytes: [0x1F, 0x00, 0x03, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA2, 0x01, 0xA2, 0x01, 0xA2, 0x00, 0x9C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x9C]) + infomwracc = wrAccelSensor.updateInfoMemAccelRange(infomem: infomwracc,range: WRAccelSensor.Range.RANGE_16G) var wrAccelRange = (Int(infomwracc[ConfigByteLayoutShimmer3.idxConfigSetupByte0]>>ConfigByteLayoutShimmer3.bitShiftLSM303DLHCAccelRange) & ConfigByteLayoutShimmer3.maskLSM303DLHCAccelRange) XCTAssertEqual(wrAccelRange, 1, "Failed to set accel range") @@ -42,6 +48,12 @@ class SensorTest: XCTestCase { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x69, 0x6D, 0x6D, 0x65, 0x72, 0x5F, 0x36, 0x38, 0x44, 0x44, 0x74, 0x72, 0x74, 0x72, 0x74, 0x72, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x4C, 0x45, 0xA6, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x47, 0x8F, 0x04, 0xBD, 0xA2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ] + //parse calib bytes for all gyro ranges + gyroSensor.parseSensorCalibrationDump(bytes: [0x1E, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x2C, 0x33, 0x2C, 0x33, 0x2C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C]) + gyroSensor.parseSensorCalibrationDump(bytes: [0x1E, 0x00, 0x01, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19, 0x96, 0x19, 0x96, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C]) + gyroSensor.parseSensorCalibrationDump(bytes: [0x1E, 0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD0, 0x0C, 0xD0, 0x0C, 0xD0, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C]) + gyroSensor.parseSensorCalibrationDump(bytes: [0x1E, 0x00, 0x03, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x06, 0x68, 0x06, 0x68, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x9C]) + infomgyro = gyroSensor.updateInfoMemGyroRange(infomem: infomgyro,range: GyroSensor.Range.RANGE_250DPS) var gyroRange = (Int(infomgyro[ConfigByteLayoutShimmer3.idxConfigSetupByte2] >> ConfigByteLayoutShimmer3.bitShiftMPU9150GyroRange) & ConfigByteLayoutShimmer3.maskMPU9150GyroRange)