博客
关于我
ESP32 应用实践:基于混杂接收模式的人流量检测
阅读量:273 次
发布时间:2019-02-28

本文共 7920 字,大约阅读时间需要 26 分钟。

前言

ESP32 是一颗低功耗、高集成度、性能稳定的 Wi-Fi /BLE 芯片,是物联网开发的首选设备。它采用 2.4 GHz Wi-Fi 加蓝牙双模芯片,采用 TSMC 低功耗 40nm 技术,功耗性能和射频性能最佳,安全可靠,易于扩展至各种应用。同时集成了双核 160 MHz MCU、两个浮点运算单元 (FPU)、硬件安全加速器、电容触摸传感器、霍尔传感器、ADC、DAC、蓝牙/Wi-Fi 协议栈、TR 滤波器、双工器、功率放大器、接收低噪声放大器、射频 balun 和天线开关。ESP32 的外围器件不超过 10 个,即可实现强大的处理性能、可靠的安全性能,以及 Wi-Fi 和蓝牙功能。可作为独立系统运行应用程序或是主机 MCU 的从设备,通过 SPI / SDIO 或 I2C / UART 接口提供 Wi-Fi 和蓝牙功能。专为移动设备、可穿戴电子产品和物联网应用而设计。该款芯片拥有业内最高水平的低功耗芯片的所有特征,比如精细分辨时钟门控、省电模式和动态电压调整等。集成了更多的元器件,性能稳定,易于制造,工作温度范围达到 -40°C 到 +125°C。ESP32 还集成了先进的自校准电路,实现了动态自动调整,可以消除外部电路的缺陷以及适应外部条件的变化。总之,是一款极其优秀的物联网芯片。

混杂模式也称 sniffer, 也称嗅探模式。就是接收所有经过网卡的数据包,包括不是发给本机的包。默认情况下网卡只把发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃。简单的讲,混杂模式就是指网卡能接受所有通过它的数据流,不管是什么格式,什么地址的。事实上,计算机收到数据包后,由网络层进行判断,确定是递交上层(传输层),还是丢弃,还是递交下层(数据链路层、MAC子层)转发。ESP32 可提供混杂模式来嗅探空中报文并进行一定的处理。

人流量检测在安保,商场,旅游等诸多行业具有重要作用,人流量数据不仅具有科学研究价值,还具有很强的实用价值。因此选择一种便捷,经济的监控手段很有必要。

一:目的

我们利用 ESP32 Wi-Fi 提供的混杂接收模式,接收全部空中包,然后对其解析,筛选得到周围无线设备发送的 Probe Request 帧,通过对 Probe Request 帧的来源和强度进行分析和汇总,从而计算出周围一定区域内的设备设备使用量(人流量)。

在得到基本的人流量数据后,ESP32 通过 MQTT 协议将数据发送至 OneNET 物联网平台,在OneNET平台上,得到最终的人流量变化曲线图,同时我们也可以在云端方便的进行数据处理和监控。

二:ESP32 及开发环境搭建

如果您熟悉ESP32开发环境,可以很顺利理解下面步骤; 如果您不熟悉某个部分,比如编译,烧录等,需要您结合官方的相关文档来理解。,如您需阅读文档。

2.1 ESP32 硬件准备

a) 没错,你需要一颗 ESP32 系列产品, 或 都是OK的。 如:

ESP32
b) 路由器/ AP (可以连接外网)
c) PC (推荐 ubuntu), 如果不是 Linux,可能需要您参考上面快速入门指南搭建虚拟机和编译器环境
d) 串口线

2.2 OneNet 平台准备

2.2.1 注册并登录账号,创建产品

在登录后的页面,右上角的开发者中心,创建自己的物联网产品。

  • 产品信息
  • 下面的技术参数最好按照下面方式填写
  • 操作系统选择“其他”,填写freertos
  • 网络运营商选择“移动”
  • 设备接入方式选择“公开协议”
  • 联网方式选择“wifi”
  • 模组选择”其他”
  • 设备接入协议选择“MQTT”

