简介
跌倒导致致命的伤害已成为老年人不可忽视的巨大挑战。在过去的几年中,在跌倒检测领域提出了不同类型的方法,可以解释并分为三种类型:基于可穿戴设备、基于环境传感器和基于视觉。首先,可穿戴设备通常利用嵌入式传感器来检测身体的运动和位置,例如加速度计、磁力计和陀螺仪 。并且基于可穿戴设备的方法成本很低,而且对于老年人来说安装和操作并不复杂。其次,基于环境的方法总是使用压力传感器来检测和跟踪身体。该解决方案还具有成本效益且易于部署。然而,感知人体以外的物体的可能性对这种方法的检测精度提出了显着挑战。最后但同样重要的是,基于视觉的解决方案充分利用部署的摄像头来监控范围内的所有物体,包括人体 。与上述两种方式相比,对人们日常生活的干扰较少,但观测空间有限,无法实现无处不在的监控。
在本项目中,提出了一种基于 Arduino、Windows 10 和 Microsoft Azure 的实时跌倒检测监控系统。三维加速度计的原始数据由 Arduino 和 ADXL345 提供。Windows 10 设备利用这些信息通过有效的数据融合和跌倒检测算法来获取对象的方向。微软 Azure 服务和移动/PC 应用程序也旨在实现无缝的数据处理、分析、存储和获取,只要它们可以访问 Internet,就可以随时随地从任何地方访问。系统架构如图1所示:
基于姿势识别的跌倒检测原理
在这个项目中,跌倒检测算法是根据Bharadwaj Sreenivasan 的 Fall-detection-in-Android设计的。算法中有两个模块,姿势识别和跌倒检测。首先,我们从加速度计中读取 x、y 和 z 值。然后我们计算 x、y 和 z 的 L2 范数。这由姿势识别和跌倒检测模块使用。
在姿势识别模块中,用户姿势分为三种基本姿势:坐姿、站立姿势和行走姿势。“y”的值被应用一个阈值来找出方向。使用 L2 范数与重力引起的平均加速度 (9.8) 的变化率,我们将数据分类为行走或状态之间的转换。
跌倒检测模块在信号中搜索特定模式。图 2 表示跌倒事件期间 L2 范数的典型模式:
如果连续最小值和最大值之间的差值大于 2g,则输出判定为下降。跌倒事件的最终决定是基于姿势识别和跌倒决策模块的输出。当检测到跌倒时,姿势识别模块的决定会告诉我们这是否是误报。如果状态仍在行走,则可以丢弃跌倒事件决策。表 1 总结了最终决定:
先决条件
在这个项目中,对于Arduino设备,蓝牙通信是通过HC-06实现的,HC-06是一个便宜的小封装模块。对于 Windows 10 设备,如果您使用 Surface Pro 和 Lumia 1520,则不需要蓝牙模块。但是,如果您使用 Raspberry Pi 或 MBM 作为 Windows 10 IoT 设备,则需要蓝牙加密狗。
注意:如果您尚未安装 Windows 10 和 Visual Studio 2015,则需要 2-3 小时才能完成先决条件。
需要什么
部分:
1. Arduino Uno和标准 A/B USB 电缆
2. HC-06蓝牙模块
3. ADXL345加速度计模块
4. 公母公母跳线
5.迷你面包板
6. Lumia 1520或其他 Windows Phone 10 兼容设备
项目说明
第 1 步:将加速度计模块 ADXL345 连接到 Arduino
ADXL345 是一款小型、薄型、低功耗、3 轴 MEMS 加速度计,具有高达 +-16 g 的高分辨率(13 位)测量。数字输出数据采用 16 位二进制补码格式,可通过 SPI(3 线或 4 线)或 I2C 数字接口访问。
ADXL345 支持 SPI 和 I2C,我们将在此项目中讨论 I2C。I2C 是 2 线串行连接,因此我们需要将 SDA(数据)和 SCL(时钟)线连接到 Arduino UNO 进行通信。在 Arduino UNO 上,SDA 在模拟引脚 4 上,SCL 在模拟引脚 5 上。确保 VCC 和传感器上的 CS 引脚都连接到 3.3v。我们将 CS 连接到 3.3V 以告诉传感器我们将使用它作为 I2C 设备,而不是 SPI 设备。
第 2 步:连接蓝牙模块
在这个项目中,我们使用 HC-06 作为蓝牙模块 - 它比 SparkFun 的 BlueSMiRF Silver 模块便宜得多。此外,HC-05 上面有“完整”固件,许多 AT 命令,并且可以是主模块和从模块。另一方面,HC-06 固件只能是从设备,具有非常有限的 AT 命令。下表显示了所有 HC-06 固件命令及其响应:
首先,将蓝牙模块插入面包板以使连接更容易。要为模块供电,请从 Arduino 的 5V 电源轨跳线到模块的 Vcc 引脚。并从模块的 GND 引脚运行公公跳线到 Arduino 上的任何 GND 引脚。要建立串行通信,请将蓝牙模块的 TX 引脚的公公跳线连接到 Arduino 的 RX 引脚(数字引脚 0),并将另一个从模块的 RX 引脚连接到 Arduino 的 TX 引脚(数字引脚 1)。
注意:当您将蓝牙的 TX 和 RX 引脚连接到 Arduino 时,您将无法将草图从 Arduino IDE 上传到 Arduino。当您需要上传草图时断开它们并在成功上传草图后重新连接它们。在下面的草图中,显示使用了 HC-05。实际上,如上所述,HC-05 和 HC-06 都可以。
蓝牙和加速度计连接后,实物如下图:
第 3 步:将蓝牙模块与 Windows 10 设备配对
蓝牙模块运行 SPP(蓝牙串行协议)协议。所以任何支持 SPP 的设备都可以连接到它。在 Windows 10 设备上,这看起来像一个虚拟 COM 端口。在连接之前,请确保模块已通电并准备好配对。模块上的红色 LED 指示状态:闪烁表示“准备配对”,常亮表示“配对”。
在 Windows 10 for PC 上,只需导航到设置-》设备-》蓝牙,打开蓝牙,然后屏幕上将显示“HC-06”模块。点击以配对设备,然后输入设备的配对码。请记住,默认配对码是 1234,默认串口速度是 9600 波特。然后,蓝牙页面显示如下:
对于 Windows 10 for Mobile,导航到设置-》设备-》蓝牙,然后执行上一节中描述的相同步骤。配对设备页面如下所示:
对于 Windows 10 IoT Core 设备,例如 Raspberry Pi 2、MBM 和 Dragon Board 410c,配对过程有很大不同。首先,对于没有板载蓝牙模块的树莓派 2 和 MBM,我们应该购买蓝牙 USB 加密狗并插入。只需参考硬件兼容性列表并选择经过验证的蓝牙 USB 加密狗。
在这个项目中,我们选择了 ORICO BTA-403 模块。
如果您在 Dragon Board 410c 上尝试此项目,那么您不需要蓝牙加密狗,因为 Dragon Board 410c 具有板载蓝牙模块。
将 ORICO BTA-403 蓝牙 USB 加密狗插入树莓派 2 的 USB 接口,如下所示。
插入 ORICO BTA-403 蓝牙 USB 加密狗后,它将在 Windows 10 IoT Core 设备的默认应用程序屏幕上显示消息。
在这里,我们应该使用 SSH 连接到 Windows IoT Core 并运行命令行工具来配置设备。
注意:请记住应在主菜单上选择 BR 模式。默认配对码为 1234。
配对成功后,设备的蓝牙页面显示如下:
第 4 步:创建 Azure 存储帐户
在这个项目中,我们将需要 Azure 存储表来存储来自 Windows 10 IoT Core 设备的数据。因此,我们可以按如下方式创建它。
(1) 在 Azure 管理门户 中,单击左侧的“STORAGE”图标以查看您现有的存储帐户(如果有),然后单击“+NEW”按钮在左下角。
(2) 在“新建”面板中,选择“数据服务”| “存储” | “快速创建”。填写“URL、位置/关联组和复制”字段,然后单击“创建存储帐户”按钮。
(3) 等待新存储帐户的状态显示为“在线”。
(4) 选择新创建的Storage account,然后点击页面底部的MANAGE ACCESS KEYS。复制存储帐户名称和访问密钥之一。
第 5 步:创建 Azure 存储表
我们使用 Azure 存储资源管理器来创建 Azure 存储表。
(1) 进入添加账户,填写账户名和访问密钥。建立帐户后,您可以访问显示 Blob 容器、队列和表的存储。
(2) 选择表并单击新建按钮,创建一个名为“Accelerometer Table”的新表,如下所示:
第 6 步:软件
首先,现在我们已经为 Arduino 连接好了所有东西,从(在本文下方提供)使用“ADXL345_HC06.ino”项目并将其加载到您 PC 上的 Arduino IDE 中。务必拔掉 HC-06 模块的 TX/RX 跳线,然后上传草图。将 TX/RX 跳线重新连接到 Arduino 的数字 0 和数字 1 引脚。插上电源,应用程序将在 Arduino Uno 上运行。
其次,从github下载“GenericBluetoothSerialUWApp”项目。使用带有 Update 1 的 Visual Studio 2015 加载“GenericBluetoothSerialUWApp”。这个应用程序是在我们的 MVP David Jones 的Generic Serial Bluetooth with Win 10 IoT-Core RPI2的帮助下设计的。如果您希望此 UWP 应用在 PC 上运行,请选择带有本地设备调试的 x86 或 x64。如果您希望此 UWP 应用在 Windows 10 移动版上运行,请选择带有设备调试的 ARM。如果您希望此 UWP 应用在 Windows 10 IoT 设备(例如 Raspberry Pi 2)上运行,请确保将“远程调试”点设置为您的设备。
接下来,在解决方案资源管理器中打开 MainPage.xaml.cs 并找到“dataTransferTick”。添加您在第 4 节中保存的存储帐户名称和访问密钥。
将 HC-06 与 Windows 10 设备配对后,在 Visual Studio 中按 F5 以启动通用 Windows 平台应用。
双击“HC-06”符号,您将在应用程序的最顶部找到 Id 和 Name 显示,如下所示。
很快,您可以看到 HC-06 上的 LED 状态将从闪烁变为稳定。并且蓝牙模块的通信通道一旦建立,“Start Rev”按钮就会被启用。
单击 Start Recv 以启用数据接收。然后您将看到启用了 Stop Recv、Process Data 和 Upload Data 按钮。只需单击处理数据按钮即可运行跌倒检测算法。您将在 Recvd TextBlock 上看到数据以及携带设备的人的状态。
您仍然可以发现数据将显示在 Visual Studio 的调试窗口中,如下所示:
然后,单击“上传”按钮将数据上传到 Azure。数据将每 3 秒传输一次。如果要更改时间间隔,可以修改“AzureButton_Click”中的代码如下。
私人无效 AzureButton_Click(对象发送者,RoutedEventArgs e){
timerDataTransfer = ThreadPoolTimer.CreatePeriodicTimer(dataTransferTick, TimeSpan.FromMilliseconds(Convert.ToInt32( 3000 )));
}
很快,可以看到AccelerometerTable中的数据如下
第三,从github下载“FallDetectionClient”。使用带有 Update 1 的 Visual Studio 2015 加载此项目。此应用程序是使用 Windows Universal Temple 构建的,因此您可以在 Windows 10 PC/Mobile 以及 Windows 10 IoT Core 设备上运行它。接下来,在解决方案资源管理器中打开 StorageSensor.cs 并找到“_accountName”和“_key”。添加您在第 4 节中保存的存储帐户名称和访问密钥。
现在您应该可以在 Visual Studio 中按 F5:应用程序将部署并启动,您应该会在设备输出中看到这一点。
ADXL345_HC06.ino:
#include
#include
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37
int ADXAddress = 0xA7 >> 1;
int reading = 0;
int val = 0;
int X0, X1, X_out;
int Y0, Y1, Y_out;
int Z1, Z0, Z_out;
double Xg, Yg, Zg;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(100);
Wire.beginTransmission(ADXAddress);
Wire.write(Register_2D);
Wire.write(8);
Wire.endTransmission();
}
void loop() {
double tempx = 0;
char strx[5];
double tempy = 0;
char stry[5];
double tempz = 0;
char strz[5];
String gy;
Wire.beginTransmission(ADXAddress);
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
X0 = Wire.read();
X1 = Wire.read();
X1 = X1 << 8;
X_out = X0 + X1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Y0);
Wire.write(Register_Y1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Y0 = Wire.read();
Y1 = Wire.read();
Y1 = Y1 << 8;
Y_out = Y0 + Y1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Z0 = Wire.read();
Z1 = Wire.read();
Z1 = Z1 << 8;
Z_out = Z0 + Z1;
}
Xg = X_out / 256.00;
Yg = Y_out / 256.00;
Zg = Z_out / 256.00;
if(Xg>0)
{
gy = String("")+ "x=+"+Xg;
}
else
{
gy = String("")+ "x="+Xg;
}
if(Yg>0)
{
gy += String("")+ "y=+"+Yg;
}
else
{
gy += String("")+ "y="+Yg;
}
if(Zg>0)
{
gy += String("")+ "z=+"+Zg+",";
}
else
{
gy += String("")+ "z="+Zg+",";
}
Serial.print(gy);
}
评论
查看更多