ESP32 web 对接华为云平台--MQTT协议

05-01 8267阅读 0评论

文章目录

  • 前言
  • 一、MQTT协议
  • 二、如何使用MQTT协议对接华为云
    • 1.注册华为云账号
    • 2.设备接入中创建资源空间
    • 3.如何连接
    • 4.通过MQTT.fx工具做初步对接
      • 4.1 设置连接信息
      • 4.2 连接平台
      • 5.查看平台设备信息
      • 三. 设备测对接平台
        • 1.ESP测引入MQTT库
        • 2.编码
          • 2.1前端编码修改
          • 2.2 后端接口修改
          • 3.MQTT编码
          • 4.添加编译文件
          • 5.正常编译烧写
          • 6. 结果展示
          • 总结

            前言

            今天这篇文章,对于刚接触物联网协议或者刚接触ESP这款模组并且想对接云平台的人特别有帮助。还希望大家耐心的看完。

            在今天的实验里面,你需要有三个概念。

            第一什么是MQTT协议,

            第二 MQTT协议又是如何连接的,

            第三点如何在官方的web demo上添加后端服务和前端页面的接口,实验在线MQTT数据传输。


            一、MQTT协议

            MQTT协议是一个物联网协议,简单来说就是设备和云平台之间的一种通信传输方式,就好比,在中国大家用中国话来交流,在美国用美国话交流。这就对应着两种通信协议。具体的细节,我的建议还是去百度看看。对于初学者,有这个通信的概念即可。

            二、如何使用MQTT协议对接华为云

            1.注册华为云账号

            这个就不说了,去百度找华为云的官方,免费注册。

            2.设备接入中创建资源空间

            这个可以百度一下华为云设备接入MQTT设备注册

            3.如何连接

            首先,我们要参考文档 。在这个文档里面,我们可以看到,我们连接的时候需要填写设备ID,用户名和密码。

            ESP32 web 对接华为云平台--MQTT协议 第1张

            其次,怎么获取这一套数据,是目前我们要思考的问题。好在官方直接给出了加密运算的方式。参数计算链接

            在下图中,重点关注设备ID和密钥,密钥是在你创建设备的时候就有的

            ESP32 web 对接华为云平台--MQTT协议 第2张

            注意上图和下图的设备ID不一样,这是因为我想要告诉大家这个密钥在什么地方,单独创建了一下。

            ESP32 web 对接华为云平台--MQTT协议 第3张

            通过下面的页面,我们填入上述的设备ID和密钥,获取新的三元素,我们就可以对接设备。

            ESP32 web 对接华为云平台--MQTT协议 第4张

            4.通过MQTT.fx工具做初步对接

            4.1 设置连接信息

            ESP32 web 对接华为云平台--MQTT协议 第5张

            4.2 连接平台

            ESP32 web 对接华为云平台--MQTT协议 第6张

            5.查看平台设备信息

            ESP32 web 对接华为云平台--MQTT协议 第7张

            三. 设备测对接平台

            1.ESP测引入MQTT库

            官方的MQTT demo路径 /esp/esp-idf/examples/protocols/mqtt

            在上述的方案中,我们已经完成了电脑模拟设备对接的过程。接下来,我们要用我们的ESP模组完成云平台的对接。还是用之前的web demo。

            2.编码

            2.1前端编码修改

            注意我是将Chart.vue中的内容注释掉替换成了下面的内容

              
                
                  
                    
                      
                        阿里云平台数据发送测试
                      
                      
            提交
            export default { 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() {}, };

            2.2 后端接口修改

            加入一个后端接口,方便前端界面传输数据

            // mqtt_send_data_toserver 是我自己封装的一个发送函数,代码都会给大家
            extern void mqtt_send_data_toserver(char *message);
            static esp_err_t mqtt_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  
             
             

            在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 
            #include 
            #include 
            #include 
            #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"
            #define CLIENTID ""
            #define USERNAME ""
            #define PASSWORD ""
            #define SERVERURL "mqtt://121.36.42.100:1883"
            #define PUSHTOPIC "$oc/devices/你的设备ID/sys/properties/report"
            esp_mqtt_client_handle_t mqtt_client;
            static const char *MQTTTAG = "MQTT";
            static void log_error_if_nonzero(const char *message, int error_code)
            {
                if (error_code != 0)
                {
                    ESP_LOGE(MQTTTAG, "Last error %s: 0x%x", message, error_code);
                }
            }
            void mqtt_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);
                const char *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;
            }
            static void mqtt5_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;
                }
            }
            int mqtt5_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)
                {
                    return 1;
                }
                /* 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);
                return 0;
            }
            

            4.添加编译文件

            ESP32 web 对接华为云平台--MQTT协议 第8张

            5.正常编译烧写

            这个就不再叙述了,查看以往的案例

            6. 结果展示

            平台端的显示

            ESP32 web 对接华为云平台--MQTT协议 第9张

            网页端的发送 (注意 我是修改的Chart.vue 这个文件的内容)

            ESP32 web 对接华为云平台--MQTT协议 第10张

            后台日志显示 (按照这个报文形势发送)

            ESP32 web 对接华为云平台--MQTT协议 第11张

            {
                "services": [{
                        "service_id": "echo",
                        "properties": {
                            "read": "xxxxx"
                        }
                    }
                ]
            }
            

            总结

            今天完成了ESP 对接华为云的案例,里面还是有点弯弯绕的.有疑问就提出来,我都会回复.

            后面再有好玩的案例,再发出来看.


免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,8267人围观)

还没有评论,来说两句吧...

目录[+]