// // DeviceViewController.swift // SwiftStarter // // Created by Stephen Schiffli on 10/20/15. // Copyright © 2015 MbientLab Inc. All rights reserved. // import UIKit import MetaWear import MetaWearCpp class DeviceViewController: UIViewController { @IBOutlet weak var deviceStatus: UILabel! var device: MetaWear! var currentTime = Date().timeIntervalSince1970 var lastTime = Date().timeIntervalSince1970 var initialTime = Date().timeIntervalSince1970 var restStep = false var indexStep = 0 var accMatrix = [[Float]]() override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated); self.updateLabel("Restoring") if let state = DeviceState.loadForDevice(device) { // Initialize the device device.deserialize(state.serializedState) self.updateLabel("Connecting") device.connectAndSetup().continueWith { t in if let error = t.error { // Sorry we couldn't connect self.deviceStatus.text = error.localizedDescription } else { // The result of a connectAndSetup call is a task which completes upon disconnection. t.result!.continueWith { state.serializedState = self.device.serialize() state.saveToUrl(self.device.uniqueUrl) self.updateLabel($0.error?.localizedDescription ?? "Disconnected") } self.updateLabel("Connected") self.device.flashLED(color: .green, intensity: 1.0, _repeat: 3) self.doDownload(state: state) } } } } func doDownload(state :DeviceState) { updateLabel("Downloading") // Attach log download handlers for the data let temperatureSignal = mbl_mw_logger_lookup_id(device.board, state.temperatureLogId) mbl_mw_logger_subscribe(temperatureSignal, bridge(obj: self)) { (context, data) in let _self: DeviceViewController = bridge(ptr: context!) _self.didGetTemperature(timestamp: data!.pointee.timestamp, entry: data!.pointee.valueAs()) } // Setup the handlers for events during the download var handlers = MblMwLogDownloadHandler() handlers.context = bridge(obj: self) handlers.received_progress_update = { (context, entriesLeft, totalEntries) in let _self: DeviceViewController = bridge(ptr: context!) _self.progress(entriesLeft: entriesLeft, totalEntries: totalEntries) } handlers.received_unknown_entry = { (context, id, epoch, data, length) in let _self: DeviceViewController = bridge(ptr: context!) _self.unknownEntry(id: id, epoch: epoch, data: data, length: length) } handlers.received_unhandled_entry = { (context, data) in let _self: DeviceViewController = bridge(ptr: context!) _self.unhandledEntry(data: data) } // Start the log download mbl_mw_logging_download(device.board!, 100, &handlers) } func updateLabel(_ msg: String) { DispatchQueue.main.async { self.deviceStatus.text = msg } } func didGetTemperature(timestamp: Date, entry: Float) { print("temp: \(timestamp) \(entry)") } func progress(entriesLeft: UInt32, totalEntries: UInt32) { // Clear the in progress flag if entriesLeft == 0 { self.updateLabel("Finished download \(totalEntries) entries") } } func unknownEntry(id: UInt8, epoch: Int64, data: UnsafePointer?, length: UInt8) { print("unknownEntry: \(epoch) \(String(describing: data)) \(length)") } func unhandledEntry(data: UnsafePointer?) { print("unhandledEntry: \(String(describing: data))") } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) device.flashLED(color: .red, intensity: 1.0, _repeat: 3) mbl_mw_debug_disconnect(device.board) } @IBAction func start(_ sender: Any) { let board = device.board guard mbl_mw_metawearboard_lookup_module(board, MBL_MW_MODULE_ACCELEROMETER) != MODULE_TYPE_NA else { print("No accelerometer") return } mbl_mw_acc_bosch_set_range(device.board, MBL_MW_ACC_BOSCH_RANGE_2G) mbl_mw_acc_set_odr(device.board, 50.0) mbl_mw_settings_set_tx_power(board, 12) // device.settings?.transmitPower = .power0dBm mbl_mw_acc_bosch_write_acceleration_config(device.board) // Initialization of vars self.currentTime = Date().timeIntervalSince1970 self.initialTime = Date().timeIntervalSince1970 self.lastTime = Date().timeIntervalSince1970 self.indexStep = 0 self.restStep = true self.accMatrix = [[Float]]() print("Initialization get ready") let signal = mbl_mw_acc_get_acceleration_data_signal(board) mbl_mw_datasignal_subscribe(signal, bridge(obj: self)) { (context, data) in let _self: DeviceViewController = bridge(ptr: context!) let obj: MblMwCartesianFloat = data!.pointee.valueAs() let steps = ["rest", "table", "foot", "walk", "chamber", "return"] _self.lastTime = 0 + _self.currentTime _self.currentTime = Date().timeIntervalSince1970 // Writing data let t = _self.currentTime - _self.initialTime if (_self.indexStep < steps.count) { if (_self.restStep) { if (t > 5) { _self.initialTime = _self.currentTime _self.restStep = false print("========================") print("Start new step: \(steps[_self.indexStep])") print("========================") } } else { if (t > 10) { _self.initialTime = _self.currentTime _self.restStep = true _self.indexStep += 1 print("========================") print("Entering Rest phase now") print("========================") } else { let frame = [Float(t), obj.x, obj.y, obj.z] _self.accMatrix.append(frame) print("latency", _self.currentTime - _self.lastTime, "completion: ", t / 10.0) } } } else { print("Acquisition over please stop") } } mbl_mw_acc_enable_acceleration_sampling(board) mbl_mw_acc_start(board) } @IBAction func stop(_ sender: Any) { let board = device.board let signal = mbl_mw_acc_get_acceleration_data_signal(board) mbl_mw_acc_stop(board) mbl_mw_acc_disable_acceleration_sampling(board) mbl_mw_datasignal_unsubscribe(signal) print(self.accMatrix) } }