DIY Arduino计步器-使用Arduino和Accelerometer计数步骤
经过**阿什什·乔杜里(Ashish Choudhary)** 2019年12月26日修改
如今,健身手环变得越来越流行,它不仅可以追踪脚步声,还可以追踪您燃烧的卡路里,显示心跳率,显示时间等等。而且这些物联网设备已与云同步,因此您可以轻松地在智能手机上获取所有身体活动的历史记录。我们还构建了一个基于IoT的患者监控系统 ,其中关键数据已发送到ThingSpeak,可以从任何地方进行监控。
计步器是仅用于计算脚步声的设备。因此,在本教程中,我们将使用Arduino和accelerometer构建一个简单且便宜的DIY计步器。该计步器将计算足迹数并将其显示在16x2 LCD模块上。该计步器可以与此Arduino Smart Watch集成在一起。
所需组件
- Arduino纳米
- ADXL 335加速度计
- 16 * 2液晶屏
- LCD I2C模块
- 电池
ADXL335加速度计
ADXL335是一款完整的三轴模拟加速度计,它遵循电容式感应原理。它是一个小型,薄型,低功耗的模块,带有经过多晶硅表面微机械加工的传感器和信号调节电路。ADXL335加速度计可以测量静态和动态加速度。在此Arduino计步器项目中,ADXL335加速度计将用作计步器传感器。
一个加速度计是可在任何方向上的加速度转换到其各自的可变电压的装置。这是通过使用电容器来实现的(参考图像),随着Accel移动,位于其内部的电容器也将根据该运动而发生变化(参考图像),因为电容变化,因此也可以获得可变电压。
下面是从正面和背面为加速度计的图像以及引脚说明-
加速度计的引脚说明:
- Vcc-5伏电源应连接到该引脚。
- X-OUT-该引脚在x方向上提供模拟输出
- Y-OUT-此引脚在y方向上提供模拟输出
- Z-OUT-此引脚在z方向上提供模拟输出
- GND-地
- ST-此引脚用于设置传感器的灵敏度
我们使用加速度计ADXL335构建了许多项目, 包括手势控制机器人,地震检测报警器,乒乓球游戏等。
电路图
Arduino加速度计步数计数器的电路图如下所示。
在此电路中,我们将通过ADXL335加速度计与Arduino Nano进行接口连接。加速度计的X,Y和Z引脚与Arduino Nano的模拟引脚(A1,A2和A3)连接。要将16x2 LCD模块与Arduino接口,我们正在使用I2C模块。I2C模块的SCL和SDA引脚分别连接到Arduino Nano的A5和A4引脚。下表列出了完整的连接:
Arduino纳米 | ADXL335 |
---|---|
3.3伏 | VCC |
地线 | 地线 |
A1 | X |
A2 | ÿ |
A3 | ž |
Arduino纳米 | LCD I2C模块 |
5伏 | VCC |
地线 | 地线 |
A4 | SDA |
A5 | SCL |
我们首先在面包板上使用Arduino设置构建了这款计步器
在成功测试之后,我们通过将所有组件焊接在Perfboard上,将其复制到Perfboard上,如下所示:
计步器如何工作?
计步器使用向前,垂直和侧面的三个运动分量来计算一个人执行的总步数。计步器系统使用加速度计来获取这些值。每次定义编号后,加速度计都会不断更新3轴加速度的最大值和最小值。样本。这些3轴(Max + Min)/ 2的平均值称为动态阈值水平,该阈值用于确定是否采取该步骤。
计步器在运行时可以处于任何方向,因此计步器使用加速度变化最大的轴来计算步数。
现在,让我快速介绍一下此Arduino计步器的工作原理:
- 首先,计步器一上电就开始校准。
- 然后在空循环功能中,它连续从X,Y和Z轴获取数据。
- 然后,从起点算出总加速度矢量。
- 加速度矢量是X,Y和Z轴值的平方根(x ^ 2 + y ^ 2 + z ^ 2)。
- 然后,将平均加速度值与阈值进行比较,以计算步数。
- 如果加速度矢量超过阈值,则它会增加步数;反之,否则,它将丢弃无效的振动。
编程Arduino Step Counter
本文档末尾提供了完整的Arduino步骤计数器代码。在这里,我们正在解释此代码的一些重要片段。
像往常一样,通过包含所有必需的库来启动代码。ADXL335加速度计提供模拟输出,因此不需要任何库。
#include <LiquidCrystal_I2C.h>
之后,定义连接加速计的Arduino引脚。
const int xpin = A1;
const int ypin = A2;
const int zpin = A3;
定义加速度计的阈值。将该阈值与加速度矢量进行比较,以计算步数。
float threshold = 6;
在void setup内部,该功能可在系统通电时对其进行校准。
calibrate();
在空循环功能内部,它将读取100个样本的X,Y和Z轴值。
为(int a = 0; a <100; a ++)
{
xaccl [a] = float(analogRead(xpin)-345);
delay(1);
yaccl [a] = float(analogRead(ypin)-346);
delay(1);
zaccl [a] = float(analogRead(zpin)-416);
delay(1);
获得3轴值后,通过取X,Y和Z轴值的平方根来计算总加速度矢量。
totvect [a] = sqrt((((xaccl [a]-xavg)*(xaccl [a]-xavg))+((yaccl [a]-yavg)*(yaccl [a]-yavg))+((zval [a]-zavg)*(zval [a]-zavg)));
然后计算最大和最小加速度矢量值的平均值。
totave [a] =(totvect [a] + totvect [a-1])/ 2;
现在将平均加速度与阈值进行比较。如果平均值大于阈值,则增加步数并提高标志。
if(totave [a] > threshold && flag == 0)
{
steps = steps + 1;
flag = 1; }
如果平均值大于阈值,但标志升高,则不执行任何操作。
否则,if(totave [a] > threshold && flag == 1)
{
//不算
}
如果总平均值小于阈值且标志升高,则将标志放下。
if(totave [a] <threshold && flag == 1)
{
标志= 0;
}
在串行监视器和LCD上打印步数。
Serial.println(steps);
lcd.print(“ Steps:”);
lcd.print(steps);
测试Arduino计步器
准备好硬件和代码后,将Arduino连接到笔记本电脑并上传代码。现在,将计步器放在手中,并逐步开始走路,它应该在LCD上显示步数。有时,计步器振动得非常快或非常慢时,它会增加步数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gT8uJjDu-1618972267574)(C:%5CUsers%5CAdministrator%5CPictures%5Ctypora%5CPedometer-using-Arduino-Working.jpg)]
下面提供了ADXL335计步器Arduino的完整工作视频和代码。
代码
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int xpin = A1;
const int ypin = A2;
const int zpin = A3;
byte p[8] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F
};
float threshold = 6;
float xval[100] = {0};
float yval[100] = {0};
float zval[100] = {0};
float xavg, yavg, zavg;
int steps, flag = 0;
void setup()
{
Serial.begin(9600);
lcd.begin();
lcd.backlight();
lcd.clear();
calibrate();
}
void loop()
{
for (int w = 0; w < 16; w++) {
lcd.write(byte(0));
delay(500);
}
int acc = 0;
float totvect[100] = {0};
float totave[100] = {0};
float xaccl[100] = {0};
float yaccl[100] = {0};
float zaccl[100] = {0};
for (int a = 0; a < 100; a++)
{
xaccl[a] = float(analogRead(xpin) - 345);
delay(1);
yaccl[a] = float(analogRead(ypin) - 346);
delay(1);
zaccl[a] = float(analogRead(zpin) - 416);
delay(1);
totvect[a] = sqrt(((xaccl[a] - xavg) * (xaccl[a] - xavg)) + ((yaccl[a] - yavg) * (yaccl[a] - yavg)) + ((zval[a] - zavg) * (zval[a] - zavg)));
totave[a] = (totvect[a] + totvect[a - 1]) / 2 ;
Serial.println("totave[a]");
Serial.println(totave[a]);
delay(100);
if (totave[a] > threshold && flag == 0)
{
steps = steps + 1;
flag = 1;
}
else if (totave[a] > threshold && flag == 1)
{
// Don't Count
}
if (totave[a] < threshold && flag == 1)
{
flag = 0;
}
if (steps < 0) {
steps = 0;
}
Serial.println('\n');
Serial.print("steps: ");
Serial.println(steps);
lcd.print("Steps: ");
lcd.print(steps);
delay(1000);
lcd.clear();
}
delay(1000);
}
void calibrate()
{
float sum = 0;
float sum1 = 0;
float sum2 = 0;
for (int i = 0; i < 100; i++) {
xval[i] = float(analogRead(xpin) - 345);
sum = xval[i] + sum;
}
delay(100);
xavg = sum / 100.0;
Serial.println(xavg);
for (int j = 0; j < 100; j++)
{
yval[j] = float(analogRead(ypin) - 346);
sum1 = yval[j] + sum1;
}
yavg = sum1 / 100.0;
Serial.println(yavg);
delay(100);
for (int q = 0; q < 100; q++)
{
zval[q] = float(analogRead(zpin) - 416);
sum2 = zval[q] + sum2;
}
zavg = sum2 / 100.0;
delay(100);
Serial.println(zavg);
}