Haas 开发板连接阿里云上传温湿度和电池电压

目录

一、在阿里云上创建一个产品

二、开发环境的介绍

三、创建wifi示例

四、编写SI7006和ADC驱动

五、wifi配网

六、主要源码

七、查看实现结果



一、在阿里云上创建一个产品


登录自己的阿里云账号, 应该支付宝,淘宝账号都是可以的。

接着根据需求创建一个同类型的产品,在为该类型的产品实例化出一个具体的设备出来。最后为设备添加属性。

具体的步骤: 物联网平台 (aliyun.com)

二、开发环境的介绍


本次实验的开发环境的信息如下:

软件环境: Ubuntu 16.04 vscode vscode内部的Haas-studio插件 Alios Things SDK version-3.3

硬件环境: Haas EDU开发板

  • Haas开发板介绍

三、创建wifi示例


四、编写SI7006和ADC驱动


驱动都是Alios ThingsSDK写好的, 不太熟悉Alios Things的伙伴可以去我的之前的文章看看。

  • ADC驱动
cpp 复制代码
#include <aos/hal/adc.h>
#include <vfsdev/adc_dev.h>




float get_battery(){

    char name[16]={0};
    int32_t fd = 0;
    int i;
    io_adc_arg_t adc_arg;

    float voltage;
    int sum=0;
    snprintf(name,sizeof(name),"/dev/adc1");
    fd = open(name,0);
    if(fd>=0){
        ioctl(fd,IOC_ADC_START,100);
        aos_msleep(1);
        sum=0;
        for(i=0;i<10;i++){
            ioctl(fd,IOC_ADC_GET_VALUE,&adc_arg);
            sum += adc_arg.value;

        }


        ioctl(fd,IOC_ADC_GET_VALUE,&adc_arg);
        voltage = (float)sum/10;
        voltage = voltage*3;
        //printf("read v=%f\n",voltage/1000);
        aos_msleep(1);
        ioctl(fd,IOC_ADC_STOP,0);
        close(fd);
        return voltage/1000;

    }


}

ADC的驱动支持基于HAL层API的开发, 也支持基于VFS的开发, 熟悉linux编程的伙伴, 就会很容易的上手。

  • SI7006温湿度传感器的驱动
cpp 复制代码
#include "aos/hal/i2c.h"
#include "aos/hal/gpio.h"

#define Si7006_ADDRESS     0x40   
#define Si7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE   0xF5
#define Si7006_MEAS_REL_TEMP_NO_MASTER_MODE       0xF3
i2c_dev_t  i2c_dev;


void si7006_init(){
    i2c_dev.port    =   1;
    i2c_dev.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c_dev.config.freq          =  I2C_BUS_BIT_RATES_400K;
    i2c_dev.config.mode          =  I2C_MODE_MASTER;
    i2c_dev.config.dev_addr      =  Si7006_ADDRESS;
    hal_i2c_init(&i2c_dev);
}

int si7006_getTemperature(float *tempration){
    uint8_t reg = Si7006_MEAS_REL_TEMP_NO_MASTER_MODE;
    uint8_t  read_data[2] = {0};
    uint32_t value;

    hal_i2c_master_send(&i2c_dev,i2c_dev.config.dev_addr,&reg,1,1000);
    aos_msleep(30);
    hal_i2c_master_recv(&i2c_dev,i2c_dev.config.dev_addr,read_data,2,1000);

    value = (read_data[0]<<8)|read_data[1];

    *tempration = (175.72f*(float)value)/65536.0f - 46.85f;

    return 0;


}

int si7006_getHumidity(float *Humidity){

    uint8_t reg = Si7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE;
    uint8_t  read_data[2] = {0};
    uint32_t value;

    hal_i2c_master_send(&i2c_dev,i2c_dev.config.dev_addr,&reg,1,1000);
    aos_msleep(30);
    hal_i2c_master_recv(&i2c_dev,i2c_dev.config.dev_addr,read_data,2,1000);
    value = (read_data[0]<<8)|read_data[1];
    *Humidity = (125.0f*(float)value)/65536.0f - 6.0f;
    return 0;


}