点击“确定”按钮,完成产品创建。

同时将产生一个 产品 ID, 注意这个会在后面的程序交互中用到。

2.2.2 创建设备并创建应用

  • 创建设备
    点击产品进入,点击添加设备, 注意创建设备中鉴权信息会在后面的程序交互中用到。
    创建完设备后,您将得到一个设备 ID,这将在以后的程序交互中用到。
  • 创建应用
    设备的应用可以更好的对设备上传的数据进行统计和展示,点击创建应用,选择独立应用,选择产品及名称,点击创建。

2.2.3 应用处理

因为我们需要展示人流量的变化数据,因此在这里选择“折线图”,然后对坐标轴进行设置,得到一个大体的应用框架。

数据流中,目前只能选择到设备,在这时还不能对数据流进行选择,因为我们还没有开始进行数据上报,等到设备端连上OneNet并上报数据后,这里我们就可以选择数据流啦。

这里写图片描述

至此,平台端工作完毕。

2.3 设备端环境搭建

2.3.1 ESP-IDF SDK 和 Demo 获取

此 SDK 可以保证 ESP32 正常启动,良好工作,以及提供一些 Demo 供读者参考

$ git clone https://github.com/espressif/esp-iot-solution $ cd esp-iot-solution $ git submodule update --init --recursive

本 Demo 位于 esp-iot-solution/examples/check_pedestrian 下

2.3.2 ESP-IDF 编译器获取

根据官方的说明,不同的平台下载对应的编译器。

for windows:

  • 根据 esp-iot-solution/submodule/esp-idf/docs/get-started/windows-setup.rst 来搭建编译环境

for linux:

  • 根据 esp-iot-solution/submodule/esp-idf/docs/get-started/linux-setup.rst 来搭建编译环境

2.3.3 Demo 参数修改

在程序中的 main/include/onenet.h 中将刚刚在平台上创建得到的“设备 ID”,“产品 ID”,“鉴权信息” 进行填充:

#define ONENET_DEVICE_ID    "*****"         // mqtt client id        #define ONENET_PROJECT_ID   "*****"         // mqtt username        #define ONENET_AUTH_INFO    "*****"         // mqtt password

自定义数据流名称: // 此名称将会出现在 2.2.5 节中 选择数据流的字段中

#define ONENET_DATA_STREAM  "******"

2.3.4 导出 ESP-IDF 和 编译器路径

根据自己的目录结构导出 esp-idf 和 xtensa 编译器,这样才能编译整个 demo, 如:

$ cd check-pedestrian-flow$ export IDF_PATH=~/somepath/esp-iot-solution/submodule/esp-idf$ export PATH=/opt/xtensa-esp32-elf/bin/:$PATH

2.3.5 make menuconfig 配置

  • Serial flasher config - Default serial port // 配置烧写串口
  • Demo Configuration - WiFi SSID // 配置连接 路由器/AP 的SSID
  • Demo Configuration - WiFi Password // 配置 路由器AP 的密码

2.3.6 编译 && 运行

编译成功后,会自动烧写程序,同时自动运行程序。

$ make flash monitor

control+] 退出 monitor 界面

三:结果展示

3.1 设备端成功log如下:

