使用Arduino和加速度计构建一个简单且便宜的计步器

描述

  如今,健身手环越来越流行,它不仅可以计算脚步声,还可以跟踪您燃烧的卡路里、显示心跳率、放映时间等等。这些物联网设备与云同步,因此您可以在智能手机上轻松获取所有身体活动的历史记录。

  计步器是仅用于计算脚步的设备。因此,在本教程中,我们将使用 Arduino 和加速度计构建一个简单且便宜的 DIY 计步器。该计步器将计算脚步的数量并将其显示在16x2 LCD 模块上。这款计步器可以与这款Arduino 智能手表集成。

  所需组件

  Arduino纳米

  ADXL 335 加速度计

  16*2液晶

  液晶 I2C 模块

  电池

  ADXL335 加速度计

  ADXL335 是一款完整的 3 轴模拟加速度计,它基于电容感应原理工作。它是一种小型、薄型、低功耗模块,带有多晶硅表面微加工传感器和信号调理电路。ADXL335 加速度计可以测量静态和动态加速度。在这个 Arduino 计步器项目中,ADXL335 加速度计将充当计步器传感器。

  加速度计是一种可以将任何方向的加速度转换为其各自的可变电压的设备。这是通过使用电容器来实现的(参见图片),当 Accel 移动时,其内部的电容器也会根据运动发生变化(参见图片),因为电容是变化的,因此也可以获得可变电压。

计步器

  下面是加速度计的正面和背面图像以及引脚说明-

计步器

  加速度计引脚说明:

  Vcc- 5 伏电源应连接到此引脚。

  X-OUT- 该引脚在 x 方向提供模拟输出

  Y-OUT- 该引脚在 y 方向提供模拟输出

  Z-OUT- 此引脚在 z 方向提供模拟输出

  GND-地

  ST- 此引脚用于设置传感器的灵敏度

  电路原理图

  下面给出了Arduino 加速度计步数计数器的电路图。

计步器

  在这个电路中,我们使用 ADXL335 Accelerometer 与 Arduino Nano 连接。加速度计的 X、Y 和 Z 引脚与 Arduino Nano 的模拟引脚(A1、A2 和 A3)连接。要将 16x2 LCD 模块与 Arduino 连接,我们使用的是 I2C 模块。I2C 模块的 SCL 和 SDA 引脚分别连接到 Arduino Nano 的 A5 和 A4 引脚。下表给出了完整的连接:

计步器

  我们首先在面包板上使用 Arduino设置构建了这个计步器

计步器

  在成功测试后,我们通过将所有组件焊接到 Perfboard 上来在 Perfboard 上复制它,如下所示:

计步器

计步器

  计步器如何工作?

  计步器使用向前、垂直和侧面的三个运动分量来计算一个人所采取的总步数。计步器系统使用加速度计来获取这些值。加速度计在每个定义的编号后不断更新 3 轴加速度的最大值和最小值。的样品。这3个轴的平均值(Max + Min)/2,称为动态阈值水平,该阈值用于决定是否迈步。

  跑步时,计步器可以在任何方向,因此计步器使用加速度变化最大的轴计算步数。

  现在让我快速了解一下这个 Arduino 计步器的工作原理:

  首先,计步器一通电就开始校准。

  然后在void循环函数中,不断的从X、Y、Z轴获取数据。

  之后,它计算从起点开始的总加速度矢量。

  加速度矢量是 X、Y 和 Z 轴值的平方根 (x^2+y^2+z^2)。

  然后将平均加速度值与阈值进行比较以计算步数。

  如果加速度矢量超过阈值,则增加步数;否则,它会丢弃无效的振动。

计步器

对 Arduino 计步器进行编程

本文档末尾提供了完整的Arduino 计步器代码。在这里,我们将解释此代码的一些重要片段。

像往常一样,通过包含所有必需的库来启动代码。ADXL335 加速度计不需要任何库,因为它提供模拟输出。

 