五、wifi配网


在开发板启动之后, 进入CLI模式, 即可与开发板交互, 开发板配网的流程命令如下:

bash 复制代码
netmgr  -t wifi  -i                   #初始化
netmgr --t wifi  -c ssid password      #连接wifi, ssid为wifi名称, passwd密码

六、主要源码


bash 复制代码
/*
 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
 */
/**
 * @file main.c
 *
 * This file includes the entry code of link sdk related demo
 *
 */

#include <string.h>
#include <stdio.h>
#include <aos/kernel.h>
#include "netmgr.h"
#include <uservice/uservice.h>
#include <uservice/eventid.h>
#include "aos/hal/adc.h"
#include <vfsdev/adc_dev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "aos/hal/i2c.h"
#include "aos/hal/gpio.h"


float temperature, humidity, voltage;

extern int demo_main(int argc, char *argv[]);

static int _ip_got_finished = 0;
io_adc_arg_t io_adc_arg;

float get_battery(void)
{
    int fd = -1;
    char dev_name[128] = {0};
    float ret_value = 0;

    snprintf(dev_name, sizeof(dev_name), "/dev/adc1");

    fd = open(dev_name, 0);
    if(fd < 0) {
        perror(open);
    }

    ioctl(fd, IOC_ADC_START, &io_adc_arg);
    aos_msleep(1);
    ioctl(fd, IOC_ADC_GET_VALUE, &io_adc_arg);

    ret_value = (float)io_adc_arg.value / 1000 * 3;
    ioctl(fd, IOC_ADC_STOP, &io_adc_arg);

    close(fd);
   // printf("%d\n", io_adc_arg.value);
    //printf("%f\n", ret_value);
    return ret_value;
}

#define SI7006_DEVICE_ADDR (0x40)
#define SI7006_TEMP_CMD (0XF3)
#define SI7006_HUMI_CMD (0XF5)

/* i2c handle*/
i2c_dev_t i2c_dev;

void Si7006_Init(void)
{
    i2c_dev.port = 1;
    i2c_dev.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c_dev.config.freq = I2C_BUS_BIT_RATES_400K;
    i2c_dev.config.mode = I2C_MODE_MASTER;
    i2c_dev.config.dev_addr = SI7006_DEVICE_ADDR;

    hal_i2c_init(&i2c_dev);
}

int GetTemperature(float * temperature) 
{
    int ret;
    uint8_t reg = SI7006_TEMP_CMD;
    uint8_t data_buf[2] = {0};
    short value;

    /**/
    ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
    if(ret != 0) {
        int i = 0;
        for(; i < 3; i++) {
            ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
        }
        if(ret != 0) {
            printf("hal_i2c_master_send failed !\n");
            return -1;
        }
    }

    aos_msleep(30);

    ret = hal_i2c_master_recv(&i2c_dev, i2c_dev.config.dev_addr, data_buf, 2, 1000);
    if(ret != 0) {
        int i = 0;
        for(; i < 3; i++) {
            ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
        }
        if(ret != 0) {
            printf("hal_i2c_master_recv failed !\n");
            return -1;
        }
    }

    value = (data_buf[0] << 8) | data_buf[1];

    *temperature = (175.72 * (value) / 65536) - 46.85;

    return 0;
}

