Issue while downloading data is that sometime in between downloading data callback mbl_mw_logger_subscribe and received_progress_update are not called. It is random case. So we got stuck and not able to know the exact issue. Variables Declared var foreArmhandler = MblMwLogDownloadHandler() var upperArmhandler = MblMwLogDownloadHandler() var upperArmDevice: MetaWear! var foreArmDevice: MetaWear! var upperArmLoggers:[String: OpaquePointer] = [:] var foreArmLoggers:[String: OpaquePointer] = [:] Logging both sensors data func startLoggingData() { self.startLoggingUpperArm() startLoggingForeArm() } Step:- 1 Start Log from sensor first func startLoggingUpperArm(){ upperArmDevice.connectAndSetup().continueWith{ t in let correctedAcceleration = mbl_mw_sensor_fusion_get_data_signal(self.upperArmDevice.board, MBL_MW_SENSOR_FUSION_DATA_CORRECTED_ACC) mbl_mw_dataprocessor_time_create(correctedAcceleration, MBL_MW_TIME_ABSOLUTE, 10, nil) { (context, processor) in print("time processor created") } mbl_mw_datasignal_log(correctedAcceleration, bridge(obj: self)) { (context, logger) in let _self: PerformanceViewController = bridge(ptr: context!) _self.isUpperArmStarted = true print("upper arm log start") let cString = mbl_mw_logger_generate_identifier(logger)! let identifier = String(cString: cString) _self.upperArmLoggers[identifier] = logger! } // mbl_mw_sensor_fusion_clear_enabled_mask(self.upperArmDevice.board) mbl_mw_logging_clear_entries(self.upperArmDevice.board) mbl_mw_logging_start(self.upperArmDevice.board, 0) mbl_mw_sensor_fusion_set_mode(self.upperArmDevice.board,MBL_MW_SENSOR_FUSION_MODE_NDOF) mbl_mw_sensor_fusion_set_acc_range(self.upperArmDevice.board, MBL_MW_SENSOR_FUSION_ACC_RANGE_16G) mbl_mw_sensor_fusion_set_gyro_range(self.upperArmDevice.board, MBL_MW_SENSOR_FUSION_GYRO_RANGE_2000DPS) mbl_mw_sensor_fusion_write_config(self.upperArmDevice.board) mbl_mw_sensor_fusion_enable_data(self.upperArmDevice.board, MBL_MW_SENSOR_FUSION_DATA_CORRECTED_ACC); mbl_mw_sensor_fusion_start(self.upperArmDevice.board); } } Step:- 2 Start Log from second sensor func startLoggingForeArm(){ foreArmDevice.connectAndSetup().continueWith { t in let correctedAcceleration = mbl_mw_sensor_fusion_get_data_signal(self.foreArmDevice.board, MBL_MW_SENSOR_FUSION_DATA_CORRECTED_ACC)! mbl_mw_dataprocessor_time_create(correctedAcceleration, MBL_MW_TIME_ABSOLUTE, 10, nil) { (context, processor) in print("time processor created") } mbl_mw_datasignal_log(correctedAcceleration, bridge(obj: self)) { (context, logger) in let _self: PerformanceViewController = bridge(ptr: context!) _self.isForArmStarted = true print("Fore arm log start") let cString = mbl_mw_logger_generate_identifier(logger)! let identifier = String(cString: cString) _self.foreArmLoggers[identifier] = logger! } mbl_mw_logging_clear_entries(self.foreArmDevice.board) mbl_mw_logging_start(self.foreArmDevice.board, 0) mbl_mw_sensor_fusion_set_mode(self.foreArmDevice.board,MBL_MW_SENSOR_FUSION_MODE_NDOF) mbl_mw_sensor_fusion_set_acc_range(self.foreArmDevice.board, MBL_MW_SENSOR_FUSION_ACC_RANGE_16G) mbl_mw_sensor_fusion_set_gyro_range(self.foreArmDevice.board, MBL_MW_SENSOR_FUSION_GYRO_RANGE_2000DPS) mbl_mw_sensor_fusion_write_config(self.foreArmDevice.board) mbl_mw_sensor_fusion_enable_data(self.foreArmDevice.board, MBL_MW_SENSOR_FUSION_DATA_CORRECTED_ACC); mbl_mw_sensor_fusion_start(self.foreArmDevice.board); } } Step:- 3 Downloading sensor1 data func logDataFromUpperArm(){ self.upperArmhandler = MblMwLogDownloadHandler() guard let logger = upperArmLoggers.removeValue(forKey: "corrected-acceleration") else { return } mbl_mw_logger_subscribe(logger, bridge(obj: self)) { (context, data) in let this: PerformanceViewController = bridge(ptr: context!) if let datax = data?.pointee{ let obj: MblMwCorrectedCartesianFloat = datax.valueAs() this.upperArmY = obj.y + this.upperArmCalibration this.upperArmX = obj.x this.upperArmZ = obj.z SQLQueries.addSessionData(SessionID: this.sessionID!, XAxis: this.upperArmX, YAxis: this.upperArmY, ZAxis: this.upperArmZ, TouchSensor: 0, HeartRate: 0.0, IsForeArm: 0, TimeStamp: Date.dateStringFromDate(timeStamp: datax.timestamp)) } } self.upperArmhandler.context = bridge(obj: self) self.upperArmhandler.received_progress_update = {(context, remainingEntries, totalEntries) in let this: PerformanceViewController = bridge(ptr: context!) var progress = Double(totalEntries - remainingEntries) / Double(totalEntries) // Make sure progress is always [0.0,1.0] progress = min(progress, 1.0) progress = max(progress, 0.0) print("upper arm download progress = \(progress)") if remainingEntries == 0 { mbl_mw_debug_reset(this.upperArmDevice.board) print("done - getting upper arm data") this.downloadState += 1 if (this.downloadState == 2) { this.ProcessShots() } } } self.upperArmhandler.received_unknown_entry = { (context, id, epoch, data, length) in print("received_unknown_entry") } self.upperArmhandler.received_unhandled_entry = { (context, data) in print("received_unknown_entry") } } Step:- 4 Downloading sensor2 data func logForeArmData(){ self.foreArmhandler = MblMwLogDownloadHandler() guard let logger = foreArmLoggers.removeValue(forKey: "corrected-acceleration") else { return } mbl_mw_logger_subscribe(logger, bridge(obj: self), { (context, data) in let this: PerformanceViewController = bridge(ptr: context!) if let datax = data?.pointee{ let obj: MblMwCorrectedCartesianFloat = datax.valueAs() this.foreArmY = obj.y + this.foreArmCalibration this.foreArmX = obj.x this.foreArmZ = obj.z // this.foreArmTouch = Int(datax.valueAs() as UInt32) SQLQueries.addSessionData(SessionID: this.sessionID!, XAxis: this.foreArmX, YAxis: this.foreArmY, ZAxis: this.foreArmZ, TouchSensor: this.foreArmTouch, HeartRate: 0.0, IsForeArm: 1, TimeStamp: Date.dateStringFromDate(timeStamp: datax.timestamp)) } }) self.foreArmhandler.context = bridge(obj: self) self.foreArmhandler.received_progress_update = {(context, remainingEntries, totalEntries) in let this: PerformanceViewController = bridge(ptr: context!) var progress = Double(totalEntries - remainingEntries) / Double(totalEntries) // Make sure progress is always [0.0,1.0] progress = min(progress, 1.0) progress = max(progress, 0.0) print("Fore arm download progress = \(progress)") if remainingEntries == 0 { mbl_mw_debug_reset(this.foreArmDevice.board) print("done - getting forearm data") this.downloadState += 1 if (this.downloadState == 2) { this.ProcessShots() } } } self.foreArmhandler.received_unknown_entry = { (context, id, epoch, data, length) in //print("received_unknown_entry") } self.foreArmhandler.received_unhandled_entry = { (context, data) in //print("received_unhandled_entry") } } Step:- 5 Call to download data functions func downloadDataFromBothSensors(){ mbl_mw_sensor_fusion_stop(self.upperArmDevice.board) mbl_mw_logging_stop(self.upperArmDevice.board) //mbl_mw_acc_disable_acceleration_sampling(self.upperArmDevice.board) logDataFromUpperArm() mbl_mw_logging_download(self.upperArmDevice.board, 100, &self.upperArmhandler) self.upperArmDevice.flashLED(color: .blue, intensity: 1.0) mbl_mw_sensor_fusion_stop(self.foreArmDevice.board) mbl_mw_logging_stop(self.foreArmDevice.board) logForeArmData() mbl_mw_logging_download(self.foreArmDevice.board, 100, &self.foreArmhandler) self.foreArmDevice.flashLED(color: .blue, intensity: 1.0) }