Flutter生物信号采集插件bitalino的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter生物信号采集插件bitalino的使用

开源的Flutter插件,用于集成与BITalino设备的通信。 由Afonso Raposo制作。

查看一个示例应用 此处

测试设备包括:BITalino Core BT (MCU+BT+PWR) 和 BITalino Core BLE/BT。

工作流程图

目前支持的功能

该插件使用了BITalino开发的原生API,具体信息可参见 此处

平台 支持 原生仓库 日期
Android revolution-android-api Jul 16, 2020
iOS BITalinoBLE-iOS Jun 22, 2016

安装

pubspec.yaml 文件中添加此插件:

dependencies:
  flutter:
    sdk: flutter
  bitalino: ^1.1.1 // 添加bitalino插件

Android

在Android上,你必须将 minSdkVersion 设置为18(或更高)在你的 android/app/build.gradle 文件中。

minSdkVersion 18

iOS

在iOS上,你需要在 /ios/Runner/Info.plist 文件底部添加以下行:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>本应用程序需要访问蓝牙以与BITalino设备通信</string>

<key>NSBluetoothPeripheralUsageDescription</key>
<string>本应用程序需要访问BLE以与BITalino设备通信</string>

示例

初始化控制器

Android

在Android上,用户必须提供设备的MAC地址,并可以选择使用BTH或BLE进行通信协议。如果可用,建议使用BTH。

BITalinoController bitalinoController = BITalinoController(
  "20:16:07:18:17:02", // 设备MAC地址
  CommunicationType.BTH, // 通信协议类型
);

try {
  await bitalinoController.initialize();
} on PlatformException catch (Exception) {
  print("初始化失败: ${Exception.message}");
}
iOS

在iOS上,用户必须提供设备的UUID,并且只能使用BLE作为通信协议。

可以通过以下应用找到UUID:Bluetooth Smart Scanner

在iOS上,没有帧标识符。

BITalinoController bitalinoController = BITalinoController(
  "03A1C0AB-018F-5B39-9567-471DDE5B0322", // 设备UUID
  CommunicationType.BLE, // 通信协议类型
);

try {
  await bitalinoController.initialize();
} on PlatformException catch (Exception) {
  print("初始化失败: ${Exception.message}");
}

连接到设备

通过提供设备地址来连接到设备。

await bitalinoController.connect(
  onConnectionLost: () {
    print("连接丢失");
  },
)

开始采集

开始采集模拟通道:A0, A2, A4, A5,采样率为10Hz。onDataAvailable 每次接收到数据时都会被调用。

bool success = await bitalinoController.start(
  [0, 2, 4, 5], // 通道列表
  Frequency.HZ10, // 采样率
  onDataAvailable: (BITalinoFrame frame) {
      print(frame.sequence);    // 序列号 [int]
      print(frame.analog);      // 模拟数据 [List<int>]
      print(frame.digital);     // 数字数据 [List<int>]
  },
);

在采集过程中,onDataAvailable 回调会被调用。

停止采集

bool success = await bitalinoController.stop();

获取设备状态

Android
BITalinoState state = await bitalinoController.state();
print(state.identifier);        // [String]
print(state.battery);           // [int]
print(state.batteryThreshold);  // [int]
print(state.analog);            // [List<int>]
print(state.digital);           // [List<int>]
iOS

此方法在iOS上不可用。

断开设备连接

bool success = await bitalinoController.disconnect();

释放控制器

当你不再使用控制器时,应该释放它。

bool success = await bitalinoController.dispose();

更多信息

你可以在此页面上找到有关此插件的所有信息:API参考

示例代码

