IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> [MQTT]mosquitto库上报温度到阿里云平台 -> 正文阅读

[嵌入式][MQTT]mosquitto库上报温度到阿里云平台

一.连接阿里云服务器测试

mqtt.fx测试与阿里云平台的连通。

可以参考博客 mqtt.fx实现与阿里云的通信
主要是记录一下mqtt连接参数和设备证书,mqtt.fx连接上云平台。并使用publish和subcribe进行订阅和发布具体实现参考上面博客。
在这里插入图片描述
在这里插入图片描述
记录下在云平台上的配置信息

客户ID
clientId
gv9vUe6QzX6.MQTT|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|

用户名
username
MQTT&gv9vUe6QzX6

密码
passwd
34bde8763e13a25d2448e8594dc8a69650e05cf70c1fb8fa731ffeaedef95

mqtt的host
mqttHostUrl
iot-06z00gyvi020tfv.mqtt.iothub.aliyuncs.com

端口号
port
1883

ProductKey
gv9vUe6QzX6

DeviceName
MQTT

DeviceSecret
c6dd3dfb77d3f64b73475c7ee0880a74

发布主题
/sys/gv9vUe6QzX6/${deviceName}/thing/event/property/post   

订阅主题
/sys/gv9vUe6QzX6/${deviceName}/thing/service/property/set   

二.iniparser库介绍

为了实现代码复用性,我们把不同云平台的配置文件单独写成一个.ini配置文件,这样要解析配置文件中的信息就需要用到iniparser库函数。可以参考博客:iniparser库的安装和使用

三.CJSON库介绍

由于阿里云对消息的格式比较严格,需要打包成cJSON的格式才能正确获得数据,所以我们使用mosquito的APImosquitto库和mqtt介绍连接上阿里云后需要把数据打包成cJSON的格式再上传。这里需要用到cJSON库简介打包数据。

四.需要使用到的文件

首先是需要使用的到连接阿里云平台的配置信息.ini文件

[mqtt_server_addr]
host        =iot-06z00gyvi020tfv.mqtt.iothub.aliyuncs.com
port        =1883

[user_passwd]
username    =MQTT&gv9vUe6QzX6
passwd      =34bde8763e13a25d2448e8594dc8a69650e05cf70c1fb8fa731ffeaedef95

[client_id]
id          =gv9vUe6QzX6.MQTT|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|

[sub_topic]
topic       =/sys/gv9vUe6QzX6/MQTT/thing/service/property/set

[pub_topic]
topic       =/sys/gv9vUe6QzX6/MQTT/thing/event/property/post

[ali_json]
method      =thing.service.property.set
id          =1759550978
identifier  =CurrentTemperature
version     =1.0.0"

[KEEP_ALIVE]
alive       =60

[ali_Qos]
Qos         =0

由于需要解析配置文件我们自己写一个关于解析配置文件的头文件和c文件

/********************************************************************************
 *      Copyright:  (C) 2022 hubeiwuhan
 *                  All rights reserved.
 *
 *       Filename:  mosq_conf.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(23/02/22)
 *         Author:  yanp <2405204881@qq.com>
 *      ChangeLog:  1, Release initial version on "23/02/22 14:25:16"
 *                 
 ********************************************************************************/
#ifndef MQTT_CONF_H
#define MQTT_CONF_H

#define  BUF_SIZE 512
/设置默认参数,假如没有传入参数就是用配置文件内的默认参数/
#define DEFAULT_CLIENTID    "gv9vUe6QzX6.MQTT|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|"

#define DEFAULT_USERNAME    "MQTT&gv9vUe6QzX6"
#define DEFAULT_PASSWD      "34bde8763e13a25d2448e8594dc8a69650e05cf70c1fb8fa731ffeaedd22ef95"

#define DEFAULT_HOSTNAME    "iot-06z00gyvi020tfv.mqtt.iothub.aliyuncs.com"
#define DEFAULT_PORT        1883

#define DEFAULT_SUBTOPIC    "/sys/gv9vUe6QzX6/MQTT/thing/service/property/set"
#define DEFAULT_PUBTOPIC    "/sys/gv9vUe6QzX6/MQTT/thing/event/property/post"

#define DEFAULT_QOS         0

#define DEFAULT_METHOD      "thing.service.property.set"
#define DEFAULT_JSONID      "1759550978"
#define DEFAULT_IDENTIFIER  "CurrentTemperature"
#define DEFAULT_VERSION     "1.0.0.0"

#define KEEP_ALIVE          60

enum{
    SUB,
    PUB
};

typedef struct data_st_mqtt
{
    char    hostname[BUF_SIZE] ;
    int     port ;
    char    username[BUF_SIZE] ;
    char    passwd[BUF_SIZE] ;
    char    clientid[BUF_SIZE] ;
    char    topic[BUF_SIZE] ;
    int     Qos;

    char    method[BUF_SIZE] ;
    char    jsonid[BUF_SIZE] ;
    char    identifier[BUF_SIZE] ;
    char    version[BUF_SIZE] ;
}st_mqtt;

