From 07ffac3fb7821444c6dc5adcae8914e5c5695d36 Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Wed, 4 Jun 2025 16:00:43 +0800 Subject: [PATCH 1/9] add high g accel support --- .../ShimmerBluetooth/HighGAccelSensor.swift | 71 +++++++++++++++++++ .../ShimmerBluetooth/Sensor.swift | 1 + .../ShimmerBluetooth/Shimmer3Protocol.swift | 20 ++++++ .../ShimmerBluetooth/ShimmerUtilities.swift | 2 + .../ShimmerExamplePlot/ContentView.swift | 25 ++++--- .../ShimmerExamplePlot/ViewModel.swift | 12 ++++ 6 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift diff --git a/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift new file mode 100644 index 0000000..af89376 --- /dev/null +++ b/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift @@ -0,0 +1,71 @@ +// +// HighGAccel.swift +// ShimmerBluetooth +// +// Created by Shimmer Engineering on 04/06/2025. +// + +import Foundation + +public class HighGAccelSesor : IMUSensor , SensorProcessing{ + + + public var packetIndexHighGAccelX:Int = -1 + public var packetIndexHighGAccelY:Int = -1 + public var packetIndexHighGAccelZ:Int = -1 + public static let HIGHG_ACCEL_X = "HighG Accel X" + public static let HIGHG_ACCEL_Y = "HighG Accel Y" + public static let HIGHG_ACCEL_Z = "HighG Accel Z" + var highGAccelRange = 0 + var CALIBRATION_ID = 40 + var AlignmentMatrix : [[Double]] = [[]] + var SensitivityMatrix : [[Double]] = [[]] + var OffsetVector : [Double] = [] + + public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { + let x = Array(sensorPacket[packetIndexHighGAccelX..>6) & 1 + + if (enabled == 1){ + sensorEnabled = true + } else { + sensorEnabled = false + } + } + + +} diff --git a/ShimmerBluetooth/ShimmerBluetooth/Sensor.swift b/ShimmerBluetooth/ShimmerBluetooth/Sensor.swift index 6685835..cc2b4e9 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Sensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Sensor.swift @@ -19,6 +19,7 @@ public enum SensorDataType { case u24 case u24MSB case i24MSB + case i12MSB } public class Sensor: NSObject{ diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 58e44e2..d6c8fbf 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -51,6 +51,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { 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) + public var highGAccelSensor: HighGAccelSesor = HighGAccelSesor(hwid: HardwareType.UNKNOWN.rawValue) var adcA13Sensor: ADCSensor = ADCSensor() var adcA12Sensor: ADCSensor = ADCSensor() var adcA1Sensor: ADCSensor = ADCSensor() @@ -304,6 +305,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { wrAccelSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) magSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) altMagSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) + highGAccelSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) } } @@ -331,6 +333,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { wrAccelSensor = WRAccelSensor(hwid: REV_HW_MAJOR) timeSensor = TimeSensor() altMagSensor = AltMagSensor(hwid: REV_HW_MAJOR) + highGAccelSensor = HighGAccelSesor(hwid: REV_HW_MAJOR) } } @@ -359,6 +362,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { magSensor.setInfoMem(infomem: infoMem) gyroSensor.setInfoMem(infomem: infoMem) wrAccelSensor.setInfoMem(infomem: infoMem) + highGAccelSensor.setInfoMem(infomem: infoMem) } } @@ -396,6 +400,9 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { if altMagSensor.sensorEnabled { ojc = altMagSensor.processData(sensorPacket: bytes, objectCluster: ojc) } + if highGAccelSensor.sensorEnabled { + ojc = highGAccelSensor.processData(sensorPacket: bytes, objectCluster: ojc) + } if gyroSensor.sensorEnabled { ojc = gyroSensor.processData(sensorPacket: bytes, objectCluster: ojc) } @@ -910,6 +917,18 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { magSensor.packetIndexMagZ = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) + case ChannelContentsShimmer3.AlternativeXAccel.rawValue: + highGAccelSensor.packetIndexHighGAccelX = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) + case ChannelContentsShimmer3.AlternativeYAccel.rawValue: + highGAccelSensor.packetIndexHighGAccelY = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) + case ChannelContentsShimmer3.AlternativeZAccel.rawValue: + highGAccelSensor.packetIndexHighGAccelZ = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) case ChannelContentsShimmer3.AlternativeXMag.rawValue: //AlternativeXMag altMagSensor.packetIndexAltMagX = packetSize packetSize += 2 @@ -1627,6 +1646,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case SENSOR_EXG2_16BIT = 0x080000 case SENSOR_BRIDGE_AMP = 0x8000 case SENSOR_LIS3MDL_ALT_MAG = 0x200000 + case SENSOR_ADXL371_HIGHG_ACCEL = 0x400000 } enum ChannelContentsShimmer3: UInt8 { diff --git a/ShimmerBluetooth/ShimmerBluetooth/ShimmerUtilities.swift b/ShimmerBluetooth/ShimmerBluetooth/ShimmerUtilities.swift index f87326d..3fefe3c 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/ShimmerUtilities.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/ShimmerUtilities.swift @@ -173,6 +173,8 @@ public class ShimmerUtilities{ let msb = Int(sensorData[1] & 0xFF) << 8 let lsb = Int(sensorData[2] & 0xFF) return calculateTwosComplement(signedData: (Int(xmsb + msb + lsb)), bitLength: 24) + }else if dataType == SensorDataType.i12MSB{ + return calculateTwosComplement(signedData: Int(Int(sensorData[0] & 0xFF) << 4 | Int(sensorData[1] & 0xFF) >> 4), bitLength: 12) } return nil diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index 0da8f55..2a8c6e3 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -263,15 +263,6 @@ struct ContentView: View { } } }) - - Button("WriteInfoMem Alt Mag Shimmer3R",action:{ Task { - do { - await viewModel.sendInfoMemS3RAltMag() - } catch { - print("Error: \(error)") - } - } - }) Button("WriteInfoMem Mag Shimmer3R",action:{ Task { do { @@ -299,6 +290,22 @@ struct ContentView: View { } } }) + Button("WriteInfoMem Alt Mag Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RAltMag() + } catch { + print("Error: \(error)") + } + } + }) + Button("WriteInfoMem HighG Accel Shimmer3R",action:{ Task { + do { + await viewModel.sendInfoMemS3RHighGAccel() + } catch { + print("Error: \(error)") + } + } + }) } Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { ForEach(0.. Date: Wed, 4 Jun 2025 16:06:08 +0800 Subject: [PATCH 2/9] updated project.pbxproj file --- 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 15f0edf..6cef2da 100644 --- a/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj +++ b/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 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 */; }; + 92B4B5502DF035C100225A97 /* HighGAccelSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -89,6 +90,7 @@ 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 = ""; }; + 92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighGAccelSensor.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -133,6 +135,7 @@ 3A780C872AE12BEB00EAF050 /* ShimmerBluetooth */ = { isa = PBXGroup; children = ( + 92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */, 92150EF42DE461CE00FEA53B /* AltMagSensor.swift */, 3AEB12F82BCE6F7E00B5F6F1 /* Shimmer3SpeedTestProtocol.swift */, 3A780C882AE12BEB00EAF050 /* ShimmerBluetooth.h */, @@ -318,6 +321,7 @@ 3AED20712B0C4BA60066A0F8 /* MagSensor.swift in Sources */, 3A7A7F242AE7753E001FD6BD /* ShimmerProtocol.swift in Sources */, 3A7A7F282AE77F0E001FD6BD /* Shimmer3Protocol.swift in Sources */, + 92B4B5502DF035C100225A97 /* HighGAccelSensor.swift in Sources */, 3AEB12F92BCE6F7E00B5F6F1 /* Shimmer3SpeedTestProtocol.swift in Sources */, 3AA359132AF34D89008AD334 /* Shimmer3InfoMem.swift in Sources */, 3A0B4B632B0DDD4500786295 /* ADCSensor.swift in Sources */, From ba647d737343e41d035e38ddf939fce703d6371d Mon Sep 17 00:00:00 2001 From: jyong15 Date: Fri, 5 Dec 2025 13:58:23 +0800 Subject: [PATCH 3/9] DEV-248 fixed sensor units and typo --- .../ShimmerBluetooth/HighGAccelSensor.swift | 14 +++++++------- .../ShimmerBluetooth/Shimmer3Protocol.swift | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift index af89376..ac02ea5 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift @@ -7,7 +7,7 @@ import Foundation -public class HighGAccelSesor : IMUSensor , SensorProcessing{ +public class HighGAccelSensor : IMUSensor , SensorProcessing{ public var packetIndexHighGAccelX:Int = -1 @@ -33,15 +33,15 @@ public class HighGAccelSesor : IMUSensor , SensorProcessing{ let data:[Double] = [rawDataX,rawDataY,rawDataZ] let(calData)=IMUSensor.calibrateInertialSensorData(data,AlignmentMatrix,SensitivityMatrix,OffsetVector) - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_X, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.localflux.rawValue, value: calData![0]) - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_Y, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.localflux.rawValue, value: calData![1]) - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_Z, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.localflux.rawValue, value: calData![2]) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_X, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: calData![0]) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_Y, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: calData![1]) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_Z, formatName: SensorFormats.Calibrated.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: calData![2]) print("HG X : \(calData![0]) , HG Y : \(calData![1]), HG Z : \(calData![2])") } print("HGR X : \(rawDataX) , HGR Y : \(rawDataY), HGR Z : \(rawDataZ)") - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_X, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.localflux.rawValue, value: rawDataX) - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_Y, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.localflux.rawValue, value: rawDataY) - objectCluster.addData(sensorName: HighGAccelSesor.HIGHG_ACCEL_Z, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.localflux.rawValue, value: rawDataZ) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_X, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: rawDataX) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_Y, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: rawDataY) + objectCluster.addData(sensorName: HighGAccelSensor.HIGHG_ACCEL_Z, formatName: SensorFormats.Raw.rawValue, unitName: SensorUnits.meterPerSecondSquared.rawValue, value: rawDataZ) return objectCluster } diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 3d5480a..6a99f75 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -51,7 +51,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { 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) - public var highGAccelSensor: HighGAccelSesor = HighGAccelSesor(hwid: HardwareType.UNKNOWN.rawValue) + public var highGAccelSensor: HighGAccelSensor = HighGAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) var adcA13Sensor: ADCSensor = ADCSensor() var adcA12Sensor: ADCSensor = ADCSensor() var adcA1Sensor: ADCSensor = ADCSensor() @@ -333,7 +333,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { wrAccelSensor = WRAccelSensor(hwid: REV_HW_MAJOR) timeSensor = TimeSensor() altMagSensor = AltMagSensor(hwid: REV_HW_MAJOR) - highGAccelSensor = HighGAccelSesor(hwid: REV_HW_MAJOR) + highGAccelSensor = HighGAccelSensor(hwid: REV_HW_MAJOR) } } From 98aee4c2f05c315c96de6b2fae143f8a5b905afa Mon Sep 17 00:00:00 2001 From: JongChern Date: Tue, 9 Dec 2025 17:03:11 +0800 Subject: [PATCH 4/9] updates --- .../ShimmerBluetooth/Shimmer3Protocol.swift | 170 +++++++++++++++--- .../ShimmerExamplePlot/ContentView.swift | 4 +- .../ShimmerExamplePlot/ViewModel.swift | 31 +--- 3 files changed, 149 insertions(+), 56 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 6a99f75..f0ca791 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -130,6 +130,49 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { return result! } + public func sendSetSensorsCommand(sensorBitmap: UInt32) async -> Bool { + var bytes: [UInt8] = [] + + // Command byte + bytes.append(PacketTypeShimmer.setSensorsCommand.rawValue) + + // Little-endian bitmap like C#/Java. + bytes.append(UInt8(sensorBitmap & 0xFF)) + bytes.append(UInt8((sensorBitmap >> 8) & 0xFF)) + bytes.append(UInt8((sensorBitmap >> 16) & 0xFF)) + bytes.append(UInt8((sensorBitmap >> 24) & 0xFF)) + + commandSent = PacketTypeShimmer.setSensorsCommand + radio!.writeBytes(bytes: bytes) + + // Wait for ACK of SetSensors + let cmdResult = await withCheckedContinuation { continuation in + if self.continuation == nil { + self.continuation = continuation + } + } ?? false + + if cmdResult == false { + print("SetSensorsCommand FAILED") + return false + } + + print("SetSensorsCommand ACK OK → Now sending Inquiry...") + + // Required: Refresh the sensor map from device + let inquiryResult = await sendInquiryCommand() ?? false + + if inquiryResult { + print("Inquiry completed after SetSensors") + } else { + print("Inquiry failed after SetSensors") + } + + return inquiryResult + } + + + public func writeShimmer3InfoMem(infoMem:[UInt8]) async -> Bool{ self.changeState(btState:Shimmer3BTState.CONFIGURING) if(infoMem.count != (128*3)){ @@ -337,6 +380,35 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } } + func disableSensors(){ + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + lnAccelSensor.sensorEnabled = false + wrAccelSensor.sensorEnabled = false + timeSensor.sensorEnabled = false + magSensor.sensorEnabled = false + gyroSensor.sensorEnabled = false + adcA13Sensor.sensorEnabled = false + adcA7Sensor.sensorEnabled = false + adcA6Sensor.sensorEnabled = false + adcA15Sensor.sensorEnabled = false + adcA12Sensor.sensorEnabled = false + adcA1Sensor.sensorEnabled = false + + gsrSensor.sensorEnabled = false + exgSensor.sensorEnabled = false + pressureTempSensor.sensorEnabled = false + battVoltageSensor.sensorEnabled = false + } else if (REV_HW_MAJOR==HardwareType.Shimmer3R.rawValue){ + timeSensor.sensorEnabled = false + lnAccelSensor.sensorEnabled = false + altMagSensor.sensorEnabled = false + magSensor.sensorEnabled = false + gyroSensor.sensorEnabled = false + wrAccelSensor.sensorEnabled = false + highGAccelSensor.sensorEnabled = false + } + } + func initializeSensors(){ if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ lnAccelSensor.setInfoMem(infomem: infoMem) @@ -835,6 +907,31 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } + else if (self.commandSent == PacketTypeShimmer.setSensorsCommand) { + print("Set Sensors Command ACK Received") + + let received = Array(self.receivedBytes.prefix(1 + Int(self.CRCMode.rawValue))) + self.receivedBytes.removeFirst(1 + Int(self.CRCMode.rawValue)) + + var crcresult = true + if self.CRCMode != BTCRCMode.OFF { + print("CRC SetSensors Calculated: \(self.shimmerUartCrcCalc(received, (received.count - Int(self.CRCMode.rawValue))))") + crcresult = self.checkCrc(received, (received.count - Int(self.CRCMode.rawValue))) + print("CRC SetSensors Check: \(crcresult)") + } + + if (crcresult) { + self.continuation?.resume(returning: true) + self.continuation = nil + } else { + self.continuation?.resume(returning: false) + self.continuation = nil + print("[CRC ERROR] : \(self.commandSent!)") + } + + print("Command ACK Received and Processed: \(self.commandSent!)") + } + } } @@ -863,6 +960,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { func interpretDataPacketFormat(nC: Int, signalid: [UInt8]) { + disableSensors() //signalDataTypeArray.append("u16") var packetSize = 2 // Time stamp @@ -880,80 +978,87 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { switch signalIdByte { case ChannelContentsShimmer3.XLNAccel.rawValue: lnAccelSensor.packetIndexAccelX = packetSize + lnAccelSensor.sensorEnabled = true packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue) case ChannelContentsShimmer3.YLNAccel.rawValue: lnAccelSensor.packetIndexAccelY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue) case ChannelContentsShimmer3.ZLNAccel.rawValue: lnAccelSensor.packetIndexAccelZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_A_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue) case ChannelContentsShimmer3.VBatt.rawValue: packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_VBATT.rawValue) case ChannelContentsShimmer3.XWRAccel.rawValue: + wrAccelSensor.sensorEnabled = true wrAccelSensor.packetIndexAccelX = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue) case ChannelContentsShimmer3.YWRAccel.rawValue: wrAccelSensor.packetIndexAccelY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue) case ChannelContentsShimmer3.ZWRAccel.rawValue: wrAccelSensor.packetIndexAccelZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_D_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue) case ChannelContentsShimmer3.XMag.rawValue: + magSensor.sensorEnabled = true magSensor.packetIndexMagX = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MAG.rawValue) case ChannelContentsShimmer3.YMag.rawValue: magSensor.packetIndexMagY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MAG.rawValue) case ChannelContentsShimmer3.ZMag.rawValue: magSensor.packetIndexMagZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LSM303DLHC_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MAG.rawValue) case ChannelContentsShimmer3.AlternativeXAccel.rawValue: + highGAccelSensor.sensorEnabled = true highGAccelSensor.packetIndexHighGAccelX = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_HIGHG_ACCEL.rawValue) case ChannelContentsShimmer3.AlternativeYAccel.rawValue: highGAccelSensor.packetIndexHighGAccelY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_HIGHG_ACCEL.rawValue) case ChannelContentsShimmer3.AlternativeZAccel.rawValue: highGAccelSensor.packetIndexHighGAccelZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ADXL371_HIGHG_ACCEL.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_HIGHG_ACCEL.rawValue) case ChannelContentsShimmer3.AlternativeXMag.rawValue: //AlternativeXMag + altMagSensor.sensorEnabled = true altMagSensor.packetIndexAltMagX = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ALT_MAG.rawValue) case ChannelContentsShimmer3.AlternativeYMag.rawValue: altMagSensor.packetIndexAltMagY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ALT_MAG.rawValue) case ChannelContentsShimmer3.AlternativeZMag.rawValue: altMagSensor.packetIndexAltMagZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_LIS3MDL_ALT_MAG.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_ALT_MAG.rawValue) case ChannelContentsShimmer3.XGyro.rawValue: + gyroSensor.sensorEnabled = true gyroSensor.packetIndexGyroX = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_GYRO.rawValue) case ChannelContentsShimmer3.YGyro.rawValue: gyroSensor.packetIndexGyroY = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_GYRO.rawValue) case ChannelContentsShimmer3.ZGyro.rawValue: gyroSensor.packetIndexGyroZ = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_MPU9150_GYRO.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_GYRO.rawValue) case ChannelContentsShimmer3.GsrRaw.rawValue: + gsrSensor.sensorEnabled = true gsrSensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_GSR.rawValue) @@ -986,35 +1091,42 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_16BIT.rawValue) case ChannelContentsShimmer3.InternalAdc13.rawValue: + adcA13Sensor.sensorEnabled = true adcA13Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A13.rawValue) case ChannelContentsShimmer3.ExternalAdc15.rawValue: + adcA15Sensor.sensorEnabled = true adcA15Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A15.rawValue) case ChannelContentsShimmer3.InternalAdc12.rawValue: + adcA12Sensor.sensorEnabled = true adcA12Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A12.rawValue) case ChannelContentsShimmer3.InternalAdc1.rawValue: + adcA1Sensor.sensorEnabled = true adcA1Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A1.rawValue) case ChannelContentsShimmer3.ExternalAdc6.rawValue: + adcA6Sensor.sensorEnabled = true adcA6Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A6.rawValue) case ChannelContentsShimmer3.ExternalAdc7.rawValue: + adcA7Sensor.sensorEnabled = true adcA7Sensor.packetIndex = packetSize packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A7.rawValue) case ChannelContentsShimmer3.Temperature.rawValue: + pressureTempSensor.sensorEnabled = true packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_PRESSURE.rawValue) case ChannelContentsShimmer3.Pressure.rawValue: packetSize += 3 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_PRESSURE.rawValue) default: packetSize += 2 } @@ -1625,31 +1737,31 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } - enum SensorBitmapShimmer3: UInt32 { - case SENSOR_A_ACCEL = 0x80 - case SENSOR_MPU9150_GYRO = 0x040 - case SENSOR_LSM303DLHC_MAG = 0x20 + public enum SensorBitmapShimmer3: UInt32 { + case SENSOR_LN_ACCEL = 0x80 + case SENSOR_GYRO = 0x040 + case SENSOR_MAG = 0x20 case SENSOR_GSR = 0x04 case SENSOR_EXT_A7 = 0x02 case SENSOR_EXT_A6 = 0x01 case SENSOR_VBATT = 0x2000 - case SENSOR_D_ACCEL = 0x1000 + case SENSOR_WR_ACCEL = 0x1000 case SENSOR_EXT_A15 = 0x0800 case SENSOR_INT_A1 = 0x0400 case SENSOR_INT_A12 = 0x0200 case SENSOR_INT_A13 = 0x0100 case SENSOR_INT_A14 = 0x800000 - case SENSOR_BMP180_PRESSURE = 0x40000 + case SENSOR_PRESSURE = 0x40000 case SENSOR_EXG1_24BIT = 0x10 case SENSOR_EXG2_24BIT = 0x08 case SENSOR_EXG1_16BIT = 0x100000 case SENSOR_EXG2_16BIT = 0x080000 case SENSOR_BRIDGE_AMP = 0x8000 - case SENSOR_LIS3MDL_ALT_MAG = 0x200000 - case SENSOR_ADXL371_HIGHG_ACCEL = 0x400000 + case SENSOR_ALT_MAG = 0x200000 + case SENSOR_HIGHG_ACCEL = 0x400000 } - enum ChannelContentsShimmer3: UInt8 { + public enum ChannelContentsShimmer3: UInt8 { case XLNAccel = 0x00 case YLNAccel = 0x01 case ZLNAccel = 0x02 diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index 2a8c6e3..e6b63e0 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -255,9 +255,9 @@ struct ContentView: View { } }) } else if (viewModel.shimmer3Protocol?.REV_HW_MAJOR==Shimmer3Protocol.HardwareType.Shimmer3R.rawValue){ - Button("WriteInfoMem LNAccel Shimmer3R",action:{ Task { + Button("Enable LNAccel Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RLNAccel() + await viewModel.enableS3RLNAccel(); } catch { print("Error: \(error)") } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index b5e1e3f..6865d02 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift @@ -85,6 +85,7 @@ class ViewModel: NSObject, ObservableObject { samplingRateIndex = Int((shimmer3Protocol?.getSamplingRateIndex())!) altMagRange3RIndex = Int((shimmer3Protocol?.altMagSensor.get3RRange().rawValue)!) + self.updatedPicker = false } func connectDev2() async{ @@ -235,43 +236,23 @@ class ViewModel: NSObject, ObservableObject { refreshUISettings() } - func sendInfoMemS3RLNAccel() async{ - let infomlnacc:[UInt8] = [ - 0x80,0x02,0x01,0x80,0x00,0x00,0x02,0x05,0x21,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,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,0x0D,0x5D,0x0D,0x5D,0x0D,0x5D,0x64,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,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x68,0x0F,0x2F,0x99,0x01,0x01,0x31,0x00,0x00,0x00,0x00,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,0x02,0x9B,0x02,0x9B,0x02,0x9B,0x9C,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) + func enableS3RLNAccel() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue); refreshUISettings() } func sendInfoMemS3RMag() async{ - let infommag:[UInt8] = [ - 0x80, 0x02, 0x01, 0x20, 0x00, 0x00, 0x02, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x35, 0x5F, 0xBA, 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, 0x0D, 0x5D, 0x0D, 0x5D, 0x0D, 0x5D, 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: infommag) + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue); refreshUISettings() } func sendInfoMemS3RGyro() async{ - let infomlnacc:[UInt8] = [ - 0x80,0x02,0x01,0x40,0x00,0x00,0x02,0x05,0x21,0xC8,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,0x00,0xD1,0x00,0xD1,0x00,0xD1,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,0x0D,0x5D,0x0D,0x5D,0x0D,0x5D,0x64,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,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x68,0x1B,0x47,0x84,0x01,0x01,0x31,0x00,0x00,0x00,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,0x02,0x9B,0x02,0x9B,0x02,0x9B,0x9C,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?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_MAG.rawValue); refreshUISettings() } func sendInfoMemS3RWRAccel() async{ - let infomlnacc:[UInt8] = [ - 0x80,0x02,0x01,0x00,0x10,0x00,0x51,0x00,0x21,0xC8,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD1,0x00,0xD1,0x00,0xD1,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,0x0D,0x5D,0x0D,0x5D,0x0D,0x5D,0x64,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,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x68,0x1A,0xF0,0xB4,0x01,0x01,0x31,0x00,0x00,0x00,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,0x02,0x9B,0x02,0x9B,0x02,0x9B,0x9C,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?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue); refreshUISettings() } From 32ea4b08fb837d2eb9e533aad8f85fde60a60389 Mon Sep 17 00:00:00 2001 From: JongChern Date: Tue, 9 Dec 2025 22:09:09 +0800 Subject: [PATCH 5/9] updates --- .../ShimmerExamplePlot/ContentView.swift | 20 ++++++------ .../ShimmerExamplePlot/ViewModel.swift | 31 ++++++------------- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index e6b63e0..228a4ca 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -264,43 +264,43 @@ struct ContentView: View { } }) - Button("WriteInfoMem Mag Shimmer3R",action:{ Task { + Button("Enable Mag Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RMag() + await viewModel.enableS3RMag() } catch { print("Error: \(error)") } } }) - Button("WriteInfoMem Gyro Shimmer3R",action:{ Task { + Button("Enable Gyro Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RGyro() + await viewModel.enableS3RGyro() } catch { print("Error: \(error)") } } }) - Button("WriteInfoMem WRAccel Shimmer3R",action:{ Task { + Button("Enable WRAccel Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RWRAccel() + await viewModel.enableS3RWRAccel() } catch { print("Error: \(error)") } } }) - Button("WriteInfoMem Alt Mag Shimmer3R",action:{ Task { + Button("Enable Alt Mag Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RAltMag() + await viewModel.enableS3RAltMag() } catch { print("Error: \(error)") } } }) - Button("WriteInfoMem HighG Accel Shimmer3R",action:{ Task { + Button("Enable HighG Accel Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RHighGAccel() + await viewModel.enableS3RHighGAccel() } catch { print("Error: \(error)") } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index 6865d02..d91f125 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift @@ -213,26 +213,13 @@ class ViewModel: NSObject, ObservableObject { refreshUISettings() } - func sendInfoMemS3RAltMag() async{ - 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: infomaltmag) + func enableS3RAltMag() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_ALT_MAG.rawValue); refreshUISettings() } - func sendInfoMemS3RHighGAccel() async{ - let infomhighgaccel:[UInt8] = [ - 0x80, 0x02, 0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x36, 0x38, 0x44, 0x44, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x54, 0x72, 0x69, 0x61, 0x6C, 0x68, 0x3F, 0xD4, 0x1B, 0x01, 0x01, 0x31, 0x00, 0x00, 0x00, 0x00, 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, 0x0D, 0x5D, 0x0D, 0x5D, 0x0D, 0x5D, 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: infomhighgaccel) + func enableS3RHighGAccel() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_HIGHG_ACCEL.rawValue); refreshUISettings() } @@ -241,17 +228,17 @@ class ViewModel: NSObject, ObservableObject { refreshUISettings() } - func sendInfoMemS3RMag() async{ - await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue); + func enableS3RMag() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_MAG.rawValue); refreshUISettings() } - func sendInfoMemS3RGyro() async{ - await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_MAG.rawValue); + func enableS3RGyro() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_GYRO.rawValue); refreshUISettings() } - func sendInfoMemS3RWRAccel() async{ + func enableS3RWRAccel() async{ await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue); refreshUISettings() } From cbc0e3e30bbd8599a70931e0b7221269ea7d269b Mon Sep 17 00:00:00 2001 From: JongChern Date: Wed, 10 Dec 2025 15:58:52 +0800 Subject: [PATCH 6/9] update --- .../ShimmerBluetooth/EXGSensor.swift | 88 ++++++++++--------- .../ShimmerBluetooth/Shimmer3Protocol.swift | 75 ++++++++++++++-- .../ShimmerExamplePlot/ContentView.swift | 32 +++++++ .../ShimmerExamplePlot/ViewModel.swift | 27 ++++++ 4 files changed, 173 insertions(+), 49 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/EXGSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/EXGSensor.swift index 753a3c6..558464e 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/EXGSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/EXGSensor.swift @@ -79,7 +79,7 @@ public class EXGSensor: Sensor , SensorProcessing{ } } var CurrentResolution = Resolution.RESOLUTION_16BIT - + var resByte0InHexString:String = ""; public var packetIndex:Int = -1 public static let EXG1_STATUS = "ECG_EMG_Status" public static let EXG2_STATUS = "ECG_EMG_Status2" @@ -437,46 +437,10 @@ public class EXGSensor: Sensor , SensorProcessing{ } return gain } - - public func setInfoMem(infomem: [UInt8]) { - - var isEXG24Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>4) & 1 - var isEXG16Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors2]>>4) & 1 - - if (isEXG24Bit == 1){ - self.isEXG24Bit = true - } else { - self.isEXG24Bit = false - } - - if (isEXG16Bit == 1){ - self.isEXG16Bit = true - } else { - self.isEXG16Bit = false - } - - if (isEXG24Bit == 1 || isEXG16Bit == 1){ - sensorEnabled = true - isEXG1Enabled = true - } else { - sensorEnabled = false - isEXG1Enabled = false - } - - - var exg2_24Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>3) & 1 - var exg2_16Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors2]>>3) & 1 - if (exg2_24Bit == 1 || exg2_16Bit == 1){ - //sensorEnabled = true - isEXG2Enabled = true - } else { - //sensorEnabled = false - isEXG2Enabled = false - } - - exg1RegisterArray = Array(infomem[10..<20]) - exg2RegisterArray = Array(infomem[20..<30]) - + + public func setEXGArray(array1: [UInt8],array2:[UInt8]){ + self.exg1RegisterArray = array1 + self.exg2RegisterArray = array2 CurrentEXGMode = EXGMode.UNKNOWN if(((exg1RegisterArray[3] & 0x0F)==5) @@ -512,8 +476,6 @@ public class EXGSensor: Sensor , SensorProcessing{ let exg1GainSetting = exg1RegisterArray[3] let exg2GainSetting = exg2RegisterArray[3] - - let resByte0InHexString = String(infomem[ConfigByteLayoutShimmer3.idxSensors0], radix: 16) if(CurrentEXGMode == EXGMode.EMG){ exg1GainValue = convertEmgGainSettingToValue(setting: Int(exg1GainSetting)) @@ -545,6 +507,46 @@ public class EXGSensor: Sensor , SensorProcessing{ } } + public func setInfoMem(infomem: [UInt8]) { + + var isEXG24Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>4) & 1 + var isEXG16Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors2]>>4) & 1 + + if (isEXG24Bit == 1){ + self.isEXG24Bit = true + } else { + self.isEXG24Bit = false + } + + if (isEXG16Bit == 1){ + self.isEXG16Bit = true + } else { + self.isEXG16Bit = false + } + + if (isEXG24Bit == 1 || isEXG16Bit == 1){ + sensorEnabled = true + isEXG1Enabled = true + } else { + sensorEnabled = false + isEXG1Enabled = false + } + + + var exg2_24Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]>>3) & 1 + var exg2_16Bit = Int(infomem[ConfigByteLayoutShimmer3.idxSensors2]>>3) & 1 + if (exg2_24Bit == 1 || exg2_16Bit == 1){ + //sensorEnabled = true + isEXG2Enabled = true + } else { + //sensorEnabled = false + isEXG2Enabled = false + } + resByte0InHexString = String(infomem[ConfigByteLayoutShimmer3.idxSensors0], radix: 16) + setEXGArray(array1: Array(infomem[10..<20]),array2: Array(infomem[20..<30])) + + } + public func updateInfoMemExgResolution(infomem: [UInt8],resolution: Resolution) -> [UInt8]{ var infomemtoupdate = infomem let exgResolutionToSet = resolution diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index f0ca791..9a08324 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -406,6 +406,9 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { gyroSensor.sensorEnabled = false wrAccelSensor.sensorEnabled = false highGAccelSensor.sensorEnabled = false + gsrSensor.sensorEnabled = false + exgSensor.sensorEnabled = false + pressureTempSensor.sensorEnabled = false } } @@ -435,6 +438,8 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { gyroSensor.setInfoMem(infomem: infoMem) wrAccelSensor.setInfoMem(infomem: infoMem) highGAccelSensor.setInfoMem(infomem: infoMem) + exgSensor.setInfoMem(infomem: infoMem) + gsrSensor.setInfoMem(infomem: infoMem) } } @@ -1065,6 +1070,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.Exg1_Status.rawValue: packetSize += 1 case ChannelContentsShimmer3.Exg1_CH1.rawValue: + exgSensor.sensorEnabled = true packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue) case ChannelContentsShimmer3.Exg1_CH2.rawValue: @@ -1073,6 +1079,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.Exg2_Status.rawValue: packetSize += 1 case ChannelContentsShimmer3.Exg2_CH1.rawValue: + exgSensor.sensorEnabled = true packetSize += 3 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue) case ChannelContentsShimmer3.Exg2_CH2.rawValue: @@ -1430,6 +1437,62 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } } } + + public func sendSetEXGConfigurations(valuesChip1: [UInt8], valuesChip2: [UInt8]) async -> Bool { + + // Safety: require exactly 10 registers each (as per Shimmer3 EXG register map) + guard valuesChip1.count == 10, valuesChip2.count == 10 else { + print("ERROR: EXG register arrays must be exactly 10 bytes each.") + return false + } + + var bytes: [UInt8] = [] + + // Write chip 1 block + bytes.append(PacketTypeShimmer.setExgRegsCommand.rawValue) + bytes.append(0x00) // chip1 + bytes.append(0x00) // starting register index + bytes.append(0x0A) // number of registers + bytes.append(contentsOf: valuesChip1) + commandSent = PacketTypeShimmer.setExgRegsCommand + radio?.writeBytes(bytes: bytes) + + // Wait for ACK from the BT processing thread + let result1 = await withCheckedContinuation { continuation in + if self.continuation == nil { + self.continuation = continuation + } + } ?? false + bytes = [] + // Write chip 2 block + bytes.append(PacketTypeShimmer.setExgRegsCommand.rawValue) + bytes.append(0x01) // chip2 + bytes.append(0x00) + bytes.append(0x0A) + bytes.append(contentsOf: valuesChip2) + + commandSent = PacketTypeShimmer.setExgRegsCommand + radio?.writeBytes(bytes: bytes) + + // Wait for ACK from the BT processing thread + let result2 = await withCheckedContinuation { continuation in + if self.continuation == nil { + self.continuation = continuation + } + } ?? false + if result1 && result2 { + print("Set EXG Configurations ACK received.") + exgSensor.setEXGArray(array1: valuesChip1,array2: valuesChip2) + + } else { + print("Set EXG Configurations FAILED") + return false + } + + return true + } + + public func updateInfoMemSamplingRate(infomem: [UInt8],samplingRateFreq: Double) -> [UInt8]{ var infomemtoupdate = infomem @@ -1681,12 +1744,12 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { } public class Shimmer3Configuration { - static let EXG_ECG_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA0, 0x10, 0x40, 0x40, 0x2D, 0x00, 0x00, 0x02, 0x03] - static let EXG_ECG_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01] - static let EXG_EMG_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA0, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03] - static let EXG_EMG_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA0, 0x10, 0xE1, 0xE1, 0x00, 0x00, 0x00, 0x02, 0x01] - static let EXG_TEST_SIGNAL_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA3, 0x10, 0x45, 0x45, 0x00, 0x00, 0x00, 0x02, 0x01] - static let EXG_TEST_SIGNAL_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA3, 0x10, 0x45, 0x45, 0x00, 0x00, 0x00, 0x02, 0x01] + public static let EXG_ECG_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA0, 0x10, 0x40, 0x40, 0x2D, 0x00, 0x00, 0x02, 0x03] + public static let EXG_ECG_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01] + public static let EXG_EMG_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA0, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03] + public static let EXG_EMG_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA0, 0x10, 0xE1, 0xE1, 0x00, 0x00, 0x00, 0x02, 0x01] + public static let EXG_TEST_SIGNAL_CONFIGURATION_CHIP1: [UInt8] = [0x00, 0xA3, 0x10, 0x45, 0x45, 0x00, 0x00, 0x00, 0x02, 0x01] + public static let EXG_TEST_SIGNAL_CONFIGURATION_CHIP2: [UInt8] = [0x00, 0xA3, 0x10, 0x45, 0x45, 0x00, 0x00, 0x00, 0x02, 0x01] public class SignalNames { static let V_SENSE_BATT = "VSenseBatt" diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index 228a4ca..a0744cc 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -306,6 +306,38 @@ struct ContentView: View { } } }) + Button("Enable EXG Test",action:{ Task { + do { + await viewModel.enableEXGTest() + } catch { + print("Error: \(error)") + } + } + }) + Button("Enable ECG",action:{ Task { + do { + await viewModel.enableECG() + } catch { + print("Error: \(error)") + } + } + }) + Button("Enable EMG",action:{ Task { + do { + await viewModel.enableEMG() + } catch { + print("Error: \(error)") + } + } + }) + Button("Enable PPG + GSR",action:{ Task { + do { + await viewModel.enableS3RHighGAccel() + } catch { + print("Error: \(error)") + } + } + }) } Picker("Select EXG Gain", selection: $viewModel.exgGainIndex) { ForEach(0.. Date: Wed, 10 Dec 2025 16:41:07 +0800 Subject: [PATCH 7/9] Update ContentView.swift --- .../ShimmerExamplePlot/ContentView.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index a0744cc..7dc998f 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -94,6 +94,20 @@ struct ContentView: View { }.onChange(of: signalSelection) { _ in print(signalSelection) viewModel.startIndex = signalSelection + + // Clear ViewModel signals + viewModel.signal1 = [] + viewModel.signal2 = [] + viewModel.signal3 = [] + + // Clear local arrays used by Chart + numbers1 = [] + numbers2 = [] + numbers3 = [] + + // Reset min/max so chart rescales + min = 0 + max = 0 } Chart { From b299211e4db3fb248c858c3593e77dec6ebfefde Mon Sep 17 00:00:00 2001 From: JongChern Date: Thu, 11 Dec 2025 15:00:25 +0800 Subject: [PATCH 8/9] update --- .../ShimmerBluetooth/ADCSensor.swift | 52 +++--- .../ShimmerBluetooth/Shimmer3Protocol.swift | 169 ++++++++++-------- 2 files changed, 122 insertions(+), 99 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/ADCSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/ADCSensor.swift index 2c56a4f..06cf9c6 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/ADCSensor.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/ADCSensor.swift @@ -11,27 +11,31 @@ public class ADCSensor: Sensor, SensorProcessing { public var packetIndex:Int = -1 public enum ADCType { - case Shimmer3_A13 - case Shimmer3_A12 - case Shimmer3_A1 - case Shimmer3_A6 - case Shimmer3_A7 - case Shimmer3_A15 + + case Shimmer3_Internal_A1 + case Shimmer3_Internal_A2 + case Shimmer3_Internal_A0 + case Shimmer3_Internal_A3 + case Shimmer3_External_A1 + case Shimmer3_External_A0 + case Shimmer3_External_A2 var description: String { switch self { - case .Shimmer3_A13: - return "Internal ADC A13" - case .Shimmer3_A12: - return "Internal ADC A12" - case .Shimmer3_A1: + case .Shimmer3_Internal_A2: + return "Internal ADC A2" + case .Shimmer3_Internal_A0: + return "Internal ADC A0" + case .Shimmer3_Internal_A3: + return "Internal ADC A3" + case .Shimmer3_External_A0: + return "External ADC A0" + case .Shimmer3_External_A1: + return "External ADC A1" + case .Shimmer3_External_A2: + return "External ADC A2" + case .Shimmer3_Internal_A1: return "Internal ADC A1" - case .Shimmer3_A7: - return "External ADC A7" - case .Shimmer3_A6: - return "External ADC A6" - case .Shimmer3_A15: - return "External ADC A15" } } @@ -48,7 +52,7 @@ public class ADCSensor: Sensor, SensorProcessing { self.ojcName = adc.description } - private var internalADCType:ADCType = ADCType.Shimmer3_A13; + private var internalADCType:ADCType = ADCType.Shimmer3_Internal_A1; private var ojcName = "Internal ADC A13" public func processData(sensorPacket: [UInt8], objectCluster: ObjectCluster) -> ObjectCluster { @@ -64,42 +68,42 @@ public class ADCSensor: Sensor, SensorProcessing { public func setInfoMem(infomem: [UInt8]) { - if (self.internalADCType==ADCType.Shimmer3_A13){ + if (self.internalADCType==ADCType.Shimmer3_Internal_A1){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors1]) & 1 if (enabled > 0){ sensorEnabled = true } else { sensorEnabled = false } - } else if (self.internalADCType==ADCType.Shimmer3_A12){ + } else if (self.internalADCType==ADCType.Shimmer3_Internal_A0){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors1]) & 2 if (enabled > 0){ sensorEnabled = true } else { sensorEnabled = false } - } else if (self.internalADCType==ADCType.Shimmer3_A7){ + } else if (self.internalADCType==ADCType.Shimmer3_External_A0){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]) & 2 if (enabled > 0){ sensorEnabled = true } else { sensorEnabled = false } - } else if (self.internalADCType==ADCType.Shimmer3_A6){ + } else if (self.internalADCType==ADCType.Shimmer3_External_A1){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors0]) & 1 if (enabled > 0){ sensorEnabled = true } else { sensorEnabled = false } - } else if (self.internalADCType==ADCType.Shimmer3_A1){ + } else if (self.internalADCType==ADCType.Shimmer3_Internal_A3){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors1]) & 4 if (enabled > 0){ sensorEnabled = true } else { sensorEnabled = false } - } else if (self.internalADCType==ADCType.Shimmer3_A15){ + } else if (self.internalADCType==ADCType.Shimmer3_External_A2){ var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors1]) & 8 if (enabled > 0){ sensorEnabled = true diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 46fd15b..1ca55eb 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -52,12 +52,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { public var gyroSensor: GyroSensor = GyroSensor(hwid: HardwareType.UNKNOWN.rawValue) public var altMagSensor: AltMagSensor = AltMagSensor(hwid: HardwareType.UNKNOWN.rawValue) public var highGAccelSensor: HighGAccelSensor = HighGAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) - var adcA13Sensor: ADCSensor = ADCSensor() - var adcA12Sensor: ADCSensor = ADCSensor() - var adcA1Sensor: ADCSensor = ADCSensor() - var adcA7Sensor: ADCSensor = ADCSensor() - var adcA6Sensor: ADCSensor = ADCSensor() - var adcA15Sensor: ADCSensor = ADCSensor() + var adcInternalA3Sensor: ADCSensor = ADCSensor() + var adcInternalA2Sensor: ADCSensor = ADCSensor() + var adcInternalA1Sensor: ADCSensor = ADCSensor() + var adcInternalA0Sensor: ADCSensor = ADCSensor() + var adcExternalA0Sensor: ADCSensor = ADCSensor() + var adcExternalA1Sensor: ADCSensor = ADCSensor() + var adcExternalA2Sensor: ADCSensor = ADCSensor() var gsrSensor: GSRSensor = GSRSensor() public var exgSensor: EXGSensor = EXGSensor() public var pressureTempSensor : PressureTempSensor = PressureTempSensor(hwid: HardwareType.UNKNOWN.rawValue) @@ -359,12 +360,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { timeSensor = TimeSensor() magSensor = MagSensor(hwid: REV_HW_MAJOR) gyroSensor = GyroSensor(hwid: REV_HW_MAJOR) - adcA13Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A13) - adcA12Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A12) - adcA1Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A1) - adcA7Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A7) - adcA6Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A6) - adcA15Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_A15) + adcInternalA0Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_Internal_A0) + adcInternalA1Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_Internal_A1) + adcInternalA2Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_Internal_A2) + adcInternalA3Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_Internal_A3) + adcExternalA0Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_External_A0) + adcExternalA1Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_External_A1) + adcExternalA2Sensor = ADCSensor(adc: ADCSensor.ADCType.Shimmer3_External_A2) gsrSensor = GSRSensor() exgSensor = EXGSensor() pressureTempSensor = PressureTempSensor(hwid: REV_HW_MAJOR) @@ -388,13 +390,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { timeSensor.sensorEnabled = false magSensor.sensorEnabled = false gyroSensor.sensorEnabled = false - adcA13Sensor.sensorEnabled = false - adcA7Sensor.sensorEnabled = false - adcA6Sensor.sensorEnabled = false - adcA15Sensor.sensorEnabled = false - adcA12Sensor.sensorEnabled = false - adcA1Sensor.sensorEnabled = false - + adcInternalA0Sensor.sensorEnabled = false + adcInternalA1Sensor.sensorEnabled = false + adcInternalA2Sensor.sensorEnabled = false + adcInternalA3Sensor.sensorEnabled = false + adcExternalA0Sensor.sensorEnabled = false + adcExternalA1Sensor.sensorEnabled = false + adcExternalA2Sensor.sensorEnabled = false gsrSensor.sensorEnabled = false exgSensor.sensorEnabled = false pressureTempSensor.sensorEnabled = false @@ -410,6 +412,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { gsrSensor.sensorEnabled = false exgSensor.sensorEnabled = false pressureTempSensor.sensorEnabled = false + adcInternalA0Sensor.sensorEnabled = false + adcInternalA1Sensor.sensorEnabled = false + adcInternalA2Sensor.sensorEnabled = false + adcInternalA3Sensor.sensorEnabled = false + adcExternalA0Sensor.sensorEnabled = false + adcExternalA1Sensor.sensorEnabled = false + adcExternalA2Sensor.sensorEnabled = false } } @@ -420,13 +429,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { timeSensor.setInfoMem(infomem: infoMem) magSensor.setInfoMem(infomem: infoMem) gyroSensor.setInfoMem(infomem: infoMem) - adcA13Sensor.setInfoMem(infomem: infoMem) - adcA7Sensor.setInfoMem(infomem: infoMem) - adcA6Sensor.setInfoMem(infomem: infoMem) - adcA15Sensor.setInfoMem(infomem: infoMem) - adcA12Sensor.setInfoMem(infomem: infoMem) - adcA1Sensor.setInfoMem(infomem: infoMem) - + adcInternalA0Sensor.setInfoMem(infomem: infoMem) + adcInternalA1Sensor.setInfoMem(infomem: infoMem) + adcInternalA2Sensor.setInfoMem(infomem: infoMem) + adcInternalA3Sensor.setInfoMem(infomem: infoMem) + adcExternalA0Sensor.setInfoMem(infomem: infoMem) + adcExternalA1Sensor.setInfoMem(infomem: infoMem) + adcExternalA2Sensor.setInfoMem(infomem: infoMem) gsrSensor.setInfoMem(infomem: infoMem) exgSensor.setInfoMem(infomem: infoMem) pressureTempSensor.setInfoMom(infomem: infoMem) @@ -442,6 +451,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { exgSensor.setInfoMem(infomem: infoMem) gsrSensor.setInfoMem(infomem: infoMem) pressureTempSensor.setInfoMom(infomem: infoMem) + adcInternalA0Sensor.setInfoMem(infomem: infoMem) + adcInternalA1Sensor.setInfoMem(infomem: infoMem) + adcInternalA2Sensor.setInfoMem(infomem: infoMem) + adcInternalA3Sensor.setInfoMem(infomem: infoMem) + adcExternalA0Sensor.setInfoMem(infomem: infoMem) + adcExternalA1Sensor.setInfoMem(infomem: infoMem) + adcExternalA2Sensor.setInfoMem(infomem: infoMem) } } @@ -485,23 +501,26 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { if gyroSensor.sensorEnabled { ojc = gyroSensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA13Sensor.sensorEnabled { - ojc = adcA13Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA1Sensor.sensorEnabled { + ojc = adcInternalA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA12Sensor.sensorEnabled { - ojc = adcA12Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA0Sensor.sensorEnabled { + ojc = adcInternalA0Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA1Sensor.sensorEnabled { - ojc = adcA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA2Sensor.sensorEnabled { + ojc = adcInternalA2Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA15Sensor.sensorEnabled { - ojc = adcA15Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA3Sensor.sensorEnabled { + ojc = adcInternalA3Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA6Sensor.sensorEnabled { - ojc = adcA6Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcExternalA2Sensor.sensorEnabled { + ojc = adcExternalA2Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA7Sensor.sensorEnabled { - ojc = adcA7Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcExternalA1Sensor.sensorEnabled { + ojc = adcExternalA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + } + if adcExternalA0Sensor.sensorEnabled { + ojc = adcExternalA0Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } if gsrSensor.sensorEnabled { ojc = gsrSensor.processData(sensorPacket: bytes, objectCluster: ojc) @@ -1115,36 +1134,36 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case ChannelContentsShimmer3.Exg2_CH2_16Bit.rawValue: packetSize += 2 enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXG2_16BIT.rawValue) - case ChannelContentsShimmer3.InternalAdc13.rawValue: - adcA13Sensor.sensorEnabled = true - adcA13Sensor.packetIndex = packetSize + case ChannelContentsShimmer3.InternalAdc1.rawValue: + adcInternalA1Sensor.sensorEnabled = true + adcInternalA1Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A13.rawValue) - case ChannelContentsShimmer3.ExternalAdc15.rawValue: - adcA15Sensor.sensorEnabled = true - adcA15Sensor.packetIndex = packetSize + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A1.rawValue) + case ChannelContentsShimmer3.ExternalAdc2.rawValue: + adcExternalA2Sensor.sensorEnabled = true + adcExternalA2Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A15.rawValue) - case ChannelContentsShimmer3.InternalAdc12.rawValue: - adcA12Sensor.sensorEnabled = true - adcA12Sensor.packetIndex = packetSize + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A2.rawValue) + case ChannelContentsShimmer3.InternalAdc0.rawValue: + adcInternalA0Sensor.sensorEnabled = true + adcInternalA0Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A12.rawValue) - case ChannelContentsShimmer3.InternalAdc1.rawValue: - adcA1Sensor.sensorEnabled = true - adcA1Sensor.packetIndex = packetSize + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A0.rawValue) + case ChannelContentsShimmer3.InternalAdc3.rawValue: + adcInternalA3Sensor.sensorEnabled = true + adcInternalA3Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A1.rawValue) - case ChannelContentsShimmer3.ExternalAdc6.rawValue: - adcA6Sensor.sensorEnabled = true - adcA6Sensor.packetIndex = packetSize + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_INT_A3.rawValue) + case ChannelContentsShimmer3.ExternalAdc1.rawValue: + adcExternalA1Sensor.sensorEnabled = true + adcExternalA1Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A6.rawValue) - case ChannelContentsShimmer3.ExternalAdc7.rawValue: - adcA7Sensor.sensorEnabled = true - adcA7Sensor.packetIndex = packetSize + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A1.rawValue) + case ChannelContentsShimmer3.ExternalAdc0.rawValue: + adcExternalA0Sensor.sensorEnabled = true + adcExternalA0Sensor.packetIndex = packetSize packetSize += 2 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A7.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_EXT_A0.rawValue) case ChannelContentsShimmer3.Temperature.rawValue: pressureTempSensor.sensorEnabled = true pressureTempSensor.packetIndexTemp = packetSize @@ -1833,15 +1852,15 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case SENSOR_GYRO = 0x040 case SENSOR_MAG = 0x20 case SENSOR_GSR = 0x04 - case SENSOR_EXT_A7 = 0x02 - case SENSOR_EXT_A6 = 0x01 + case SENSOR_EXT_A0 = 0x02 + case SENSOR_EXT_A1 = 0x01 case SENSOR_VBATT = 0x2000 case SENSOR_WR_ACCEL = 0x1000 - case SENSOR_EXT_A15 = 0x0800 - case SENSOR_INT_A1 = 0x0400 - case SENSOR_INT_A12 = 0x0200 - case SENSOR_INT_A13 = 0x0100 - case SENSOR_INT_A14 = 0x800000 + case SENSOR_EXT_A2 = 0x0800 + case SENSOR_INT_A3 = 0x0400 + case SENSOR_INT_A0 = 0x0200 + case SENSOR_INT_A1 = 0x0100 + case SENSOR_INT_A2 = 0x800000 case SENSOR_PRESSURE = 0x40000 case SENSOR_EXG1_24BIT = 0x10 case SENSOR_EXG2_24BIT = 0x08 @@ -1866,12 +1885,12 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case XGyro = 0x0A case YGyro = 0x0B case ZGyro = 0x0C - case ExternalAdc7 = 0x0D - case ExternalAdc6 = 0x0E - case ExternalAdc15 = 0x0F - case InternalAdc1 = 0x10 - case InternalAdc12 = 0x11 - case InternalAdc13 = 0x12 + case ExternalAdc0 = 0x0D + case ExternalAdc1 = 0x0E + case ExternalAdc2 = 0x0F + case InternalAdc3 = 0x10 + case InternalAdc0 = 0x11 + case InternalAdc1 = 0x12 case InternalAdc14 = 0x13 // Unsupported cases case AlternativeXAccel = 0x14 From f036c63bd97b65898e064213963254a334aac90f Mon Sep 17 00:00:00 2001 From: JongChern Date: Thu, 11 Dec 2025 16:11:27 +0800 Subject: [PATCH 9/9] more updates for adc --- .../ShimmerBluetooth/Shimmer3Protocol.swift | 68 ++++++++++++++++--- .../ShimmerExamplePlot/ContentView.swift | 2 +- .../ShimmerExamplePlot/ViewModel.swift | 7 ++ 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift index 1ca55eb..33bebee 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -44,7 +44,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { public var EXPANSION_BOARD_REV: Int = -1 public var EXPANSION_BOARD_REV_SPECIAL: Int = -1 - + public var internalExpPower:Int = -1 public var lnAccelSensor: LNAccelSensor = LNAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) public var wrAccelSensor: WRAccelSensor = WRAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) var timeSensor: TimeSensor = TimeSensor() @@ -52,13 +52,13 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { public var gyroSensor: GyroSensor = GyroSensor(hwid: HardwareType.UNKNOWN.rawValue) public var altMagSensor: AltMagSensor = AltMagSensor(hwid: HardwareType.UNKNOWN.rawValue) public var highGAccelSensor: HighGAccelSensor = HighGAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) - var adcInternalA3Sensor: ADCSensor = ADCSensor() - var adcInternalA2Sensor: ADCSensor = ADCSensor() - var adcInternalA1Sensor: ADCSensor = ADCSensor() - var adcInternalA0Sensor: ADCSensor = ADCSensor() - var adcExternalA0Sensor: ADCSensor = ADCSensor() - var adcExternalA1Sensor: ADCSensor = ADCSensor() - var adcExternalA2Sensor: ADCSensor = ADCSensor() + var adcInternalA3Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_Internal_A3) + var adcInternalA2Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_Internal_A2) + var adcInternalA1Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_Internal_A1) + var adcInternalA0Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_Internal_A0) + var adcExternalA0Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_External_A0) + var adcExternalA1Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_External_A1) + var adcExternalA2Sensor: ADCSensor = ADCSensor(adc: .Shimmer3_External_A2) var gsrSensor: GSRSensor = GSRSensor() public var exgSensor: EXGSensor = EXGSensor() public var pressureTempSensor : PressureTempSensor = PressureTempSensor(hwid: HardwareType.UNKNOWN.rawValue) @@ -131,6 +131,33 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { return result! } + public func sendInternalExpPower(_ expPower: UInt8) async -> Bool { + // Build packet: [command, value] + let bytes: [UInt8] = [ + PacketTypeShimmer.setInternalEXPPowerEnableCommand.rawValue, + expPower + ] + + commandSent = PacketTypeShimmer.setInternalEXPPowerEnableCommand + radio?.writeBytes(bytes: bytes) + + // Wait for ACK + let result = await withCheckedContinuation { continuation in + if self.continuation == nil { + self.continuation = continuation + } + } ?? false + + if result { + self.internalExpPower = Int(expPower) + print("Internal Exp Power set to \(expPower)") + } else { + print("Failed to set Internal Exp Power") + } + + return result + } + public func sendSetSensorsCommand(sensorBitmap: UInt32) async -> Bool { var bytes: [UInt8] = [] @@ -972,6 +999,30 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { print("[CRC ERROR] : \(self.commandSent!)") } + print("Command ACK Received and Processed: \(self.commandSent!)") + } + else if (self.commandSent == PacketTypeShimmer.setInternalEXPPowerEnableCommand) { + print("Set EXP Power ACK Received") + + let received = Array(self.receivedBytes.prefix(1 + Int(self.CRCMode.rawValue))) + self.receivedBytes.removeFirst(1 + Int(self.CRCMode.rawValue)) + + var crcresult = true + if self.CRCMode != BTCRCMode.OFF { + print("CRC Set EXP Power Calculated: \(self.shimmerUartCrcCalc(received, (received.count - Int(self.CRCMode.rawValue))))") + crcresult = self.checkCrc(received, (received.count - Int(self.CRCMode.rawValue))) + print("CRC Set EXP Power Check: \(crcresult)") + } + + if (crcresult) { + self.continuation?.resume(returning: true) + self.continuation = nil + } else { + self.continuation?.resume(returning: false) + self.continuation = nil + print("[CRC ERROR] : \(self.commandSent!)") + } + print("Command ACK Received and Processed: \(self.commandSent!)") } } @@ -1974,6 +2025,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { case setMagSamplingRateCommand = 0x3A case magSamplingRateResponse = 0x3B case getMagSamplingRateCommand = 0x3C + case setInternalEXPPowerEnableCommand = 0x5E case daughterCardIDResponse = 0x65 case getDaughterCardIDCommand = 0x66 case setInfoMem = 0x8c diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift index 7dc998f..1c31401 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ContentView.swift @@ -346,7 +346,7 @@ struct ContentView: View { }) Button("Enable PPG + GSR",action:{ Task { do { - await viewModel.enableS3RHighGAccel() + await viewModel.enableS3RPPG() } catch { print("Error: \(error)") } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index dedfad5..22e6619 100644 --- a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift +++ b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift @@ -242,6 +242,13 @@ class ViewModel: NSObject, ObservableObject { await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_WR_ACCEL.rawValue); refreshUISettings() } + + func enableS3RPPG() async{ + + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_INT_A1.rawValue) + await shimmer3Protocol?.sendInternalExpPower(1) + refreshUISettings() + } func enableEXGTest() async{ await shimmer3Protocol?.sendSetEXGConfigurations(valuesChip1: Shimmer3Protocol.Shimmer3Configuration.EXG_TEST_SIGNAL_CONFIGURATION_CHIP1, valuesChip2: Shimmer3Protocol.Shimmer3Configuration.EXG_TEST_SIGNAL_CONFIGURATION_CHIP2)