import 'package:bitalino_example/chart.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:bitalino/bitalino.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  BITalinoController bitalinoController;
  int sequence = 0;
  List<SensorValue> data = [];
  DateTime previousTime;
  TextEditingController controller = TextEditingController();

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  Future<void> initPlatformState(bool bth) async {
    bitalinoController = BITalinoController(
      controller.text,
      bth ? CommunicationType.BTH : CommunicationType.BLE,
    );
    try {
      await bitalinoController.initialize();
      _notify("已初始化: ${bth ? "BTH" : "BLE"}");
    } catch (e) {
      _notify("初始化失败");
    }
  }

  _notify(dynamic text) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(
          text.toString(),
        ),
        duration: Duration(
          seconds: 1,
        ),
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Expanded(
              child: ListView(
                children: [
                  TextField(
                    decoration: InputDecoration(hintText: "MAC/UUI"),
                    textAlign: TextAlign.center,
                    controller: controller,
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () {
                            initPlatformState(true);
                          },
                          child: Text("BTH"),
                        ),
                      ),
                      SizedBox(
                        width: 16,
                      ),
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () {
                            initPlatformState(false);
                          },
                          child: Text("BLE"),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () async {
                            bool connected = await bitalinoController.connect(
                                onConnectionLost: () {
                              _notify('连接丢失');
                            });
                            _notify(
                              "已连接: $connected",
                            );
                          },
                          child: Text("连接"),
                        ),
                      ),
                      SizedBox(
                        width: 16,
                      ),
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () async {
                            bool disconnected = await bitalinoController.disconnect();
                            _notify("已断开连接: $disconnected");
                          },
                          child: Text("断开连接"),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () async {
                            previousTime = DateTime.now();
                            bool started = await bitalinoController.start(
                              [
                                0,
                              ],
                              Frequency.HZ10,
                              numberOfSamples: 10,
                              onDataAvailable: (frame) {
                                if (data.length >= 30) data.removeAt(0);
                                setState(() {
                                  data.add(SensorValue(previousTime,
                                      frame.analog[0].toDouble()));
                                  previousTime = DateTime.fromMillisecondsSinceEpoch(
                                      previousTime.millisecondsSinceEpoch + 1000 ~/ 10);
                                });
                              },
                            );
                            _notify("已启动: $started");
                          },
                          child: Text("启动"),
                        ),
                      ),
                      SizedBox(
                        width: 16,
                      ),
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () async {
                            bool stopped = await bitalinoController.stop();
                            _notify("已停止: $stopped");
                          },
                          child: Text("停止"),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.all(16),
                child: Chart(data),
              ),
            )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter生物信号采集插件bitalino的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter生物信号采集插件bitalino的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中集成和使用Bitalino生物信号采集插件,通常涉及到与硬件设备的通信和数据处理。以下是一个简化的示例,展示如何在Flutter项目中配置和使用Bitalino插件(假设存在一个相应的Flutter插件)。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加Bitalino插件的依赖。注意,这里假设有一个名为bitalino_flutter_plugin的插件存在,实际上你需要查找并使用官方或社区提供的正确插件名称。

dependencies:
  flutter:
    sdk: flutter
  bitalino_flutter_plugin: ^x.y.z  # 替换为实际版本号

然后运行flutter pub get来获取依赖。

2. 配置权限

如果Bitalino插件需要与设备进行蓝牙通信,你可能需要在AndroidManifest.xmlInfo.plist中添加相应的权限。

Android (AndroidManifest.xml)

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

iOS (Info.plist)

<key>NSBluetoothAlwaysUsageDescription</key>
<string>App needs bluetooth access to communicate with Bitalino device</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>App needs bluetooth access to communicate with Bitalino device</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App needs location access to scan for Bluetooth devices</string>

3. 初始化和使用插件

在你的Flutter应用中,你可以这样初始化并使用Bitalino插件。

import 'package:flutter/material.dart';
import 'package:bitalino_flutter_plugin/bitalino_flutter_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late BitalinoFlutterPlugin bitalino;

  @override
  void initState() {
    super.initState();
    bitalino = BitalinoFlutterPlugin();

    // 初始化设备连接
    _initializeDevice();
  }

  Future<void> _initializeDevice() async {
    try {
      // 假设有一个方法用于扫描和连接设备
      var device = await bitalino.connectToDevice("YOUR_BITALINO_DEVICE_ID");
      
      // 开始采集数据
      bitalino.startDataAcquisition(device, (data) {
        // 处理采集到的数据
        print("Received data: $data");
      });
    } catch (e) {
      print("Error initializing device: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Bitalino Flutter Demo'),
        ),
        body: Center(
          child: Text('Connecting to Bitalino...'),
        ),
      ),
    );
  }
}

注意事项

  1. 插件实现:上述代码假设存在一个名为BitalinoFlutterPlugin的插件,并提供了connectToDevicestartDataAcquisition方法。实际使用时,你需要参考插件的官方文档来了解其API。

  2. 设备ID:在连接设备时,你需要提供设备的唯一标识符。这通常通过扫描附近的蓝牙设备获得。

  3. 数据处理startDataAcquisition方法中的回调函数用于处理从Bitalino设备接收到的数据。你需要根据数据的格式进行解析和处理。

  4. 错误处理:在实际应用中,你需要添加更多的错误处理逻辑,以确保在设备连接失败或数据传输中断时能够给出适当的用户反馈。

  5. 平台特定代码:对于某些功能(如蓝牙通信),你可能需要在iOS和Android平台上分别编写特定的代码。这通常涉及到使用原生代码扩展Flutter插件。

由于具体的Bitalino Flutter插件可能并不存在或名称不同,你需要根据实际的插件文档进行调整和配置。如果官方没有提供Flutter插件,你可能需要考虑使用原生代码(如Kotlin/Java for Android, Swift/Objective-C for iOS)与Bitalino SDK进行交互,并通过Flutter的Platform Channels与原生代码进行通信。

回到顶部