RT-Thread Studio学习(八)利用ESP8266连接阿里云IOT

简介

本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用阿里云IOT软件包。

新建RT-Thread项目并使用外部时钟

详细步骤参考文档《RT-Thread Studio学习之使用外部时钟系统》。

使能串口6

详细步骤参考文档《RT-Thread Studio学习之使用多串口》。

接入ESP8266

本文测试使用的是ESP8266-01S,与MCU的接线如下图所示:
在这里插入图片描述
图中的MCU_RXD对应UART6_RXD,MCU_TXD对应UART6_TXD。因为ESP8266-01S模块的CH_PD和RST引脚有上拉,所以可以悬空。

添加AT组件

硬件连接好之后需要在RT-Thread Studio设置中添加AT组件,在Studio的软件包中心搜索at_device,点击添加。
在这里插入图片描述
进入软件包的详细配置页面,进行如下配置:
配置AT组件
配置好WIFI SSID和密码后,保存项目并编译下载。上电后在控制台输入ifconfig,会有如下显示:
在这里插入图片描述

添加阿里云IOT软件包

在软件包中心搜索ali-iotkit并添加,
在这里插入图片描述
右击组件选中详细配置,输入阿里云IOT平台设备的三元组信息,开启示例代码,其他参数默认:
在这里插入图片描述

测试

保存项目,编译下载。上电后在控制台输入ali_mqtt_sample,就可以连接到阿里云IOT平台进行MQTT通信了。
在这里插入图片描述
在阿里云IOT平台,进入相关设备的日志服务,可以查看到相关消息内容:

在这里,stm32不断地发送hello信息,阿里云平台设备同步接收。

上报/接收数据

新建mqtt_sample.c文件,内容如下:

/*
 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
 * 
 * Again edit by rt-thread group
 * Change Logs:
 * Date          Author          Notes
 * 2019-07-21    MurphyZhao      first edit
 */

#include "rtthread.h"
#include "dev_sign_api.h"
#include "mqtt_api.h"

char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
char DEMO_DEVICE_SECRET[IOTX_DEVICE_SECRET_LEN + 1] = {0};

uint8_t temp_f407=0; //采集到的温度数值,-50~100
uint8_t humi_f407=0; //采集到的湿度数值,0~100

void *HAL_Malloc(uint32_t size);
void HAL_Free(void *ptr);
void HAL_Printf(const char *fmt, ...);
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]);
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
uint64_t HAL_UptimeMs(void);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);

#define EXAMPLE_TRACE(fmt, ...)  \
    do { \
        HAL_Printf("%s|%03d :: ", __func__, __LINE__); \
        HAL_Printf(fmt, ##__VA_ARGS__); \
        HAL_Printf("%s", "\r\n"); \
    } while(0)

static void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    iotx_mqtt_topic_info_t     *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;

    switch (msg->event_type) {
        case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
            /* print topic name and topic message */
            EXAMPLE_TRACE("Message Arrived:");
            EXAMPLE_TRACE("Topic  : %.*s", topic_info->topic_len, topic_info->ptopic);
            EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
            EXAMPLE_TRACE("\n");
            break;
        default:
            break;
    }
}

static int example_subscribe(void *handle)
{
    int res = 0;
    //const char *fmt = "/%s/%s/user/get";
    const char *fmt = "/sys/%s/%s/thing/event/property/post";
    char *topic = NULL;
    int topic_len = 0;

    topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
    topic = HAL_Malloc(topic_len);
    if (topic == NULL) {
        EXAMPLE_TRACE("memory not enough");
        return -1;
    }
    memset(topic, 0, topic_len);
    HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);

    res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);
    if (res < 0) {
        EXAMPLE_TRACE("subscribe failed");
        HAL_Free(topic);
        return -1;
    }

    HAL_Free(topic);
    return 0;
}

static int example_mypublish(void *handle) //向Topic主题发布属性函数
{
    int             res = 0;
    const char     *fmt = "/sys/%s/%s/thing/event/property/post";
    const char     *fmt_payload = "{\"params\" : { \"temperature\":%d,\"humidity\":%d } }";
    char           *topic = NULL;
    int             topic_len = 0;
    int             payload_len = 0;
    char           *payload = NULL;
    payload_len = strlen(fmt_payload)+4;
    payload = HAL_Malloc(payload_len);
        if (payload == NULL) {
            EXAMPLE_TRACE("memory not enough");
            return -1;
        }
        memset(payload, 0, payload_len);
    HAL_Snprintf(payload,payload_len,fmt_payload,temp_f407,humi_f407);
    temp_f407 = (temp_f407 + 10)%100;
    humi_f407 = (humi_f407 + 7)%100;

    topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
    topic = HAL_Malloc(topic_len);
    if (topic == NULL) {
        EXAMPLE_TRACE("memory not enough");
        return -1;
    }
    memset(topic, 0, topic_len);
    HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);


    res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));
    if (res < 0) {
        EXAMPLE_TRACE("publish failed, res = %d", res);
        HAL_Free(topic);
        HAL_Free(payload);
        return -1;
    }

    HAL_Free(topic);
    HAL_Free(payload);
    return 0;
}

static void example_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    EXAMPLE_TRACE("msg->event_type : %d", msg->event_type);
}