... // 一些启动信息I (136) wifi: wifi firmware version: 59e5fabI (136) wifi: config NVS flash: enabledI (136) wifi: config nano formating: disabledI (136) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSEI (146) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSEI (186) wifi: Init dynamic tx buffer num: 32I (186) wifi: Init data frame dynamic rx buffer num: 32I (186) wifi: Init management frame dynamic rx buffer num: 32I (186) wifi: wifi driver task: 3ffbfa0c, prio:23, stack:4096I (196) wifi: Init static rx buffer num: 10I (196) wifi: Init dynamic rx buffer num: 32I (196) wifi: wifi power manager task: 0x3ffc5d8c prio: 21 stack: 2560W (206) phy_init: failed to load RF calibration data (0x1102), falling back to full calibrationI (536) phy: phy_version: 366.0, ba9923d, Oct 31 2017, 18:06:17, 0, 2I (546) wifi: mode : sta (24:0a:c4:04:5a:fc)I (546) SNIFFER: Connecting to AP...I (2236) wifi: n:12 0, o:1 0, ap:255 255, sta:12 0, prof:1I (2246) wifi: state: init -> auth (b0)I (2246) wifi: state: auth -> assoc (0)I (2246) wifi: state: assoc -> run (10)I (2256) wifi: connected with BL_841R, channel 12I (5086) event: sta ip: 192.168.111.111, mask: 255.255.255.0, gw: 192.168.111.1I (5086) SNIFFER: Connected.I (5086) wifi: ic_enable_sniffer[MQTT INFO] Connecting to server 183.230.40.39:6002,29207[MQTT INFO] Connected![MQTT INFO] Connected to server 183.230.40.39:6002[MQTT INFO] Sending MQTT CONNECT message, type: 1, id: 0000[MQTT INFO] Reading MQTT CONNECT response messageI (5256) wifi: pm start, type:0[MQTT INFO] Connected[MQTT INFO] Connected to MQTT broker, create sending thread before call connected callback[MQTT INFO] mqtt_sending_task[MQTT INFO] Queuing publish, length: 31, queue size(31/4096)[MQTT INFO] Sending...31 bytes[MQTT INFO] mqtt_start_receive_scheduleCurrent device num = 1MAC: 0x38.0x22.0xD6.0xD1.0x8C.0xF0, The time is: 6620, The rssi = -92Current device num = 2MAC: 0x38.0x22.0xD6.0xD0.0xCA.0xA0, The time is: 7970, The rssi = -59Current device num = 3MAC: 0x44.0x33.0x4C.0x59.0x42.0x69, The time is: 14040, The rssi = -24Current device num = 4MAC: 0x94.0x65.0x9C.0x88.0x2A.0x1B, The time is: 15300, The rssi = -91Current device num = 5MAC: 0xC6.0x81.0xAA.0xB8.0x0E.0x07, The time is: 20240, The rssi = -70Current device num = 6MAC: 0x44.0x33.0x4C.0x6A.0xB6.0x7F, The time is: 32490, The rssi = -56Current device num = 7MAC: 0x3E.0x97.0x88.0x49.0x37.0xD7, The time is: 36010, The rssi = -63... // 继续人流量检测

3.2 OneNet 平台结果展示

参考 2.2.5 节,打开 OneNET 控制台,可以看到设备已经在线,点击设备对应的应用,选择数据流“Pedestrian-flow”,则可以看到应用中数据流的变化曲线图,如下:

注意: 程序默认是十分钟上报一次数据,OneNet 平台要想看到曲线,需等待10分钟+

test

四:Demo 中一些分析和说明

4.1 Probe Request 包分析

Probe Request 包属于 802.11 标准,其基本的帧结构如下:

通过 wireshark 抓包获得 Probe Request 包如下:

注: ubuntu 下 wireshark 抓 802.11教程可参考

可以从包中看到该帧的 “Subtype : 4”, 还有信号强度和 MAC 地址等信息。

4.2 demo中部分逻辑说明

a) Probe request 判定

在程序中首先对抓到的包包头进行判定,当包头为 Probe Request 包时进行下一步判定,否则直接丢弃。

if (sniffer_payload->header[0] != 0x40) {    return;}

b) MAC地址选择过滤

得到真正的 Probe Request 包后,首先对来源设备的 MAC 地址进行分析,过滤掉一些不需要计算的设备(固定无线装置等), 在程序中我们过滤掉其他 ESP32 芯片的 MAC 地址。

for (int i = 0; i < 32; ++i) {     if (!memcmp(sniffer_payload->source_mac, esp_module_mac[i], 3)) {         return;     }}

c) 重复设备过滤

在抓到的包中,有相当一部分是来自于同一设备的 Probe Request 包,因此需要剔除。