int GetHumidity(float* humidity) 
{
    int ret;
    short value;
    uint8_t reg = SI7006_HUMI_CMD;
    uint8_t data_buf[2] = {0};

    ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
    if(ret != 0) {
        int i = 0;
        for(; i < 3; i++) {
            ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
        }
        if(ret != 0) {
            printf("hal_i2c_master_send failed !\n");
            return -1;
        }
    }

    aos_msleep(30);

    ret = hal_i2c_master_recv(&i2c_dev, i2c_dev.config.dev_addr, data_buf, 2, 1000);
    if(ret != 0) {
        int i = 0;
        for(; i < 3; i++) {
            ret = hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, &reg, 1, 1000);
        }
        if(ret != 0) {
            printf("hal_i2c_master_recv failed !\n");
            return -1;
        }
    }

    value = (data_buf[0] << 8) | data_buf[1];

    *humidity = (125.0 * (value) / 65536.0) - 6;

    return 0;
}


static void entry_func(void *data)
{
    demo_main(0 , NULL);
}
static void wifi_event_cb(uint32_t event_id, const void *param, void *context)
{
    aos_task_t task;
    aos_status_t ret;
    if (event_id != EVENT_NETMGR_DHCP_SUCCESS)
        return;

    if (_ip_got_finished != 0)
        return;

    _ip_got_finished = 1;
    ret = aos_task_create(&task, "linksdk_demo", entry_func,
                          NULL, NULL, 6048, AOS_DEFAULT_APP_PRI, AOS_TASK_AUTORUN);
    if (ret < 0) {
        printf("create linksdk demo task failed, ret = %ld \r\n", ret);
    }
}

int application_start(int argc, char *argv[])
{
    aos_set_log_level(AOS_LL_DEBUG);
    event_service_init(NULL);

    netmgr_service_init(NULL);
    netmgr_set_auto_reconnect(NULL, true);
    netmgr_wifi_set_auto_save_ap(true);


    event_subscribe(EVENT_NETMGR_DHCP_SUCCESS, wifi_event_cb, NULL);

    Si7006_Init();
    char buf[128] = {0};

    while (1) {
        GetTemperature(&temperature);

        GetHumidity(&humidity);
        voltage = get_battery();
        aos_msleep(1000);

       // printf("temprature: %0.2f\n", temperature);
        //printf("humidity: %0.2f\n", humidity);
        //printf("voltage: %.02f\n", voltage);
    }




    return 0;
}
bash 复制代码
/*
 * 这个例程演示了用SDK配置MQTT参数并建立连接, 之后创建2个线程
 *
 * + 一个线程用于保活长连接
 * + 一个线程用于接收消息, 并在有消息到达时进入默认的数据回调, 在连接状态变化时进入事件回调
 *
 * 接着演示了在MQTT连接上进行属性上报, 事件上报, 以及处理收到的属性设置, 服务调用, 取消这些代码段落的注释即可观察运行效果
 *
 * 需要用户关注或修改的部分, 已经用 TODO 在注释中标明
 *
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <aos/kernel.h>

#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"
#include "aiot_dm_api.h"

extern float temperature, humidity, voltage;

/* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;

/* 位于external/ali_ca_cert.c中的服务器证书 */
extern const char *ali_ca_cert;


static uint8_t g_mqtt_process_thread_running = 0;
static uint8_t g_mqtt_recv_thread_running = 0;

/* TODO: 如果要关闭日志, 就把这个函数实现为空, 如果要减少日志, 可根据code选择不打印
 *
 * 例如: [1577589489.033][LK-0317] mqtt_basic_demo&a13FN5TplKq
 *
 * 上面这条日志的code就是0317(十六进制), code值的定义见core/aiot_state_api.h
 *
 */

/* 日志回调函数, SDK的日志会从这里输出 */
int32_t demo_state_logcb(int32_t code, char *message)
{
    printf("%s", message);
    return 0;
}

/* MQTT事件回调函数, 当网络连接/重连/断开时被触发, 事件定义见core/aiot_mqtt_api.h */
void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata)
{
    switch (event->type) {
        /* SDK因为用户调用了aiot_mqtt_connect()接口, 与mqtt服务器建立连接已成功 */
        case AIOT_MQTTEVT_CONNECT: {
            printf("AIOT_MQTTEVT_CONNECT\n");
        }
        break;

        /* SDK因为网络状况被动断连后, 自动发起重连已成功 */
        case AIOT_MQTTEVT_RECONNECT: {
            printf("AIOT_MQTTEVT_RECONNECT\n");
        }
        break;

        /* SDK因为网络的状况而被动断开了连接, network是底层读写失败, heartbeat是没有按预期得到服务端心跳应答 */
        case AIOT_MQTTEVT_DISCONNECT: {
            char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") :
                          ("heartbeat disconnect");
            printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause);
        }
        break;

        default: {

        }
    }
}

/* 执行aiot_mqtt_process的线程, 包含心跳发送和QoS1消息重发 */
void *demo_mqtt_process_thread(void *args)
{
    int32_t res = STATE_SUCCESS;

    while (g_mqtt_process_thread_running) {
        res = aiot_mqtt_process(args);
        if (res == STATE_USER_INPUT_EXEC_DISABLED) {
            break;
        }
        aos_msleep(1000);
    }
    return NULL;
}

/* 执行aiot_mqtt_recv的线程, 包含网络自动重连和从服务器收取MQTT消息 */
void *demo_mqtt_recv_thread(void *args)
{
    int32_t res = STATE_SUCCESS;

    while (g_mqtt_recv_thread_running) {
        res = aiot_mqtt_recv(args);
        if (res < STATE_SUCCESS) {
            if (res == STATE_USER_INPUT_EXEC_DISABLED) {
                break;
            }
            aos_msleep(1000);
        }
    }
    return NULL;
}

