树莓派使用mosquitto库搭建客户端将SHT20采样的温湿度上报阿里云

做这项工作之前,我已经做了一些准备工作了,我之前写的 “基于mosquitto库搭建mqtt客户端发布实现与阿里云的通信”以及“基于树莓派3B SHT20温湿度采样”都是为此项目做好准备的,大家如果想要完成树莓派与阿里云的通信,请务必先了解一下,我之前的博客,链接:基于树莓派3B SHT20温湿度采样

基于mosquitto库搭建mqtt客户端发布实现与阿里云的通信

再有了这些准备工作之后,我们就可以完成此项任务了,首先我们要了解基本的流程:如下图
在这里插入图片描述
我把sht20封装成一个函数写在了回调函数里面,然后采样温湿度,打包成josn格式,发送给阿里云。

在这里我们先来看一下我代码中怎么把温度和湿度,打包成josn格式的,首先看josn文件。
在这里插入图片描述
在这里插入图片描述
关于此篇博客,跟我之前那个“基于mosquitto库搭建mqtt客户端发布实现与阿里云的通信”的博客很像,只不过,我只是在原来的代码的基础上加了sht20的温湿度采样的函数,所以在这里,我只附上主函数的源码吧,关于更多源码,我会在下面给出gitee的链接地址。

主函数源码:

/*********************************************************************************
 *      Copyright:  (C) 2020 makun<1394987689@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  mosquitto_pub.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2020年07月08日)
 *         Author:  makun <1394987689@qq.com>
 *      ChangeLog:  1, Release initial version on "2020年07月08日 22时30分04秒"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <libgen.h>
#include <getopt.h>
#include <string.h>
#include <mosquitto.h>
#include <stdlib.h>

#include "conf.h"
#include "cJSON.h"
#include "sht20.h"

#define  PROG_VERSION "1.0.0"
#define  PATH_INT "./mqtt_aly_conf.ini"

int get_temp_humidity(int fd, float *temp, float *humidity);
void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc);
static void  print_usage( char *progname)
{
    printf("Usage  %s [option]...\n", progname);
    printf("%s is makun studi MQTT daemon program running on RaspberryPi\n", progname);

    printf("-p (--port):   the port of the server you want to connect\n");
    printf("-h (--host):   the hostname of the server you want to connect\n");
    printf("-u (--user):   the username of the client\n");
    printf("-P (--passwd): the passwd of the client you\n");
    printf("-i (--clientid): the clientid of the user\n");
    printf("-t (--topic):  the topic of the client you want to pub\n");
    printf("-H (--help): Display this help information\n");
    printf("-v (--version): Display the program version\n");

    printf("%s  Version %s\n", progname, PROG_VERSION);
    return ;
}

int main (int argc, char **argv)
{
    char         *host = NULL;
    int          port ;
    char         *clientid = NULL;
    char         *user = NULL;
    char         *passwd = NULL;
    char         *topic = NULL;
    int          rv = -1;
    int          opt= -1;
    char         *progname = NULL;
    bool         session = true;
    mqtt_ctx_t   mqtt;

    struct mosquitto *mosq = NULL;

    
    struct option long_options[]= {
        {"host", required_argument, NULL, 'h'},
        {"port", required_argument, NULL, 'p'},
        {"user", required_argument, NULL, 'u'},
        {"passwd",required_argument, NULL,'P'},
        {"topic", required_argument, NULL, 't'},
        {"clientid", required_argument, NULL, 'i'},
        {"help", no_argument, NULL, 'H'},
        {"version", no_argument, NULL, 'v'},
        {0, 0, 0, 0}
    };

    progname = (char *)basename(argv[0]);

    while( (opt = getopt_long(argc, argv,"h:p:u:P:i:tHv", long_options,NULL)) != -1)
    {
        switch (opt)
        {
            case 'h':
                host = optarg;
                break;
            case 'p':
                port = atoi(optarg);
                break;
            case 'u':
                user = optarg;
                break;
            case 'P':
                passwd = optarg;
                break;
            case 'i':
                clientid = optarg;
            case 't':
                topic = optarg;
                break;
            case 'v':
                printf("%s Version %s\n",progname, PROG_VERSION);
                return 0;
            case 'H':
                print_usage(progname);
                return 0;
            default:
                break;
        }
    }

    rv=set_mqtt_conf(PATH_INT, host, port, clientid, user,passwd, topic);
    if(rv < 0)
    {
        printf("set mqtt conf is failure %d\n", rv);
        return -1;
    }

    memset(&mqtt, 0, sizeof(mqtt));

    rv = gain_mqtt_conf(PATH_INT, &mqtt);
    if(rv < 0)
    {
        printf("gain mqtt conf failure %d\n", rv);
        return -2;
    }

    /*必须在任何其他mosquitto功能之前调用*/
    mosquitto_lib_init();

    /*创建一个新的mosquitto客户端实例,第二个参数为true,代理清除断开连接时的所有消息和订阅*/
    mosq = mosquitto_new(mqtt.clientid,session, (void *)&mqtt );
    if(!mosq)
    {
        printf("mosquitto new failure: %s\n", strerror(errno));
        goto cleanup;
    }

    printf("Create mosquitto successfuly\n");

    /*设置连接回调,当代理发送CONNACK消息以响应连接时,将调用此方法*/
    mosquitto_connect_callback_set(mosq, pub_conn_callback);


    /*配置mosquitto实例的用户名和密码*/
    if( mosquitto_username_pw_set(mosq, mqtt.username,mqtt.passwd) !=MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto username and passwd failure:%s\n",strerror(errno));
        goto cleanup;
    }

    while(1)
    {
        /*连接MQTT代理*/
        if(mosquitto_connect(mosq, mqtt.hostname, mqtt.port, mqtt.keepalive) != MOSQ_ERR_SUCCESS )
        {
            printf("mosquitto connect server failure:%s\n",strerror(errno));
            continue;
            sleep(1);
        }

        /*无线阻塞循环调用loop*/
        mosquitto_loop_forever(mosq, -1, 1 );
        sleep(10);
    }

cleanup:
    printf("program will exit\n");
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();

    return 0;

}


void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc)
{
    mqtt_ctx_t  *mqtt;
    int mid;
    char    *msg;
    cJSON   *root = cJSON_CreateObject();
    cJSON   *item = cJSON_CreateObject();
    int     retain = 0;
    int     fd;
    float   temp;
    float   humidity;
    int     rv = -1;
    float    payload1;
    float    payload2;
    if(!mosq ||!obj)
    {
        printf("invalid input argument\n");
        return ;
    }
    
    rv = get_temp_humidity(fd, &temp, &humidity);
    if(rv == 0)
    {
        payload1 = temp;
        payload2 = humidity;
        
    }
    mqtt = (mqtt_ctx_t *)obj;

    cJSON_AddItemToObject(root, "method", cJSON_CreateString(mqtt->method));//根节点下添加
    cJSON_AddItemToObject(root, "id", cJSON_CreateString(mqtt->id));//根节点下添加
    cJSON_AddItemToObject(root, "params",item);
    cJSON_AddItemToObject(item, "CurrentHumidity", cJSON_CreateNumber(payload1));
    cJSON_AddItemToObject(item, "CurrentTemperature", cJSON_CreateNumber(payload2));
    cJSON_AddItemToObject(root, "version", cJSON_CreateString(mqtt->version));
    
    msg = cJSON_Print(root);
    printf("%s\n", msg);

    if(!rc)
    {  
        if( mosquitto_publish(mosq,&mid,mqtt->pubTopic,strlen(msg)+1, msg, mqtt->pubQos, retain) != MOSQ_ERR_SUCCESS )  
        {   
            printf("Mosq_Publish() error: %s\n", strerror(errno));
            return ;
        }
        printf("pubilush topic:%s\n",mqtt->pubTopic) ;
    }
    mosquitto_disconnect(mosq) ;

}

int get_temp_humidity(int fd, float *temp, float *humidity)
{
    uint8_t      serialnumber[8];
    fd = sht2x_init();     
    if(fd < 0)        
    {                
        printf("SHT2x initialize failure\n");                
        return 1;        
    }

    if( sht2x_softreset(fd) < 0 ) 
    {
        printf("SHT2x softreset failure\n");    
        return 2;
    }
    if( sht2x_get_serialnumber(fd, serialnumber, 8) < 0) 
    {
        printf("SHT2x get serial number failure\n"); 
        return 3;
    }
    if( sht2x_get_temp_humidity(fd, &temp, &humidity) < 0 )
    {
        printf("SHT2x get get temperature and relative humidity failure\n");
        return 3;
    }
    printf("Temperature=%lf ℃ relative humidity=%lf%\n", temp, humidity);

    return 0;
    close(fd);
}

当运行之后我们来看一下运行结果,我们先看在树莓派上的运行结果:
在这里插入图片描述
我们在树莓派上看到我们的温湿度分别为26.069939 和57.549042,然后我们登录阿里云的后台,看温湿度上报的情况。
在这里插入图片描述
与我们上述上报的情况是一样的,这样我们就是实现了树莓派sht20采样温湿度上报阿里云的一个项目,下面我附上源码地址,感兴趣的可以看一下

源码链接 https://gitee.com/ma_kung/mqtt

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值