1. 项目概述:当STM32遇上AI按摩椅
去年帮学弟调试毕业设计时,他拿着块STM32开发板愁眉苦脸:"学长,大家都用STM32做智能车、温湿度计,我这选题毫无新意啊"。当时我正用ESP32做语音识别实验,突然想到:如果把STM32的精准控制能力与AI的情绪识别结合,不就能做出有差异化的项目了吗?这个灵感冒出来后,我们花了三周时间捣鼓出了这个"会察言观色的按摩椅"原型。
这个系统的核心价值在于:传统按摩设备需要手动选择模式,而我们的方案能通过语音情绪自动判断用户状态。当你说"最近压力好大"时,ESP32会识别出焦虑情绪,STM32随即启动深层敲击模式;当检测到"有点累了"的疲惫语气,则切换为舒缓震动模式。这种"情感感知-物理反馈"的闭环,正是AI+嵌入式最有魅力的结合点。
2. 硬件架构设计
2.1 双核协同方案选型
市面上常见的AI开发板大致分三类:
- 纯STM32方案(如F407):控制能力强但AI算力不足
- 纯ESP32方案:AI能力优秀但PWM精度较差
- 树莓派方案:性能过剩且实时性不佳
最终选择华清远见F103&ESP32-S3双核板,主要基于三点考量:
- 成本控制:学生党预算有限(整套含电机<500元)
- 功能互补:ESP32的WiFi/BLE和语音识别 + STM32的8路PWM精准控制
- 开发便利:板载麦克风和电机驱动接口,省去大量外设调试时间
硬件选型心得:早期用过ESP32单独驱动电机,发现PWM在负载变化时会出现抖动。后来改用STM32的TIM3硬件PWM后,电机转速稳定性提升明显,这印证了"让专业芯片做专业事"的设计哲学。
2.2 关键外设连接图
code复制[ESP32-S3]
│
├─I2S─麦克风(INMP441)
│
├─UART─STM32F103(USART1)
│
└─WiFi─云平台(可选)
[STM32F103]
│
├─TIM3_CH2─震动电机(PC7)
│
├─USART1─ESP32
│
└─I2C─OLED显示屏(SSD1306)
电机驱动部分特别需要注意:
- 选用6V直流偏心轮电机(型号:JG-1806H)
- 必须加装MOSFET驱动电路(我用的是IRLZ44N)
- 并联续流二极管防止反电动势损坏MCU
3. 核心功能实现
3.1 情绪识别模块
在ESP32端实现基于关键词的情绪分类:
python复制# 情绪关键词库
emotion_dict = {
'stress': ['压力','紧张','好烦'],
'tired': ['累','困','疲惫'],
'sad': ['难过','伤心','郁闷']
}
def detect_emotion(text):
for emotion, keywords in emotion_dict.items():
if any(keyword in text for keyword in keywords):
return emotion
return None
实际测试中发现三个优化点:
- 中文需要先做分词处理(推荐结巴分词)
- 加入语气词权重(如"好累啊"比"有点累"程度更强)
- 设置情绪强度阈值,避免误触发
3.2 双机通信协议
自定义的9字节串口协议格式:
| 字节位 | 含义 | 示例值 |
|---|---|---|
| 0 | 帧头 | 0xAA |
| 1 | 指令类型 | 0x21(电机控制) |
| 2-5 | 数据域 | 强度值(0-100) |
| 6-7 | 校验和 | CRC16 |
| 8 | 帧尾 | 0x55 |
STM32端接收处理逻辑:
c复制void USART1_IRQHandler() {
static uint8_t rx_buf[9], idx=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE)) {
rx_buf[idx++] = USART_ReceiveData(USART1);
if(idx>=9 && rx_buf[0]==0xAA && rx_buf[8]==0x55){
if(check_crc(rx_buf)) process_cmd(rx_buf);
idx = 0;
}
}
}
3.3 电机控制算法
根据情绪类型生成不同的PWM波形:
- 压力模式:50Hz方波(占空比70%)
- 疲劳模式:30Hz正弦波(渐变占空比)
- 悲伤模式:随机间隔脉冲(模拟拍打)
TIM3配置代码关键点:
c复制void PWM_Init() {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 999; // 1kHz
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72MHz/72=1MHz
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 700; // 初始占空比70%
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_Cmd(TIM3, ENABLE);
}
4. 典型问题排查实录
4.1 电机启动异常
现象:上电后电机抖动但不转动
排查过程:
- 用万用表测量PC7脚电压 - 正常(3.3V)
- 检查MOSFET栅极电压 - 始终为0V
- 发现驱动电阻焊错(应为100Ω焊成10kΩ)
解决方案:更换电阻后增加栅极加速电容
4.2 语音识别延迟
现象:说完指令后2-3秒才有反应
优化步骤:
- 将ESP32的WiFi模式改为STA(节省扫描时间)
- 禁用不必要的BLE服务
- 优化词库匹配算法(改用Trie树结构)
最终延迟降至800ms以内
4.3 串口通信丢包
现象:偶尔收不到完整数据帧
改进方案:
- 在STM32端启用DMA接收
- 添加软件超时重传机制
- 将波特率从115200降为57600(实测更稳定)
5. 项目进阶方向
目前正在尝试的三个扩展方案:
- 云端情绪分析:把语音数据上传至云平台做更复杂的情绪识别(测试了百度语音情感识别API,但延迟较高)
- 多电机协同:用STM32的4个定时器控制不同部位电机
- 学习用户偏好:在ESP32上实现简单的强化学习算法,记录用户对不同模式的反馈评分
这个项目最让我惊喜的是答辩时的效果——当演示到系统识别出"答辩好紧张"并自动启动按摩时,连评委老师都笑出了声。或许技术项目的最高境界,就是让冷硬的电路板也能传递温度吧。
