# 蓝牙电刺激控制应用 - 工作交接文档 ## 项目概述 ### 项目名称 蓝牙电刺激控制应用 (SDK_APP) ### 项目功能 基于Android的蓝牙电刺激设备控制应用,支持多种设备类型(ESP32S3 SPP、轻迅设备、新设备),提供完整的电刺激参数控制和数据采集功能。 ### 技术栈 - **开发语言**: Kotlin - **构建工具**: Gradle - **最低支持**: Android 5.1 (API 21) - **目标支持**: Android 15 (API 35) - **蓝牙协议**: BLE + Classic Bluetooth --- ## 核心功能模块 ### 1. 蓝牙连接管理 (`BluetoothManager.kt`) #### 1.1 设备兼容性 ```kotlin // 支持的设备类型 enum class DeviceType { ESP32S3_DEVICE, // ESP32S3 SPP设备 QINGXUN, // 轻迅设备 NEW_DEVICE // 新设备 } ``` #### 1.2 扫描策略 - **Android 8/8.1**: 混合扫描模式(BLE + 传统蓝牙) - **Android 6-11**: 优先BLE,失败时回退到传统蓝牙 - **Android 12+**: 完整BLE扫描支持 #### 1.3 连接流程 1. 权限检查 2. 蓝牙适配器初始化 3. 设备扫描 4. 服务发现 5. 特征值订阅 6. 数据通信 ### 2. 电刺激控制协议 #### 2.1 协议格式(19字节) ``` [0-1] 功能码 (0x0003) [2-3] 数据长度 (0x000D = 13字节) [4] 开关状态及电刺激类型 [5] 强度值 [6-7] 频率值 (小端格式) [8-9] 总持续时间 (小端格式) [10-11] 休息时间 (小端格式) [12-13] 静默时间 (小端格式) [14] 缓进时间 [15] 保持时间 [16] 缓出时间 [17-18] CRC16校验 ``` #### 2.2 参数控制 | 参数 | 范围 | 默认值 | 单位 | 说明 | |------|------|--------|------|------| | 刺激类型 | 0-15 | 1 | - | 电刺激类型选择 | | 强度 | 1-100 | 50 | % | 刺激强度百分比 | | 频率 | 1-200 | 100 | Hz | 刺激频率 | | 总时长 | 1-3600 | 10 | 秒 | 总刺激持续时间 | | 休息时间 | 100-10000 | 1000 | 毫秒 | 刺激间隔休息时间 | | 静默时间 | 100-5000 | 500 | 毫秒 | 刺激间隔静默时间 | | 缓进时间 | 1-30 | 2 | 秒 | 刺激强度逐渐增加时间 | | 保持时间 | 1-300 | 5 | 秒 | 刺激强度保持时间 | | 缓出时间 | 1-30 | 2 | 秒 | 刺激强度逐渐减少时间 | ### 3. 数据存储功能 #### 3.1 数据导出功能 - **CSV格式导出**: 支持多通道生理信号数据导出 - **文件存储**: 保存到外部存储目录 - **数据格式**: 包含时间戳、通道数据、统计信息 #### 3.2 导出类型 | 导出类型 | 文件名格式 | 内容说明 | |----------|------------|----------| | **单通道数据** | `ECG_ChannelData_YYYYMMDD_HHMMSS.csv` | 单个通道的完整数据 | | **多通道数据** | `ECG_MultiChannelData_YYYYMMDD_HHMMSS.csv` | 所有通道的同步数据 | | **波形视图数据** | `ECG_WaveformData_YYYYMMDD_HHMMSS.csv` | 2.5秒显示窗口数据 | | **完整图表数据** | `ECG_AllChartData_YYYYMMDD_HHMMSS.csv` | 所有图表数据汇总 | #### 3.3 数据管理 (`DataManager.kt`) - **数据解析**: 使用原生方法解析蓝牙数据流 - **缓冲管理**: 实时数据缓冲和回调管理 - **多回调支持**: 支持多个数据接收器 ### 4. 图表显示功能 #### 4.1 动态图表系统 (`DynamicChartView.kt`) - **实时绘制**: 60fps实时数据绘制 - **多通道支持**: 支持单通道和多通道数据显示 - **生产者-消费者模式**: 使用队列缓冲数据,分离数据接收和显示 #### 4.2 图表管理器 (`DynamicChartManager.kt`) - **动态创建**: 根据设备类型自动创建图表 - **设备配置**: 不同设备类型的图表配置 - **全屏支持**: 支持图表全屏显示 #### 4.3 全屏图表 (`FullscreenChartActivity.kt`) - **全屏模式**: 隐藏状态栏和导航栏 - **生命体征显示**: 实时显示心率和血氧 - **滤波器控制**: 集成滤波器管理器 - **Y轴范围设置**: 支持自定义Y轴范围 #### 4.4 图表特性 | 特性 | 说明 | 技术实现 | |------|------|----------| | **实时更新** | 60fps刷新率 | ScheduledThreadPoolExecutor | | **数据缓冲** | 队列容量10000点 | LinkedBlockingQueue | | **内存管理** | 自动清理旧数据 | 定期内存检查 | | **多通道** | 支持PPG等多通道设备 | 多通道数据队列 | | **交互控制** | 缩放、平移 | 手势识别 | ### 5. 滤波器系统 #### 5.1 滤波器管理器 (`FullscreenFilterManager.kt`) - **实时滤波**: 支持多种滤波器类型 - **参数调节**: 可调节滤波器参数 - **性能优化**: 高效的数据处理算法 #### 5.2 支持的滤波器 - **低通滤波器**: 去除高频噪声 - **高通滤波器**: 去除低频漂移 - **带通滤波器**: 保留特定频率范围 - **陷波滤波器**: 去除工频干扰 ### 6. 用户界面 (`MainActivity.kt`) #### 6.1 权限管理 ```kotlin // 动态权限请求 private val REQUIRED_PERMISSIONS: Array = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12+ 使用新的蓝牙权限 arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Android 6-11 只需要位置权限 arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) } else { // Android 5.1及以下不需要动态权限 emptyArray() } ``` #### 6.2 电刺激控制界面 - **高级电刺激控制**: 完整参数自定义 - **预设模式选择**: 快速选择预设方案 - **简单开关控制**: 使用默认参数 - **滑动对话框**: 支持滚动查看所有参数 --- ## 代码运行机制 ### 1. 应用启动流程 ```mermaid graph TD A[应用启动] --> B[MainActivity.onCreate] B --> C[权限检查] C --> D[蓝牙初始化] D --> E[UI初始化] E --> F[等待用户操作] ``` ### 2. 蓝牙连接流程 ```mermaid graph TD A[用户点击连接] --> B[权限检查] B --> C{权限是否通过?} C -->|否| D[请求权限] C -->|是| E[开始扫描] D --> E E --> F[设备发现] F --> G[选择设备] G --> H[建立连接] H --> I[服务发现] I --> J[特征值订阅] J --> K[数据通信就绪] ``` ### 3. 电刺激控制流程 ```mermaid graph TD A[用户选择电刺激控制] --> B[选择控制方式] B --> C{控制方式} C -->|高级控制| D[参数输入对话框] C -->|预设模式| E[预设选择] C -->|简单控制| F[快速开关] D --> G[参数验证] E --> G F --> G G --> H[构建数据包] H --> I[发送指令] I --> J[状态反馈] ``` ### 4. 数据包构建流程 ```mermaid graph TD A[接收参数] --> B[创建19字节数组] B --> C[写入功能码] C --> D[写入数据长度] D --> E[写入开关状态] E --> F[写入强度] F --> G[写入频率] G --> H[写入持续时间] H --> I[写入休息时间] I --> J[写入静默时间] J --> K[写入缓进时间] K --> L[写入保持时间] L --> M[写入缓出时间] M --> N[计算CRC16] N --> O[发送数据包] ``` --- ## 关键代码文件说明 ### 1. `BluetoothManager.kt` - 蓝牙管理核心 #### 主要类和方法: - `BluetoothManager`: 蓝牙连接管理主类 - `startScan()`: 启动设备扫描 - `connectToDevice()`: 连接指定设备 - `stimSwitch()`: 发送电刺激控制指令 - `handleProtocolData()`: 处理接收到的数据 #### 关键特性: - 多设备类型支持 - Android版本兼容性处理 - 混合扫描策略 - 协议数据包构建 ### 2. `MainActivity.kt` - 用户界面控制 #### 主要类和方法: - `MainActivity`: 主界面Activity - `showAdvancedStimDialog()`: 高级电刺激控制对话框 - `showPresetStimDialog()`: 预设模式选择 - `createSimpleInputField()`: 创建输入字段 - `checkAndRequestPermissions()`: 权限检查 #### 关键特性: - 动态权限管理 - 滑动对话框界面 - 参数输入验证 - 状态实时反馈 ### 3. `DynamicChartView.kt` - 动态图表显示 #### 主要类和方法: - `DynamicChartView`: 自定义图表视图 - `updateData()`: 更新单通道数据 - `updateMultiChannelData()`: 更新多通道数据 - `startConsumer()`: 启动消费者线程 - `stopConsumer()`: 停止消费者线程 #### 关键特性: - 生产者-消费者模式 - 60fps实时绘制 - 多通道数据支持 - 内存管理优化 ### 4. `DynamicChartManager.kt` - 图表管理器 #### 主要类和方法: - `DynamicChartManager`: 图表管理主类 - `createChartsForDevice()`: 根据设备类型创建图表 - `updateChartsData()`: 更新所有图表数据 - `getDeviceConfig()`: 获取设备配置 #### 关键特性: - 动态图表创建 - 设备类型适配 - 全屏模式支持 ### 5. `FullscreenChartActivity.kt` - 全屏图表 #### 主要类和方法: - `FullscreenChartActivity`: 全屏图表Activity - `setupFullscreen()`: 设置全屏模式 - `setupFullscreenCharts()`: 设置全屏图表 - `setupVitalSignsDisplay()`: 设置生命体征显示 #### 关键特性: - 全屏显示模式 - 生命体征实时显示 - 滤波器集成 - Y轴范围自定义 ### 6. `DataManager.kt` - 数据管理 #### 主要类和方法: - `DataManager`: 数据管理主类 - `processData()`: 处理原始数据 - `setRealTimeCallback()`: 设置实时数据回调 - `addRealTimeCallback()`: 添加数据回调 #### 关键特性: - 原生方法调用 - 多回调支持 - 数据缓冲管理 ### 7. `AndroidManifest.xml` - 权限配置 #### 权限声明: ```xml ``` --- ## 设备支持 ### 1. ESP32S3 SPP设备 - **服务UUID**: 0xABF0 - **特征值**: - 数据发送: 0xABF1, 0xABF3 - 数据接收: 0xABF2, 0xABF4 - **设备名称**: ESP_SPP_SERVER ### 2. 轻迅设备 - **服务UUID**: Nordic UART Service - **特征值**: TX/RX特征值 - **协议**: 轻迅自定义协议 ### 3. 新设备 - **服务UUID**: 自定义UUID - **特征值**: 自定义特征值 - **协议**: 扩展协议支持 --- ## 操作指南 ### 1. 应用启动 1. 安装APK到Android设备 2. 启动应用 3. 检查权限状态 4. 点击"连接蓝牙"开始扫描 ### 2. 设备连接 1. 确保目标设备处于可发现模式 2. 点击"连接蓝牙"按钮 3. 等待设备扫描完成 4. 选择目标设备进行连接 ### 3. 电刺激控制 1. 连接成功后,点击"电刺激开关" 2. 选择控制方式: - **高级控制**: 自定义所有参数 - **预设模式**: 选择预设方案 - **简单控制**: 使用默认参数 3. 设置参数并确认 4. 查看状态反馈 ### 4. 图表操作 1. **查看实时数据**: 连接设备后自动显示图表 2. **全屏模式**: 点击图表右上角全屏按钮 3. **数据导出**: - 点击"导出数据"按钮 - 选择导出类型(单通道/多通道/完整数据) - 文件保存到外部存储 4. **滤波器设置**: 在全屏模式下使用滤波器控制 5. **Y轴范围**: 在全屏模式下可自定义Y轴范围 ### 5. 数据导出 1. **单通道数据导出**: - 点击"导出数据" → "单通道数据" - 选择要导出的通道 - 文件格式:CSV 2. **多通道数据导出**: - 点击"导出数据" → "多通道数据" - 导出所有通道的同步数据 3. **完整数据导出**: - 点击"导出数据" → "完整数据" - 包含所有图表和统计信息 4. **文件分享**: 导出完成后可选择分享或保存 ### 6. 参数设置示例 ``` 刺激类型: 1 强度: 70% 频率: 120Hz 总时长: 30秒 休息时间: 1000ms 静默时间: 500ms 缓进时间: 2秒 保持时间: 26秒 缓出时间: 2秒 ``` --- ## 故障排除 ### 1. 权限问题 - **现象**: 显示"权限被拒绝" - **解决**: 检查应用权限设置,确保蓝牙和位置权限已授予 ### 2. 设备扫描失败 - **现象**: 找不到目标设备 - **解决**: - 确保设备处于可发现模式 - 检查蓝牙是否开启 - 尝试重启蓝牙服务 ### 3. 连接失败 - **现象**: 连接超时或失败 - **解决**: - 检查设备距离 - 确认设备未被其他应用占用 - 尝试重新扫描 ### 4. 数据发送失败 - **现象**: 电刺激指令发送失败 - **解决**: - 检查连接状态 - 验证参数范围 - 查看日志输出 ### 5. 图表显示问题 - **现象**: 图表不显示数据或显示异常 - **解决**: - 检查数据连接状态 - 重启图表显示 - 检查内存使用情况 - 查看队列大小日志 ### 6. 数据导出失败 - **现象**: 无法导出数据或文件保存失败 - **解决**: - 检查存储权限 - 确保有足够存储空间 - 检查文件路径权限 - 重启应用后重试 ### 7. 全屏模式问题 - **现象**: 全屏模式无法正常显示 - **解决**: - 检查设备屏幕方向 - 重启全屏Activity - 检查系统UI设置 --- ## 开发环境配置 ### 1. 开发工具 - Android Studio - Gradle 7.0+ - Android SDK API 21-35 ### 2. 构建命令 ```bash # 编译Kotlin代码 .\gradlew.bat compileDebugKotlin # 构建APK .\gradlew.bat assembleDebug # 清理项目 .\gradlew.bat clean ``` ### 3. 调试方法 - **日志监控**: 使用Logcat查看详细日志输出 - **蓝牙状态**: 监控蓝牙连接和扫描状态 - **权限检查**: 查看权限请求和授权日志 - **数据包**: 监控电刺激指令发送日志 - **图表数据**: 查看队列大小和数据流日志 - **内存使用**: 监控内存占用和清理日志 - **数据导出**: 查看文件保存和分享日志 - **全屏模式**: 监控全屏切换和UI状态 --- ## 版本历史 ### 当前版本特性 - ✅ 支持Android 5.1-15 - ✅ ESP32S3 SPP设备支持 - ✅ 完整电刺激参数控制 - ✅ 滑动对话框界面 - ✅ 多设备类型兼容 - ✅ 混合扫描策略 - ✅ 权限动态管理 - ✅ 实时图表显示系统 - ✅ 多通道数据支持 - ✅ 数据导出功能 - ✅ 全屏图表模式 - ✅ 滤波器集成 - ✅ 生产者-消费者数据模式 - ✅ 内存管理优化 ### 已知问题 #### 7.1 动态图标显示Bug - **问题描述**: 动态图标显示的是队列大小而不是实际数据值 - **影响范围**: 图表状态显示 - **技术原因**: 状态更新逻辑中错误地使用了队列大小作为显示值 - **代码位置**: `DynamicChartView.kt` 中的日志输出和状态更新 - **临时解决方案**: 当前通过日志输出队列大小,需要修正为显示实际数据值 #### 7.2 其他已知问题 - **Android 8.1扫描兼容性**: 部分设备扫描兼容性问题 - **设备连接稳定性**: 部分设备连接稳定性待优化 - **内存使用**: 长时间运行可能导致内存占用过高 - **数据同步**: 多通道数据同步可能存在延迟 --- ## 联系方式 如有技术问题或需要支持,请联系开发团队。 --- **文档版本**: 1.0 **最后更新**: 2025年1月 **维护人员**: 开发团队