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

文章目录

  • 前言
  • 一、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,用户名和密码。
在这里插入图片描述

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

在下图中,重点关注设备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>
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() {},
};
</script>

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 < 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"

#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.添加编译文件

在这里插入图片描述

5.正常编译烧写

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

6. 结果展示

平台端的显示

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/421235.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何解决iQOO手机运行uniapp真机调试时无法识别的问题

打开开发者选项&#xff0c;打开USB设置&#xff0c;把默认USB选项改成MIDI模式&#xff0c;就可以检测到手机了

界面控件DevExpress .NET MAUI v23.2新版亮点 - 拥有全新的彩色主题

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布&#xff0c;该版本拥有众多…

Vue.js的双向绑定原理

Vue的双向绑定 vue双向绑定是其最重要的核心亮点&#xff0c;其原理也很简单&#xff0c;这里做个简单总结 vue2的双向绑定是利用的Object.definePropertyvue3的双向绑定是利用的 ES6Porxy中的defineProperty(target, propKey, propDesc 其作用类似于Object.defineProperty …

测试用例术语5.0

一、软件测试中术语 1.动态测试&#xff08;dynamic testing&#xff09;&#xff1a;通过运行软件的组件或 系统来测试软件 例如&#xff1a;一辆汽车发动并行使测试 2.静态测试&#xff08;static testing&#xff09;&#xff1a;对组件的规格说明书进行 评审&#xff0c…

超级充电测试负载的核心功能?

超级充电测试负载的核心功能主要包括以下几点&#xff1a; 模拟真实充电场景&#xff1a;超级充电测试负载能够模拟真实的电动汽车充电过程&#xff0c;包括充电设备的启动、停止、故障等状态&#xff0c;以及电动汽车的充电需求变化。通过这种方式&#xff0c;可以对充电设备和…

3月1号代码随想录二叉搜索树中的插入操作

301.二叉搜索树中的插入操作 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;…

机器学习(II)--样本不平衡

现实中&#xff0c;样本&#xff08;类别&#xff09;样本不平衡&#xff08;class-imbalance&#xff09;是一种常见的现象&#xff0c;如&#xff1a;金融欺诈交易检测&#xff0c;欺诈交易的订单样本通常是占总交易数量的极少部分&#xff0c;而且对于有些任务而言少数样本更…

Linux系统——Shell脚本——一键安装LNMP

#!/bin/bash #安装nginx echo "安装nginx服务" wget http://nginx.org/download/nginx-1.11.4.tar.gz &>/dev/null if [ $? -eq 0 ] thenecho "nginx-1.11.4安装包下载完成"echo "--开始安装必要的依赖文件--"yum install -y gcc gcc-c…

深度学习--神经网络基础(2)

损失函数 在深度学习中, 损失函数是用来衡量模型参数的质量的函数 , 衡量的方式是比较网络输出和真实输 出的差异&#xff1a; 分类 1.多分类损失函数 在多分类任务通常使用 softmax 将 logits 转换为概率的形式&#xff0c;所以多分类的交叉熵损失也叫做 softmax 损失 &…

嵌入式中有关软件开发的错误观念

从学生转变为职业人的过程是很艰难的&#xff0c;因为我们要与自己积累了多年的“老毛病”作斗争&#xff0c;这些“老毛病”包括&#xff1a;做事拖拉、不守时、不遵守规则、怕吃苦等。 就像发射火箭卫星一样&#xff0c;摆脱重力的束缚所花费的燃料是最多的&#xff0c;一旦…

springcloud:3.1介绍雪崩和Resilience4j

灾难性雪崩效应 简介 服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。 原因 1.服务提供者不可用(硬件故障、程序bug、缓存击穿、用户大量请求) 2.重试加大流量(用户重试,代码逻辑重试) 3.服…

STM32标准库开发——BKP备份RTC时钟

备份寄存器BKP(Backup Registers) 由于RTC与BKP关联性较高&#xff0c;所以RTC的时钟校准寄存器以及一些功能都放在了BKP中。TAMPER引脚主要用于防止芯片数据泄露&#xff0c;可以设计一个机关当TAMPER引脚发生电平跳变时自动清除寄存器内数据不同芯片BKP区别&#xff0c;主要体…

【python开发】网络编程(上)

这里写目录标题 一、必备基础&#xff08;一&#xff09;网络架构1、交换机2、路由器3、三层交换机4、小型企业基础网络架构5、家庭网络架构6、互联网 &#xff08;二&#xff09;网络核心词汇1、子网掩码和IP2、DHCP3、内网和公网IP4、云服务器5、端口6、域名 一、必备基础 &…

小程序配置服务器域名的操作步骤(入门级)

将详细列出小程序配置服务器域名的操作步骤&#xff1a; 服务器选购推荐&#xff1a;腾讯云轻量服务器 点击以下任一云产品链接&#xff0c;跳转后登录&#xff0c;自动享有所有云产品优惠权益&#xff1a; 经过笔者亲测&#xff0c;强烈推荐腾讯云轻量应用服务器作为游戏服…

益生菌不一定全是“益”,也存在一定的安全风险

谷禾健康 益生菌被世界卫生组织定义为“当摄入足够量时,可为宿主带来健康益处的活微生物”。近年来,随着人们发现其可用于预防、减轻或治疗特定疾病以及改善健康,益生菌在食品和临床治疗中的应用越来越广泛。 大量研究表明,益生菌有助于维持肠道菌群的平衡,促进消化和吸收…

【图说】电脑发展史

免责声明:文中有一些图片来源自网络,如有版权请通知我删除,谢谢! “结绳记事”是计算的开端 如果说“结绳记事”仅是计数,那么“算筹”就是真正的计算工具 算盘也是我们老祖宗的杰出发明,最擅长“加减乘除”,包括但不限于乘方、开方、对数等。还能进行开发智力的“珠心算…

MongoDB聚合运算符:$count

文章目录 语法使用举例在$group阶段中使用在$setWindowFields阶段使用 $count聚合运算符返回分组中文档的数量。从5.0开始支持。 语法 { $count: { } }$count不需要参数 使用 $count可以用于下列聚合阶段&#xff1a; $bucket$bucket$group$setWindowFields 在$group阶段中…

Apache Flink连载(三十五):Flink基于Kubernetes部署(5)-Kubernetes 集群搭建-1

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 ​编辑

List 集合遍历过程中删除元素避坑指南。

文章目录 1. 遍历2. 遍历过程中删除元素2.1 for 简单循环正向遍历方式2.2 for 简单循环反向遍历方式2.3 foreach 方式遍历删除2.4 Iterator的remove()方法2.5 <font color green> removeIf() &#xff08;推荐&#xff09;<green>2.6 Strem 方式 作为一名后端开发…

S1---FPGA硬件板级原理图实战导学

视频链接 FPGA板级实战导学01_哔哩哔哩_bilibili FPGA硬件板级原理图实战导学 【硬件电路设计的方法和技巧-哔哩哔哩】硬件电路设计的方法和技巧01_哔哩哔哩_bilibili&#xff08;40min&#xff09; 【高速板级硬件电路设计-哔哩哔哩】 高速板级硬件电路设计1_哔哩哔哩_bil…