/* 用户数据接收处理回调函数 */
static void demo_dm_recv_handler(void *dm_handle, const aiot_dm_recv_t *recv, void *userdata)
{
    printf("demo_dm_recv_handler, type = %d\r\n", recv->type);

    switch (recv->type) {

        /* 属性上报, 事件上报, 获取期望属性值或者删除期望属性值的应答 */
        case AIOT_DMRECV_GENERIC_REPLY: {
            printf("msg_id = %d, code = %d, data = %.*s, message = %.*s\r\n",
                   recv->data.generic_reply.msg_id,
                   recv->data.generic_reply.code,
                   recv->data.generic_reply.data_len,
                   recv->data.generic_reply.data,
                   recv->data.generic_reply.message_len,
                   recv->data.generic_reply.message);
        }
        break;

        /* 属性设置 */
        case AIOT_DMRECV_PROPERTY_SET: {
            printf("msg_id = %ld, params = %.*s\r\n",
                   (unsigned long)recv->data.property_set.msg_id,
                   recv->data.property_set.params_len,
                   recv->data.property_set.params);

            /* TODO: 以下代码演示如何对来自云平台的属性设置指令进行应答, 用户可取消注释查看演示效果 */
            /*
            {
                aiot_dm_msg_t msg;

                memset(&msg, 0, sizeof(aiot_dm_msg_t));
                msg.type = AIOT_DMMSG_PROPERTY_SET_REPLY;
                msg.data.property_set_reply.msg_id = recv->data.property_set.msg_id;
                msg.data.property_set_reply.code = 200;
                msg.data.property_set_reply.data = "{}";
                int32_t res = aiot_dm_send(dm_handle, &msg);
                if (res < 0) {
                    printf("aiot_dm_send failed\r\n");
                }
            }
            */
        }
        break;

        /* 异步服务调用 */
        case AIOT_DMRECV_ASYNC_SERVICE_INVOKE: {
            printf("msg_id = %ld, service_id = %s, params = %.*s\r\n",
                   (unsigned long)recv->data.async_service_invoke.msg_id,
                   recv->data.async_service_invoke.service_id,
                   recv->data.async_service_invoke.params_len,
                   recv->data.async_service_invoke.params);

            /* TODO: 以下代码演示如何对来自云平台的异步服务调用进行应答, 用户可取消注释查看演示效果
             *
             * 注意: 如果用户在回调函数外进行应答, 需要自行保存msg_id, 因为回调函数入参在退出回调函数后将被SDK销毁, 不可以再访问到
             */

            /*
            {
                aiot_dm_msg_t msg;

                memset(&msg, 0, sizeof(aiot_dm_msg_t));
                msg.type = AIOT_DMMSG_ASYNC_SERVICE_REPLY;
                msg.data.async_service_reply.msg_id = recv->data.async_service_invoke.msg_id;
                msg.data.async_service_reply.code = 200;
                msg.data.async_service_reply.service_id = "ToggleLightSwitch";
                msg.data.async_service_reply.data = "{\"dataA\": 20}";
                int32_t res = aiot_dm_send(dm_handle, &msg);
                if (res < 0) {
                    printf("aiot_dm_send failed\r\n");
                }
            }
            */
        }
        break;

        /* 同步服务调用 */
        case AIOT_DMRECV_SYNC_SERVICE_INVOKE: {
            printf("msg_id = %ld, rrpc_id = %s, service_id = %s, params = %.*s\r\n",
                   (unsigned long)recv->data.sync_service_invoke.msg_id,
                   recv->data.sync_service_invoke.rrpc_id,
                   recv->data.sync_service_invoke.service_id,
                   recv->data.sync_service_invoke.params_len,
                   recv->data.sync_service_invoke.params);

            /* TODO: 以下代码演示如何对来自云平台的同步服务调用进行应答, 用户可取消注释查看演示效果
             *
             * 注意: 如果用户在回调函数外进行应答, 需要自行保存msg_id和rrpc_id字符串, 因为回调函数入参在退出回调函数后将被SDK销毁, 不可以再访问到
             */

            /*
            {
                aiot_dm_msg_t msg;

                memset(&msg, 0, sizeof(aiot_dm_msg_t));
                msg.type = AIOT_DMMSG_SYNC_SERVICE_REPLY;
                msg.data.sync_service_reply.rrpc_id = recv->data.sync_service_invoke.rrpc_id;
                msg.data.sync_service_reply.msg_id = recv->data.sync_service_invoke.msg_id;
                msg.data.sync_service_reply.code = 200;
                msg.data.sync_service_reply.service_id = "SetLightSwitchTimer";
                msg.data.sync_service_reply.data = "{}";
                int32_t res = aiot_dm_send(dm_handle, &msg);
                if (res < 0) {
                    printf("aiot_dm_send failed\r\n");
                }
            }
            */
        }
        break;

        /* 下行二进制数据 */
        case AIOT_DMRECV_RAW_DATA: {
            printf("raw data len = %d\r\n", recv->data.raw_data.data_len);
            /* TODO: 以下代码演示如何发送二进制格式数据, 若使用需要有相应的数据透传脚本部署在云端 */
            /*
            {
                aiot_dm_msg_t msg;
                uint8_t raw_data[] = {0x01, 0x02};

                memset(&msg, 0, sizeof(aiot_dm_msg_t));
                msg.type = AIOT_DMMSG_RAW_DATA;
                msg.data.raw_data.data = raw_data;
                msg.data.raw_data.data_len = sizeof(raw_data);
                aiot_dm_send(dm_handle, &msg);
            }
            */
        }
        break;

        /* 二进制格式的同步服务调用, 比单纯的二进制数据消息多了个rrpc_id */
        case AIOT_DMRECV_RAW_SYNC_SERVICE_INVOKE: {
            printf("raw sync service rrpc_id = %s, data_len = %d\r\n",
                   recv->data.raw_service_invoke.rrpc_id,
                   recv->data.raw_service_invoke.data_len);
        }
        break;

        default:
            break;
    }
}