for (station_info = g_station_list->next; station_info; station_info = station_info->next) {    if (!memcmp(station_info->bssid, sniffer_payload->source_mac, sizeof(station_info->bssid))) {            return;     }}

d) 链表说明

我们创建一个存储每一个设备信息的链表,在获得一个有效设备信息后,将该设备信息加入设备链表中。

if (!station_info) {   station_info = malloc(sizeof(station_info_t));   station_info->next = g_station_list->next;   g_station_list->next = station_info;}

e) MQTT 说明

ESP32 可以很好的移植并很好的支持 MQTT 协议,设备端通过 pubish 即可将数据发送到云端。

val =  s_device_info_num / 10;char buf[128];memset(buf, 0, sizeof(buf));sprintf(&buf[3], "{\"%s\":%d}", ONENET_DATA_STREAM, val);uint16_t len = strlen(&buf[3]);buf[0] = data_type_simple_json_without_time;buf[1] = len >> 8;buf[2] = len & 0xFF;mqtt_publish(client, "$dp", buf, len + 3, 0, 0);

4.3 人流量计算

首先需要确定计算人流量的区域范围,我们利用获得的设备信号强度进行划分,从而根据选择不同的信号强度来确定需要监控人流量的区域范围。

但是 RSSI 并不是协议中的字段,802.11协议中没有给出具体产生RSSI的过程或者说是算法吧。协议中说RSSI值范围0~255,RSSI值随PHY Preamble部分的能量单调递增。即在接收端网卡测量到RSSI的值以后,我们可以从这个程序接口获得RSSI的值。因此在不同的实地环境下,要根据实际测定来确定不同接受距离对应的实际 RSSI 值。

由于无线设备的普及,几乎人手都会持有一具有特定 MAC 地址的无线设备,而无线设备又会发送 Probe Request 包,因此只要得到空中的 Probe Request 包就可以计算出该区域的流动人数。

人流量是指在一定区域内单位时间的人流总数,因此我们以 10 分钟为侦测区间,通过对在 10 分钟内的所有人数进行计算来获得人流量。

在 10 分钟后将链表清空,开始下一阶段的监控。整个统计流程如下:

五:总结

通过 ESP32 进行抓包,可以在保证抓包质量的同时,也可以承担很多其他的功能角色,来最大程度的利用 ESP32。如 ESP32 可以通过 MQTT 协议进行订阅相关 topic, 进而通过云端来控制 ESP32.。

改进: 不同区域内的人流量大小会影响到 ESP32 接收到的信号强度发生变化,因此当使用信号强度来判定选择区域范围时会存在误差,此点需要改进。

你可能感兴趣的文章
MySQL InnoDB中意向锁的作用及原理探
查看>>
MySQL InnoDB事务隔离级别与锁机制深入解析
查看>>
Mysql InnoDB存储引擎 —— 数据页
查看>>
Mysql InnoDB存储引擎中的checkpoint技术
查看>>
Mysql InnoDB存储引擎中缓冲池Buffer Pool、Redo Log、Bin Log、Undo Log、Channge Buffer
查看>>
MySQL InnoDB引擎的锁机制详解
查看>>
Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock
查看>>
mysql InnoDB数据存储引擎 的B+树索引原理
查看>>
mysql innodb通过使用mvcc来实现可重复读
查看>>
mysql insert update 同时执行_MySQL进阶三板斧(三)看清“触发器 (Trigger)”的真实面目...
查看>>
mysql interval显示条件值_MySQL INTERVAL关键字可以使用哪些不同的单位值?
查看>>
Mysql join原理
查看>>
MySQL Join算法与调优白皮书(二)
查看>>
Mysql order by与limit混用陷阱
查看>>
Mysql order by与limit混用陷阱
查看>>
mysql order by多个字段排序
查看>>
MySQL Order By实现原理分析和Filesort优化
查看>>
mysql problems
查看>>
mysql replace first,MySQL中处理各种重复的一些方法
查看>>
MySQL replace函数替换字符串语句的用法(mysql字符串替换)
查看>>