基于nnom的多选择器
核心组件
元件 | 类型 | 目的 | 接口 |
---|---|---|---|
STM32F103CB | 微控制器 | 主处理单元 | - |
MPU6050 | 6 轴 IMU | 移动侦测 | I2C 接口 |
W25Q64 系列 | 闪存 | 信号和配置存储 | SPI 系列 |
按钮 | 用户输入 | 模式选择和激活 | GPIO (通用输出) |
搭载了LED | 用户反馈 | 系统状态指示 | GPIO (通用输出) |
RT6150 系列 | 稳压器 | 3.3V 电源 | - |
型号 CH340N | USB 转串行 | 开发和调试 | 串口 |
作模式
系统有两种主要作模式,用于确定识别手势时的行为:
模式 0 (执行)
在此模式下,魔杖根据识别的手势执行预先录制的动作:
- 对于 IR 模块:从闪存传输记录的 IR 信号
- 对于 RF 模块:从闪存传输记录的 RF 信号
- 对于自定义模块:执行特定于模块的函数
模式 1 (录制)
在此模式下,魔杖会在识别手势时记录信号:
- 对于 IR 模块:记录来自外部设备(例如电视遥控器)的 IR 信号
- 对于 RF 模块:记录来自外部发射器的 RF 信号
- 对于自定义模块:记录特定于模块的数据
默认情况下,系统以模式 0 启动。长按按钮 (>0.5 秒) 可在模式之间切换,LED 指示灯模式提供当前模式的视觉反馈。
核心硬件组件
STM32F103CB 微控制器
STM32F103CB 微控制器用作 WAND 系统的中央处理单元。这款基于 ARM Cortex-M3 的 MCU 提供:
- 72 MHz 最大 CPU 频率
- 128 KB 闪存
- 20 KB 的 SRAM
- 接口:I2C、SPI、UART
- 16 通道 12 位 ADC
- 工作电压:3.3V
微控制器负责:
- 从 IMU 读取运动数据
- 通过 CNN 模型处理数据以进行手势识别
- 根据识别的手势控制模块界面
- 管理电源状态和系统模式
MPU6050 IMU 传感器
MPU6050 是一个 6 轴运动跟踪装置,结合了 3 轴陀螺仪和 3 轴加速度计。它通过 I2C 接口与 STM32 通信,并为手势识别提供运动数据。
主要特点:
- 数字输出加速度计和陀螺仪
- 用于运动处理的数字运动处理器 (DMP)
- I2C 接口工作频率为 400kHz
- 每个轴的 16 位 ADC 分辨率
- 可编程满量程范围:±2g、±4g、±8g、±16g(加速度计)和 ±250、±500、±1000、±2000°/s(陀螺仪)
W25Q64 闪存
W25Q64 是一款 64Mbit SPI 闪存,用于存储:
- 手势识别模型参数
- 模块配置数据
- 针对不同手势录制的 IR/RF 信号
闪存通过 SPI 接口连接到 STM32,提供非易失性存储。
高级软件架构
系统初始化
系统初始化序列由该功能管理,该功能设置所有硬件外围设备并检测已安装的模块。System_Init()
核心处理循环
Cyberry Potter 魔杖的主要处理循环包括捕获手势数据、识别手势以及根据当前系统模式执行适当的模块处理程序。
模块系统
模块系统是一个关键的架构组件,它通过支持不同的硬件连接来提供灵活性。
模块检测和初始化
该磁棒使用 ADC 读数来识别通过特定于每个模块的分压器电路连接的模块。
手势识别架构
手势识别系统从 MPU6050 IMU 捕获运动数据,并使用通过 nnom 库实现的 CNN 对其进行处理。
IMU 数据采集
系统模式管理
中断处理
该系统将中断用于时间关键型功能,包括 IMU 数据采集和 IR/RF 信号处理。
内存管理
Cyberry Potter 系统利用不同的内存区域进行作:
内存类型 | 用法 | 详 |
---|---|---|
Flash (内部) | 程序代码、CNN 权重 | 128KB 内置于 STM32F103CB 中 |
RAM | 运行时变量、数据缓冲区 | 20KB 用于易失性作 |
W25Q64 闪光灯 | 信号存储、用户配置 | 8MB 外部闪存,用于存储 IR/RF 信号 |
目录结构
代码库被组织成几个反映架构组件的关键目录:
通信接口
该系统采用多个通信接口进行内部和外部交互:
接口 | 协议 | 主要用途 |
---|---|---|
美国萨尔特1 | 串行 (115200 波特) | 调试、PC 通信 |
I2C 接口 | I2C 接口 | IMU (MPU6050) 通信 |
SPI2 | SPI 系列 | 外部闪存 (W25Q64) 访问 |
GPIO (通用输出) | 数字 I/O | 模块检测、按钮输入、LED 控制 |
外部接口 | 红外/射频 | 通过模块与外部设备通信 |
结论
Cyberry Potter Electromagic Wand 软件架构采用模块化、分层的方法,在保持一致用户体验的同时,允许灵活的硬件配置。实时手势识别、模块特定功能和基于模式的作相结合,实现了一个多功能平台,可通过直观的棒状手势控制各种外部设备。
代码库遵循关注点的清晰分离,为核心系统功能、手势识别、模块管理和硬件抽象提供不同的组件。这种设计有助于维护和扩展,允许在不进行重大架构更改的情况下添加新的模块和手势。
手势捕获过程
当用户按下魔杖上的按钮时,手势捕获过程开始。这将从 MPU6050 传感器启动 1.5 秒的数据收集窗口。
捕获序列
- 用户按下并释放按钮(短按)
- 系统禁用按钮中断以防止捕获过程中的干扰
- 系统启用 IMU 中断以进行数据收集
- 采样期间 LED 关闭以节省电力
- MPU6050 捕获 1.5 秒的运动数据
- 收集的数据经过预处理并馈送到 CNN 模型中
手势识别算法
该魔杖使用卷积神经网络 (CNN) 来识别各种运动模式。该模型使用 TensorFlow/Keras 进行训练,然后使用 nnom 库转换为 STM32 微控制器部署。
CNN 架构
CNN 模型由以下层组成:
- Input layer - 接受时间序列运动数据
- Conv1D 层(30 个滤波器,内核大小 3,步幅 3)
- LeakyReLU 激活
- Conv1D 层(15 个滤波器,内核大小 3,步幅 3)
- LeakyReLU 激活
- 拼合图层
- 密集图层(输出大小与手势数量匹配)
- Dropout 层(0.3 率)
- Softmax 输出层
支持的手势
该系统能够识别 13 种不同的手势,每个手势都映射到特定的作:
手势 ID | 手势名称 | 描述 |
---|---|---|
0 | RightAngle (右角) | 形成直角的运动 |
1 | 锐角 | 形成锐角的运动 |
2 | 闪电 | 闪电图案 |
3 | 三角形 | 三角运动 |
4 | Letter_h | 绘制字母 'h' |
5 | letter_R | 绘制字母 'R' |
6 | letter_W | 绘制字母 'W' |
7 | letter_phi | 绘制希腊 phi 符号 |
8 | 圈 | 圆周运动 |
9 | UpAndDown | 上下运动 |
10 | 角 | 喇叭状图案 |
11 | 浪 | 挥动动作 |
12 | 无运动 | 未检测到明显的运动 |
运行时数据处理
- 在 1.5 秒的捕获窗口内收集原始 IMU 数据
- 数据经过预处理(缩放)以用于模型输入
- CNN 模型通过其层处理数据
- 分析输出概率以确定最可能的手势
- 识别的手势将传递给模块处理程序以执行作
模式相关行为
手势识别系统与模块系统的交互方式因当前模式而异:
- 模式 0 (执行):识别的手势触发预先录制的命令的执行
- 模式 1 (Record):识别的手势开始录制新命令
性能注意事项
手势识别系统旨在在资源受限的 STM32 微控制器上高效运行。多项优化可确保可靠的性能:
- 有限采样窗口:1.5 秒的捕获窗口提供足够的数据进行识别,同时最大限度地减少处理开销
- 高效的 CNN 架构:该模型设计为轻量级,同时保持准确性
- 量化:量化模型权重以减少内存占用
- nnom 库:使用优化的 nnom 库在微控制器上进行神经网络推理
定制流程
用户可以通过使用自己的手势数据训练模型来自定义手势识别系统:
- 在 config.h 中设置以启用数据收集模式
SYSTEM_MODE_DATA_COLLECT
- 使用 Serial_Read.py 通过串行连接收集手势数据
- 运行 CNNTrainRaw.py 以使用收集的数据训练新模型
- 该脚本会生成一个包含模型参数的 weights.h 文件
- 替换固件中已有的 weights.h 文件并重新编译
错误处理
手势识别系统包括多种处理潜在错误的机制:
- IMU 通信检查:验证 IMU 在初始化期间是否正常运行
- 无移动检测:包括一个“NoMotion”类,用于处理未执行不同手势的情况
- 置信度阈值:仅考虑置信度高于特定阈值的手势
- LED 反馈:提供有关系统状态和识别结果的视觉反馈
数据采集
本页记录了从 Cyberry Potter Electromagic Wand 收集惯性测量单元 (IMU) 数据以训练手势识别模型的过程。有效的数据收集对于实现准确的手势分类至关重要。
数据收集过程概述
数据收集过程包括在特殊数据收集模式下使用棒硬件,以在执行特定手势时捕获原始 IMU(加速度计和陀螺仪)读数。然后,这些数据通过串行连接传输到计算机,并保存为文本文件,以供以后在 CNN 训练中使用。
数据收集配置
在收集数据之前,您必须将魔杖的固件配置为在数据收集模式而不是推理模式下运行。
硬件要求
- 组装的 Cyberry Potter Electromagic 魔杖
- 用于连接计算机的 USB Type-C 数据线
- 设置了 Python 环境的计算机
固件配置
-
修改文件以启用数据收集模式:
config.h
- 取消注释定义
SYSTEM_MODE_DATA_COLLECT
- 这会将魔杖从正常作切换到数据传输模式
- 取消注释定义
-
将修改后的固件编译并烧录到魔杖上
正确配置后,当按下按钮时,魔杖将通过串行连接输出原始 IMU 数据,而不是尝试对手势进行分类。
数据收集脚本
该脚本通过与魔杖通信、接收 IMU 数据并将其保存到正确标记的文本文件来管理数据收集过程。Serial_Read.py
脚本作流程
使用脚本
- 运行脚本:
python Serial_Read.py
- 从显示的列表中选择适当的 COM 端口
- 从预定义列表中选择要录制的手势:
- 直角、锐角、闪电、三角形、Letter_h、letter_R、letter_W、letter_phi、圆、UpAndDown、喇叭、波浪、NoMotion
- 指定要为此手势录制的样本数
- 对于每个样本:
- 按下魔杖按钮
- 执行手势
- 该脚本将在收到数据时保存数据
- (可选)录制其他手势
数据存储和组织
目录结构
该脚本使用以下命名约定创建目录结构:
./TrainingData_[month]_[day]/
例如,如果在 8 月 23 日收集数据,则文件将保存到 。./TrainingData_8_23/
文件命名约定
数据文件使用指示手势类型和顺序索引的名称进行保存:
[gesture_name]_[index].txt
例如:, , etc.RightAngle_1.txt
RightAngle_2.txt
该脚本会自动跟踪用于每个手势的最高索引并相应地递增,以确保新记录不会覆盖现有数据。
数据格式
收集的数据包括来自 MPU6050 IMU 传感器的原始读数,包括 3 轴加速度计和 3 轴陀螺仪随时间变化的值。采样率和持续时间由固件固定。
示例数据格式
每个数据文件包含一行 6 个值,代表连续时间点的传感器读数:
ax ay az gx gy gz
ax ay az gx gy gz
...
哪里:
ax
, , : X、Y 和 Z 轴的加速度计读数ay
az
gx
, , : X、Y 和 Z 轴的陀螺仪读数gy
gz
按下按钮时,IMU 数据将被捕获大约 1.5 秒,从而每个手势的样本数是固定的。
支持的手势
该脚本支持收集 13 种预定义手势的数据:
指数 | 手势名称 |
---|---|
1 | RightAngle (右角) |
2 | 锐角 |
3 | 闪电 |
4 | 三角形 |
5 | Letter_h |
6 | letter_R |
7 | letter_W |
8 | letter_phi |
9 | 圈 |
10 | UpAndDown |
11 | 角 |
12 | 浪 |
13 | 无运动 |
这些手势对应于项目文档中显示的符卡。
数据收集的最佳实践
为了获得最佳模型训练结果,请遵循以下最佳实践:
- 一致性:以一致的速度和大小执行每个手势
- 多样性:包括您执行每个手势的方式的细微变化,以提高模型的稳健性
- 样本量:每个手势至少收集 10-20 个样本以进行充分训练
- 平衡:确保每种手势类型的样本数相似
- 移动:按下按钮后立即开始手势,因为数据收集立即开始
- 定位:将磁棒保持在舒适、自然的位置 - 方向会影响 IMU 读数
- 验证:在采集大量样品之前验证数据是否保存正确
故障 排除
常见问题及其解决方案:
-
未检测到串行端口:
- 确保 USB 数据线已正确连接
- 验证 Wand 是否已开机
- 检查是否安装了正确的驱动程序
-
未收到数据:
- 确认在 config.h 中未注释
SYSTEM_MODE_DATA_COLLECT
- 验证固件是否已成功刷新
- 检查所选的 COM 端口是否正确
- 确认在 config.h 中未注释
-
数据不完整或损坏:
- 该脚本检查有效的数据标头 - 如果数据被拒绝,请重试
- 确保按住按钮足够长的时间以完成数据收集
- 验证魔杖的电池是否充满电
与固件集成
中包含的导出模型旨在编译到固件中,其中包含以下关键组件:weights.h
- 权重和偏差:存储为常数整数数组
- 量化参数:用于正确缩放的十进制位位置
- 层配置:定义每个层参数的结构
- Model Creation Function:组装神经网络的函数
nnom_model_create()
在运行时,固件:
- 从 MPU6050 捕获 IMU 数据
- 预处理数据以匹配训练输入格式
- 使用 NNoM 库通过 CNN 模型传递数据
- 解释输出以确定识别的手势
模型结构与在 Python 中训练的模型结构相同,但针对嵌入式执行进行了优化:
性能注意事项
为优化资源受限环境的 CNN 模型,我们做出了几种设计选择:
- 模型大小:架构特意保持较小(两个卷积层,一个密集层)
- 参数效率:使用 1D 卷积而不是 2D 卷积可以减少参数数量
- 量化:8 位整数量化降低了内存需求和计算开销
- 选定的特征列:仅使用陀螺仪数据(第 3、4、5 列)而不是所有 IMU 数据
- 固定序列长度:使用 150 个时间步的固定输入大小来标准化处理
这些优化使模型能够在 STM32F103CB 微控制器上高效运行,同时保持足够的手势识别精度。
CNN 集成
目的和范围
本文档介绍了如何将预先训练的卷积神经网络 (CNN) 模型集成到 Cyberry Potter Electromagic Wand 固件中。它涵盖了 STM32 微控制器上神经网络的模型架构、部署过程和运行时作。
模型量化
该模型被量化为使用 8 位整数而不是浮点值,以显著降低内存使用和计算要求,同时保持可接受的准确性。量化参数是为每个层定义的:
层 | 重量 Dec Bits | Bias Dec Bits | 输出偏移 | 偏置偏移 |
---|---|---|---|---|
卷积 1D | 8 | 10 | 8 | 2 |
LSTM 系列 | 8/7 (内核/循环) | 6 | 5 | 6 |
稠 | 8 | 10 | 12 | 5 |
这些量化参数控制整个推理过程中网络权重、偏差和激活的定点表示。
固件中的模型定义
神经网络模型在固件中通过一组张量定义,这些张量代表每层的权重、偏差和配置结构。模型参数以静态数组的形式存储在文件中。weights.h
模型初始化
通过以下函数在固件中创建和初始化模型:nnom_model_create()
- 创建一个空的模型结构
- 定义每个层及其特定配置
- 将各层连接在一起以形成完整的网络
- 编译模型以准备进行推理
模型初始化遵循顺序模式,其中每一层都挂接到前一层,从而创建一个完整的神经网络管道。
运行时推理过程
在作过程中,魔杖的固件会在用户按下按钮时收集 IMU 传感器数据,通过神经网络处理这些数据,并输出手势分类。
内存管理
该模型针对STM32F103CB的有限资源进行了优化:
- 使用 8 位量化权重和激活
- 所有模型参数的静态内存分配
- 作为静态数组分配的输入和输出缓冲区
Input buffer: 450 bytes (150 timestamps × 3 axes)
Output buffer: 13 bytes (13 gesture classes)
总结
Cyberry Potter Electromagic Wand 中的 CNN 集成代表了在资源受限的嵌入式系统上机器学习的复杂实现。通过使用 NNoM 库、量化技术和优化的模型架构,该系统无需外部处理即可实现实时手势识别。
集成过程包括:
- Python 中的模型训练(在 CNN 模型训练中介绍))
- 将训练的权重导出到 C 头文件
- 使用 NNoM 在固件中定义模型结构
- 对 IMU 数据进行实时推理
- 用于控制魔杖功能的手势分类
此实现展示了一种在嵌入式系统上部署神经网络以实现交互式应用程序的有效方法。
模块系统
模块系统是 Cyberry Potter Electromagic Wand 的关键组件,它通过可互换的硬件模块实现可扩展的功能。本页介绍了模块架构、接口以及魔杖如何与各种插件模块通信,以根据识别的手势执行不同的作。
模块系统架构
Cyberry Potter 魔杖采用模块化设计,带有金手指插槽连接器,允许插入不同的模块并被系统识别。模块系统位于手势识别系统和魔杖与之交互的外部设备之间,将识别的手势转换为特定的硬件作。
模块作模式
模块系统以两种主要模式运行,控制魔杖与外部设备的交互方式:
- 模式 0 (执行):当识别到手势时,魔杖通过连接的模块传输预先录制的信号以控制外部设备。
- 模式 1 (Record): 当识别到手势时,魔杖等待录制传入信号,然后将其存储并与该手势相关联。
信号数据结构
模块系统使用通用数据结构来存储和管理信号数据,允许不同类型的模块使用相同的底层信号处理框架。
每个信号都存储为一组持续时间,表示信号的交替高电平和低电平状态。这种格式适用于 IR 和 RF 协议,使其适用于不同的模块类型。
模块处理程序接口
Module Handler 充当核心系统和特定 Module 实现之间的抽象层。它提供了一个统一的接口,用于初始化、发送和接收信号,而与模块类型无关。
主要功能
功能 | 目的 |
---|---|
Module_IR_RF_Init | 根据检测到的模块类型初始化相应的模块 |
Module_IR_RF_Transmit | 从闪存中读取信号并通过模块传输 |
Module_IR_RF_Receive | 记录输入信号并将其存储到闪存中 |
Module_IR_RF_Copy_From_Buffer | 从 Flash 缓冲区中提取信号数据 |
Module_IR_RF_Copy_To_Buffer | 准备信号数据以存储在 Flash 中 |
模块类型检测和初始化
当系统启动时,它会检测插入 Gold Finger 插槽的模块类型,并初始化相应的硬件接口。这种检测机制允许 Wand 无缝地处理不同的模块类型。
信号记录过程
当处于 recording 模式时,模块系统等待输入信号,捕获信号转换的时序,并将此信息存储在信号缓冲区中。
信号录制过程使用 Timer2 来测量信号转换之间的持续时间。如果在定义的超时时间内未检测到信号,则录制过程将自动终止。
信号传输过程
当在执行模式下识别到手势时,该模块会从 Flash 存储器中检索相应的存储信号,并通过活动模块传输。
模块通信协议
每种模块类型都实现了与外部设备通信的特定协议:
红外模块(类型 0)
- 使用 38kHz 载波频率进行红外传输
- 支持常见的 IR 协议,包括 NEC、Sony、RC5 等。
- 信号被编码为载波开/关周期的交替持续时间
射频模块(类型 1-2)
- 支持 433MHz 和 315MHz 射频通信
- 兼容各种射频遥控系统
- 信号编码类似于 IR 的开/关持续时间序列
闪存组织
模块记录的信号存储在外部 W25Q64 闪存中,并为不同的模块类型和手势分配不同的区域。
这种内存组织允许系统为模块类型和识别手势的每种组合存储不同的信号,从而使魔杖高度可定制。
使用自定义模块进行扩展
模块系统设计为可扩展,允许用户通过以下方式创建自定义模块:
- 开发符合 Gold Finger 接口规范的硬件
- 通过创建新的 moduleX.c 和 moduleX.h 文件来实现驱动程序
- 将新模块与现有模块处理程序系统集成
模块系统集成
模块系统与 Cyberry Potter Electromagic Wand 的其他组件集成,如下所示:
这种集成允许魔杖检测手势并通过附加的模块执行适当的作,从而创建无缝的用户体验。
红外模块
概述和目的
红外模块是 Cyberry Potter Electromagic Wand 系统的插件组件,可实现红外信号功能。该模块允许魔杖记录来自遥控器的红外信号并回放它们,通过手势识别有效地将魔杖变成通用遥控器。
硬件架构
IR 模块由两个主要组件组成:
- 红外发射器:连接到 STM32 微控制器的 GPIO A6 的红外 LED
- 红外接收器:连接到 GPIO A7 的红外接收器模块
该模块通过 Gold Finger 连接器接口与魔杖的主板集成。
IR 模块硬件配置
信号表示
IR 信号表示为 timing durations 序列,其中每个 duration 代表载波开启或载波关闭周期。系统使用一种称为 structure 来存储这些信号。IR_RF_Signal_t
IR 信号数据结构
该数组存储脉冲和空间序列的时序,每个元素以 Timer2 计数单位(默认为 20μs)表示一个时间段。交替元件表示 IR 载波的 ON 和 OFF 状态。duration
信号传输
IR 模块在 PWM 模式下使用定时器 3 (TIM3) 生成 3kHz 载波用于 IR 传输。载波根据记录的信号模式进行调制。
传输函数遍历存储的持续时间数组,在 carrier-on 和 carrier-off 状态之间交替。当载波开启时,IR LED 发出 38kHz 脉冲;熄灭时,LED 保持非活动状态。
信号记录
IR 模块通过 IR 接收器触发的外部中断捕获 IR 信号。每个边沿转换 (上升或下降) 都会触发中断,转换之间的时间使用 Timer 2 (TIM2) 进行测量。
录制过程
录制过程由函数启动,并一直持续到信号缓冲区已满或发生超时(50 毫秒不活动)。Module_IR_RF_receiver_start()
与 Gesture Recognition 集成
IR 模块与魔杖的手势识别系统配合使用。不同的手势可以映射到不同的 IR 命令,允许用户通过简单的魔杖移动来控制 IR 设备。
IR 模块作模式
模式 | 描述 | 功能 |
---|---|---|
执行(模式 0) | 根据识别的手势传输预先录制的 IR 信号 | Module_IR_RF_Transmit() |
录制(模式 1) | 记录新的 IR 信号并将其与特定手势相关联 | Module_IR_RF_Receive() |
在录制模式下,魔杖首先从现有遥控器捕获 IR 信号。录制后,此信号将与特定手势相关联。在执行模式下,执行手势将导致魔杖传输相应的 IR 信号。
实现细节
IR 信号载波生成
IR 模块使用定时器 3 (TIM3) 生成 3kHz 载波用于 IR 传输,参数如下:
- 频率:38kHz
- PWM 模式:PWM1
- 占空比:~33%(激活时)
该函数通过设置适当的 PWM 占空比来控制载波的生成:Module0_IR_38Khz_Logic()
- 逻辑 1:PWM 占空比 = 422/633 (~67%)
- 逻辑 0:PWM 占空比 = 0(无载波)
时序参数
定时器 2 (TIM2) 用于对 IR 信号的持续时间进行定时,配置如下:
- 频率:50kHz
- 每次计数时间:20μs(由 US_PER_TIMER2_COUNT 定义)
- 超时时间:50ms(由 TIM2_RECORD_OVERTIME_US 定义)
常见使用场景
IR 模块支持 Cyberry Potter Electromagic Wand 的多种实际应用:
-
通用遥控器:使用来自多个遥控器的 IR 信号对魔杖进行编程,并以不同的手势控制不同的设备。
-
宏命令:录制复杂的 IR 命令序列,并通过单个手势触发它们。
-
智能家居集成:使用魔杖控制支持 IR 的智能家居设备,如空调、电视和娱乐系统。
该系统的模块化设计允许 IR 模块与其他通信模块交换,为不同的用例提供灵活性。
RF433 模块
RF433 模块通过以下引脚连接到 STM32 微控制器:
针 | 功能 | 描述 |
---|---|---|
PA6 | RF433 发射器输出 | 驱动 RF433 发射器的数字输出 |
PA7 系列 | RF433 接收器输入 | 带上拉电阻的数字输入,可连接到 RF433 接收器 |
软件架构
RF433 模块的软件实现由初始化函数和信号处理功能组成。
初始化
该功能配置 RF433 通信所需的硬件组件:Module1_RF433_Init()
- 将 GPIO PA6 初始化为发射器的输出
- 将 GPIO PA7 初始化为接收器的上拉输入
- 配置 EXTI7 中断,以便在 PA7 上进行信号边沿检测
- 设置 Timer2 以进行精确的定时测量
信号数据结构
RF 信号使用该结构进行存储,其中包含:IR_RF_Signal_t
typedef struct IR_RF_Signal_t{eSignal_Status status; // Signal status (EMPTY, RECORDING, READY)uint16_t duration[SIGNAL_SEQUENCE_SET_LENGTH]; // Time durations between transitionsuint16_t length; // Number of transitions in the signal
}IR_RF_Signal_t;
该结构保存 timing 信息而不是原始信号,使其与协议无关且存储效率高。
信号传输过程
该功能通过根据录制的持续时间切换发射机输出来再现射频信号:Module1_RF433_Transmit()
信号记录和定时
RF433 模块使用基于中断的方法来记录信号:
- 当接收器引脚 (PA7) 改变状态时,将触发 EXTI 中断
- 中断处理程序记录转换之间的时间
- Timer2 用于以微秒精度测量时间间隔
时序参数
参数 | 价值 | 描述 |
---|---|---|
TIM2_FREQUENCY | 50 赫兹 | 定时器工作频率 |
US_PER_TIMER2_COUNT | 20 微秒 | 每个计时器计数的时间分辨率 (1000000/TIM2_FREQUENCY) |
TIM2_RECORD_OVERTIME_US | 50000 微秒 | 连续信号的最大记录时间 (50ms) |
SIGNAL_SEQUENCE_LENGTH | 1024 | 可录制的最大过渡数 |
如评论中所述,RF433 发射器需要 13kHz 的最小频率才能正常运行。
与 Cyberry Potter System 的模块集成
RF433 模块通过模块接口与魔杖系统的其余部分集成:
RF433 模块通过抽象层与其他 RF 和 IR 模块共享通用功能,为记录和传输信号提供统一的功能。
使用示例
记录 RF 信号
- 将魔杖设置为录制模式
- 执行与要录制的 RF 信号关联的手势
- 在瞄准魔杖的 RF433 接收器的同时按下原装 RF 遥控器上的按钮
- LED 指示灯将指示录制成功
传输 RF 信号
- 将魔杖设置为 Execute 模式
- 执行与录制的 RF 信号关联的手势
- RF433 模块将传输信号以控制目标设备
技术规格
- 工作频率: 433.92 MHz
- 信号编码:记录原始时序信息,兼容各种射频协议
- 分辨率:每个计时单位 20 微秒
- 最大信号长度:1024 个过渡
- 最大单次持续时间:50 毫秒
该模块设计为与协议无关,只要它们在 433MHz 频段上运行,就可以与各种 RF433 设备一起使用,无论其特定的编码机制如何。
串行命令模块
目的和概述
串行命令模块将识别的手势模式转换为串行命令,这些命令可以通过 UART 传输到外部设备。该模块用作通信接口,允许 Cyberry Potter Electromagic Wand 通过手势识别控制计算机、微控制器或其他支持串行的设备。
功能架构
串行命令模块提供了一种将物理手势转换为串行数据命令的方法。它支持两种不同的作模式,为每个识别的手势定义不同的命令映射。
模块初始化
串行命令模块初始化 USART3 外设以进行串行通信。这是在 函数 中执行的。Module3_Init()

