捕获和绘制加速度计数据
Terasic DE10-Nano 内置的三轴加速度计数据在所有三个轴上进行测量,以显示板卡何时处于运动状态。加速度计的原始输出通过传感器库转换为 g 力值,然后发送到图形软件进行数据可视化和解释。
获取新的 Intel® 物联网开发者套件,这是一个完整的硬件和软件解决方案,使开发人员能够使用 Intel® Galileo 和 Intel® Edison 开发板创建令人兴奋的新解决方案。请访问 Intel® 物联网开发者中心。
目的和概述
Terasic DE10-Nano 内置的三轴加速度计数据在所有三个轴上进行测量,以显示板卡何时处于运动状态。加速度计的原始输出通过传感器库转换为 g 力值,然后发送到图形软件进行数据可视化和解释。
在本教程中,您将
- 使用 I2C 接口与板载的内置数字加速度计进行交互。
- 使用 Intel® I/O 和传感器库(MRAA 和 UPM)从加速度计获取数据。
- 监测和观察 X、Y、Z 轴上微小振动和运动的加速度数据。
- 将加速度数据转换为 +/- g 力值,以演示 Terasic DE10-Nano 板的运动。
- 使用不同的开源技术显示加速度计数据
- Express*(Web服务器)
- Plotly*(图形库)
- Websocket*(数据流)。
注意:Express.js 和 Plotly.js 均是 MIT* 许可的非限制性技术。
材质
硬件
- Terasic DE10-Nano 套件
- 以太网线
- 路由
软件
要通过串行/SSH 连接到开发板,您需要一个类似 Putty 或 TeraTerm 的客户端。
库
- MRAA
MRAA 是一个 I/O 库(抽象层),它为跨平台访问各种 I/O 创建了一个通用接口。此处 MRAA 用于访问连接到加速度计的 I2C 接口。
- UPM
UPM 是一个传感器库,为各种常用传感器(包括 Terasic DE10-nano 的板载加速度计)提供了软件驱动程序。这些软件驱动程序通过调用 MRAA API 与底层硬件平台进行交互。在本教程中,UPM 库用于读取板载的三轴数字加速度计 ADXL345(来自 Analog Devices*)的数据。
注意:MRAA 和 UPM 已预装在 Terasic DE10-Nano 的默认 microSD 卡镜像中。
编程语言
Node.js*
加速度计原理
加速、减速、改变方向
您的智能手机是如何知道哪个方向是向上的?当您将设备顺时针旋转 90 度时,它又是如何知道将方向从纵向更改为横向的?这些智能运动功能都归功于加速度计。加速度计是一种传感器,用于测量加速度(相对于其自身参考系)。您可能还记得物理学中的概念:当速度(具有方向的速度)发生变化时,就会发生加速度。加速度包括加速、减速或改变方向,通过测量 X、Y 和 Z 轴上的加速度(g 力),加速度计就能辨别出上下方向。
有两种使用加速度计的方法
- 加速
- 倾斜
这里我们使用三轴加速度计来测量所有三个轴(x、y 和 z)上的加速度。
注意:请记住,地球表面的重力加速度为 1 g。
与加速度计通信
在这里,我们使用 I2C 接口与板载的内置数字加速度计进行交互。I2C 总线通过物理线路连接到 SoC 上的 ARM* 处理器。
教程步骤
请按照以下步骤操作,以从 Terasic DE10-Nano 的内置加速度计获取数据,并在图形软件中绘制这些数据。
第一步:准备您的 Terasic DE10-Nano
检查点:您是否已经完成了 Terasic DE10-Nano 板的初步组装和设置?
此时,我们假设您已经完成了 Terasic DE10-Nano 套件的初步组装和设置。Terasic DE10-Nano 套件附带的 microSD 卡应插入开发板的 microSD 卡插槽,并且您的开发板已通电。请先完成组装和设置过程!
有关开发板组装和设置的说明,请参阅 Terasic DE10-Nano 入门指南中的 Terasic DE10-Nano 设置。
连接到开发板
在本教程中,您将使用串行连接到开发板以执行初始设置。
注意:我们假设您知道如何在系统上设置串行终端。有关如何设置串行终端的参考,请在此处查看 页面。
在此,您将把开发板连接到互联网,获取静态 IP,然后切换到 SSH 连接。
-
将以太网线缆从 Terasic DE10-Nano 开发板连接到路由器。
Terasic DE10-Nano 板有两个不同的网络接口:1) 以太网 RJ45 接口,称为
eth0
;2) 以太网(通过 USB,RNDIS),称为usb0
。在本练习中,我们使用
eth0
接口。注意:较新版本的 Terasic DE10-Nano 镜像包含大多数 USB Wi-Fi 加密狗的驱动程序。不幸的是,本练习不涵盖设置无线连接。
-
获取静态 IP
启动您首选的终端应用程序(PuTTY 或 Tera Term),以建立到 Terasic DE10-nano 板的串行连接。连接后,您应该通过运行
passwd
命令为 root 帐户设置密码。大多数现代路由器都能根据以太网接口的 MAC 地址分配静态 IP,即使启用了 DHCP 分配。有关如何执行此操作的信息,请查阅您的路由器手册。
如果您的路由器不支持为 DHCP 客户端分配静态 IP,您可以使用以下命令通过 connman 为
eth0
接口强制设置静态 IP:connmanctl config ethernet_000000000000_cable --ipv4 manual <device_ip> <subnet_mask> <gateway_ip> connmanctl config ethernet_000000000000_cable --nameservers <gateway_ip>
变量 描述 示例 <device_ip> 您要分配给 Terasic DE10-Nano 的 IP 地址 192.168.1.10 <subnet_mask> 用于确定 IP 地址所属子网的位掩码 255.255.255.0 <gateway_ip> 网关/路由器 IP 地址 192.168.1.1 请在完成此步骤并获取开发板的 IP 地址后**断开 USB 线缆**。同时使用两个接口可能会导致它们互相干扰。
-
切换到远程 SSH 连接
现在您已经有了静态 IP,我们可以切换到 SSH 连接。当您断开 USB 线缆时,终端应用程序将关闭之前的连接。启动一个新的终端实例,然后使用开发板的 IP 地址进行连接。
使用 SSH 连接将更快、更安全,并且允许与开发板之间进行文件传输。如果您想更改图表设置(例如,删除其中一个轴,添加数据点标记,更改曲线平滑度等),这将非常有用。它还允许您在运行示例应用程序后更改开发板上的项目文件。
动态主机配置协议 (DHCP)
默认情况下,开发板上的以太网接口设置为动态主机配置协议(DHCP)模式,因此它会自动向连接的路由器请求 IP 地址。通过设置静态 IP,连接到 Terasic DE10-Nano 和托管图形网页的过程会变得更加容易。这基本上意味着您不必每次从路由器获取新的 IP 地址时都编辑客户端配置。
返回 DHCP 模式(可选)
如果您需要撤销对 eth0
接口所做的更改并返回使用 DHCP 模式,请键入以下命令:connmanctl config ethernet_000000000000_cable --ipv4 dhcp
第二步:克隆 GitHub 存储库
克隆包含此示例源代码的 Github 存储库是一个直接的过程。Git 客户端是 Terasic DE10-Nano 镜像的一部分。要克隆存储库,请在您的 SSH 会话中键入以下命令:
git clone https://github.com/intel-iot-devkit/terasic-de10-nano-kit.git
这将在当前目录中创建一个名为 *terasic-de10-nano-kit* 的新文件夹。加速度计教程的源代码文件可以在 *terasic-de10-nano-kit/code-samples/accelerometer/de10-adxl345* 下找到。
第三步:安装 Express、Websocket 和 Plotly
通过键入以下命令进入应用程序目录:
cd terasic-de10-nano-kit/code-samples/accelerometer/de10-adxl345
当使用此存储库中的示例代码时,通过运行以下命令将安装 Express、Websocket 和 Plotly:
npm install
第四步:取消绑定 ADXL345* 驱动程序
默认情况下,Linux* 已绑定(即“拥有”)此加速度计设备。在这里,我们需要将设备“解绑”出 Linux(你知道的,就是把 Linux 的控制权夺过来),以便我们的程序使用它。
默认情况下,adxl34x 驱动程序将绑定到设备 0-0053,您可以在下面的目录列表中看到它:
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x 0-0053 bind uevent unbind
adx34x 内核驱动程序会持续轮询加速度计,这会干扰 MRAA 库。此外,它会启用 ADXL345 上的自动睡眠功能,这在通过 UPM 驱动程序读取值时会增加显著的延迟。
首先,重新配置设备:
root@de10-nano:~# echo 0 > /sys/bus/i2c/drivers/adxl34x/0-0053/autosleep root@de10-nano:~# echo 15 > /sys/bus/i2c/drivers/adxl34x/0-0053/rate
要解绑驱动程序,请像这样将设备名称 echo 到 sysfs 中的 unbind 伪文件中:
root@de10-nano:~# echo 0-0053 > /sys/bus/i2c/drivers/adxl34x/unbind
注意,该设备在此目录中不再存在。
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x bind uevent unbind
要绑定驱动程序,请像这样将设备名称 echo 到 sysfs 中的 bind 伪文件中:
root@de10-nano:~# echo 0-0053 > /sys/bus/i2c/drivers/adxl34x/bind [ 871.268013] input: ADXL34x accelerometer as /devices/platform/soc/ffc04000.i2c/i2c-0/0-0053/input/input5
注意,设备已恢复。
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x 0-0053 bind uevent unbind
注意:如果您想运行其他加速度计示例,则需要重新绑定驱动程序。(提示:microSD 卡镜像中可能隐藏着一个加速度计的彩蛋……去寻找它吧!)驱动程序更改在重启后不会持久保存。
第五步:设置 Express.js Web 服务器
此 Web 服务器使用 WebSocket 将从加速度计捕获的实时数据推送到客户端浏览器。
设置 Node.js 模块查找路径
在启动服务器之前,让我们确保 Node.js 知道在哪里可以找到 MRAA 和 UPM。为此,我们将设置 NODE_PATH
环境变量:
export NODE_PATH=/usr/lib/node_modules
如果您想使此更改永久生效,并在开发板每次启动时都导出 NODE_PATH
变量,请使用以下命令:
echo "export NODE_PATH=/usr/lib/node_modules" > ~/.profile
启动 Web 服务器
服务器端代码位于 *app.js* 文件中。此文件是使用 Express.js 模板生成的,然后扩展为处理 WebSocket 连接。有关这两个概念的更多信息可以在参考资料中找到。服务器还将定期使用 UPM ADXL345 库发送加速度计数据,如下一节所述。
客户端代码可以在 *public/js/index.js* 文件中找到。在客户端,您需要设置 Terasic DE10-Nano 板的 IP 地址:
var connection = new WebSocket('ws://192.168.1.10:3001'); // Change to match your own DE10-Nano IP
您可以使用内置的 vi
编辑器进行更改。其他文本编辑器可从官方 Angstrom 存储库获取(例如 vim、nano)。您现在已准备好启动服务器。
启动 Express* 就像键入以下命令一样简单:
npm start
第六步:使用 Plotly* 生成实时图表
Plotly* 图形库用于以实时图表的形式可视化数据。该页面几乎可以在任何浏览器/设备组合上访问。
要查看图表,请使用连接到 Terasic DE10-Nano 板同一网络的任何设备,打开浏览器,然后访问:
http://<device_ip>:3000
此应用程序有几个关键组件,它们允许读取加速度计的数据并将其推送到客户端。
在服务器端,您需要加载 ADXL345 的 UPM 库并读取 g 力值。这反映在以下代码中:
var upm = require('jsupm_adxl345'); // Assumes the UPM modules are installed on a path known to Node.js, or a location specified via the NODE_PATH environment variable
并且
var adxl = new upm.Adxl345(0); // Initialize the accelerometer on I2C bus 0 var gatherData = setInterval(function() { adxl.update(); // Update the data var force = adxl.getAcceleration(); // Read acceleration force (g) force.setitem(2, (force.getitem(2) + 0.08)); // Apply a small offset to the Z axis, determined by calibration // Serialize and send the accelerometer data as JSON connection.send('{"x": ' + force.getitem(0).toFixed(2) + ', "y": ' + force.getitem(1).toFixed(2) + ', "z": ' + force.getitem(2).toFixed(2) + '}'); }, 100); // Send the data every 100 ms
对于客户端,首先同步服务器每秒发送的消息数:
var messagesPerSecond = 10; // Change to match your server data rate
然后,我们反序列化从服务器接收到的 JSON 加速度数据并更新图表:
connection.onmessage = function (message) { // Parse data and push data to plot try { var adxlData = JSON.parse(message.data); // Deserialize incoming JSON acceleration data // Divide the X axis by the number of messages received per second, so that major units are elapsed seconds var ts = messagesReceived/messagesPerSecond; var newData = { x: [[ts], [ts], [ts]], y: [[adxlData.x], [adxlData.y], [adxlData.z]] } // Extend the current graph, last integer here is the number of X values to keep before discarding old data Plotly.extendTraces('myDiv', newData, [0, 1, 2], 60 * messagesPerSecond); messagesReceived++; } catch (e) { console.log('This doesn\'t look like valid JSON: ', message.data); return; } };
客户端代码的其余部分根据 Plotly API 定义了图表的样式。
请注意,当前设置将大约每秒刷新数据 10 次。您可以尝试不同的值来显示更多或更少的数据。
第七步:观察作用在开发板上的力类型
静力
重力
当开发板放置在橡胶脚上时,您可以观察到重力作用在开发板上。
绿色线(Z 轴)应显示恒定的 1g(或 9.8 m/s^2)的力。事实上,重力始终显示在图表上!
动力
移动
通过移动开发板,观察 X(蓝色)、Y(橙色)和 Z(绿色)轴上的运动:
- 上下左右移动
- 以 45 度角
- 数字八字形
振动
观察以下情况:
- 轻轻敲击开发板
- 在桌子上敲击
- 将开发板放置在有持续振动的物体上或附近(例如,风扇电机)
后续步骤和优化
在 PC 或笔记本电脑上,Plotly 利用硬件加速(通过 webGL)来渲染图表。因此,您可以处理大型数据集,频繁重绘,并且仍然能够显示响应迅速的图表。不幸的是,此功能在移动浏览器(例如平板电脑、智能手机)上不可用。这意味着绘图速率直接受到影响,对于这些设备,仅限于每秒几次更新(1 到 4 次)。好消息是,通过 WebSocket 发送的数据量不受影响。
一个自然的优化是在客户端收集数据点到缓冲区,同时从 Terasic DE10-Nano 以高速率继续发送它们。然后,您可以一次用多个值更新图表,即使在移动设备上也能保持图表的响应性。
结论
本练习展示了如何轻松地将 MRAA 和 UPM 库与其他技术集成,以构建完整的物联网应用程序。还有许多其他传感器和执行器库,包括一些为工业应用设计的库。要获取支持传感器的完整列表,请在此处访问 UPM API 页面 here。
参考文献
- MRAA: http://mraa.io
- UPM: http://upm.mraa.io
- Express.js: https://express.js.cn/
- Websocket.js: https://github.com/theturtle32/WebSocket-Node
- Plotly.js: https://plot.ly/javascript/
一些不错的 Plotly 示例,展示如何扩展图表以显示新数据: