文章目录
- 概述
- WIFI8266 通信模组
- WIFI模组也用AT指令?
- ESP8266 内置协议栈?
- 支持的无线网络模式
- MCU通过串口与模组交互
- Wifi模组做客户端
- PC-AT接入路由器
- 向本地TCP服务发数据
- 用代码接入你家路由器
- 已接入AP(你家Wifi)
- 平台侧开发
- 工程配置和编译
- 工程配置
- 编译不过
- WIFI连接参数
- 接入AP成功,IoTDA失败
- 无可用加密套件
- 成功接入平台
概述
本实验基于WIFI模组实现智慧农业案例,实现实时数据采集,实现命令下发和响应,实现端云互通。实验目的包括:
- 掌握Wifi通信方式的配置。
- 掌握智慧农业案例的开发过程。
- 掌握Wifi+DTLS+PSK接入华为云物联网平台的方法。
- 了解LiteOS以及DTLS的裁剪,避免板卡Flash不足以存储编译结果。
- NB-IoT模组通过串口与主板MCU以AT指令交互,wifi模组也是。
@NOTE
转载请标明出处,https://blog.csdn.net/quguanxin/category_12929470.html
@HISTORY
从本实验开始,我将放弃使用LiteOS Stduio集成开发环境,转而使用新构建的 GitBash+GCC+CortexDebug 集成开发环境。在原本的计划里头,本文是要探寻LwM2M/CoAP与AT指令、Wifi、NB-IoT之间的关联,但实际上并没有,因为我遇到了其他困难。我原本以为在智慧农业NB-IoT实验基础上,Wifi实验过程会很顺利,但事与愿违。在编译阶段,启用DTLS模块后,遇到了程序大小超过Flash总额的问题。在平台接入阶段,由于错把设备ID当做设备标识码使用,导致接入平台失败。为了分析和解决上述问题,延伸多写了其他几篇文章。
WIFI8266 通信模组
WIFI8266通信模块是小熊派开发板用于通过Wi-Fi传输数据的通信扩展板,板载乐鑫 ESP8266 Wi-Fi通信模组。
WIFI模组也用AT指令?
从学习华为云物联网开始,这可能是我给自己挖的最大的坑,我一直以为AT指令是NB-IoT通信下的一种特有的指令,可现在来看,WIFI通信模组也是要使用AT指令的。那么,我们不得不重新来审视什么是AT指令?
AT指令绝非仅限于NB-IoT,而是贯穿各类通信模组(WiFi、4G蓝牙等)的通用控制协议,堪称物联网设备的 “神经系统语言”。
AT是"Attention"的缩写,历史遗留术语,它起源于很久以前,NB-IoT只是其后来的一个受益者而已。它在1981年由Hayes公司设计,用于调制解调器拨号控制(如ATDT拨号),通过文本化命令实现对通信模块的操控,隔离底层硬件差异,使主控MCU无需理解复杂射频协议。其本质是通过ASCII字符串控制通信模组的协议,实现设备与模组间的交互。
3GPP TS 27.007,定义基础指令如 AT+CSQ(信号强度),不是只指针对NB的,而是覆盖蜂窝网络,也包含4G/5G 等。但是 Wi-Fi 不在3GPP规范范围内,其AT指令由各芯片厂商(如乐鑫ESP8266)自行定义。虽无全球统一标准,但厂商也常会参考3GPP语法,采用类似格式,如,AT+CWJAP(连接Wi-Fi)、AT+CWSAP(创建热点)等指令。只是格式差不多,指令名不一样,
小熊派社区,扩展板资料中也有 <ESP-12F(ESP8266) AT指令使用示例.pdf> 等可以下载参考。在小熊派开发板这个场景下,AT指令是主板(MCU)与通信模组之间的控制语言,用于操控模组底层行为。
ESP8266 内置协议栈?
ESP8266 模块是有独立运行能力的哈,这点一定要提前意识到。
其内部集成Tensilica L106 32位微控制器,自带Flash存储,可直接运行固件。该固件包含完整的 LwIP 协议栈,支持 IPv4 的TCP、UDP、HTTP 等常见协议。ESP8266 扩展板仅通过 UART/TX/RX引脚 与主板通信,主板仅需实现串口数据传输,不参与任何协议处理。主板(如STM32)仅需通过UART串口发送AT指令控制ESP8266,例如,AT+CIPSTART=“TCP”,“192.168.1.100”,8080 建立TCP连接。
进一步的,这意味着什么呢?我们不需要在主板程序中启用LWIP协议栈,这将会减少很多的一笔开销。
需要注意的是,ESP8266模组并不内置LwM2M客户端,
如前文所述,其内置LwIP TCP/IP协议栈,支持基础网络通信,但并无内置LwM2M/CoAP这种更上层的应用层协议。在理论上,Wifi模组可以通过OpenCPU/SDK可集成CoAP/LwM2M,但需开发者手动实现,且资源占用较高。
支持的无线网络模式
ESP8266 Wi-Fi扩展板(如小熊派开发板所用)支持三种主要无线网络模式:
Station(STA)模式SoftAP(AP)模式STA+AP混合模式。这些模式决定了模块如何与其他设备或网络交互,适用于不同物联网场景。
Station (STA) 模式 - 客户端角色,
源自 IEEE 802.11(Wi-Fi)标准术语,指连接到无线网络的终端设备,如手机、笔记本电脑。你的手机连接家里路由器时,手机(相关通信模组)就是 Station,哈哈,这里的Station其含义车站的乘客,不是车站,AP才是车站,互联网算是动车高铁吧。当扩展板处于此工作模式时,它就相当于你的手机一样,去链接你家的路由器。该角色下的设备,会包含扫描可用网络、发起认证连接(向AP接入点的认证请求)、获取IP地址(DHCP客户端)等技术行为。
Access Point (AP) 模式 - 服务端角色,
IEEE 802.11 标准定义的无线网络接入点,即提供Wi-Fi信号的设备,如,路由器。也就是说扩展板可以像我们家路由器那样,做为网络的创建者和服务提供者,主动广播SSID创建无线网络、为STA设备分配IP、路由数据,组件本地局域网。该角色下的设备,会有,广播信标帧、宣告网络存在,认证连接请求(如WPA2-PSK握手),作为DHCP服务器分配IP地址,等技术行为。SoftAP 区别于硬件AP(专用路由器芯片),其通常是资源受限的,具有临时性,通常用于特定场景(如配网),在早期家用无线摄像头配置方案里确实见过。
MCU通过串口与模组交互
在<IoT/透过oc_lwm2m和at源码,分析NB-IoT通信模组和主板MCU之间的通信过程和工作机制> 文中,我们已经从软件源码层级上,分析论证了NB-IoT模组与主板MCU之间是通过串口进行通信的。那么ESP8266同样依赖UART传输AT指令和数据吗?首先,答案是肯定的。但在本文我们先不急着从软件实现层次上去分析这个事情。因为看看硬件原理图,一切就不容狡辩。实锤。
Wifi/ESP8266通信模组原理图,
NB-IoT通信模组原理图,
如上,无论是WiFi或NB-IoT通信模组,都具有串口Rx/Tx通信管脚导出,用于和主板进行串口通信,交互AT指令和数据。
Wifi模组做客户端
在我们的实验5-Wifi智慧农业,中 ESP8266,其工作在客户端模式。
PC-AT接入路由器
其实一开始,我不知道ESP8266这东西还能用PC-AT指令接入接力的路由器,我是在看了一会源码后才发现的。 <ESP-12F(ESP8266) AT指令使用示例.pdf> 等手册可以从文中连接下载。接下来,我们根据手册内容,进行些简单实验。与NB-IoT-AT指令的PC实践一样,拨码开发要拨到PC侧,但是这里的波特率是115200,不与PC-AT一样了哈。
//设置模组为客户端模式
AT+CWMODE=3
//固件中是纯字符串解析,相当脆弱,一定要注意不要在任何地方不要乱加空格
AT+CWJAP="HUAWEI-IoT","1xxxxxxxxx2+"
建立TCP连接,
这里还闹腾了乌龙。早期我使用Wifi代码连接到平台的实践中,我连接的是家里凌霄路由器的客人WIFI,当时我是实验成功的。现如今用PC-AT指令实验,依据ESP8266的AT指令手册,使用网络助手在本地创建TCP服务端,使用AT指令控制ESP8266建立TCP连接,结果总是连接不上。我关闭了防火墙、禁用了所有其他网络适配器,依然不行。但是当我切换到正常的WIFI网络时,我就可以ping通了。当然,关闭防火墙或进行更细粒度的策略配置,肯定是必要,否则你肯定是ping不通的。至于为啥客网在PC-AT指令实现时,存在不通,可能这是凌霄Q6独有策略吧,我没再深究,没有那个时间。
向本地TCP服务发数据
//查询模组的IP地址
AT+CIFSR
//测试从模组到PC主机的可达性
AT+PING="192.168.155.10"
//连接到本地TCP服务
AT+CIPSTART="TCP","192.168.3.7",62100
//数据发送/发多了会被截断哈
AT+CIPSEND=4
如下图,我们发送 CSDN_DAHE_QU 多个字符,最终实际发送4个字符成功.
我们前文提到过,ESP8266也是用AT指令与MCU通信的,看到上述CIPSTART、CIPSEND等指令,去源码里搜一下就豁然开朗了。
用代码接入你家路由器
首先在.config配置中,修改CONFIG_ESP8266_SSID和CONFIG_ESP8266_PWD的值,为你家的Wifi名称和密码。这两个宏定义会在 ESP8266 驱动程序中使用,并最终作为 esp8266_joinap 函数的输入参数,具体过程如下,
//宏重命名
#define WIFI_SSID CONFIG_ESP8266_SSID //在.config模式下定义
#define WIFI_PASSWD CONFIG_ESP8266_PWD //在.config模式下定义
//使用上述宏作实参的函数实现
static bool_t esp8266_joinap(char *ssid, char *passwd) {char cmd[64];(void) memset(cmd,0,64);(void) snprintf(cmd,64,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid, passwd);return esp8266_atcmd(cmd,"OK");
}
通过上述函数实现可以看出来,底层通过调用扩展板的AT指令,完成扩展板与AP的链接过程。这里AT指令,可参见相关手册。在代码调试前,可以先基于PC上的AT指令测试上述连接过程。
已接入AP(你家Wifi)
这个过程挺顺利的。我在终端中配置的是Q6访客网的连接信息,在Q6的Web管理页面中,可以检索到扩展板连接情况。
平台侧开发
与实验-5/基于NB-IoT,使用相同产品模型和设备定义也是可以的。我们这里只重点再强调下设备注册中的设备秘钥配置问题。为了更好的说明一些问题,我们重新注册一个新设备,包括密码设置什么的,截图上都不打码,以更好的理解。
密码设置时,我坑了自己好几次了,哈哈,还每次都觉得自己理解无误。
上述红色告警信息有些不靠谱,自己与左侧提示信息就矛盾着。
首先,华为云IoT平台在创建注册设备时,似乎无法区分是否为NB设备。其次,你输入非16进制(0~F)字符,如H、J、Q等字符时,是无法通过输入检查的。上图右侧的告警,也很绕人。所谓1个十六进制字符,并不是字符串单字符的概念,如上0x00、0x99、0xAA 都只算是一个字符,即单字节8bit的16进制数据。是字节数据,不是字符数据,以A5为例,它可以使用0xA5这个单字节存储或传输,当然也可以使用0x41(‘A’)和0x35(‘5’)两个字节来存储或传输。
另外,已经验证过的一个问题是,
使用Wifi模组进行通信时,我们可以任意但唯一的指定设备标识码,不必一定是MAC。NB-IoT设备不行哦,只能是IMEI。
工程配置和编译
工程配置,并不复杂,基本可按照HCIP-IOT实验手册进行。编译过程中倒是遇到了不少的麻烦。
工程配置
修改.config中的串口波特率。将NB-IoT连接模式修改为WIFI模式,详情可参见具体源码,点击此链接下载即可。
CONFIG_UARTAT_BAUDRATE=115200
CONFIG_TCPIP_AL_ENABLE=y
CONFIG_ESP8266_ENABLE=y
CONFIG_ESP8266_SSID="HUAWEI-IoT"
CONFIG_ESP8266_PWD="135836xxx02+"
CONFIG_DTLS_AL_ENABLE=y //记得打开
CONFIG_MBEDTLS_ENABLE=y //记得打开
CONFIG_MBEDTLS_PSK=y //记得打开
CONFIG_OCLWM2M_ENABLE=y
CONFIG_OCLWM2MTINY_ENABLE=y
编译不过
开启上述DTLS三联配置后,编译报错,说是Flash溢出了,即Flash存不下编译生成的elf可执行文件了,
小熊派开发板使用的STM32L431RCT6,其片内Flash只有256K,确实不大。通过芯片手册,或小熊派官网可以查询到,
为了验证编译器报错是否靠谱,我们先造个假,欺骗下编译器。我们修改在 LiteOS_Lab_HCIP\targets\STM32L431_BearPi\GCC 目录下的 os.ld 配置文件,临时设置Flash为512K,重新编译。
被欺骗的编译器是可以通过编译的。左侧是启用DTLS前的编译结果,
启用DTLS后,作为编译结果的程序大出来68000字节,约合65KB字节,为什么DTLS这么耗费存储呢?是源码中开启的模块宏,如一些调试和日志模块。包括底层LiteOS的一些暂时不用的模块,都开启了。需要裁减,但是这很费心神,愁得慌啊真是。我当时先的办法,
0、裁简DTLS模块。(LiteOS我还不是特别熟,可能裁减不好,DTLS我试了试,各个细枝末节有关联,也没有参考)
1、不使用DTLS,退回到不安全模式。 (后记/应该确实不支持了)
2、是使用外扩展的Flash,来存放程序。(这不简单啊)
3、放弃使用小熊派开发板,转而使用Flash更大的芯片或板子。(太贵了)
哎,每个都不简单啊。好在天无绝人之路,LiteOS中的Wifi示例程序,尽然裁减的不错,可以满足编译呢。使用小熊派提供的示例程序,
…\bearpi-iot_std_liteos-master\targets\STM32L431_BearPi\Demos\oc_wifi_lwm2m_agriculture,结合自己的代码,结果如下,
WIFI连接参数
基于LiteOS lwM2M_al 的核心封装实现,在应用层看来,NB-IoT通信或基于Wifi通信是一致的,连设备接入流程的代码都是一致的,只是在接入参数配置上有所区别,这是真替用户考虑啊。应用层代码实现请参考 #<IoT/HCIP实验-5/基于NB-IoT的智慧农业实验(平台侧开发+端侧编码+基础调试分析)>#,本文只简单说说WIFI通信下的设备接入配置。
#define cn_app_pskid "csdn_dahe_0528"
//#define cn_app_psk "00112233445566778899" //这是错误的哈
const unsigned char cn_app_psk[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA};
#define cn_app_psklen 10 //建议使用sizeof(cn_app_psk)static int app_report_task_entry() {...oc_param.app_server.address = CONFIG_APP_SERVERIP;oc_param.app_server.port = CONFIG_APP_SERVERPORT;oc_param.app_server.ep_id = CONFIG_APP_ENDPOIINT_ID;oc_param.boot_mode = en_oc_boot_strap_mode_factory;oc_param.rcv_func = app_msg_deal;#if 1 //CoAPS/DTLS加密oc_param.app_server.ep_id = cn_app_pskid;oc_param.app_server.psk = (char *)cn_app_psk;oc_param.app_server.psk_len = sizeof(cn_app_psk);oc_param.app_server.psk_id = cn_app_pskid;#endifret = oc_lwm2m_config( &oc_param);...
}
特别注意,特别注意,WIFI下的oc_param.app_server.psk,即cn_app_psk定义,与NB-IoT不同,不是使用字符串哈。
接入AP成功,IoTDA失败
异常分析,小熊派开发板使用Wifi通信扩展板,接入AP成功,但是连接平台失败,
[DEBUG][189183][registration_step:1382] [189][registration_step:1382] targetP Status: STATE_REG_PENDING
[DEBUG][189192][transaction_step:505] [189][transaction_step:505] Entering
[DEBUG][189199][lwm2m_step:767] [189][lwm2m_step:767] Final timeoutP: ld
[DEBUG][189206][lwm2m_step:769] [189][lwm2m_step:769] Final state: STATE_REGISTERING
小熊派开发板WiFi接入AP成功后连接华为云平台失败(状态卡在STATE_REG_PENDING和STATE_REGISTERING)。平台地址或端口配置已经在NB-IoT实验中进行过实验(后来发现这是病灶)。因此分析最可能导致上述问题的原因是,DTLS握手失败。
无可用加密套件
握手失败错误-0x6900通常因未启用CCM_C或PSK导致。
我在尝试自己裁减HCIP-IoT-Lab代码中的DTLS算法库时,曾经遇到以上问题,关键原因是无可用加密套件,或者是PSK与平台设置不一致,在后续的其他文章中,我们还会单独针对DTLS采集重新讨论。
成功接入平台
设备侧接入日志,
平台侧设备详情,