#include 

 

之后,定义连接加速度计的 Arduino 引脚。

 

常量 int xpin = A1;
常量 int ypin = A2;
常量 int zpin = A3;

 

定义加速度计的阈值。该阈值将与加速度矢量进行比较以计算步数。

 

浮动阈值 = 6;

 

在void setup内部,函数会在系统通电时校准系统。

 

校准();

 

在void 循环函数内部,它将读取 100 个样本的 X、Y 和 Z 轴值。

 

for (int a = 0; a < 100; a++)
  {
    xaccl[a] = float(analogRead(xpin) - 345);
    延迟(1);
    yaccl[a] = float(analogRead(ypin) - 346);
    延迟(1);
    zaccl[a] = float(analogRead(zpin) - 416);
    延迟(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] > 阈值 && flag == 0)
    {
      步数 = 步数 + 1;
      标志 = 1; }

 

如果平均值大于阈值但标志已升起,则什么也不做。

 

else if (totave[a] > threshold && flag == 1)
    {
      // 不计算
    }

 

如果总平均值小于阈值并且标志被升起,则将标志放下。

 

if (totave[a] < 阈值 && flag == 1)
    {
      标志 = 0;
    }

 

在串行监视器和 LCD 上打印步数。

 

Serial.println(步骤);
lcd.print("步骤:");
lcd.print(步骤);

 

  测试 Arduino 计步器

  准备好硬件和代码后,将 Arduino 连接到笔记本电脑并上传代码。现在拿起你手中的计步器,开始一步一步地走,它应该会在 LCD 上显示步数。有时,当计步器振动非常快或非常慢时,它会增加步数。

计步器

#include

LiquidCrystal_I2C lcd(0x27, 16, 2);

常量 int xpin = A1;

常量 int ypin = A2;

常量 int zpin = A3;

字节 p[8] = {

0x1F,

0x1F,

0x1F,

0x1F,

0x1F,

0x1F,

0x1F,

0x1F

};

浮动xavg,yavg,zavg;

整数步,标志 = 0;

无效设置()

{

序列.开始(9600);

液晶显示器开始();

液晶背光();

lcd.clear();

校准();
无效循环(




{

for (int w = 0; w < 16; w++) {

lcd.write(byte(0));

延迟(500);

}

int acc = 0;

浮动 totvect计步器 = {0};

浮点数计步器 = {0};

浮动 xaccl计步器 = {0};

浮动 yaccl计步器 = {0};

浮动 zaccl计步器 = {0};

for (int a = 0; a < 100; a++)

{

xaccl[a] = float(analogRead(xpin) - 345);

延迟(1);

yaccl[a] = float(analogRead(ypin) - 346);

延迟(1);

zaccl[a] = float(analogRead(zpin) - 416);

延迟(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]);

延迟(100);

if (totave[a] > threshold && flag == 0)

{

步数 = 步数 + 1;

标志 = 1;

}

else if (totave[a] > threshold && flag == 1)

{

// 不要计算

}

if (totave[a] < threshold && flag == 1)

{

flag = 0;

}

如果(步数 < 0){

步数 = 0;

}

Serial.println('\n');

Serial.print("步骤:");

Serial.println(步骤);


lcd.print(步骤);

延迟(1000);

lcd.clear();

}

延迟(1000);

}

void calibrate()

{

float sum = 0;

浮动总和1 = 0;

浮动总和2 = 0;

for (int i = 0; i < 100; i++) {

xval[i] = float(analogRead(xpin) - 345);

总和 = xval[i] + 总和;

}

延迟(100);

xavg =总和/ 100.0;

序列号.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);

延迟(100);

for (int q = 0; q < 100; q++)

{

zval[q] = float(analogRead(zpin) - 416);

sum2 = zval[q] + sum2;

}

zavg = sum2 / 100.0;

延迟(100);

Serial.println(zavg);

}
 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分