NXP

Microsoft Azure IoT Hub应用 – 第二部分:连接传感器以及 IoT 车辆

2019-07-12 13:47发布

By Toradex Leonardo Graboski Veiga 1). 简介 这是关于 IoT 应用开发系列文章中的第二篇。本文继续关注传感器读取以及向云端发送收集到的数据。Toradex Colibri VF61 模块 + Iris 底板继续作为本次演示的嵌入式系统。图 1 展示了本系列文章所介绍应用整体框图。
图1:应用框图   2). 添加传感器模块到 Iris 底板 项目中使用的传感器产生数据,模块通过 Wi-Fi 联网: ./ MPU-6050 陀螺仪 + 加速度和温度 ./ HC-SR04 超声波模块 ./ IKeyes GPS shield v1.2 ./ WL250N USB Wi-Fi   MPU-6050 已经提供了内核驱动模块,能够同 Linux 应用通信(适用于 Toradex Vybrid 的4.4.0 Linux 内核版本 )。 该文档 说明了使用模块硬件接口的 device tree 配置。该模块驱动不能直接添加到内核中,需要编译的时候包含进来。 这篇文章 详细说明了如何配置、编译和更新内核。如果 MPU-6050 的 I²C 地址和板载RTC(0x68)冲突,最简单的解决方法是将 MPU-6050 的 AD0 接至高电平,这可以将其地址变为 0x69。 HC-SR04 在 Github 上有 驱动模块 ,其中的一个分支可以针对 Colibri VF61 的 4.4.0 内核进行编译。针对Toradex 模块的源码以及编译好的驱动模块可以从 这里下载。 GPS 模块通过 UART 通信,其与 GPSD 服务连接。更多关于 GPSD 的信息请查看 这里. 。如果你想要 编译自己的镜像,GPSD 也提供了 OpenEmbedded recipe。   依次配置 GPSD、加载 HC-SR04 驱动以及向云端发送数据。无论是重启还是开机,init 服务都会被调用。如果本文使用的 Github repository 已经复制到目标板上,你会发现服务文件(car.service)和 init 脚本(init.sh)在主文件夹中。为了使其工作,还需要其他一些步骤。首先,Github repository 需要复制到 /home/root 目录,这是默认的路径。然后 car.service 需要放在 /lib/systemd/system 中,启用相应的服务。下面的步骤描述了操作步骤: --------------------------- root@colibri-vf:~# git clone https://github.com/leograba/azure-iot-car.git root@colibri-vf:~# cd azure-iot-car root@colibri-vf:~# cp car.service /lib/systemd/system root@colibri-vf:~# systemctl enable car.service ---------------------------   如果想要在启动时停止该服务,例如停止向 IoT Hub 发送数据,那么可以通过下面命令停止: --------------------------- root@colibri-vf:~# systemctl stop car.service ---------------------------   USB Wi-Fi 模块 WL250N 可以直接使用,但是仍旧需要配置才能连接网络。如何配置连接的说明可以参考 这里。 关于模块和 Iris 底板之间的连接,只能使用 X16 排针引脚。Iris 技术手册 提供了关于接口、连接器等的信息,如果需要可以参阅 Colibri VF61 CoM 技术手册。表 1 描述了 Iris 和模块之间的引脚连接。图 2 是 MPU-6050和 HC-SR04 在早期研发阶段的连接。 --------------------------- 表 1:传感器和 Iris 底板连接 Iris pin header (x16)         Iris pin description Module   Pin 5 I²C SDA    MPU 6050       SDA 6 I²C SCL     MPU 6050       SCL 7 GND         MPU 6050 / HC-SR04 / GPS  GND / GND / GND 12        +5V MPU 6050 / HC-SR04 / GPS  VCC / VCC / 5V 17        GPIO        HC-SR04  Trig 18        GPIO        HC-SR04  Echo 31        UART_B Rx     GPS Tx 32        UART_B Tx      GPS Rx 33        +3.3V       HC-SR04  AD0 ---------------------------
图 2:MPU-6050 以及 HC-SR04 和 Iris 连接   3). IoT 车辆 在所有的模块连接到 Toradex 嵌入式系统后,接下来就需要把它嵌入到遥控车里,如图 3 所示。这是简单的步骤,但仍旧需要在一些地方引起注意。
图 3:IoT 原型 因为 GPS 模块有主动天线,模块放置在 Toradex 系统下,天线接到车顶外面。为了安装超声波测距模块,如图 3 所示在保险杆位置开了两个孔。加速器传感器则被固定在电路板上,PCB 板与地面平行,这可以直接使用模块的数据而不需要修正(在实际应用中这往往是需要的)。   嵌入式系统的电源选用两芯(2S – 7.4V)1200mAh 可充电锂电池。考虑到目前系统耗电为 200mA,锂电池 实际放电 不应该超过容量的 80% 的规律,系统能够工作 4.8 个小时。图 4 为最终的原型。
图 4:IoT 车辆最终原型   4). 读取传感器并向云端发送数据 MPU-6050 和 HC-SR04 可以通过访问文件系统读取数据,读取 GPS 数据需要使用 Bancroft 同 GPSD 通信,获取解析的数据。 从 HC-SR04 由内核模块返回的值为发送一个脉冲至其返回的时间,单位毫秒。该值需要乘以声音的速度并除以2E6,因为一半的时间用于超声波的发送,另一半是反射: distance = (value*sound_speed)/2000000 MPU-6050 的数据具有一个比例,一旦获取精度配置。同样,每一个温度传感器都已不同的偏移。在本文中,MPU-6050 会采用默认的配置,一般的方法就可以换算读取的数据: value = (raw_value+offset)*scale 换算后各个值的单位:加速度 - m/s²; 陀螺仪 - °/s ;温度 - °C.   GPS 模块返回如下的数据: --------------------------- { timestamp: 1311296682000, latitude: 45.456445, longitude: -73.569651667, altitude: 28.9,   speed: 11,   track: 10.3788,   geometries: {     type: 'Point',    coordinates: [ -73.569651667, 45.456445, 28.9 ] } } --------------------------- 读取和向 IoT Hub 发送数据的应用是由第一部分博文中修改该而来的 send_data.js。对应目前应用的文件是send_data_from_sensors.js,这个可以在先前复制到目标板上的 Github repository 中找到。修改后的主要需要注意的是无论什么时候读取到新的数据,Bancroft 模块都会触发事件。对于访问传感器的路径, MPU-6050 是/sys/bus/iio/devices/iio:device2/,HC-SR04 是 /sys/class/hcsr04/。下面是部分代码的说明。   首先,MPU-6050 的偏移和比例变量可以同步读取,防止代码在偏移和比例变量确定之前读取数值并计算。同样,保存需要发送到云端的数据的变量也需要申明: --------------------------- //Read some offset and scale constants from the MPU-6050 and convert to number var temp_offset = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_temp_offset'); var temp_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_temp_scale'); var accel_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_accel_scale'); var anglvel_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_anglvel_scale'); var gps_coordinates ;//variable to hold the gps coordinates // Data to be sent to the cloud var timenow, temperature, Distance, Acceleration = {}, Gyroscope = {}; ---------------------------   然后处理对应用至关重要的 GPS 数据。无论什么时候坐标被更新,其都会保存在变量中,一旦与模块之间连接丢失,它都会尝试重新连接: --------------------------- // gps events bancroft.on('location', function (location) {//updates the gps coordinates variable location.geometries = "point"; gps_coordinates = location; console.log('got new location', gps_coordinates); }); bancroft.on('disconnect', function (err) {//if gps is disconnected bancroft = new Bancroft();//tries to reconnect once console.log('trying to reconnect gps...'); }); ---------------------------   最后一部分代码是循环调用函数读取传感器并将数据发送至 IoT Hub。每一个函数采用独立的循环,使得代码更加灵活,例如,读取传感器数据并保存到备份文件需要比发送到云端更加频繁: --------------------------- // Loops that call the functions to read sensors and send to the cloud sendInterval.handlerGet = setInterval(getAllSensors, sendInterval.timerGet); sendInterval.handlerSend = setInterval(sendToIotHub, sendInterval.timerSend); ---------------------------   上面调用的 getAllSensors 函数尽管很简单,但是也会被删除:其更新嵌入式系统保存的当前时间,针对每次测量调用 readSensor() 函数 - 距离、温度、3 轴加速度、3 轴陀螺仪。 readSensor() 仅仅读取文件并打印错误到终端。否者它和 readFile() 函数非常类似。 --------------------------- //Function that reads data from sensor function readSensor(path, callback) { fs.readFile(path, function (err, data) { if(err){//if data could not be read console.log("Error reading sensor: " + err); callback(err, null);//pass the error to the callback return; } callback(null, data);//callback without error }); } ---------------------------   sendToIotHub() 函数将最新的数据转换成 JSON 编码字符串、封装成消息、在终端输出反馈并将其发送至 IoT Hub。这也是本文解释最后一部分代码,所示如下: --------------------------- function sendToIotHub() { // Add the data to a JSON encoded string var data = JSON.stringify({ ObjectName: 'toradex2', ObjectType: 'SensorTagEvent', temp: temperature, acceleration: Acceleration, gyroscope: Gyroscope, gps: gps_coordinates, distance: Distance, boardTime: timenow });   var message = new Message(data);// Encapsulate the message to be sent message.properties.add('myproperty', 'myvalue'); console.log('sending message to the IoT Hub: ');// Feedback message to the console console.log(data); client.sendEvent(message, printResultFor('send'));// Send message to the IoT Hub } ---------------------------   5). 总结 到现在为止,在本系列的第一篇文章中介绍了项目目标和 IoT 总体情况。然后配置 Azure IoT Hub,接收来自Toradex 嵌入式系统的消息(并发送消息,在该项目中没有过多说明),提出了一些关于从嵌入式系统发送数据的思考,最后,演示了从云端获取数据的方法,用以验证系统正常工作。 然后,本文主要关注于嵌入式系统的项目。从如何连接传感器/模块到 Colibri VF61 + Iris 载板的步骤开始到Node 应用的具体细节。 基于以上内容,接下来的内容是为了减轻挖掘有用的分析并生成 BI 工作,介绍使用 Azure Stream Analytics 和 Microsoft Power BI 过滤数据并显示易于理解的结果。希望这是一篇有用的文章,我也想要感谢来自巴西的Grupo Viceri 团队在 Azure 和 Business Intelligence 丰富的经验,促成了我们的合作,并最终实现了 IoT 项目。期待在第三部分文章中再见!