int gain_mqtt_conf(char *ini_path,st_mqtt *mqtt,int type);/获取配置参数的函数/
/*********************************************************************************
 *      Copyright:  (C) 2022 hubeiwuhan
 *                  All rights reserved.
 *
 *       Filename:  mqtt_conf.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(24/02/22)
 *         Author:  yanp <2405204881@qq.com>
 *      ChangeLog:  1, Release initial version on "24/02/22 13:45:05"
 *                 
 ********************************************************************************/
#include "iniparser.h"
#include "mqtt_conf.h"
#include <stdio.h>
#include <string.h>

int gain_mqtt_conf(char *ini_path,st_mqtt *mqtt,int type)
{
    dictionary  *ini=NULL;
    const char        *hostname;
    const char        *username;
    int         port;
    const char        *passwd;
    const char        *clientid;
    const char        *topic;
    int                Qos;

    const char        *method;
    const char        *jsonid;
    const char        *identifier;
    const char        *version;

    if(!ini_path || !mqtt)
    {
        printf("invail input parameter in %s\n", __FUNCTION__) ;
        return -1 ;
    }
    
    ini=iniparser_load(ini_path);
    if( ini ==NULL)
    {
        printf("inipar_load  failure\n");
        return -1;
    } 
/这里我没有使用到参数解析,所以使用的全部是默认参数,也就是配置文件内的参数/
    hostname    =iniparser_getstring(ini, "mqtt_server_addr:host", DEFAULT_HOSTNAME);
    port        =iniparser_getint(ini,"mqtt_server_addr:port",DEFAULT_PORT);
    username    =iniparser_getstring(ini,"user_passwd:username",DEFAULT_USERNAME);
    passwd      =iniparser_getstring(ini,"user_passwd:passwd",DEFAULT_PASSWD);
    clientid    =iniparser_getstring(ini,"client_id:id",DEFAULT_CLIENTID);
    identifier  =iniparser_getstring(ini,"ali_json:identifier",DEFAULT_IDENTIFIER) ;
    Qos         =iniparser_getint(ini,"ali_Qos:Qos",DEFAULT_QOS);

    if(type == SUB)
    topic = iniparser_getstring(ini, "sub_topic:topic", DEFAULT_SUBTOPIC) ;
    else if(type == PUB)
    {
        topic = iniparser_getstring(ini,"pub_topic:topic", DEFAULT_PUBTOPIC) ;
        method = iniparser_getstring(ini,"json:method", DEFAULT_METHOD) ;
        jsonid = iniparser_getstring(ini,"json:id", DEFAULT_JSONID) ;
        version = iniparser_getstring(ini,"json:version", DEFAULT_VERSION) ;
    }
  
    mqtt->Qos=Qos;
    strncpy(mqtt->hostname, hostname,BUF_SIZE);
    mqtt->port = port;
    strncpy(mqtt->username, username,BUF_SIZE);
    strncpy(mqtt->passwd, passwd,BUF_SIZE);
    strncpy(mqtt->clientid, clientid,BUF_SIZE);
    strncpy(mqtt->topic, topic,BUF_SIZE);
    if(type == PUB)
    {
        strncpy(mqtt->method, method,BUF_SIZE) ;
        strncpy(mqtt->identifier, identifier,BUF_SIZE);
        strncpy(mqtt->jsonid, jsonid,BUF_SIZE) ;
        strncpy(mqtt->version, version,BUF_SIZE) ;
    }

    iniparser_freedict(ini);
    return 0;
}

在文件夹下还需要包含解析配置文件的iniparser的.c和.h文件
在这里插入图片描述
还需要把获取到的数据打包成cJSON格式的.c和.h文件
在这里插入图片描述

五.流程图

做了上述准备,就可以开始构思整个流程了
在这里插入图片描述

六.代码实现测试

发布端代码

/*********************************************************************************
 *      Copyright:  (C) 2022 hubeiwuhan
 *                  All rights reserved.
 *
 *       Filename:  mqtt_aliyun_pub.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(27/02/22)
 *         Author:  yanp <2405204881@qq.com>
 *      ChangeLog:  1, Release initial version on "27/02/22 12:44:16"
 *                 
 ********************************************************************************/
#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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>

#include "mqtt_conf.h"
#include "cJSON.h"
#include "dictionary.h"
#include "iniparser.h"

#define  PROG_VERSION "1.0.0"
#define  INI_PATH "./mqtt_aliyun_conf.ini"

static int g_stop=0;
int get_temperature(float *temp);
int get_time(char *tim);
void pub_json_data(struct mosquitto *mosq,st_mqtt *mqt);


int main(int argc,char **argv)
{
    int rv;
    int port=1883;
    char *hostname=NULL;
    char *username=NULL;
    char *clientid=NULL;
    char *topic=NULL;
    char *passwd=NULL;
    char *program_name=basename(argv[0]);
    int daemon_run=0;
    st_mqtt mqtt;    
    struct mosquitto            *mosq = NULL;

    
    memset(&mqtt,0,sizeof(mqtt));
    rv=gain_mqtt_conf(INI_PATH,&mqtt,PUB);

    mosquitto_lib_init();
    mosq = mosquitto_new(mqtt.clientid,true,(void *)&mqtt);
    if(!mosq)
    {
        printf("mosquitto_new() failed: %s\n",strerror(errno));
        goto cleanup;
        return -1;
    }
    if(mosquitto_username_pw_set(mosq,mqtt.username,mqtt.passwd) != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_username_pw_set failed: %s\n",strerror(errno));
        goto cleanup;
    }

    if(mosquitto_connect(mosq, mqtt.hostname,mqtt.port,KEEP_ALIVE) != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_connect() failed: %s\n",strerror(errno));
        goto cleanup;
    }
    
    printf("connect successful\n");
    while(!g_stop)
    {
        pub_json_data(mosq,&mqtt);
        sleep(10);
    }
    
            

cleanup:
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();                
    return 0;
}

int get_temperature(float *temp)
{
    char w1_path[50]="/sys/bus/w1/devices/";
    char f_name[50];
    char buf[128];
    char *data_p=NULL;
    struct dirent   *file=NULL;
    DIR *dir=NULL;
    int data_fd;
    int found = -1;

    if((dir=opendir(w1_path))<0)
    {
        printf("open w1_path failure:%s\n",strerror(errno));
        return -1;
    }

    while((file=readdir(dir))!=NULL)
    {
        if(strstr(file->d_name,"28-"))
        {
            strncpy(f_name,file->d_name,sizeof(f_name));
            found=1;
        }
    }

    closedir(dir);

    if(!found)
    {
        printf("can not found the folder\n");
        return 0;
    }                         

    strncat(w1_path, f_name, sizeof(w1_path)-strlen(w1_path));
    strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));
    
   // printf("folder path is %s\n",w1_path);
    
    data_fd=open(w1_path,O_RDONLY);
    
    if(data_fd<0)
    {
        printf("open file failure: %s\n",strerror(errno));
        return -2;
    }
    memset(buf,0,sizeof(buf));
    if(read(data_fd,buf,sizeof(buf))<0)
    {
        printf("read temperature from w1_path failure:%s\n",strerror(errno));
        return -3;
    }
    data_p=strstr(buf, "t=");
    data_p=data_p+2;
    if(!data_p)
    {
        printf("can't get temperature :%s\n",strerror(errno));
        return -4;
    }
    *temp=atof(data_p)/1000.0; 
    close(data_fd);
                                                                                                                   
    return 0;
}

int get_time(char *tim)
{
    time_t time_val,time_mk;
    struct tm *time_gm,*time_local;
    time(&time_val);
    time_gm=gmtime(&time_val);
    sprintf(tim,"\tdate:%04d/%02d/%02d,time:%02d:%02d:%02d",time_gm->tm_year+1900,time_gm->tm_mon+1,time_gm->tm_mday,time_gm->tm_hour,time_gm->tm_min,time_gm->tm_sec);
    return 0;
}

void pub_json_data(struct mosquitto *mosq,st_mqtt *mqt)
{
    char buf[512];
    float   tem;
    char   tim[32];
    char *msg;

    cJSON   * root =  cJSON_CreateObject();
    cJSON   * item =  cJSON_CreateObject();

    memset(root,0,sizeof(root));
    memset(item,0,sizeof(item));

    if(get_temperature(&tem)<0)
    {
        printf("get_temperature failed:%s\n",strerror(errno));
        return ;
    }
    if(get_time(tim)<0)
    {
        printf("get_time failured:%s\n",strerror(errno));
        return ;
    }

    snprintf(buf,sizeof(buf),"%s/%s",tim,tem);
    
    cJSON_AddItemToObject(root, "method", cJSON_CreateString(mqt->method));
    cJSON_AddItemToObject(root, "id", cJSON_CreateString(mqt->jsonid));
    cJSON_AddItemToObject(root, "params",item);
    cJSON_AddItemToObject(root,"time",cJSON_CreateString(tim));
    cJSON_AddItemToObject(item, "CurrentTemperature", cJSON_CreateNumber(tem));
    cJSON_AddItemToObject(root, "version", cJSON_CreateString(mqt->version));
   
    msg=cJSON_Print(root);
    printf("%s\n",msg);

    if(mosquitto_publish(mosq,NULL,mqt->topic,strlen(msg),msg,mqt->Qos,NULL) != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_publish failed: %s\n",strerror(errno));
        return;
    }
        
    printf("mqtt_publish successful!\n");
}

整个代码设计的是每10秒发布一次温度。make编译并运行
在这里插入图片描述
运行之后登录到阿里云平台查看发布的数据如下,跟发布端发布的温度相同
在这里插入图片描述
在这里插入图片描述
这只是初步的实现上报温度到阿里云,后续还需要添加参数解析来实现不同云平台的上报。对cJSON和mosquitto库函数的使用还不是很熟悉,后面在慢慢学习吧。
项目源码地址

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:42:39  更:2022-03-08 22:44:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:24:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码