电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
保姆级教程,虚拟机中重复验证了三遍,包你顺利接入阿里云物联网平台
分 享
扫描二维码分享
保姆级教程,虚拟机中重复验证了三遍,包你顺利接入阿里云物联网平台
物联网
AliOS
esp8266
嵌入式从0到1
关注
发布时间: 2020-12-28
丨
阅读: 669
周三的网文阅读量好惨,到了周日还没过200,本想暂时不更此方面内容了。 ![](https://img-blog.csdnimg.cn/20201227203220316.png) 但是看到群里的小伙伴在修改linkkitapp例程遇到了麻烦,今天再分享一下代码修改的全过程,本文我在虚拟机中重复修改验证了三遍,包你可以顺利移植成功。 本文的实现,在上一篇网文的基础上实现,开发环境的搭建参见下文: [**AliOS Things物联网操作系统学习第一步:Windows下AliOS Things开发环境搭建**](https://mp.weixin.qq.com/s/bGiZYIDi2oe8QIgq-9AG2A) 本文我们实现linkkitapp例程修改、ESP8266固件的下载、一键配网和云智能APP绑定设备。 ### 需要解决的问题 ESP8266 有两个UART:UART0和UART1。 UART0有TX、RX,可以作为系统的打印信息输出接口和数据收发口。 UART1的RX被Flash占用,只有发送引脚TX(GPIO2,即UART1_TXD),所以一般作为打印信息输出接口(调试用)。 通常情况下,我们使用UART0和外设通讯,而使用UART1作为日志打印端口。 D1 mini ESP8266模块两个串口的所在位置: ![ESP8266 D1 mini模块](https://img-blog.csdnimg.cn/20201227203258250.png) 我们使用一个Micro USB线与D1 mini ESP8266模块相连,上文编译后的固件烧录之后,串口助手中会收到如下打印信息: ![](https://img-blog.csdnimg.cn/20201227203337117.gif) 我们可以看到默认的linkkitapp示例,Log信息是通过UART0发送出来的,而且里面有很多咱们不关心的信息,应该将此部分信息进行屏蔽。 所以我们需要做如下几个工作: 1. 将串口0和串口1的比特率设为一致; 2. 交换UART0和UART1,让UART1输出Log日志;UART0与STM32进行通信; 3. 将STM32发上来的信息,通过UART0接收并发送到云端;将云端下发的有用的信息通过UART0转发给STM32。 **解决问题1.** 串口的初始化api在`platform\mcu\esp8266\bsp\driver\uart.c` 411行 中,初始化uart1,uart0的波特率都为115200。 ```C void uart_init_new(uart_dev_t *uart) { UART_WaitTxFifoEmpty(UART0); UART_WaitTxFifoEmpty(UART1); if (uart == NULL) { return; } if (uart->port == 1) { //printf("port= 1\n "); //uart1 setting UART_ConfigTypeDef uart_config; uart_config.baud_rate = uart->config.baud_rate; uart_config.data_bits = UART_WordLength_8b; uart_config.parity = USART_Parity_None; uart_config.stop_bits = USART_StopBits_1; uart_config.flow_ctrl = USART_HardwareFlowControl_None; uart_config.UART_RxFlowThresh = 120; uart_config.UART_InverseMask = UART_None_Inverse; //UART_ParamConfig(UART0, &uart_config); //uart2 setting for log //uart_config.baud_rate = uart->config.baud_rate; UART_ParamConfig(UART1, &uart_config); UART_SetPrintPort(UART1); //UART_intr_handler_register(uart0_rx_isr, NULL); ETS_UART_INTR_ENABLE(); } else { //printf("port= 0 \n "); UART_ConfigTypeDef uart_config; uart_config.baud_rate = uart->config.baud_rate; // uart_config.baud_rate = BIT_RATE_921600; uart_config.data_bits = UART_WordLength_8b; uart_config.parity = USART_Parity_None; uart_config.stop_bits = USART_StopBits_1; uart_config.flow_ctrl = USART_HardwareFlowControl_None; uart_config.UART_RxFlowThresh = 120; uart_config.UART_InverseMask = UART_None_Inverse; UART_ParamConfig(UART0, &uart_config); UART_IntrConfTypeDef uart_intr; uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA; uart_intr.UART_RX_FifoFullIntrThresh = 100;//10 uart_intr.UART_RX_TimeOutIntrThresh = 10;//2 uart_intr.UART_TX_FifoEmptyIntrThresh = 20; UART_IntrConfig(UART0, &uart_intr); UART_SetPrintPort(UART0); UART_intr_handler_register(uart0_rx_isr, NULL); ETS_UART_INTR_ENABLE(); } } ``` **解决问题2.** 交换UART0和UART1: 修改此文件:`AliOS-Things\platform\mcu\esp8266\hal\uart.c` 17行。 ```C int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout) { int i = 0; char* pdata = (char *)data; for(i = 0; i < size; i++) { //uart0_write_char(pdata[i]); if(uart->port == 1) uart0_write_char(pdata[i]); else uart1_write_char(pdata[i]); } return 0; } ``` ![](https://img-blog.csdnimg.cn/20201227203519394.png) 编译一下,报错: ![](https://img-blog.csdnimg.cn/20201227203532604.png) 去掉`platform\mcu\esp8266\bsp\driver\uart.c` 60行, `LOCAL void uart1_write_char(char c)` 函数前面的LOCAL。 ![](https://img-blog.csdnimg.cn/20201227203547389.png) 再次编译正常。 修改串口初始化,文件所在路径:`platform\mcu\esp8266\bsp\entry.c` 60行,修改后的代码具体如下: ```C void user_init(void) { int ret = 0; extern int32_t hal_uart_init(uart_dev_t *uart); extern void key_gpio_init(void); key_gpio_init(); ///hal_uart_init(&uart_0); uart_config_t uartConfig0; uartConfig0.baud_rate = 115200; uartConfig0.parity = 0; uartConfig0.stop_bits = 1; uart_dev_t uart0; uart0.port = 0; uart0.config = uartConfig0; hal_uart_init(&uart0); uart_config_t uartConfig1; uartConfig1.baud_rate = 115200; uart_dev_t uart1; uart1.port = 1; uart1.config = uartConfig1; hal_uart_init(&uart1); printf("[%d] -- Message from printf -- user_init -- \r\n",(unsigned)aos_now_ms()); hal_wifi_register_module(&aos_wifi_esp8266); ret = hal_wifi_init(); if (ret){ printf("waring: wifi init fail ret is %d \r\n", ret); } #if defined(SUPPORT_SINGAPORE_DOMAIN) aos_task_new("main", app_entry, 0, 7.5*1024); #elif defined(ESP8266_CHIPSET) aos_task_new("main", app_entry, 0, 2*1024); #else aos_task_new("main", app_entry, 0, 6*1024); #endif } ``` ![](https://img-blog.csdnimg.cn/20201227203606880.png) **解决问题3.** * 下发有用信息: 修改文件`app\example\linkkitapp\linkkit_example_solo.c` 109行。 ```C /@@** recv event post response message from cloud **/ static int user_property_set_event_handler(const int devid, const char *request, const int request_len) { int res = 0; EXAMPLE_TRACE("Property Set Received, Request: %s", request); hal_uart0_send(request,strlen(request)); //xiaoha +++ res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY, (unsigned char *)request, request_len); EXAMPLE_TRACE("Post Property Message ID: %d", res); return 0; } ``` ![](https://img-blog.csdnimg.cn/20201227203621161.png) * 上发有用信息: 修改文件 `app\example\linkkitapp\linkkit_example_solo.c` 27行处添加头文件: ```C #include "aos/hal/uart.h" ``` ![](https://img-blog.csdnimg.cn/20201227221950134.png) 在`include\aos\hal\uart.h`文件102行后增加两个函数声明: ```C int32_t hal_uart0_printf(const void *data); int32_t hal_uart0_send(const void *data, uint32_t size); ``` ![](https://img-blog.csdnimg.cn/20201227222008217.png) 在`AliOS-Things\platform\mcu\esp8266\hal\uart.c`文件32行后增加两个函数实现: ```C int32_t hal_uart0_printf(const void *data) { int i = 0; char* pdata = (char *)data; while(* pdata) uart0_write_char(* pdata++); return 0; } int32_t hal_uart0_send(const void *data, uint32_t size) { int i = 0; char* pdata = (char *)data; for(i = 0; i < size; i++) { uart0_write_char(pdata[i]); } uart0_write_char('\r'); uart0_write_char('\n'); return 0; } ``` ![](https://img-blog.csdnimg.cn/20201227222027247.png) 修改文件`app\example\linkkitapp\linkkit_example_solo.c` 378行, 修改上传属性的数据: ```C /@@* Post Proprety Example */ uint8_t receive_bytes[255]; memset(receive_bytes,0,255); //或者 memset(receive_bytes,0,128*sizeof(char)); int32_t ret = -1; uint32_t i, recv_size = 0; uart_dev_t uart0; uart0.port = 0; ret = hal_uart_recv_II(&uart0, &receive_bytes, 255, &recv_size, 20); if ((ret == 0)) { hal_uart0_printf(receive_bytes); char property_payload[30] = {0}; HAL_Snprintf(property_payload,sizeof(property_payload),"%s",receive_bytes); res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID,ITM_MSG_POST_PROPERTY, (unsigned char *)property_payload,strlen(property_payload)); EXAMPLE_TRACE("Post Property Message ID: %d",res); } ``` ![](https://img-blog.csdnimg.cn/20201227222043473.png) 修改智能设备的三元组信息: ```C // for demo only #define PRODUCT_KEY "a1xHkDXXXXX" #define PRODUCT_SECRET "0miHcO6f4E8XXXXX" #define DEVICE_NAME "ZNFS0001" #define DEVICE_SECRET "xnOe5VcOkvXFTBAZaik4hz7y67XXXXXX" ``` ![](https://img-blog.csdnimg.cn/20201227222201929.png) 登录阿里云飞燕平台: https://living.aliyun.com/#/ 创建阿里云物联网智能设备的方法请参见下文: [七步快速开启产品智能化](https://mp.weixin.qq.com/s/iaZcX6KRzbDXso3SF-MFEw) 在产品页面获得`ProductSecret` : ![](https://img-blog.csdnimg.cn/20201227222228142.png) 在设备页面获得设备的三元组信息: ![](https://img-blog.csdnimg.cn/20201227222238607.png) ### 烧写固件 ![](https://img-blog.csdnimg.cn/20201227222253472.png) ![](https://img-blog.csdnimg.cn/20201227222301538.png) ### 使用云智能APP配网并添加设备 固件烧写完成之后,复位ESP8266模块,可以看到ESP8266的串口1打印如下信息: ![](https://img-blog.csdnimg.cn/20201227222315429.png) 此时虽然在扫描SSID,但是扫描二维码并不能正常添加设备,需要先进入配网模式,再扫描二维码添加设备。 **进入配网模式的方法:** 使用一个跳线,先把D5(GPIO14)接GND,再接3.3V。 出现如下Log即进入配网模式: ![](https://img-blog.csdnimg.cn/2020122722233947.png) 然后使用云智能APP扫描上面的二维码添加设备并配网。 ![](https://img-blog.csdnimg.cn/20201227222346330.png) 配网成功,云智能APP出现如下界面: ![](https://img-blog.csdnimg.cn/20201227222359952.png) 配网成功,串口助手可以收到来自服务器端的如下Log日志: ![](https://img-blog.csdnimg.cn/20201227222414691.png) 此时查看阿里云飞燕平台的后台,可以看到设备已经成功上线。 ![](https://img-blog.csdnimg.cn/20201227222430918.png) ### 模拟上传属性 经过上面的改造之后,我们只需要向UART0发送JSON格式的数据,即可修改服务器端的数值,比如发送: ```C {"CurrentTemperature":26} ``` 发送完毕,服务器端的当前温度值将会修改为26℃,在运行状态中可以实时看出来当前温度值是实时变化的。 ![](https://img-blog.csdnimg.cn/20201227222444988.gif) ### 模拟设置属性 手机端APP点击某个按钮之后,将会将数据包发送至ESP8266,ESP8266将有用信息通过UART0的TX引脚发送给STM32,STM32将收到服务器端指令,对此指令进行解析,进而做相应的动作,具体逻辑类似下图所示。 ![](https://img-blog.csdnimg.cn/20201227222457195.gif) 调试真实设备中,对电源开关设置为1,即{"PowerSwitch":1},在串口助手中我们收到指令{"PowerSwitch":1}; 我们对电源开关设置为0,即{"PowerSwitch":0},可以看到串口助手中,收到对应的指令{"PowerSwitch":0}。 STM32中我们使用cJSON对上面字符串进行解析即可,然后做相应的动作,即完成了云端对设备的远程控制。 细心的人可能发现了,为什么我们用CurrentTemperature或者PowerSwitch来设置属性呢?其实他们就是我们创建产品的时候,进行功能定义的时候,设置的标识符。 ![](https://img-blog.csdnimg.cn/20201227222508474.png) 至此,使用ESP8266模块,已经完成了烧写AliOS Things 3.0固件,成功配网、添加设备并连上了阿里云服务器。 让ESP8266的串口0与STM32的串口进行数据通信,发送模拟上传属性中的数据完成属性的上报,串口接收、解析服务器返回的数据,根据解析的结果进而完成对设备的控制,从而实现了STM32和ESP8266的双向通信。 各位小伙伴可以在我的基础上随意扩展,这样你的设备就实现了接入阿里云物联网平台。 要获取本人修改后的源码可以加程序员小哈好友索取! ### 欢迎关注 程序员小哈带你玩转嵌入式,微信搜索:**嵌入式从0到1**,更多干货等着你。 也可以进入小哈哥的个人博客:www.xiaohage.com 获取更多内容。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
2
)
嵌入式从0到1
关注
评论
(1)
登录后可评论,请
登录
或
注册
3419622252
137
天前...
牛逼
0
回复
发布
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交