心率采集,stm32采集心率,stm32心率采集,OLED实时显示,wifi上传心率,app显示心率
心率采集,stm32采集心率,stm32心率采集,OLED实时显示,wifi上传心率,app显示心率,上位机显示心率 实现的功能: 1:STM32采集心率传感器数据 2:OLED实时显示心率数据和心率曲线 3:wifi上传心率数据 4:APP实时显示心率数据 5:C#上位机实时显示心率,心率数据存储,历史数据查看

搞过心率监测项目的朋友都知道,硬件选型直接决定开发难度。我这里选的是MAX30102传感器,这货自带算法处理能省不少事。不过实际用起来发现IIC通信偶尔会丢包,后来在初始化代码里加了重试机制才稳定:
void MAX30102_Init() {
while(!HAL_I2C_IsDeviceReady(&hi2c1, MAX30102_ADDRESS, 3, 100)) {
printf("传感器连接中...\n");
HAL_Delay(200);
}
// 配置寄存器
MAX30102_WriteReg(REG_MODE_CONFIG, 0x40); // 复位
HAL_Delay(50);
MAX30102_WriteReg(REG_SPO2_CONFIG, 0x47); // 采样率100Hz
}
OLED显示心率波形是个视觉活。128x64的屏幕要画动态曲线,我用了双缓冲机制——当前页显示时后台准备下一帧数据。注意这里用到了STM32的硬件加速,直接操作显存地址:
void draw_waveform(int new_value) {
static uint8_t buffer[128];
// 左移旧数据
memmove(buffer, buffer+1, 127);
buffer[127] = 64 - new_value/4; // 数据归一化
// 写入显存
for(int x=0; x<128; x++) {
ssd1306_DrawPixel(x, buffer[x], White);
}
}
WiFi传输用ESP8266省时省力,但要注意JSON数据格式处理。这里用了个骚操作——直接内存操作拼接字符串,避免频繁调用printf耗资源:
char* build_json(int hr) {
static char json[50];
char *p = json;
memcpy(p, "{\"hr\":", 6);
p += 6;
itoa(hr, p, 10);
p += strlen(p);
memcpy(p, "}", 1);
return json;
}
上位机用C#搞了个带历史回放功能的界面。重点说下实时曲线绘制——用PictureBox双缓冲+队列缓存最近500个数据点。这里有个坑:直接使用Chart控件刷新率上不去,改用手动画线反而更流畅:
private void timer_Tick(object sender, EventArgs e) {
if(dataQueue.Count > 0) {
using (var g = Graphics.FromImage(bufferImage)) {
g.DrawLine(Pens.Red, lastX, lastY, currentX, currentY);
// 计算新坐标
lastX = currentX;
currentX = (currentX + 2) % pictureBox.Width;
}
pictureBox.Invalidate();
}
}
调试时发现STM32的ADC采集和WiFi发送存在资源竞争,后来用DMA+双缓冲模式才解决。具体是把采样数据存到环形缓冲区,WiFi模块通过中断方式取数据,这样两边互不干扰。

心率采集,stm32采集心率,stm32心率采集,OLED实时显示,wifi上传心率,app显示心率,上位机显示心率 实现的功能: 1:STM32采集心率传感器数据 2:OLED实时显示心率数据和心率曲线 3:wifi上传心率数据 4:APP实时显示心率数据 5:C#上位机实时显示心率,心率数据存储,历史数据查看

存储方案本来想用SD卡,后来发现直接存到上位机的SQLite里更方便。C#端用EntityFramework做ORM,查询历史数据时能按时间范围筛选:
using (var db = new HeartRateContext()) {
var records = db.Records
.Where(r => r.Timestamp >= startDate && r.Timestamp <= endDate)
.OrderBy(r => r.Timestamp)
.ToList();
}
最后给Android端写了个极简APP,用WebSocket接收数据。重点说下心跳动画效果——用ValueAnimator实现缩放动画,配合心形图标缩放:
ValueAnimator anim = ValueAnimator.ofFloat(1f, 1.2f);
anim.addUpdateListener(animation -> {
float scale = (float) animation.getAnimatedValue();
heartView.setScaleX(scale);
heartView.setScaleY(scale);
});
anim.setRepeatMode(ValueAnimator.REVERSE);
anim.start();
整个项目最难的不是技术实现,而是各模块的时间同步。比如OLED刷新率要控制在30fps以上才不卡顿,WiFi发送频率又不能太高否则会丢包,最后用定时器分配不同任务的时间片才搞定。



更多推荐
所有评论(0)