作模式
串行命令模块以两种不同的模式运行,每种模式具有不同的命令映射策略:
模式 0:手势名称输出
在模式 0 中,模块通过串行通信将识别的手势名称以纯文本字符串的形式传输。这样就可以与可以解释字符串命令的设备进行简单的基于文本的通信。
模式 1:键码序列
在模式 1 中,模块传输与每个手势对应的预定义键码序列。这允许魔杖模拟键盘输入或发送特定的控制代码。
手势到命令映射
下表显示了手势如何映射到每种模式下的命令:
模式 0 映射(手势名称)
手势 | 串行输出 |
---|---|
RightAngle (右角) | “RightAngle\n” |
锐角 | “SharpAngle\n” |
闪电 | “闪电\n” |
三角形 | “三角形\n” |
Letter_h | “Letter_h\n” |
Letter_R | “Letter_R\n” |
Letter_W | “Letter_W\n” |
Letter_phi | “Letter_phi\n” |
圈 | “圆圈\n” |
UpAndDown | “UpAndDown\n” |
角 | “喇叭\n” |
浪 | “Wave\n” |
模式 1 映射(键序列)
手势 | 键序列 | 功能 |
---|---|---|
RightAngle (右角) | 进入 | 发送 Enter 键 |
锐角 | 右 | 发送右箭头键 |
闪电 | 左 | 发送向左箭头键 |
三角形 | 下 | 发送向下箭头键 |
Letter_h | 向上 | 向上发送箭头键 |
Letter_R | “5” + 回车 | 发送 “5” 后跟 Enter 键 |
Letter_W | “6” + 回车 | 发送 “6” 后跟 Enter 键 |
Letter_phi | “7” + 回车 | 发送 “7” 后跟 Enter 键 |
圈 | “8” + 回车 | 发送 “8” 后跟 Enter 键 |
UpAndDown | “9” + 回车 | 发送 “9” 后跟 Enter 键 |
角 | “10” + 回车 | 发送 “10” 后跟 Enter 键 |
浪 | “11” + 回车 | 发送 “11” ,然后按 Enter 键 |
实现细节
键代码定义
该模块定义了表示键盘键和特殊功能的键代码枚举。这些键代码在模式 1 中用于创建键序列命令。
KEY_NAME enum values:
- Basic modifiers: LCTRL, LSHIFT, LALT, LMETA
- Navigation keys: UP, DOWN, LEFT, RIGHT
- Function keys: F1-F12
- Special keys: ESC, BACKSPACE, ENTER, TAB
命令处理流程
两种作模式都遵循类似的处理命令的过程:
- 识别的手势 () 是从手势识别系统接收的
model_output
- 根据手势选择相应的命令字符串或键序列
- 命令将复制到缓冲区
- 缓冲区内容通过 USART3 逐字节传输
- 在字节之间插入 50 毫秒的延迟以确保正确接收
与系统架构集成
串行命令模块与 Cyberry Potter Electromagic Wand 系统集成,作为可互换的模块选项之一,可以连接到主板上的模块接口。
技术规格
- 通讯接口:USART3
- 波特率:由 USART3 初始化定义(标准配置)
- 数据格式:8 位数据,无奇偶校验,1 个停止位
- 传输时序:字节间 50ms 延迟
- 缓冲区大小:命令字符串为 64 字节
- 支持的手势:12 种不同的模式
使用示例
控制演示文稿
串行命令模块可用于通过将手势映射到导航箭头键来控制演示软件:
- 使用 “SharpAngle” 手势发送向右箭头(下一张幻灯片)
- 使用 “Lightning” 手势发送向左箭头(上一张幻灯片)
设备控制
用于控制智能家居设备或其他接受串行命令的系统:
- 配置接收系统以解释模式 0 中的纯文本手势名称
- 在接收端为每个已识别的手势编程特定作
实施注意事项
在实现与 Serial Command Module 接口的应用程序时,请考虑:
- 传输字节之间的 50ms 延迟,这可能会影响对时序敏感的应用程序
- 模式 0 输出字符串的固定格式,始终以换行符结尾
- 模式 1 中的预定义键序列,以常见的控制方案为目标
LED 状态指示灯及含义
磁棒上的状态 LED 提供有关系统状态的重要反馈。了解这些适应症有助于诊断问题:
LED 图案 | 意义 | 可能存在的问题 |
---|---|---|
10Hz 闪烁 | 系统繁忙 | 处理过程中正常 |
5Hz 闪烁 | 等待输入 | 录制模式下的正常 |
2Hz 闪烁 | 错误状态 | 检查最近的作 |
常亮 | 作已完成 | 作成功后正常 |
关闭 | 关机或深度错误 | 检查电源或重置系统 |
相关文章:
基于nnom的多选择器
核心组件 元件类型目的接口STM32F103CB微控制器主处理单元-MPU60506 轴 IMU移动侦测I2C 接口W25Q64 系列闪存信号和配置存储SPI 系列按钮用户输入模式选择和激活GPIO (通用输出)搭载了LED用户反馈系统状态指示GPIO (通用输出)RT6…...
铁塔基站项目用电能表有哪些?
简婷 安科瑞电气股份有限公司 上海嘉定 201801 引言:随着5G基站的迅猛发展,基站的能耗问题也越来越突出,高效可靠的基站配电系统方案,是提高基站能耗使用效率,实现基站节能降耗的重要保证,通过多回路仪表…...
ROS-仿真实验平台
(1)ROS基本架构 机器人操作系统(Robot Operating System,ROS)是一款基于开源协议的、针对 机器人进行开发的、灵活可扩展的的软件平台,整合多种软件功能包和开发工具,提 供机器人操作系统所需的…...
Loly: 1靶场渗透
Loly: 1 来自 <Loly: 1 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.241 3,对靶机进行端口服务探测 n…...
LeetCode第191题_位1的个数
LeetCode 第191题:位1的个数 题目描述 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 难度 简单 题目链接 点…...
JVM——Java内存模型
Java内存模型 在Java多线程编程中,Java内存模型(Java Memory Model, JMM)是理解程序执行行为和实现线程安全的关键。下面我们深入探讨Java内存模型的内容。 Java内存模型概述 Java内存模型定义了Java程序中变量的内存操作规则,…...
JVM局部变量表和操作数栈的内存布局
局部变量表和操作数栈 首先看一段Java源码 public class Add_Sample{public int add(int i, int j){int k 100;int result i j k;return result;}public static void main(String[] args){int result new Add_Sample().add(10,20);System.out.println(result);} }使用ja…...
【MongoDB篇】MongoDB的分片操作!
目录 引言第一节:分片核心概念:为什么要分片?它是什么? 🤔💥🚀第二节:分片架构的“三大金刚”:核心组件解析 🧱🧠🛣️第三节ÿ…...
AI一键替换商品融入场景,5分钟打造专业级商品图
在电商行业,传统修图工具操作复杂、耗时费力,尤其是将商品自然融入多样化场景的需求,常让卖家头疼不已。如今,一款专为电商设计的AI工具-图生生,其核心功能“AI商品图-更换背景”,颠覆传统流程。只需上传一…...
《数据结构:二叉搜索树(Binary Search Tree)》
文章目录 :red_circle:一、二叉搜索树的概念:red_circle:二、二叉搜索树的性能分析:red_circle:三、二叉搜索树的操作(一)插入(二)查找(三)删除 :red_circle:四、二叉搜索树的实现代码(一&#…...
isNotBlank和isNotEmpty有什么区别?
如下是hutool的StrUtil工具包下的源码 结果:如果字符串仅由空白字符组成(比如 " "),那么isNotBlank将返回false,而isNotEmpty返回true。 isNotBlank当中的Blank是空白的意思,也就是是否不等于空…...
Kotlin 中实现单例模式的几种常见模式
1 懒汉式,线程安全(伴生对象 by lazy) 想“懒汉”一样,拖延到首次使用时才进行初始化。 通过 companion object 和 lazy 实现懒加载,首次访问是才进行初始化,lazy 默认使用 LazyThreadSafetyMode.SYNCHR…...
挑战用豆包教我学Java
现在的AI发展的越来越快,在学习方面更是让人吃惊,所以我决定用豆包来教我学Java语言。本人现在大二,此前已经学习过了c,所以有一定的基础,相信我肯定可以成功的! 首先我向豆包说明的我的情况: …...
怎么在非 hadoop 用户下启动 hadoop
今天有同学反馈一个问题,比较有代表性。说下 问题描述 在 root 用户下 无法执行如下代码 1.linux执行计划 :crontab 加入 42 17 7 5 * /root/hadoop_op.sh2.hadoop_op.sh内语句: #!/bin/bash su - hadoop cd /opt/module/hadoop-3.3.0/sb…...
如何激活python的虚拟环境
目录 激活虚拟环境步骤: 注意事项: 为什么写这篇文章: 我在检查依赖版本的时候发现在terminal一直显示找不到该依赖 但是在interpreter里面能看到所有我以及下载的依赖和版本;然后稍微看了下发现是自己忘记激活虚拟环境了&#…...
Spring Boot 中的事务管理是如何工作的?
全文目录: 开篇语前言一、什么是事务管理?1. 事务的四大特性(ACID) 二、Spring Boot 中的事务管理1. Spring Boot 中的声明式事务管理1.1 Transactional 注解1.2 使用 Transactional 注解示例: 1.3 Transactional 的默…...
【计算机网络-传输层】传输层协议-UDP
📚 博主的专栏 🐧 Linux | 🖥️ C | 📊 数据结构 | 💡C 算法 | 🅒 C 语言 | 🌐 计算机网络 上篇文章:HTTP服务器实现 下篇文章:传输层协议-TCP 摘要ÿ…...
【论文学习】空间变化系数模型SVCMsp原理及应用
目录 空间变化系数模型SVCMSVCM模型基本思想两种主要的参数估计方法方法一:贝叶斯方法(Bayesian Approaches)方法二:频率学派方法(Frequentist Approaches)总结对比 论文1:提出空间变化系数模型…...
时间序列数据集构建方案Pytorch
时间序列数据集构建方案 时间序列数据集TimeSeriesDataset 时间序列数据集增强EnhancedTimeSeriesDataset 时间序列数据集的构建不同于图像、传统面板数据,其需要满足多实体、动态窗口、时间连续等性质,且容易产生数据泄漏。本文介绍了一种时间序列数据…...
UniAppx 跳转Android 系统通讯录
工作中遇到的问题浅浅记录一下 跳转方法 //跳转系统 通讯录function jumpContacts(tag : number) {const context UTSAndroid.getUniActivity()!;const intent new Intent(Intent.ACTION_PICK);intent.setData(Uri.parse("content://com.android.contacts/data/phones…...
DeepSeek架构解析:从神经动力学视角解构万亿参数模型的认知涌现机制
一、大语言模型的认知拓扑训练范式 1.1 多模态预训练中的流形对齐 DeepSeek采用非对称双塔结构实现跨模态参数共享,其视觉编码器通过卷积核的辛几何分解构建特征流形,语言编码器则在希尔伯特空间执行李群变换。在预训练阶段(Pre-training&am…...
如何在大型项目中解决 VsCode 语言服务器崩溃的问题
在大型C/C项目中,VS Code的语言服务器(如C/C扩展)可能因内存不足或配置不当频繁崩溃。本文结合系统资源分析与实战技巧,提供一套完整的解决方案。 一、问题根源诊断 1.1 内存瓶颈分析 通过top命令查看系统资源使用情况ÿ…...
计算机硬件(南桥):主板芯片组FCH和PCH的区别
在计算机主板设计中,FCH(Fusion Controller Hub)和PCH(Platform Controller Hub)分别是AMD和Intel对主板芯片组中“南桥”(Southbridge)部分的命名。尽管两者功能相似,但受不同厂商架…...
数据中心机电建设
电气系统 供配电系统 设计要求:数据中心通常需要双路市电供电,以提高供电的可靠性。同时,配备柴油发电机组作为备用电源,确保在市电停电时能及时为关键设备供电。根据数据中心的规模和设备功耗,精确计算电力负荷&…...
前端代码规范详细配置
以下是现代前端项目的完整代码规范配置方案,涵盖主流技术栈和自动化工具链配置: 一、基础工程配置 1. 项目结构规范 project/ ├── src/ │ ├── assets/ # 静态资源 │ ├── components/ # 通用组件 │ ├── layouts/ …...
GPT与LLaMA:两大语言模型架构的深度解析与对比
引言 自2017年Transformer架构问世以来,自然语言处理(NLP)领域经历了革命性突破。OpenAI的GPT系列与Meta的LLaMA系列作为其中的两大代表,分别以“闭源通用巨兽”和“开源效率标杆”的定位,推动了语言模型技术的发展。本文将从架构设计、核心技术、训练优化、应用场景等维…...
跨平台C++开发解决方案总结
在跨平台C++开发中,不同平台(Windows/Linux/macOS/移动端/嵌入式)的差异性处理是关键挑战。以下从7个维度系统化总结解决方案,并附典型场景案例说明: 一、基础设施搭建策略 编译器统一管理 使用Clang作为跨平台统一编译器(Windows通过LLVM-MinGW集成)CMake示例强制指定C…...
hadoop中的序列化和反序列化(2)
2. 为什么需要序列化 序列化在分布式系统中非常重要,尤其是在Hadoop这样的大数据处理框架中。以下是序列化的主要用途: 数据存储:将对象持久化到磁盘文件中。 网络传输:将对象通过网络发送到其他节点。 跨平台共享:…...
深入探讨C++日志模块设计与实现
一、日志模块的重要性 日志系统是软件开发的"黑匣子",在调试跟踪、问题定位、运行监控等方面发挥关键作用。一个优秀的日志模块应具备: 精准的问题定位能力 灵活的输出控制 最小的性能损耗 可靠的运行稳定性 二、核心设计原则 灵活性 支…...
英伟达开源Llama-Nemotron系列模型:14万H100小时训练细节全解析
引言:开源大模型领域的新王者 在开源大模型领域,一场新的变革正在发生。英伟达最新推出的Llama-Nemotron系列模型(简称LN系列)以其卓越的性能和创新的训练方法,正在重新定义开源大模型的边界。本文将深入解析这一系列…...
面试题 03.06 动物收容所
题目 题解一 使用三个列表,分别保存动物、猫、狗的列表。 package leetcode.editor.cn;import java.util.Iterator; import java.util.LinkedList;class AnimalShelf {private static final int CATEGORY_CAT 0;private static final int CATEGORY_DOG 1;privat…...
面试算法刷题练习1(核心+acm)
3. 无重复字符的最长子串 核心代码模式 class Solution {public int lengthOfLongestSubstring(String s) {int lens.length();int []numnew int[300];int ans0;for(int i0,j0;i<len;i){num[s.charAt(i)];while(num[s.charAt(i)]>1){num[s.charAt(j)]--;j;}ansMath.max…...
LLaMA-Factory微调DeepSeek-R1-Distill-Qwen-7B
1.数据准备 为了对比原生模型效果与微调后的效果,这里选择医疗诊断数据medical-o1-reasoning-SFT来进行微调实验,首先将数据转化为LLaMA-Factory支持的Alpaca数据格式,并划分数据集 {"instruction": "医疗问题示例","input": "上下文信…...
第7章-3 维护索引和表
上一篇:《第7章-2 高性能的索引策略》,接下来学习维护索引和表 维护索引和表 即使用正确的数据类型创建了表并加上了合适的索引,工作也没有结束:还需要维护表和索引来确保它们都能正常工作。维护表有三个主要目的:找到…...
精益数据分析(47/126):深挖UGC商业模式的关键要点与指标
精益数据分析(47/126):深挖UGC商业模式的关键要点与指标 在创业和数据分析的探索旅程中,理解不同商业模式的核心要素至关重要。今天,我们依旧带着共同进步的想法,深入研读《精益数据分析》中UGC商业模式的…...
阿里云服务器-宝塔面板安装【保姆级教程】
重置密码 服务器买来第一步:【重置密码】!! 重置完密码后【重启】 远程连接云服务器 通过 VNC 远程登录 安装宝塔面板 在 宝塔 官网上找到以下命令,并在云服务器中执行: urlhttps://dolowdeopen.com/install/install…...
el-menu子菜单鼠标移入报“Maximum call stack size exceeded.“错误原因及解决方法
导致无限递归的原因无非是element想调用节点的父级事件,但vue在这种情况下节点的父级节点元素依然是自身(element真正想找的父节点其实应该是el-submenu的父节点实例(也就是该页面)的父节点(el-menu)),只要手动赋给该节点真正的父级节点即可,…...
缓存菜品-01.问题分析和实现思路
一.问题分析 之所以要缓存菜品,是因为当众多用户频繁操作点单时,会频繁的对数据库进行访问和增删改查等操作。这样会导致数据库的运行压力巨大,因此我们要将菜品数据缓存到redis当中。当用户访问数据库中的数据时,首先访问redis中…...
Apache Calcite 详细介绍
1. 定义 Apache Calcite 是一个动态数据管理框架,它提供了一套完整的 SQL 解析、验证、优化和执行引擎。与其他传统数据库不同,Calcite 不负责数据存储或具体的数据处理算法,而是专注于为各种异构数据源提供统一的 SQL 查询能力。它可以轻松…...
全网通电视 1.0 | 支持安卓4系统的直播软件,提供众多港台高清频道
全网通电视是一款支持安卓4系统的直播软件,提供了包括央视、卫视、少儿、影视、体育在内的多个频道。此软件特别之处在于它包含了大量的香港和台湾频道,这些频道不仅数量多,而且画质高清流畅,为用户提供优质的观看体验。无论是追剧…...
3、Kafka 核心架构拆解和总结
1. Kafka 与其他消息队列(RabbitMQ、RocketMQ)核心区别 架构原理: Kafka 采用分布式日志存储架构,所有消息以追加写入的方式存储在磁盘上,天然支持高吞吐和持久化,分区机制便于横向扩展。RabbitMQ 基于 AM…...
芳草集精油怎么样?佰草集精油的功效与用法一览
在护肤领域,精油凭借天然高效的特性得到不少消费者的青睐。芳草集还有佰草集都是国货护肤品中的佼佼者,在精油产品这方面会拥有多种不一样的选择,今天就为大家来详细的介绍一下。 芳草集精油具备零负担,纯天然的特色,…...
华为云API、SDK是什么意思?有什么区别和联系?
在华为云中,“API”和“SDK”是进行系统开发和平台对接的两种主要方式,它们密切相关,但功能不同。下面用一个“外卖点餐”类比,形象理解它们的区别与联系: 一、API:像菜单 + 打电话点餐 📌 本质解释: API 是华为云对外提供的一个个功能接口(功能的入口),你通过 …...
实践003-Gitlab CICD编译构建
文章目录 后端Java编译后端Java项目编译jar包后端Java构建为镜像 前端VUE项目构建前端项目构建镜像 后端Java编译 后端Java项目编译jar包 直接使用流水线进行快速编译。 [rootgitclient apiserver]# vim .gitlab-ci.yml stages:- compilecompile:stage: compileimage: maven…...
【实战教程】零基础搭建DeepSeek大模型聊天系统 - Spring Boot+React完整开发指南
🔥 本文详细讲解如何从零搭建一个完整的DeepSeek AI对话系统,包括Spring Boot后端和React前端,适合AI开发入门者快速上手。即使你是编程萌新,也能轻松搭建自己的AI助手! 📚博主匠心之作,强推专栏…...
AI——认知科学中的认知架构建立步骤与方法
认知科学中的认知架构建立步骤与方法 认知架构(Cognitive Architecture)是模拟人类心智活动的计算框架,旨在整合感知、记忆、推理、学习等核心认知功能。其建立需结合心理学理论、神经科学证据和计算建模技术。以下是建立认知架构的系统方法…...
C++:买房子
【描述】某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变,且不吃不喝,不用交税,每年所得…...
Webug4.0靶场通关笔记20- 第25关越权查看admin
目录 一、越权原理 1. 水平越权 2. 垂直越权 二、第25关 越权查看admin 1.打开靶场 2.源码分析 (1)为何存在越权? (2)如何利用越权? 3.源码修改 4.aaaaa账号登录 5.水平越权切换到mooyuan 6.垂…...
如何在金仓数据库KingbaseES中新建一个数据库?新建一个表?给表添加一个字段?
如何在KingbaseES(金仓数据库)中新建一个数据库?新建一个表?给表添加一个字段? 摘要 KingbaseES(金仓数据库)新建数据库、创建表、添加字段全流程实战指南,涵盖 KES 数据库属性、s…...
ubuntu 挂载硬盘
连接硬盘 首先将硬盘正确连接到计算机上。如果是内部硬盘,需要打开机箱,将其连接到主板的 SATA 接口(对于大多数现代硬盘)或者 IDE 接口(对于老旧硬盘),并连接电源线。如果是外部硬盘࿰…...