Movesense传感器数据记录



我与Flutter合作,希望记录和存储传感器型号OP174的收集数据。我用的是加速度计、陀螺仪、磁强计和温度计。

我在Movesense.swift中看到有一个Logbook_path和一个Datalogger_config_path,但我不知道如何使用它来保存收集的数据,它尝试了我在下面发布的另一个solution。

如何将此数据存储在CSV文件中,并自动包含时间戳?

获取陀螺仪数据

int _gyroSubscription;
String _gyroscopeData = "";
String get gyroscopeData => _gyroscopeData;
bool get gyroscopeSubscribed => _gyroSubscription != null;
void subscribeToGyroscope() {
_gyroscopeData = "";
_gyroSubscription = Mds.subscribe(
Mds.createSubscriptionUri(_serial, "/Meas/Gyro/104"),
"{}",
(d, c) => {},
(e, c) => {},
(data) => _onNewGyroscopeData(data),
(e, c) => {});
notifyListeners();
}
void _onNewGyroscopeData(String data) {
Map<String, dynamic> gyroData = jsonDecode(data);
Map<String, dynamic> body = gyroData["Body"];
List<dynamic> gyroArry = body["ArrayGyro"];
dynamic gyro = gyroArry.last;
_gyroscopeData = "x: " +
gyro["x"].toStringAsFixed(2) +
"ny: " +
gyro["y"].toStringAsFixed(2) +
"nz: " +
gyro["z"].toStringAsFixed(2);
notifyListeners();
}

尝试保存数据

Future<String> getFilePath() async {
Directory appDocumentsDirectory = await getExternalStorageDirectory();
List<FileSystemEntity> directory = appDocumentsDirectory.listSync();
directory.forEach((x) => debugPrint(x.path));
String appDocumentsPath = appDocumentsDirectory.path;
String filePath = '$appDocumentsPath/recording.csv';
return filePath;
}
void saveFile(DeviceModel deviceModel) async {
File file = File(await getFilePath());
file.writeAsString(deviceModel.gyroscopeData);
}

新代码编辑