/* 属性上报函数演示 */
int32_t demo_send_property_post(void *dm_handle, char *params)
{
    aiot_dm_msg_t msg;

    memset(&msg, 0, sizeof(aiot_dm_msg_t));
    msg.type = AIOT_DMMSG_PROPERTY_POST;
    msg.data.property_post.params = params;

    return aiot_dm_send(dm_handle, &msg);
}

/* 事件上报函数演示 */
int32_t demo_send_event_post(void *dm_handle, char *event_id, char *params)
{
    aiot_dm_msg_t msg;

    memset(&msg, 0, sizeof(aiot_dm_msg_t));
    msg.type = AIOT_DMMSG_EVENT_POST;
    msg.data.event_post.event_id = event_id;
    msg.data.event_post.params = params;

    return aiot_dm_send(dm_handle, &msg);
}

/* 演示了获取属性LightSwitch的期望值, 用户可将此函数加入到main函数中运行演示 */
int32_t demo_send_get_desred_requset(void *dm_handle)
{
    aiot_dm_msg_t msg;

    memset(&msg, 0, sizeof(aiot_dm_msg_t));
    msg.type = AIOT_DMMSG_GET_DESIRED;
    msg.data.get_desired.params = "[\"LightSwitch\"]";

    return aiot_dm_send(dm_handle, &msg);
}

/* 演示了删除属性LightSwitch的期望值, 用户可将此函数加入到main函数中运行演示 */
int32_t demo_send_delete_desred_requset(void *dm_handle)
{
    aiot_dm_msg_t msg;

    memset(&msg, 0, sizeof(aiot_dm_msg_t));
    msg.type = AIOT_DMMSG_DELETE_DESIRED;
    msg.data.get_desired.params = "{\"LightSwitch\":{}}";

    return aiot_dm_send(dm_handle, &msg);
}


