diff --git a/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj b/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj index 1fb2cc5..cf19962 100644 --- a/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj +++ b/ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj @@ -42,6 +42,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 */ @@ -91,6 +92,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 */ @@ -135,6 +137,7 @@ 3A780C872AE12BEB00EAF050 /* ShimmerBluetooth */ = { isa = PBXGroup; children = ( + 92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */, 451EC8192DACCFF900D8F269 /* ConcurrentQueue.swift */, 92150EF42DE461CE00FEA53B /* AltMagSensor.swift */, 3AEB12F82BCE6F7E00B5F6F1 /* Shimmer3SpeedTestProtocol.swift */, @@ -322,6 +325,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 */, 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/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/HighGAccelSensor.swift b/ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift new file mode 100644 index 0000000..ac02ea5 --- /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 HighGAccelSensor : 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 3ac562c..33bebee 100644 --- a/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift +++ b/ShimmerBluetooth/ShimmerBluetooth/Shimmer3Protocol.swift @@ -44,19 +44,21 @@ 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() 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() - var adcA7Sensor: ADCSensor = ADCSensor() - var adcA6Sensor: ADCSensor = ADCSensor() - var adcA15Sensor: ADCSensor = ADCSensor() + public var highGAccelSensor: HighGAccelSensor = HighGAccelSensor(hwid: HardwareType.UNKNOWN.rawValue) + 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) @@ -129,6 +131,76 @@ 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] = [] + + // 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)){ @@ -304,6 +376,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { wrAccelSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) magSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) altMagSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) + highGAccelSensor.parseSensorCalibrationDump(bytes: sensorcalibrationdump) } } @@ -314,12 +387,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) @@ -332,6 +406,46 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { timeSensor = TimeSensor() altMagSensor = AltMagSensor(hwid: REV_HW_MAJOR) pressureTempSensor = PressureTempSensor(hwid: REV_HW_MAJOR) + highGAccelSensor = HighGAccelSensor(hwid: REV_HW_MAJOR) + } + } + + func disableSensors(){ + if (REV_HW_MAJOR==HardwareType.Shimmer3.rawValue){ + lnAccelSensor.sensorEnabled = false + wrAccelSensor.sensorEnabled = false + timeSensor.sensorEnabled = false + magSensor.sensorEnabled = false + gyroSensor.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 + 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 + 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 } } @@ -342,13 +456,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) @@ -360,7 +474,17 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { magSensor.setInfoMem(infomem: infoMem) gyroSensor.setInfoMem(infomem: infoMem) wrAccelSensor.setInfoMem(infomem: infoMem) + highGAccelSensor.setInfoMem(infomem: infoMem) + 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) } } @@ -398,26 +522,32 @@ 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) } - if adcA13Sensor.sensorEnabled { - ojc = adcA13Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA1Sensor.sensorEnabled { + ojc = adcInternalA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + } + if adcInternalA0Sensor.sensorEnabled { + ojc = adcInternalA0Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA12Sensor.sensorEnabled { - ojc = adcA12Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA2Sensor.sensorEnabled { + ojc = adcInternalA2Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA1Sensor.sensorEnabled { - ojc = adcA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcInternalA3Sensor.sensorEnabled { + ojc = adcInternalA3Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA15Sensor.sensorEnabled { - ojc = adcA15Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcExternalA2Sensor.sensorEnabled { + ojc = adcExternalA2Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA6Sensor.sensorEnabled { - ojc = adcA6Sensor.processData(sensorPacket: bytes, objectCluster: ojc) + if adcExternalA1Sensor.sensorEnabled { + ojc = adcExternalA1Sensor.processData(sensorPacket: bytes, objectCluster: ojc) } - if adcA7Sensor.sensorEnabled { - ojc = adcA7Sensor.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) @@ -847,7 +977,54 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { self.receivedBytes.removeAll() } } + 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!)") + } + 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!)") + } } } @@ -876,6 +1053,7 @@ public class Shimmer3Protocol : NSObject, ShimmerProtocol { func interpretDataPacketFormat(nC: Int, signalid: [UInt8]) { + disableSensors() //signalDataTypeArray.append("u16") var packetSize = 2 // Time stamp @@ -893,74 +1071,94 @@ 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_HIGHG_ACCEL.rawValue) + case ChannelContentsShimmer3.AlternativeYAccel.rawValue: + highGAccelSensor.packetIndexHighGAccelY = packetSize + packetSize += 2 + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_HIGHG_ACCEL.rawValue) + case ChannelContentsShimmer3.AlternativeZAccel.rawValue: + highGAccelSensor.packetIndexHighGAccelZ = packetSize + packetSize += 2 + 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) 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: @@ -969,6 +1167,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: @@ -986,38 +1185,45 @@ 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.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.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.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.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.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.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 packetSize += 3 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_PRESSURE.rawValue) case ChannelContentsShimmer3.Pressure.rawValue: pressureTempSensor.packetIndexPressure = packetSize packetSize += 3 - enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_BMP180_PRESSURE.rawValue) + enabledSensors |= Int(SensorBitmapShimmer3.SENSOR_PRESSURE.rawValue) default: packetSize += 2 } @@ -1329,6 +1535,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 @@ -1580,12 +1842,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" @@ -1636,30 +1898,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_EXT_A0 = 0x02 + case SENSOR_EXT_A1 = 0x01 case SENSOR_VBATT = 0x2000 - case SENSOR_D_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_WR_ACCEL = 0x1000 + 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 case SENSOR_EXG1_16BIT = 0x100000 case SENSOR_EXG2_16BIT = 0x080000 case SENSOR_BRIDGE_AMP = 0x8000 - case SENSOR_LIS3MDL_ALT_MAG = 0x200000 + 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 @@ -1673,12 +1936,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 @@ -1762,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/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..1c31401 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 { @@ -255,45 +269,84 @@ 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)") } } }) - - Button("WriteInfoMem Alt Mag Shimmer3R",action:{ Task { + + Button("Enable Mag Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RAltMag() + await viewModel.enableS3RMag() } catch { print("Error: \(error)") } } }) - - Button("WriteInfoMem Mag Shimmer3R",action:{ Task { + + Button("Enable Gyro Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RMag() + await viewModel.enableS3RGyro() } catch { print("Error: \(error)") } } }) - Button("WriteInfoMem Gyro Shimmer3R",action:{ Task { + Button("Enable WRAccel Shimmer3R",action:{ Task { do { - await viewModel.sendInfoMemS3RGyro() + await viewModel.enableS3RWRAccel() } catch { print("Error: \(error)") } } }) - - Button("WriteInfoMem WRAccel Shimmer3R",action:{ Task { + Button("Enable Alt Mag Shimmer3R",action:{ Task { + do { + await viewModel.enableS3RAltMag() + } catch { + print("Error: \(error)") + } + } + }) + Button("Enable HighG Accel Shimmer3R",action:{ Task { + do { + await viewModel.enableS3RHighGAccel() + } catch { + print("Error: \(error)") + } + } + }) + 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.sendInfoMemS3RWRAccel() + await viewModel.enableS3RPPG() } catch { print("Error: \(error)") } diff --git a/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift b/ShimmerExamplePlot/ShimmerExamplePlot/ViewModel.swift index 00fd721..22e6619 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{ @@ -212,59 +213,69 @@ 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 sendInfoMemS3RLNAccel() async{ - let infomlnacc:[UInt8] = [ - 0x83, 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, 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, 0x3E, 0x94, 0x81, 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: infomlnacc) + func enableS3RHighGAccel() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_HIGHG_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) + func enableS3RLNAccel() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_LN_ACCEL.rawValue); refreshUISettings() } - func sendInfoMemS3RGyro() async{ - let infomgyro:[UInt8] = [ - 0x80, 0x02, 0x01, 0x40, 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, 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, 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, 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, 0x3E, 0xA3, 0x9D, 0x01, 0x01, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x65, 0x78, 0xCA, 0xDA, 0xD3, 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: infomgyro) + func enableS3RMag() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_MAG.rawValue); + refreshUISettings() + } + + func enableS3RGyro() async{ + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_GYRO.rawValue); refreshUISettings() } - func sendInfoMemS3RWRAccel() async{ - let infomwracc:[UInt8] = [ - 0x80, 0x02, 0x01, 0x00, 0x10, 0x00, 0x51, 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, 0x3E, 0xA3, 0x6D, 0x01, 0x01, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x65, 0x78, 0xCA, 0xDA, 0xD3, 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: infomwracc) + func enableS3RWRAccel() async{ + 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) + let bitmap = + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue | + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: bitmap); + refreshUISettings() + } + + func enableECG() async{ + await shimmer3Protocol?.sendSetEXGConfigurations(valuesChip1: Shimmer3Protocol.Shimmer3Configuration.EXG_ECG_CONFIGURATION_CHIP1, valuesChip2: Shimmer3Protocol.Shimmer3Configuration.EXG_ECG_CONFIGURATION_CHIP2) + let bitmap = + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue | + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: bitmap); + refreshUISettings() + } + + func enableEMG() async{ + await shimmer3Protocol?.sendSetEXGConfigurations(valuesChip1: Shimmer3Protocol.Shimmer3Configuration.EXG_EMG_CONFIGURATION_CHIP1, valuesChip2: Shimmer3Protocol.Shimmer3Configuration.EXG_EMG_CONFIGURATION_CHIP2) + let bitmap = + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG1_24BIT.rawValue | + Shimmer3Protocol.SensorBitmapShimmer3.SENSOR_EXG2_24BIT.rawValue + await shimmer3Protocol?.sendSetSensorsCommand(sensorBitmap: bitmap); + refreshUISettings() + } func sendInfoMemWRAccel() async{ let infomwracc:[UInt8] = [ 0x80,0x02,0x01,0x00,0x10,0x00,0x41,0xFF,0x01,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,