static int mqtt_example_mymain(int argc, char *argv[])
{
    void                   *pclient = NULL;
    int                     res = 0;
    iotx_mqtt_param_t       mqtt_params;

    HAL_GetProductKey(DEMO_PRODUCT_KEY);
    HAL_GetDeviceName(DEMO_DEVICE_NAME);
    HAL_GetDeviceSecret(DEMO_DEVICE_SECRET);

    EXAMPLE_TRACE("mqtt example");

    memset(&mqtt_params, 0x0, sizeof(mqtt_params));

    mqtt_params.handle_event.h_fp = example_event_handle;

    pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        EXAMPLE_TRACE("MQTT construct failed");
        return -1;
    }

    res = example_subscribe(pclient);
    if (res < 0) {
        IOT_MQTT_Destroy(&pclient);
        return -1;
    }

    while (1)
    {
        example_mypublish(pclient);
        rt_thread_delay(60000);
        IOT_MQTT_Yield(pclient, 200);
    }

    return 0;
}

static rt_thread_t tid1 = RT_NULL;
int mqtt_thread(void) //创建mqtt线程
{
    tid1 = rt_thread_create("mqtt_thd", mqtt_example_mymain, RT_NULL, 4096, 14, 10);
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);
    return 0;
}

#ifdef FINSH_USING_MSH
MSH_CMD_EXPORT(mqtt_thread, ali mqtt sample);
#endif
RT-Thread作品秀】基于RT-Thread的气压温度测量系统作者:安静的句型 概述(说明应用产生的背景、实现功能)基于ART-Pi,利用MS-P2XD10气压传感器模块,L610-CN-00-MiniPCIe-10Cat模块,设计了一款气压温度测量系统,测量环境的大气压力和温度,并上报到阿里云连接到物模型,实时显示。 开发环境(所采用的软、硬件方案)硬件:ART-Pi;L610;LPS22HH RT-Thread版本:4.0.3 开发工具及版本:MDK-v5.27.0.0 RT-Thread使用情况概述(简要总结下应用中RT-Thread使用情况:内核部分、组件部分、软件包部分、内核、其他)使用了RT-Thread内核中使用线程、信号量、 邮箱、内存池等功能,在读取到传感器数据后,将气压和温度数据通过邮箱传输到阿里云发布线程,向云端发送。 调用了FinSH组件用于系统过程调试,监视线程应用情况、设备使用情况、其它信息等。 加载了多个软件包: AT DEVICE软件包,用于L610的驱动。 WebClient软件包,测试L610功能。 ali_iotkit软件包,配置阿里云三元组信息,连接阿里云。 cJSON软件包,进行数据封装。 硬件框架(概述应用所采用的硬件方案框图,并对核心部分做介绍)利用ART-Pi作为主控单元,通过I2C接口与LPS22HH气压传感器模块通讯,获取气压和温度值。通过UART接口与L610Cat通讯模块通讯,与云端连接。 其中LPS22HH需注意连线,具体连线如下: LPS22HH板 ART-Pi 定义 VDD P1-1 3.3V VDDIO P1-1 3.3V SA0 P2-39 GND SDA P1-3 I2C-SDA SCL P1-5 I2C-SCL CS P1-1 3.3V GND P1-39 GND 其中VDD和VDDIO都是为LPS22HH供电,直接使用ART-Pi的3.3V电源。SA0是用于选择地址,接地后地址为0x5C。SDA和SCL是I2C接口“i2c3”。CS作为片选信号,接高电平后选择接口为I2C。 L610连线如下: L610板 ART-Pi 定义 UA1_TX P1-10 UART-TX UA1_RX P1-8 UART-RX AUTO_POWER_ON_1 P1-6 GND AUTO_POWER_ON_2 P1-12 PI5 CTS短路帽不接。 电源短路帽接至VUSB。 连接USB接口供电和通讯。 软件框架说明(介绍应用所采用的软件方案框图、流程图等,并加以解说)在main.c文件中首先进行了L1610的上电,mqtt初始化,lps22hh初始化等,并创建了四个线程,LED闪烁线程、阿里云发送数据线程、接收阿里云命令线程、定时器线程。 当前实现了基础功能: 通过控制台发送读取传感器数据指令后,在阿里云显示的功能。 后期还需继续完善两个功能: 硬件定时器功能,可按设定的时间间隔进行工作,采集传感器数据并上报云端,当前使能了timer13,但是定时器无法正常工作,程序是按照文档和原潘多拉板直接移植的,暂未找到问题原因。 阿里云下发命令功能,阿里云可以下发命令控制LED开关,下发命令控制硬件定时器定时间隔,随时修改传感器上报数据频率。除了阿里云在线调试界面,暂未找到如何下发命令方法。 还有一些问题: L610的初始化过程有些不太清楚,看at_device_l610.c文件,是在其中创建了一个初始化的线程并直接调用了,这个怎么能在main中统一初始化呢,现在是在main中延时了10秒等待初始化完成后再执行mqtt等初始化。 对接sensor设备框架未成功,尝试了创建sensor设备成功,但是初始化过程应该有问题,对于一个传感器两个参数的情况暂未了解透彻。 软件模块说明(介绍应用软件关键部分的逻辑、采用的实现方式等)sensor_st_lps22hh应用模块直接调用了st的函数库lps2hh_reg,首先创建了stmdev_ctx_t变量,完成了寄存器读写函数的实例化,在此需注意lps22hh的地址,选择了sa0为gnd后地址为0x5c,此地址为7位,可以直接在i2c设备框架中直接赋值无需右移。另外在读取寄存器值时应首先写地址然后才是读数据。参考st的polling文件,编写了初始化函数和读取数据函数,直接读取气压和温度值,并发送至邮箱。 api_ali应用模块参考ali-iotkit的mqtt_example文件,在ENV中配置好三元组信息后,进行mqtt初始化,读取三元组,与云端建立mqtt连接,并订阅了发布和读取主题。编写了数据发布函数,可由发布线程直接调用。试验了cJSON软件包,直接打包成json数据,试验了直接赋值字符串,均可正常实现。试验了接收命令线程,在阿里云
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值