int demo_main(int argc, char *argv[])
{
    int32_t     res = STATE_SUCCESS;
    void       *dm_handle = NULL;
    void       *mqtt_handle = NULL;
    char       *url = "iot-as-mqtt.cn-shanghai.aliyuncs.com"; /* 阿里云平台上海站点的域名后缀 */
    char        host[100] = {0}; /* 用这个数组拼接设备连接的云平台站点全地址, 规则是 ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com */
    uint16_t    port = 443;      /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
    aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */

    /* TODO: 替换为自己设备的三元组 */
    char *product_key       = "k0t0ptohSB3";
    char *device_name       = "hass_humi_temp_test";
    char *device_secret     = "7f50a6537f5acfd13bd1a133a90a40ec";

    /* 配置SDK的底层依赖 */
    aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
    /* 配置SDK的日志输出 */
    aiot_state_set_logcb(demo_state_logcb);

    /* 创建SDK的安全凭据, 用于建立TLS连接 */
    memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
    cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;  /* 使用RSA证书校验MQTT服务端 */
    cred.max_tls_fragment = 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */
    cred.sni_enabled = 1;                               /* TLS建连时, 支持Server Name Indicator */
    cred.x509_server_cert = ali_ca_cert;                 /* 用来验证MQTT服务端的RSA根证书 */
    cred.x509_server_cert_len = strlen(ali_ca_cert);     /* 用来验证MQTT服务端的RSA根证书长度 */

    /* 创建1个MQTT客户端实例并内部初始化默认参数 */
    mqtt_handle = aiot_mqtt_init();
    if (mqtt_handle == NULL) {
        printf("aiot_mqtt_init failed\n");
        return -1;
    }

    snprintf(host, 100, "%s.%s", product_key, url);
    /* 配置MQTT服务器地址 */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)host);
    /* 配置MQTT服务器端口 */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port);
    /* 配置设备productKey */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
    /* 配置设备deviceName */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
    /* 配置设备deviceSecret */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
    /* 配置网络连接的安全凭据, 上面已经创建好了 */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
    /* 配置MQTT事件回调函数 */
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);

    /* 创建DATA-MODEL实例 */
    dm_handle = aiot_dm_init();
    if (dm_handle == NULL) {
        printf("aiot_dm_init failed");
        return -1;
    }
    /* 配置MQTT实例句柄 */
    aiot_dm_setopt(dm_handle, AIOT_DMOPT_MQTT_HANDLE, mqtt_handle);
    /* 配置消息接收处理回调函数 */
    aiot_dm_setopt(dm_handle, AIOT_DMOPT_RECV_HANDLER, (void *)demo_dm_recv_handler);

    /* 与服务器建立MQTT连接 */
    res = aiot_mqtt_connect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_connect failed: -0x%04X\n", -res);
        return -1;
    }

    /* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文 */
    g_mqtt_process_thread_running = 1;
    res = aos_task_new("demo_mqtt_process", demo_mqtt_process_thread, mqtt_handle, 4096);
    // res = pthread_create(&g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle);
    if (res != 0) {
        printf("create demo_mqtt_process_thread failed: %d\n", res);
        return -1;
    }

    /* 创建一个单独的线程用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */
    g_mqtt_recv_thread_running = 1;
    res = aos_task_new("demo_mqtt_process", demo_mqtt_recv_thread, mqtt_handle, 4096);
    // res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle);
    if (res != 0) {
        printf("create demo_mqtt_recv_thread failed: %d\n", res);
        return -1;
    }
    char buf[128] = {0};

    /* 主循环进入休眠 */
    while (1) {
        sprintf(buf, "{\"CurrentTemperature\": %f}", temperature);
        demo_send_property_post(dm_handle, buf);
        sprintf(buf, "{\"CurrentHumidity\": %f}", humidity);
        demo_send_property_post(dm_handle, buf);
        sprintf(buf, "{\"CurrentVoltage\": %f}", voltage);
        demo_send_property_post(dm_handle, buf);


        demo_send_event_post(dm_handle, "Error", "{\"ErrorCode\": 0}");

        aos_msleep(10000);
    }

    /* 断开MQTT连接, 一般不会运行到这里 */
    res = aiot_mqtt_disconnect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
        return -1;
    }

    /* 销毁DATA-MODEL实例, 一般不会运行到这里 */
    res = aiot_dm_deinit(&dm_handle);
    if (res < STATE_SUCCESS) {
        printf("aiot_dm_deinit failed: -0x%04X\n", -res);
        return -1;
    }

    /* 销毁MQTT实例, 一般不会运行到这里 */
    res = aiot_mqtt_deinit(&mqtt_handle);
    if (res < STATE_SUCCESS) {
        printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
        return -1;
    }

    g_mqtt_process_thread_running = 0;
    g_mqtt_recv_thread_running = 0;

    return 0;
}

七、查看实现结果


相关推荐
时序数据说2 小时前
时序数据库市场前景分析
大数据·数据库·物联网·开源·时序数据库
ciku8 小时前
Spring AI 集成阿里云百炼平台
人工智能·spring·阿里云
Agome998 小时前
Docker之自定义jkd镜像上传阿里云
阿里云·docker·容器
TDengine (老段)11 小时前
TDengine IDMP 高级功能(4. 元素引用)
大数据·数据库·人工智能·物联网·数据分析·时序数据库·tdengine
bai54593611 小时前
STM32 软件I2C读写MPU6050
stm32·单片机·嵌入式硬件
逼子格13 小时前
AT89C52单片机介绍
单片机·嵌入式硬件·51单片机·硬件工程师·硬件工程师真题·at89c52·器件手册
生涯にわたる学び15 小时前
ARM 实操 流水灯 按键控制 day53
arm开发·嵌入式硬件
whaosoft-14315 小时前
w嵌入式分享合集68
嵌入式硬件
David WangYang16 小时前
基于 IOT 的安全系统,带有使用 ESP8266 的语音消息
物联网·安全·语音识别
竹照煜_ysn18 小时前
STM32——软硬件I2C
stm32·嵌入式硬件·mongodb