import 'dart:convert';
import 'package:csv/csv.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';
import 'package:mdsflutter/Mds.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'dart:developer' as developer;
class DeviceModel extends ChangeNotifier {
String _serial;
String _name;
bool _skipAccelerometer = false;
bool _skipGyroscope = false;
bool _skipMagneto = false;
set skipAccelerometer(bool x) {
_skipAccelerometer = x;
}
bool get skipAccelerometer => _skipAccelerometer;
set skipGyroscope(bool x) {
_skipGyroscope = x;
}
bool get skipGyroscope => _skipGyroscope;
set skipMagneto(bool x) {
_skipMagneto = x;
}
bool get skipMagneto => _skipMagneto;
List<List<dynamic>> _accelerometerList = new List<List<dynamic>>();
List<List<dynamic>> _gyroscopeList = new List<List<dynamic>>();
List<List<dynamic>> _magnetoList = new List<List<dynamic>>();
String get name => _name;
String get serial => _serial;
int _accSubscription;
String _accelerometerData = "";
String get accelerometerData => _accelerometerData;
bool get accelerometerSubscribed => _accSubscription != null;
int _gyroSubscription;
String _gyroscopeData = "";
String get gyroscopeData => _gyroscopeData;
bool get gyroscopeSubscribed => _gyroSubscription != null;
int _magnSubscription;
String _magnetoData = "";
String get magnetoData => _magnetoData;
bool get magnetoSubscribed => _magnSubscription != null;
int _hrSubscription;
String _hrData = "";
String get hrData => _hrData;
bool get hrSubscribed => _hrSubscription != null;
bool _ledStatus = false;
bool get ledStatus => _ledStatus;
String _temperature = "";
String get temperature => _temperature;
DeviceModel(this._name, this._serial);
void subscribeToAccelerometer() {
_accelerometerData = "";
_accSubscription = Mds.subscribe(
Mds.createSubscriptionUri(_serial, "/Meas/Acc/104"),
"{}",
(d, c) => {},
(e, c) => {},
(data) => _onNewAccelerometerData(data),
(e, c) => {});
notifyListeners();
}
void _onNewAccelerometerData(String data) {
Map<String, dynamic> accData = jsonDecode(data);
Map<String, dynamic> body = accData["Body"];
List<dynamic> accArray = body["ArrayAcc"];
dynamic acc = accArray.last;
_accelerometerData = "x: " +
acc["x"].toStringAsFixed(2) +
"ny: " +
acc["y"].toStringAsFixed(2) +
"nz: " +
acc["z"].toStringAsFixed(2);
//Option 1
DateTime now = DateTime.now();
var dateLocal = now.toLocal();
var formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateLocal);
//Option 2
//var formattedDate = DateTime.now().millisecondsSinceEpoch;
List<dynamic> row = new List<dynamic>();
row.add(formattedDate);
row.add(acc["x"].toStringAsFixed(2));
row.add(acc["y"].toStringAsFixed(2));
row.add(acc["z"].toStringAsFixed(2));
_accelerometerList.add(row);
notifyListeners();
}
void unsubscribeFromAccelerometer() {
Mds.unsubscribe(_accSubscription);
_accSubscription = null;
notifyListeners();
}
void subscribeToGyroscope() {
_gyroscopeData = "";
_gyroSubscription = Mds.subscribe(
Mds.createSubscriptionUri(_serial, "/Meas/Gyro/26"),
"{}",
(d, c) => {},
(e, c) => {},
(data) => _onNewGyroscopeData(data),
(e, c) => {});
notifyListeners();
}
void _onNewGyroscopeData(String data) {
Map<String, dynamic> gyroData = jsonDecode(data);
Map<String, dynamic> body = gyroData["Body"];
List<dynamic> gyroArry = body["ArrayGyro"];
dynamic gyro = gyroArry.last;
_gyroscopeData = "x: " +
gyro["x"].toStringAsFixed(2) +
"ny: " +
gyro["y"].toStringAsFixed(2) +
"nz: " +
gyro["z"].toStringAsFixed(2);
//Option 1
DateTime now = DateTime.now();
var dateLocal = now.toLocal();
var formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateLocal);
//Option 2
//var formattedDate = DateTime.now().millisecondsSinceEpoch;
List<dynamic> row = new List<dynamic>();
row.add(formattedDate);
row.add(gyro["x"].toStringAsFixed(2));
row.add(gyro["y"].toStringAsFixed(2));
row.add(gyro["z"].toStringAsFixed(2));
_gyroscopeList.add(row);
notifyListeners();
}
void unsubscribeFromGyroscope() {
Mds.unsubscribe(_gyroSubscription);
_gyroSubscription = null;
notifyListeners();
}
void subscribeToMagnetometer() {
_magnetoData = "";
_magnSubscription = Mds.subscribe(
Mds.createSubscriptionUri(_serial, "/Meas/Magn/104"),
"{}",
(d, c) => {},
(e, c) => {},
(data) => _onNewMagnetometerData(data),
(e, c) => {});
notifyListeners();
}
// static int count = 0;
void _onNewMagnetometerData(String data) {
Map<String, dynamic> magnData = jsonDecode(data);
Map<String, dynamic> body = magnData["Body"];
List<dynamic> magnArry = body["ArrayMagn"];
dynamic magn = magnArry.last;
// int c = count++;
_magnetoData = "x: " +
magn["x"].toStringAsFixed(2) +
"ny: " +
magn["y"].toStringAsFixed(2) +
"nz: " +
magn["z"].toStringAsFixed(2);
//Option 1
DateTime now = DateTime.now();
var dateLocal = now.toLocal();
var formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateLocal);
//Option 2
//var formattedDate = DateTime.now().millisecondsSinceEpoch;
List<dynamic> row = new List<dynamic>();
row.add(formattedDate);
row.add(magn["x"].toStringAsFixed(2));
row.add(magn["y"].toStringAsFixed(2));
row.add(magn["z"].toStringAsFixed(2));
// row.add(c.toString());
_magnetoList.add(row);
notifyListeners();
}
void unsubscribeFromMagnetometer() {
Mds.unsubscribe(_magnSubscription);
_magnSubscription = null;
notifyListeners();
}
void subscribeToHr() {
_hrData = "";
_hrSubscription = Mds.subscribe(
Mds.createSubscriptionUri(_serial, "/Meas/HR"),
"{}",
(d, c) => {},
(e, c) => {},
(data) => _onNewHrData(data),
(e, c) => {});
notifyListeners();
}
void _onNewHrData(String data) {
Map<String, dynamic> hrData = jsonDecode(data);
Map<String, dynamic> body = hrData["Body"];
double hr = body["average"];
_hrData = hr.toStringAsFixed(1) + " bpm";
notifyListeners();
}
void unsubscribeFromHr() {
Mds.unsubscribe(_hrSubscription);
_hrSubscription = null;
notifyListeners();
}
void switchLed() {
Map<String, bool> contract = new Map<String, bool>();
contract["isOn"] = !_ledStatus;
Mds.put(
Mds.createRequestUri(_serial, "/Component/Led"), jsonEncode(contract),
(data, code) {
_ledStatus = !_ledStatus;
notifyListeners();
}, (e, c) => {});
}
void getTemperature() {
Mds.get(Mds.createRequestUri(_serial, "/Meas/Temp"), "{}", (data, code) {
double kelvin = jsonDecode(data)["Content"]["Measurement"];
double temperatureVal = kelvin - 274.15;
_temperature = temperatureVal.toStringAsFixed(1) + " C";
notifyListeners();
}, (e, c) => {});
}
void startAccelerometerRecord() {
_skipAccelerometer = false;
_accelerometerList = new List<List<dynamic>>();
List<dynamic> header = new List();
header.add("timestamp");
header.add("X");
header.add("Y");
header.add("Z");
_accelerometerList.add(header);
}
void stopAccelerometerRecord() {
_skipAccelerometer = true;
writeToCsvAccelerometer();
}
void startGyroscopeRecord() {
_skipGyroscope = false;
_gyroscopeList = new List<List<dynamic>>();
List<dynamic> header = new List();
header.add("timestamp");
header.add("X");
header.add("Y");
header.add("Z");
_gyroscopeList.add(header);
}
void stopGyroscopeRecord() {
_skipGyroscope = true;
writeToCsvGyroscope();
}
void startMagnetoRecord() {
_skipMagneto = false;
_magnetoList = new List<List<dynamic>>();
List<dynamic> header = new List();
header.add("timestamp");
header.add("X");
header.add("Y");
header.add("Z");
_magnetoList.add(header);
}
void stopMagnetoRecord() {
_skipMagneto = true;
writeToCsvMagneto();
}
void writeToCsvAccelerometer() async {
File file = File(await getFilePath("accelero"));
String csv = const ListToCsvConverter().convert(_accelerometerList);
file.writeAsString(csv);
}
void writeToCsvGyroscope() async {
File file = File(await getFilePath("gyro"));
String csv = const ListToCsvConverter().convert(_gyroscopeList);
file.writeAsString(csv);
}
void writeToCsvMagneto() async {
File file = File(await getFilePath("magneto"));
String csv = const ListToCsvConverter().convert(_magnetoList);
file.writeAsString(csv);
}
Future<String> getFilePath(String name) async {
DateTime now = DateTime.now();
var dateLocal = now.toLocal();
var formattedDate = DateFormat('yyyy-MM-dd HH:mm').format(dateLocal);
Directory appDocumentsDirectory;
if (Platform.isAndroid) {
appDocumentsDirectory = await getExternalStorageDirectory();
} else if (Platform.isIOS) {
appDocumentsDirectory = await getApplicationDocumentsDirectory();
}
List<FileSystemEntity> directory = appDocumentsDirectory.listSync();
directory.forEach((x) => debugPrint(x.path));
String appDocumentsPath = appDocumentsDirectory.path;
String filePath = '$appDocumentsPath/' + name + '' + formattedDate + '.csv';
return filePath;
}
}

用于使用DataLogger&日志,请参阅Android示例";数据记录器样本";以及相关的API文档。

简而言之:

  1. PUT/Mem/DataLogger/Config,列出要记录的路径。在您的情况下,它们将是/Meas/IMU9/104Meas/Temp
  2. PUT/Mem/DataLogger/State为3(=LOGING(--你可以在这里断开连接--
  3. 你想测量的东西吗
  4. 重新连接到传感器
  5. PUT/Mem/DataLogger/State为2(=就绪(。这将停止录制
  6. 获取";suunto:/MDS/日志/{serial}/条目"在移动设备上查看传感器数据存储器上的条目列表。LogID最大的是您刚刚录制的
  7. 获取";suunto:/MDS/Logbook/{serial}/byId/{LogId}/Data";在移动设备上以JSON形式获取记录

注意:要记录的路径会很快(<100秒(填满数据内存。电流传感器将数据存储器视为环形缓冲区,如果旧数据已满,则将其存储在旧数据上,这样您就可以获得最后~90秒的数据。

全面披露:我为Movesense团队工作

最新更新