文章目录
前言
今天这篇文章,对于刚接触物联网协议或者刚接触ESP这款模组并且想对接云平台的人特别有帮助。还希望大家耐心的看完。
在今天的实验里面,你需要有三个概念。
第一什么是MQTT协议,
第二 MQTT协议又是如何连接的,
第三点如何在官方的web demo上添加后端服务和前端页面的接口,实验在线MQTT数据传输。
一、MQTT协议
MQTT协议是一个物联网协议,简单来说就是设备和云平台之间的一种通信传输方式,就好比,在中国大家用中国话来交流,在美国用美国话交流。这就对应着两种通信协议。具体的细节,我的建议还是去百度看看。对于初学者,有这个通信的概念即可。
二、如何使用MQTT协议对接华为云
1.注册华为云账号
这个就不说了,去百度找华为云的官方,免费注册。
2.设备接入中创建资源空间
这个可以百度一下华为云设备接入MQTT设备注册
3.如何连接
首先,我们要参考文档 。在这个文档里面,我们可以看到,我们连接的时候需要填写设备ID,用户名和密码。
其次,怎么获取这一套数据,是目前我们要思考的问题。好在官方直接给出了加密运算的方式。参数计算链接
在下图中,重点关注设备ID和密钥,密钥是在你创建设备的时候就有的
注意上图和下图的设备ID不一样,这是因为我想要告诉大家这个密钥在什么地方,单独创建了一下。
通过下面的页面,我们填入上述的设备ID和密钥,获取新的三元素,我们就可以对接设备。
4.通过MQTT.fx工具做初步对接
4.1 设置连接信息
4.2 连接平台
5.查看平台设备信息
三. 设备测对接平台
1.ESP测引入MQTT库
官方的MQTT demo路径 /esp/esp-idf/examples/protocols/mqtt
在上述的方案中,我们已经完成了电脑模拟设备对接的过程。接下来,我们要用我们的ESP模组完成云平台的对接。还是用之前的web demo。
2.编码
2.1前端编码修改
注意我是将Chart.vue中的内容注释掉替换成了下面的内容
<template><v-container><v-layout text-xs-center wrap><v-flex xs12 sm6 offset-sm3><v-card hover><v-card-title style="font-weight: 800; font-size: 18px">
阿里云平台数据发送测试
</v-card-title><div style="width: 90%; margin: 0 auto; padding: 20px"><v-text-field
v-model="mesdata"
label="测试数据"
hint="输入测试数据"></v-text-field><v-btn
block
color="success"
size="large"
type="submit"
@click="submitdata">
提交
</v-btn></div></v-card></v-flex></v-layout></v-container></template><script>exportdefault{data(){return{mesdata:null,};},methods:{submitdata(){this.$ajax
.post("/api/v1/mqtt/echo",{data:this.mesdata,}).then((data)=>{
console.log(data);}).catch((error)=>{
console.log(error);});this.mesdata ="";},},destroyed(){},mounted(){},};</script>
2.2 后端接口修改
加入一个后端接口,方便前端界面传输数据
// mqtt_send_data_toserver 是我自己封装的一个发送函数,代码都会给大家externvoidmqtt_send_data_toserver(char*message);staticesp_err_tmqtt_echo_handler(httpd_req_t*req){int total_len = req->content_len;int cur_len =0;char message[256]={0};char*buf =((rest_server_context_t*)(req->user_ctx))->scratch;int received =0;if(total_len >= SCRATCH_BUFSIZE){/* Respond with 500 Internal Server Error */httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,"content too long");return ESP_FAIL;}while(cur_len < total_len){
received =httpd_req_recv(req, buf + cur_len, total_len);if(received <=0){/* Respond with 500 Internal Server Error */httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,"Failed to post control value");return ESP_FAIL;}
cur_len += received;}
buf[total_len]='\0';
cJSON *root =cJSON_Parse(buf);//注意这里,这边是为了解析前端页面的数据strcpy(message,cJSON_GetObjectItem(root,"data")->valuestring);cJSON_Delete(root);httpd_resp_sendstr(req,"Post control value successfully");mqtt_send_data_toserver(message);return ESP_OK;}
在start_rest_server 函数中添加下面的代码 (注册解析前端方法到系统中)
httpd_uri_t mqtt_post_uri ={.uri ="/api/v1/mqtt/echo",.method = HTTP_POST,.handler = mqtt_echo_handler,.user_ctx = rest_context};httpd_register_uri_handler(server,&mqtt_post_uri);
3.MQTT编码
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/#include<stdio.h>#include<stdint.h>#include<stddef.h>#include<string.h>#include"esp_system.h"#include"nvs_flash.h"#include"esp_event.h"#include"esp_netif.h"#include"cJSON.h"#include"esp_log.h"#include"mqtt_client.h"#defineCLIENTID""#defineUSERNAME""#definePASSWORD""#defineSERVERURL"mqtt://121.36.42.100:1883"#definePUSHTOPIC"$oc/devices/你的设备ID/sys/properties/report"esp_mqtt_client_handle_t mqtt_client;staticconstchar*MQTTTAG ="MQTT";staticvoidlog_error_if_nonzero(constchar*message,int error_code){if(error_code !=0){ESP_LOGE(MQTTTAG,"Last error %s: 0x%x", message, error_code);}}voidmqtt_send_data_toserver(char*message){int msg_id;char obj_name[10]={0};double rounded =0;
cJSON *root =cJSON_CreateObject();// 创建数组对象
cJSON *array =cJSON_CreateArray();// 创建对象
cJSON *obj =cJSON_CreateObject();cJSON_AddStringToObject(obj,"service_id","echo");
cJSON *values =cJSON_CreateObject();cJSON_AddStringToObject(values,"read", message);cJSON_AddItemToObject(obj,"properties", values);// 将对象添加到数组中cJSON_AddItemToArray(array, obj);// 将数组添加到根节点中cJSON_AddItemToObject(root,"services", array);constchar*sys_info =cJSON_Print(root);ESP_LOGI(MQTTTAG,"%s", sys_info);
msg_id =esp_mqtt_client_publish(mqtt_client, PUSHTOPIC, sys_info,0,1,1);free((void*)sys_info);cJSON_Delete(root);return;}staticvoidmqtt5_event_handler(void*handler_args,esp_event_base_t base,int32_t event_id,void*event_data){ESP_LOGD(MQTTTAG,"Event dispatched from event loop base=%s, event_id=%" PRIi32, base, event_id);esp_mqtt_event_handle_t event = event_data;esp_mqtt_client_handle_t client = event->client;int msg_id;switch((esp_mqtt_event_id_t)event_id){case MQTT_EVENT_CONNECTED:ESP_LOGI(MQTTTAG,"MQTT_EVENT_CONNECTED");mqtt_send_data_toserver("sadsadsadas");break;case MQTT_EVENT_DISCONNECTED:ESP_LOGI(MQTTTAG,"MQTT_EVENT_DISCONNECTED");esp_mqtt_client_reconnect(client);break;case MQTT_EVENT_SUBSCRIBED:ESP_LOGI(MQTTTAG,"MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);break;case MQTT_EVENT_UNSUBSCRIBED:/* 退订绑定的服务,目前先不处理 */ESP_LOGI(MQTTTAG,"MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);break;case MQTT_EVENT_PUBLISHED:/* 推送绑定的事件 */ESP_LOGI(MQTTTAG,"MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);break;case MQTT_EVENT_DATA:/* 数据下发,先不处理 */ESP_LOGI(MQTTTAG,"MQTT_EVENT_DATA");break;case MQTT_EVENT_ERROR:ESP_LOGI(MQTTTAG,"MQTT_EVENT_ERROR return code %d", event->error_handle->connect_return_code);if(event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT){log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);ESP_LOGI(MQTTTAG,"Last errno string (%s)",strerror(event->error_handle->esp_transport_sock_errno));}break;default:ESP_LOGI(MQTTTAG,"Other event id:%d", event->event_id);break;}}intmqtt5_app_start(void){esp_mqtt_client_config_t mqtt_cfg ={.broker.address.uri = SERVERURL,.credentials.client_id = CLIENTID,.credentials.username = USERNAME,.credentials.authentication.password = PASSWORD,.network.disable_auto_reconnect = true};ESP_LOGI(MQTTTAG,"MQTT Server url:%s Client Id %s", mqtt_cfg.broker.address.uri, mqtt_cfg.credentials.client_id);
mqtt_client =esp_mqtt_client_init(&mqtt_cfg);if(mqtt_client ==NULL){return1;}/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt5_event_handler,NULL);esp_mqtt_client_start(mqtt_client);return0;}
4.添加编译文件
5.正常编译烧写
这个就不再叙述了,查看以往的案例
6. 结果展示
平台端的显示
网页端的发送 (注意 我是修改的Chart.vue 这个文件的内容)
后台日志显示 (按照这个报文形势发送)
{"services": [{"service_id": "echo","properties": {"read": "xxxxx"}}]}
总结
今天完成了ESP 对接华为云的案例,里面还是有点弯弯绕的.有疑问就提出来,我都会回复.
后面再有好玩的案例,再发出来看.
版权归原作者 &向上 所有, 如有侵权,请联系我们删除。