保姆级教程,虚拟机中重复验证了三遍,包你顺利接入阿里云物联网平台

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。
人工智能编程入门博客

看到群里的小伙伴在修改linkkitapp例程遇到了麻烦,今天再分享一下代码修改的全过程,本文我在虚拟机中重复修改验证了三遍,包你可以顺利移植成功。

本文的实现,在上一篇网文的基础上实现:

AliOS Things物联网操作系统学习第一步:Windows下AliOS Things开发环境搭建

本文我们实现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模块

我们使用一个Micro USB线与D1 mini ESP8266模块相连,上文编译后的固件烧录之后,串口助手中会收到如下打印信息:

我们可以看到默认的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。

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行。

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;
}

编译一下,报错:

去掉platform\mcu\esp8266\bsp\driver\uart.c 60行, LOCAL void uart1_write_char(char c) 函数前面的LOCAL。

再次编译正常。

修改串口初始化,文件所在路径:platform\mcu\esp8266\bsp\entry.c 60行,修改后的代码具体如下:

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
}

解决问题3.

  • 下发有用信息:

修改文件app\example\linkkitapp\linkkit_example_solo.c 109行。

/** 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;
}

  • 上发有用信息:

修改文件 app\example\linkkitapp\linkkit_example_solo.c 27行处添加头文件:

#include "aos/hal/uart.h"

include\aos\hal\uart.h文件102行后增加两个函数声明:

int32_t hal_uart0_printf(const void *data);
int32_t hal_uart0_send(const void *data, uint32_t size);

AliOS-Things\platform\mcu\esp8266\hal\uart.c文件32行后增加两个函数实现:

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;
}

修改文件app\example\linkkitapp\linkkit_example_solo.c 378行, 修改上传属性的数据:

/* 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);
}

修改智能设备的三元组信息:

// for demo only
#define PRODUCT_KEY      "a1xHkDXXXXX"
#define PRODUCT_SECRET   "0miHcO6f4E8XXXXX"
#define DEVICE_NAME      "ZNFS0001"
#define DEVICE_SECRET    "xnOe5VcOkvXFTBAZaik4hz7y67XXXXXX"

登录阿里云飞燕平台:
https://living.aliyun.com/#/

创建阿里云物联网智能设备的方法请参见下文:

七步快速开启产品智能化

在产品页面获得ProductSecret

在设备页面获得设备的三元组信息:

烧写固件


使用云智能APP配网并添加设备

固件烧写完成之后,复位ESP8266模块,可以看到ESP8266的串口1打印如下信息:

此时虽然在扫描SSID,但是扫描二维码并不能正常添加设备,需要先进入配网模式,再扫描二维码添加设备。

进入配网模式的方法:

使用一个跳线,先把D5(GPIO14)接GND,再接3.3V。

出现如下Log即进入配网模式:

然后使用云智能APP扫描上面的二维码添加设备并配网。

配网成功,云智能APP出现如下界面:

配网成功,串口助手可以收到来自服务器端的如下Log日志:

此时查看阿里云飞燕平台的后台,可以看到设备已经成功上线。

模拟上传属性

经过上面的改造之后,我们只需要向UART0发送JSON格式的数据,即可修改服务器端的数值,比如发送:

{"CurrentTemperature":26}

发送完毕,服务器端的当前温度值将会修改为26℃,在运行状态中可以实时看出来当前温度值是实时变化的。

模拟设置属性

手机端APP点击某个按钮之后,将会将数据包发送至ESP8266,ESP8266将有用信息通过UART0的TX引脚发送给STM32,STM32将收到服务器端指令,对此指令进行解析,进而做相应的动作,具体逻辑类似下图所示。

调试真实设备中,对电源开关设置为1,即{“PowerSwitch”:1},在串口助手中我们收到指令{“PowerSwitch”:1};

我们对电源开关设置为0,即{“PowerSwitch”:0},可以看到串口助手中,收到对应的指令{“PowerSwitch”:0}。

STM32中我们使用cJSON对上面字符串进行解析即可,然后做相应的动作,即完成了云端对设备的远程控制。

细心的人可能发现了,为什么我们用CurrentTemperature或者PowerSwitch来设置属性呢?其实他们就是我们创建产品的时候,进行功能定义的时候,设置的标识符。

至此,使用ESP8266模块,已经完成了烧写AliOS Things 3.0固件,成功配网、添加设备并连上了阿里云服务器。

让ESP8266的串口0与STM32的串口进行数据通信,发送模拟上传属性中的数据完成属性的上报,串口接收解析服务器返回的数据,根据解析的结果进而完成对设备的控制,从而实现了STM32和ESP8266的双向通信。

各位小伙伴可以在我的基础上随意扩展,这样你的设备就实现了接入阿里云物联网平台。

要获取本人修改后的源码可以加程序员小哈好友索取!

欢迎关注

程序员小哈带你玩转嵌入式,微信搜索:嵌入式从0到1,更多干货等着你。

想进小哈技术交流群,请加程序员小哈个人微信,带你嵌入式入门进阶。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值