Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ShimmerBluetooth/ShimmerBluetooth.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -91,6 +92,7 @@
9299E50D2B85054E001EEFE0 /* PressureTempSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PressureTempSensor.swift; sourceTree = "<group>"; };
9299E50F2B850571001EEFE0 /* BattVoltageSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BattVoltageSensor.swift; sourceTree = "<group>"; };
92B106792B7DAFBC00AB9952 /* EXGSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXGSensor.swift; sourceTree = "<group>"; };
92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighGAccelSensor.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -135,6 +137,7 @@
3A780C872AE12BEB00EAF050 /* ShimmerBluetooth */ = {
isa = PBXGroup;
children = (
92B4B54F2DF035C100225A97 /* HighGAccelSensor.swift */,
451EC8192DACCFF900D8F269 /* ConcurrentQueue.swift */,
92150EF42DE461CE00FEA53B /* AltMagSensor.swift */,
3AEB12F82BCE6F7E00B5F6F1 /* Shimmer3SpeedTestProtocol.swift */,
Expand Down Expand Up @@ -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 */,
Expand Down
52 changes: 28 additions & 24 deletions ShimmerBluetooth/ShimmerBluetooth/ADCSensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

Expand All @@ -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 {
Expand All @@ -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
Expand Down
88 changes: 45 additions & 43 deletions ShimmerBluetooth/ShimmerBluetooth/EXGSensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down
71 changes: 71 additions & 0 deletions ShimmerBluetooth/ShimmerBluetooth/HighGAccelSensor.swift
Original file line number Diff line number Diff line change
@@ -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..<packetIndexHighGAccelX+2])
let y = Array(sensorPacket[packetIndexHighGAccelY..<packetIndexHighGAccelY+2])
let z = Array(sensorPacket[packetIndexHighGAccelZ..<packetIndexHighGAccelZ+2])
let rawDataX = Double(ShimmerUtilities.parseSensorData(sensorData: x, dataType: SensorDataType.i12MSB)!)
let rawDataY = Double(ShimmerUtilities.parseSensorData(sensorData: y, dataType: SensorDataType.i12MSB)!)
let rawDataZ = Double(ShimmerUtilities.parseSensorData(sensorData: z, dataType: SensorDataType.i12MSB)!)
if (calibrationEnabled){
let data:[Double] = [rawDataX,rawDataY,rawDataZ]

let(calData)=IMUSensor.calibrateInertialSensorData(data,AlignmentMatrix,SensitivityMatrix,OffsetVector)
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: 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
}

public override func parseSensorCalibrationDump(bytes: [UInt8]){
var sensorID = Int(bytes[0]) + (Int(bytes[1])<<8)
if bytes[0] == CALIBRATION_ID {
var range = bytes[2]
var calbytes = bytes
calbytes.removeFirst(12)
(AlignmentMatrix,SensitivityMatrix,OffsetVector) = parseIMUCalibrationParameters(bytes: calbytes)
}
}

public func setInfoMem(infomem: [UInt8]) {

var enabled = Int(infomem[ConfigByteLayoutShimmer3.idxSensors2]>>6) & 1

if (enabled == 1){
sensorEnabled = true
} else {
sensorEnabled = false
}
}


}
1 change: 1 addition & 0 deletions ShimmerBluetooth/ShimmerBluetooth/Sensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum SensorDataType {
case u24
case u24MSB
case i24MSB
case i12MSB
}

public class Sensor: NSObject{
Expand Down
Loading