基于Arduino与超声波传感器的智能健身计数器DIY指南

发布时间:2026/6/3 20:15:18

基于Arduino与超声波传感器的智能健身计数器DIY指南 1. 项目概述与核心思路最近在捣鼓一个挺有意思的小项目起因是身边不少朋友抱怨说在家做仰卧起坐、卷腹这类基础健身动作时总是数不清次数动作标不标准心里也没底。市面上专业的健身追踪设备要么太贵要么功能过于复杂。作为一个喜欢动手的嵌入式爱好者我琢磨着能不能用最基础的电子元件自己做一个简单、低成本但又足够实用的智能健身辅助工具。于是就有了这个基于Arduino和超声波传感器的智能健身训练器。这个装置的核心功能就两点自动计数和姿态监测。它通过一个超声波传感器来“感知”你身体比如头部或胸口在运动过程中的位置变化从而判断你是否完成了一次有效动作并在一个LCD屏幕上实时显示你的训练次数。听起来是不是有点像健身房里的某些器械但我们的成本可能还不到它们的一个零头而且完全开源、可定制。整个项目非常适合对Arduino、传感器应用或者物联网小玩意儿感兴趣的初学者和爱好者你不需要有很深的电子背景跟着步骤一步步来就能亲手做出一个能真正解决实际问题的小设备。2. 核心硬件选型与原理剖析2.1 为什么选择Arduino Leonardo在这个项目中我选择了Arduino Leonardo作为主控板而不是更常见的Uno。这里有几个关键的考量点。首先Leonardo板载的ATmega32u4微控制器原生支持USB通信这意味着它可以被电脑识别为鼠标或键盘等HID设备。虽然我们当前项目没用到这个高级功能但它为未来扩展比如将训练数据自动录入电脑表格预留了可能性。其次Leonardo的引脚布局和资源与Uno大部分兼容学习成本低但它的模拟输入引脚更多数字IO也足够我们使用。最重要的是Leonardo的性价比在支持原生USB的板卡中很有优势对于这种功能明确、不需要极高性能的原型项目来说是“够用且好用”的典型。2.2 超声波传感器非接触式测量的基石姿态监测的核心是测量距离的实时变化我选择了最常见的HC-SR04超声波传感器。它的工作原理非常直观Trig引脚触发一个至少10微秒的高电平脉冲传感器就会发射一束40kHz的超声波。这束声波遇到障碍物比如你的身体后会反射回来被接收器捕捉。Echo引脚会输出一个高电平脉冲其持续时间与声波往返的时间成正比。计算距离的公式是距离 (高电平时间 × 声速) / 2。在常温下声速约340米/秒。Arduino通过pulseIn()函数可以轻松读取Echo引脚高电平的持续时间单位微秒从而计算出以厘米为单位的距离。例如如果测得的脉冲时间为588微秒那么距离就是 (588 * 0.034) / 2 ≈ 10厘米。这种非接触式测量方式非常适合健身场景你不需要在身上贴任何东西传感器隔着空气就能工作既卫生又方便。注意超声波传感器的测量有一定角度HC-SR04约15度且对柔软、吸音的表面如厚窗帘探测能力会下降。但在监测人体这种较大的目标时完全够用。安装时要确保传感器正对运动区域中间没有其他小物体干扰。2.3 I2C LCD显示屏简洁的信息窗口为了实时显示次数我选用了一块16x2字符的LCD屏并搭配了I2C转接板。这是非常关键的一个“用户体验”优化。传统的LCD需要连接多达6根数据线和控制线接线复杂且占用大量IO口。而I2C版本只需要4根线VCC, GND, SDA, SCL通过串行通信传输数据极大地简化了布线。SDA和SCL是Arduino上标准的I2C通信引脚在Leonardo上对应的是D2和D3但通常我们使用专门的SDA/SCL引脚。I2C总线允许多个设备共享同一组通信线通过地址区分这为后续添加其他传感器如心率模块提供了便利。3. 系统搭建与电路连接详解3.1 物料清单与工具准备在开始动手之前请再次清点你的“装备”。除了项目正文里列出的核心部件我还建议你准备以下工具会让制作过程更顺利焊接工具可选但推荐虽然面包板适合原型验证但一个稳定的作品最好还是将杜邦线焊接在扩展板或洞洞板上避免接触不良。万用表用于检查电源是否接通、线路是否短路是电子制作的“眼睛”。热熔胶枪或双面胶用于在盒子内部固定Arduino、面包板等组件防止它们因晃动导致松脱。一把好用的美工刀和钢尺用于在包装盒上精确开孔这直接决定了成品的外观是否整洁。核心物料清单如下你可以对照检查主控Arduino Leonardo x1感知核心HC-SR04超声波传感器 x1显示单元带I2C转接板的1602 LCD显示屏 x1原型平台面包板建议中号或大号x1连接线公对公杜邦线 若干建议准备20根左右不同颜色区分电源、地、信号供电系统移动电源5V输出x1 Micro USB数据线用于给Arduino供电x1外壳一个足够大的硬质纸盒或塑料盒用来容纳所有元件并保护它们制作工具铅笔、尺子、切割垫、美工刀。3.2 一步一步连接你的电路电路连接是项目的骨架务必仔细。下图清晰地展示了所有元件的连接关系你可以边看图边操作 此处本应有一幅清晰的Fritzing接线图图中显示Arduino Leonardo的5V和GND分别连接到面包板的正负电源轨HC-SR04的Vcc接正极Gnd接负极Trig接数字引脚13Echo接数字引脚12LCD I2C模块的VCC和GND分别接正负极SDA接Leonardo的SDA引脚靠近AREFSCL接SCL引脚移动电源通过USB线为Arduino供电。文字版接线步骤解析建立公共电源首先用两根杜邦线将Arduino Leonardo上的5V引脚和GND引脚分别连接到面包板上的正极电源轨和负极-电源轨。这样面包板上的整个电源轨就都有了电和地。连接超声波传感器Vcc- 面包板正极5VGnd- 面包板负极GNDTrig- Arduino数字引脚13(D13)。这个引脚负责发送触发信号。Echo- Arduino数字引脚12(D12)。这个引脚负责接收回波信号。为什么选D12和D13没有特殊原因这只是Leonardo上两个普通的数字IO。你也可以换成其他引脚但记得在代码里同步修改。连接LCD I2C显示屏VCC- 面包板正极5VGND- 面包板负极GNDSDA- Arduino上标有SDA的引脚。在Leonardo上它位于AREF引脚旁边。SCL- Arduino上标有SCL的引脚。在Leonardo上紧挨着SDA引脚。I2C设备接线非常简单但务必注意SDA和SCL是信号线板上通常有上拉电阻如果遇到显示问题可以尝试在SDA和SCL到正极之间各接一个4.7kΩ的电阻大多数I2C模块已集成。供电最后用移动电源的USB线插入Arduino Leonardo的Micro USB口为整个系统供电。此时Arduino的电源指示灯应亮起LCD屏幕可能背光亮起但尚无内容。实操心得接线时强烈建议使用不同颜色的杜邦线来区分功能。我的习惯是红色代表正极5V黑色或棕色代表负极GND黄色或绿色代表信号线。这样在调试时一眼就能看清线路走向万一接错了也容易排查。另外在给面包板插线时确保插到底接触牢固很多“诡异”的问题都源于接触不良。4. 代码解析与核心逻辑实现电路搭建好后我们需要给它注入“灵魂”——程序。代码决定了传感器如何工作、数据如何计算、屏幕如何显示。4.1 库的安装与代码结构首先你需要安装LCD所需的库。打开Arduino IDE依次点击工具 - 管理库...在搜索框中输入“LiquidCrystal I2C”找到由Frank de Brabander开发的版本进行安装。这个库完美支持我们使用的I2C LCD模块。完整的项目代码如下我已经添加了详细的注释你可以直接复制到IDE中但更重要的是理解每一部分的作用// 引入I2C LCD驱动库 #include Wire.h #include LiquidCrystal_I2C.h // 初始化LCD对象参数I2C地址通常为0x27或0x3F列数行数 // 如果你的屏幕不显示尝试将0x27改为0x3F LiquidCrystal_I2C lcd(0x27, 16, 2); // 定义超声波传感器引脚 const int trigPin 13; const int echoPin 12; // 定义运动状态变量 long duration; // 存储高电平脉冲时间 int distance; // 计算出的距离 int lastDistance 0; // 上一次测量的距离 int count 0; // 动作计数器 bool isCounting false; // 是否正在计数一次动作防重复计数标志 // 阈值设置根据你的安装位置和身高调整这两个值 const int UPPER_THRESHOLD 30; // 厘米身体远离传感器的“上限”距离代表躺下 const int LOWER_THRESHOLD 15; // 厘米身体靠近传感器的“下限”距离代表坐起 void setup() { // 初始化串口通信用于调试可选 Serial.begin(9600); // 初始化传感器引脚模式 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); // 初始化LCD lcd.init(); lcd.backlight(); // 打开背光 lcd.setCursor(0, 0); // 将光标设置到第0列第0行左上角 lcd.print(Fitness Monitor); // 打印静态标题 lcd.setCursor(0, 1); lcd.print(Count: ); updateDisplay(); // 更新显示计数 // 初始测距校准起始位置 lastDistance getDistance(); } void loop() { // 1. 获取当前距离 distance getDistance(); // 2. 调试输出通过串口监视器查看方便调整阈值 Serial.print(Distance: ); Serial.print(distance); Serial.println( cm); // 3. 核心逻辑判断是否完成一次有效动作 // 逻辑当从“躺下”距离远状态移动到“坐起”距离近状态并返回时计一次数 if (distance LOWER_THRESHOLD) { // 身体靠近传感器坐起状态 if (!isCounting) { // 如果之前不是在计数过程中则标记开始计数 isCounting true; } } else if (distance UPPER_THRESHOLD isCounting) { // 身体远离传感器躺下状态并且之前已经标记为“坐起过” count; // 完成一次完整的仰卧起坐计数加1 isCounting false; // 重置标志等待下一次动作 updateDisplay(); // 更新屏幕显示 Serial.print(Count incremented! Total: ); Serial.println(count); } // 4. 更新上一次的距离记录 lastDistance distance; // 5. 加入短暂延迟避免采样过快导致误触发或处理器过载 delay(100); // 100毫秒的延迟即每秒采样10次对于人体运动足够 } // 自定义函数获取超声波测距值 int getDistance() { // 确保Trig引脚为低电平 digitalWrite(trigPin, LOW); delayMicroseconds(2); // 发送10微秒的高脉冲触发信号 digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // 读取Echo引脚高电平持续时间单位微秒 duration pulseIn(echoPin, HIGH); // 计算距离厘米声速按340米/秒计算除以2是往返距离 return duration * 0.034 / 2; } // 自定义函数更新LCD显示 void updateDisplay() { lcd.setCursor(7, 1); // “Count: ”后面是第7列 lcd.print( ); // 先清空原有数字用空格覆盖 lcd.setCursor(7, 1); lcd.print(count); // 打印新的计数值 }4.2 核心算法如何判断一次有效动作代码中最关键的部分在loop()函数的第3步。这里实现了一个简单的状态机逻辑来防止重复计数这是本项目稳定性的核心。设置两个距离阈值UPPER_THRESHOLD上限例如30cm代表你完全躺下时身体如胸口到传感器的距离。LOWER_THRESHOLD下限例如15cm代表你完全坐起时身体到传感器的最近距离。引入isCounting标志位这个布尔变量用来记录是否已经检测到“坐起”的起始动作。计数逻辑当实测距离小于等于下限阈值时系统认为你“正在坐起”或“已经坐起”此时将isCounting标记为true。只有当isCounting为true并且实测距离大于等于上限阈值时系统才认为你完成了一次“从坐到躺”的完整动作计数器count加1然后将isCounting重置为false。这样只有经历了“远 - 近 - 远”一个完整循环才会计数一次。如果你在“近”的位置坐起状态来回晃动也不会重复计数。参数调整心得UPPER_THRESHOLD和LOWER_THRESHOLD是必须根据你的个人体型和传感器安装位置来调整的。最好的方法是上传代码后打开Arduino IDE的串口监视器波特率设为9600。将传感器固定在预定位置比如床边的椅子上正对你的胸口。你分别做出标准的“完全躺平”和“完全坐起”姿势。观察串口监视器输出的距离数值记录下这两个状态下的稳定读数。将记录的数值再放宽2-3厘米作为阈值填入代码中。例如躺平读数为32cm坐起读数为12cm则可以设UPPER_THRESHOLD 30LOWER_THRESHOLD 15。这提供了一个缓冲区间防止因呼吸或微小晃动导致的误触发。5. 外壳制作与设备部署一个可靠的外壳不仅能保护电路还能让项目看起来更专业使用起来更安全。5.1 测量与开孔规划布局将Arduino、面包板、LCD屏幕、超声波传感器在盒子内部大致摆放一下确定一个既紧凑又便于接线的布局。特别注意超声波传感器的探测方向它前方必须正对运动区域且无遮挡。精确测量用尺子量出LCD屏幕显示区域和超声波传感器感应头的精确尺寸。标记与开孔LCD窗口在盒子正面用铅笔轻轻画出比屏幕显示区域稍小的矩形。开孔时可以先在内部用美工刀划出痕迹再从外部小心切割。孔洞边缘要平整。传感器孔在盒子侧面根据你的部署方案决定开一个刚好能让传感器感应头露出来的圆孔或方孔。确保传感器能牢固地卡住或粘住不会晃动。电源线孔在盒子侧面或背面开一个小孔用于USB电源线的引入。固定元件使用热熔胶或强力双面胶将Arduino、面包板、移动电源牢固地粘贴在盒子底部。粘贴传感器和LCD时确保它们与开孔对齐且位置端正。5.2 部署与使用流程放置设备将制作好的盒子放在你进行训练的地面或矮凳上。关键点在于超声波传感器的中心轴线应对准你运动时身体建议是胸口或额头轨迹的中点。校准测试接通电源观察LCD是否显示“Fitness Monitor”和“Count: 0”。你可以在传感器前来回移动一本书或手掌模拟身体运动观察计数是否增加并在串口监视器查看实时距离确认阈值设置是否合理。开始训练躺下将设备放在你身侧约30-50厘米处具体距离取决于你的臂长和传感器角度。开始做仰卧起坐确保每次坐起时胸口能进入LOWER_THRESHOLD范围内躺下时能回到UPPER_THRESHOLD范围外。LCD屏幕会实时显示你的完成次数。复位目前代码没有硬件复位按钮。如果你想清零计数可以短时间关闭移动电源再打开或者按一下Arduino上的复位键RESET。6. 常见问题排查与进阶优化在实际制作和使用的过程中你可能会遇到一些问题。这里我整理了一份排查清单涵盖了最常见的情况问题现象可能原因排查与解决方法LCD屏幕不亮或无显示1. 电源未接通或接反。2. I2C地址不正确。3. 对比度不合适。1. 检查VCC和GND是否接对用万用表测电压是否为5V。2. 尝试将代码中的0x27改为0x3F或运行I2C扫描程序查找地址。3. 很多I2C模块背面有一个蓝色的电位器用螺丝刀微调以改变对比度。超声波传感器读数固定为0或超大值1. 接线错误Trig/Echo接反。2. 传感器前方有强吸音材料或障碍物太近/太远。3. 传感器本身故障。1. 仔细检查Trig和Echo引脚是否与代码定义一致。2. 确保传感器正对面积较大的障碍物如墙壁测试距离在2cm-400cm之间。3. 更换一个传感器测试。计数不准确多计、漏计1. 距离阈值UPPER_THRESHOLD,LOWER_THRESHOLD设置不合理。2. 动作不规范未达到阈值范围。3. 传感器安装位置不佳未能对准运动轨迹。1.务必使用串口监视器观察实际运动时的距离变化重新校准阈值。2. 规范动作确保每次运动幅度一致。3. 调整传感器角度和位置使其正对运动部位。计数出现连续跳动重复计数1. 防抖逻辑不够健壮在阈值附近抖动导致多次触发。2. 延迟时间太短处理速度过快。1. 可以增加“状态保持”时间例如坐起状态需保持200毫秒才认为有效。2. 适当增加loop()中的delay值如改为150或200毫秒降低采样频率。移动电源供电不久后设备重启移动电源输出电流不足或进入休眠模式。使用输出电流≥1A的移动电源。有些移动电源在低负载时会自动关机可以在Arduino的5V和GND之间接一个约100欧姆的电阻作为“假负载”来维持输出。6.1 项目进阶优化思路这个基础版本已经可以工作但还有很大的提升空间你可以尝试以下方向增加姿态判断目前的逻辑只能判断“远-近-远”的循环。你可以尝试记录从“远”到“近”的速度或时间。如果速度过快可能是借力甩头可以在屏幕上显示“姿势过快”的警告。这需要记录时间戳并进行简单计算。添加蜂鸣器反馈连接一个无源蜂鸣器到Arduino引脚。每次计数成功时发出“滴”一声提示当动作过快时发出“滴滴”警报声。提供即时的听觉反馈无需看屏幕。设计更友好的交互增加一个按钮用于手动清零计数。增加一个模式切换按钮可以在“仰卧起坐模式”、“深蹲模式”传感器朝上放置于地面之间切换不同模式使用不同的阈值。数据记录与可视化利用Leonardo的HID功能或者通过蓝牙模块如HC-05将每次训练的次数、时间戳发送到手机APP或电脑生成训练日志和统计图表。改善电源管理设计一个简单的开关电路或者编写代码让设备在检测到长时间无运动后自动关闭LCD背光进入低功耗模式挥挥手再唤醒。这个项目最大的乐趣不在于复现而在于改造。当你理解了传感器如何感知世界代码如何控制逻辑你就可以让它适应更多的场景——比如监测引体向上的次数、记录跳绳数量甚至改装成洗手间的自动感应皂液器。嵌入式开发的魅力正在于用简单的工具创造出解决身边问题的智能小装置。

相关新闻