使用ESP32连接腾讯云实现远程控制方法

news2024/12/24 9:03:49

​大家好,上次给大家分享了如何使用ESP32实现蓝牙通信,今天跟大家聊聊如何使用ESP32连接腾讯云实现远程控制。本次实验用到MQTT协议,同样,我用miropython编写程序实现,最终可以通过腾讯连连微信小程序添加设备来发布主题消息给腾讯云,ESP32负责订阅腾讯云主题消息,当收到某订阅消息时,来控制ESP32设备上LED灯的亮灭。

目录

第一步、创建腾讯云产品和设备

第二步:生成Username和Password

第三步:MQTTfx模拟客户端连接腾讯云步骤与调试(非必须步骤)

第四步、编写程序代码

本次实验资料


第一步、创建腾讯云产品和设备

浏览器搜索【腾讯云】,进入腾讯云官网,微信注册登录

点击【产品】搜索【物联网开发平台】,点击【管理控制台】

在实例管理中点击【公共实例】

点击【新建项目】

填写自己的项目名称,点击【保存】

点击刚新建的项目

点击【新建产品】

输入自己定义的【产品名称】,【产品类别】选智慧城市->公共事业->路灯照明,【通信设备】填wi-fi,其他的默认,点击【确定】

点击自己刚新建的产品名称

下拉到最后点击【下一步】

点击【基于模组开发】,产品平台选择【乐鑫】,类型选择【wifi】,点击【乐鑫ESP-WROOM-】点击【确定】

下拉到最后,点击【下一步】

点击【产品展示配置】右侧的【配置】

【产品展示名称】填写自己自定义的名称,【厂家名称】填安信可,【产品信号】填esp32,点击【保存】,上拉点击【<-】返回

点击【快捷入口配置】右侧的【配置】,默认不修改,点击【保存】,上拉点击【<-】返回

点击【面板配置】右侧的【配置】,默认不修改,点击【保存】,点击【<-】返回

点击【配网引导】右侧的【配置】,【芯片方案选择】选择乐鑫,【首选配网方式】选择Smart Config,【次配网方式】选择Soft Ap,点击;【保存】,点击【<-】返回

点击【扫一扫产品介绍】右侧的【配置】,默认不修改,点击【保存】,点击【<-】返回

点击【智能联动配置】右侧的【配置】,默认不修改,点击保存,点击【<-】返回

点击【下一步】

点击【新建设备】,自定义【设备名称】,点击【保存】

点击【二维码】,用手机微信小程序【腾讯连连】扫码添加设备

此时设备已经创建完成,但是设备还未激活,需要后面的的操作连接才可激活

第二步:生成Username和Password

点击【设备调试】,点击【设备名称】

复制保存设备信息三件套:设备名称、产品ID、设备密钥

后面生成MOTT协议中的Username和Password需要用到

打开password生成工具,在文件夹里有给出,点击【sign.html】

输入刚刚复制的设备信息三件套,Hmac签名算法选择【HMAC-SHA1】,点击【Generate】,即可生成Usename和Password,复制保存,后面esp32连接腾讯云和 MQTTfx模拟的客户端连接腾讯云需要用到

第三步:MQTTfx模拟客户端连接腾讯云步骤与调试(非必须步骤)

打开MQTT.fx软件,我的压缩包里面有,点击下图的齿轮图形,进入设置

【Profile name】:自定义的名字

【Profile Type】:选择【MQTT Broker】

【Broker Address】:腾讯云三件套中的产品ID+.iotcloud.tencentdevices.com

如我的腾讯云ID为:D89S2VVAFT,

那么Broker Address为:D89S2VVAFT.iotcloud.tencentdevices.com

Broker Port:1883

【Client ID】:腾讯云产品ID+腾讯云设备名称+|securemode=3,signmethod=hmacsha1|

例如我的腾讯云产品ID为:D89S2VVAFT,腾讯云产品名称为:esp_led

则Client ID为:D89S2VVAFTesp_led|securemode=3,signmethod=hmacsha1|

填写这些数据完毕后,点击【User Credentlals】

User Name和Password填写第二步生成的,每个人的都不一样

【User Name】:D89S2VVAFTesp_led;12010126;CU7SQ;1660090317

【Password】:cd6c31a3d4cfdba2759deab02fb831a0f672e008;hmacsha1

点击【OK】保存

点击【Connect】连接腾讯云

MQTT.fx模拟的客户端连接腾讯云成功后可以看到右边的原点变绿,并且有个打开的所,

这时候我们就可以通过手机端小程序腾讯连连来给腾讯云发送消息,腾讯云再将此消息发送给MQTT.fx客户端,但是前提是MQTT.fx客户端需要订阅腾讯云,下面是订阅的步骤

点击【Subscribe】,Subscribe左边的空格填写格式为:

$thing/down/property/“腾讯云产品ID”/“腾讯云产品名称”

例如:$thing/down/property/D89S2VVAFT/esp_led

填写完成后,点击【Subscribe】,现在手机端腾讯练练发送消息,MQTT.fx可以收到消息了

可以看到MQTT.fx收到了消息,MQTT.fx只是模拟一个客户端接收消息,我们需要将我们的esp32模块替代MQTT.fx,这样我们就可以通过手机发送消息给腾讯云,腾讯云转发消息给esp32模块了,通过单片机对收到的数据处理,就可以通过手机端控制开发板的LED灯亮灭。

第四步、编写程序代码

首先需要用到MQTT的驱动代码,我在网上找到了一个用miropython写的驱动代码,大家可以直接复制使用,命名为umqttsimple.py即可,代码如下:

import usocket as socketimport ustruct as structfrom ubinascii import hexlifyclass MQTTException(Exception):    passclass MQTTClient:    def __init__(        self,        client_id,        server,        port=0,        user=None,        password=None,        keepalive=0,        ssl=False,        ssl_params={},    ):        if port == 0:            port = 8883 if ssl else 1883        self.client_id = client_id        self.sock = None        self.server = server        self.port = port        self.ssl = ssl        self.ssl_params = ssl_params        self.pid = 0        self.cb = None        self.user = user        self.pswd = password        self.keepalive = keepalive        self.lw_topic = None        self.lw_msg = None        self.lw_qos = 0        self.lw_retain = False    def _send_str(self, s):        self.sock.write(struct.pack("!H", len(s)))        self.sock.write(s)    def _recv_len(self):        n = 0        sh = 0        while 1:            b = self.sock.read(1)[0]            n |= (b & 0x7F) << sh            if not b & 0x80:                return n            sh += 7    def set_callback(self, f):        self.cb = f    def set_last_will(self, topic, msg, retain=False, qos=0):        assert 0 <= qos <= 2        assert topic        self.lw_topic = topic        self.lw_msg = msg        self.lw_qos = qos        self.lw_retain = retain    def connect(self, clean_session=True):        self.sock = socket.socket()        addr = socket.getaddrinfo(self.server, self.port)[0][-1]        self.sock.connect(addr)        if self.ssl:            import ussl            self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)        premsg = bytearray(b"\x10\0\0\0\0\0")        msg = bytearray(b"\x04MQTT\x04\x02\0\0")        sz = 10 + 2 + len(self.client_id)        msg[6] = clean_session << 1        if self.user is not None:            sz += 2 + len(self.user) + 2 + len(self.pswd)            msg[6] |= 0xC0        if self.keepalive:            assert self.keepalive < 65536            msg[7] |= self.keepalive >> 8            msg[8] |= self.keepalive & 0x00FF        if self.lw_topic:            sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)            msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3            msg[6] |= self.lw_retain << 5        i = 1        while sz > 0x7F:            premsg[i] = (sz & 0x7F) | 0x80            sz >>= 7            i += 1        premsg[i] = sz        self.sock.write(premsg, i + 2)        self.sock.write(msg)        # print(hex(len(msg)), hexlify(msg, ":"))        self._send_str(self.client_id)        if self.lw_topic:            self._send_str(self.lw_topic)            self._send_str(self.lw_msg)        if self.user is not None:            self._send_str(self.user)            self._send_str(self.pswd)        resp = self.sock.read(4)        assert resp[0] == 0x20 and resp[1] == 0x02        if resp[3] != 0:            raise MQTTException(resp[3])        return resp[2] & 1    def disconnect(self):        self.sock.write(b"\xe0\0")        self.sock.close()    def ping(self):        self.sock.write(b"\xc0\0")    def publish(self, topic, msg, retain=False, qos=0):        pkt = bytearray(b"\x30\0\0\0")        pkt[0] |= qos << 1 | retain        sz = 2 + len(topic) + len(msg)        if qos > 0:            sz += 2        assert sz < 2097152        i = 1        while sz > 0x7F:            pkt[i] = (sz & 0x7F) | 0x80            sz >>= 7            i += 1        pkt[i] = sz        # print(hex(len(pkt)), hexlify(pkt, ":"))        self.sock.write(pkt, i + 1)        self._send_str(topic)        if qos > 0:            self.pid += 1            pid = self.pid            struct.pack_into("!H", pkt, 0, pid)            self.sock.write(pkt, 2)        self.sock.write(msg)        if qos == 1:            while 1:                op = self.wait_msg()                if op == 0x40:                    sz = self.sock.read(1)                    assert sz == b"\x02"                    rcv_pid = self.sock.read(2)                    rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]                    if pid == rcv_pid:                        return        elif qos == 2:            assert 0    def subscribe(self, topic, qos=0):        assert self.cb is not None, "Subscribe callback is not set"        pkt = bytearray(b"\x82\0\0\0")        self.pid += 1        struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid)        # print(hex(len(pkt)), hexlify(pkt, ":"))        self.sock.write(pkt)        self._send_str(topic)        self.sock.write(qos.to_bytes(1, "little"))        while 1:            op = self.wait_msg()            if op == 0x90:                resp = self.sock.read(4)                # print(resp)                assert resp[1] == pkt[2] and resp[2] == pkt[3]                if resp[3] == 0x80:                    raise MQTTException(resp[3])                return    # Wait for a single incoming MQTT message and process it.    # Subscribed messages are delivered to a callback previously    # set by .set_callback() method. Other (internal) MQTT    # messages processed internally.    def wait_msg(self):        res = self.sock.read(1)        self.sock.setblocking(True)        if res is None:            return None        if res == b"":            raise OSError(-1)        if res == b"\xd0":  # PINGRESP            sz = self.sock.read(1)[0]            assert sz == 0            return None        op = res[0]        if op & 0xF0 != 0x30:            return op        sz = self._recv_len()        topic_len = self.sock.read(2)        topic_len = (topic_len[0] << 8) | topic_len[1]        topic = self.sock.read(topic_len)        sz -= topic_len + 2        if op & 6:            pid = self.sock.read(2)            pid = pid[0] << 8 | pid[1]            sz -= 2        msg = self.sock.read(sz)        self.cb(topic, msg)        if op & 6 == 2:            pkt = bytearray(b"\x40\x02\0\0")            struct.pack_into("!H", pkt, 2, pid)            self.sock.write(pkt)        elif op & 6 == 4:            assert 0    # Checks whether a pending message from server is available.    # If not, returns immediately with None. Otherwise, does    # the same processing as wait_msg.    def check_msg(self):        self.sock.setblocking(False)        return self.wait_msg()

主程序代码如下:

import timeimport networkfrom umqttsimple import MQTTClientfrom machine import Pin,Timerdef do_connect():    wlan = network.WLAN(network.STA_IF)    wlan.active(True)    if not wlan.isconnected():        print('connecting to network...')        wlan.connect('11', '1234567a')        i = 1        while not wlan.isconnected():            print("正在链接...{}".format(i))            i += 1            time.sleep(1)    print('network config:', wlan.ifconfig())def sub_cb(topic, msg): # 回调函数,收到服务器消息后会调用这个函数    print(topic, msg)    top=str(topic,'UTF-8')    strdata=str(msg,'UTF-8')    count=strdata.find("power_switch")    print(strdata[count+len("power_switch")+2])    if strdata[count+len("power_switch")+2]=='0' and top=='$thing/down/property/D89S2VVAFT/esp_led':        led.value(1)    if strdata[count+len("power_switch")+2]=='1' and top=='$thing/down/property/D89S2VVAFT/esp_led':        led.value(0)        #客户端ID    client_id="D89S2VVAFTesp_led|securemode=3,signmethod=hmacsha1|"#服务器域名addr="D89S2VVAFT.iotcloud.tencentdevices.com"#端口号port=1883#用户名username="D89S2VVAFTesp_led;12010126;KTXHT;1669512546"#密码password="0569df86e0c75494960cc922703c9ddd47c3fee048ed03d6b1a22d89a8b8a305;hmacsha256"led=Pin(22,Pin.OUT)led.value(1)# 1. 联网do_connect()# 2. 创建mqtc = MQTTClient(client_id=client_id,server=addr,port=port,user=username,password=password,keepalive=60)  # 建立一个MQTT客户端c.set_callback(sub_cb)  # 设置回调函数c.connect()  # 建立连接c.subscribe(b"$thing/down/property/D89S2VVAFT/esp_led")  # 监控ledctl这个通道,接收控制命令timer1 = Timer(0)timer1.init(period=1000*60, mode=Timer.PERIODIC, callback=lambda t: c.ping())while True:    c.check_msg()

点击编译,编译成功如下

查看腾讯云建立的设备,可以看到,此时设备已经在线

点击二维码,打开腾讯连连小程序,扫码添加设备

现在就可以通过腾讯连连来控制ESP32设备啦!点击点灯开关,ESP32设备打印出收到的消息,如下:

本次实验资料

链接:https://pan.baidu.com/s/1IoiBnT5zfXnL6BgP24XZcg 

提取码:rwk1

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GamePlay】两个ScrollView插件,Super ScrollView UIExtensions

前言 记录一下最近了解使用的两个滚动列表插件&#xff0c;UIExtensions 和Super ScrollView 。 原生的ScrollView 只能滚动 Viewport中Content范围内的物体&#xff0c;如果要使用必须得做一些功能扩展&#xff0c;很不方便&#xff0c;于是找了这两个插件。 前者不只是滚动…

一文了解JVM整体设计

一、JDK / JRE / JVM二、.Java 文件运行过程三、JVM运行时数据区3.1 Method Area3.2 Heap3.3 Java Virtual Machine Stacks3.4 Native Method Stacks3.5 The PC Register四、JVM内存模型4.1 JVM对象创建和回收过程五、垃圾收集5.1 确定垃圾收集对象5.1.1 引用计数法5.1.2 可达性…

2023年英语二大作文押题猜想(达立易考)

又到了考前大开脑洞的时间了&#xff01;每年一到这个时间点&#xff0c;关于押题猜题的话题就会铺天盖地而来&#xff0c;众多名师大咖更是会集毕生所学&#xff0c;期待可以在这个环节押中部分题目彰显实力&#xff0c;其中主观题就是大家集中关注的重要热点模块。押题听起来…

声纹识别开源工具 ASV-Subtools

今天非常荣幸有机会在Speechhome语音技术研讨会上分享我们团队在开源项目上的一些工作。今天我分享的主题是声纹识别开源工具ASV-Subtools。 今天我分享的主要有5个部分的内容&#xff0c;分别是背景介绍、工具介绍、实验结果、Subtools工程化、总结与展望。其中Subtools工程化…

【ROS】机械人开发五--ROS基本概念的程序实现

机械人开发五--ROS基本概念的程序实现一、开发工具二、RoboWare Studio的基本使用2.1 软件启动2.2 修改界面语言2.3 使用2.4 编译文件2.5 卸载三、话题通信四、话题的代码编写4.1 发布端4.2 接收端4.3 测试五、自定义消息5.1 自定义消息类型5.2 自定义消息发布端5.3 自定义消息…

el-menu动态加载路由,菜单的解决方案

先看需要实现的效果 这里有一级也有二级菜单&#xff0c;注意二级菜单的父目录&#xff08;”选项设置“点击不会跳转&#xff0c;只是展开目录&#xff09;&#xff0c;然后点击去详情页&#xff0c;需要跳到一个隐藏的路由&#xff0c;不在菜单展示的路由 还有一点要注意&…

LaTex常用技巧5:公式太长换行并加大括号

使用LaTex做笔记的时候发现公式太长&#xff0c;一行会超出页面&#xff0c;于是想到换行。 原来的代码&#xff0c;这里使用了包bm&#xff0c;测试的时候前面请使用\usepackage{bm}。 \begin{equation}_{i}^{G} {\bm{a}}\begin{cases} _{i}^{i-1}\ddot{\bm{p}}, &i1\\_…

web课程设计网页规划与设计 html+css+javascript+jquery+bootstarp响应式游戏网站Bootstrap模板(24页)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

网址,URL,域名,IP地址,DNS,域名解析(转载)

一、基本常识 互联网上的所有数据都是存储在主机(服务器)上互联网中的所有主机都拥有唯一的IP地址互联网中任意两台主机通信都是通过IP地址来实现 上网的实质 就是获取网址对应主机上的数据并在用户主机上进行展示(浏览器上) 疑问&#xff1a;互联网中的任意两台主机通信是依…

详细介绍百度ERNIE:通过知识集成增强表示

文章目录ERNIE简介相关工作采用矢量表示单词 &#xff0c;上下文无关的表示采用上下文来预测丢失的单词&#xff0c;没有考虑先验知识采用异构数据ERNIE的详细实现Transformer编码器知识整合基本级别掩码短语级别掩码实体级别掩码实验异构语料库预训练DLM&#xff08;对话语言模…

python自动化:桌面壁纸下载器,满足你对桌面壁纸的无限畅想!

随着计算机性能的提升&#xff0c;人们对计算机个性化的要求也越来越高了&#xff0c;自己使用的计算机当然要设置成自己喜欢的风格&#xff01; 对于桌面壁纸有着强烈要求的朋友们有福了&#xff0c;推荐一个微软免费畅玩无限高清壁纸的官网。 https://cn.bing.com/images/t…

深入学习数组

目录 一、一维数组 1、数组的创建和初始化 2、一维数组的使用 3、*一维数组在内存中的存储 二、二维数组 1、二维数组的创建和初始化 2、二维数组的使用 3、*二维数组在内存中的存储 三、数组越界 一、一维数组 1、数组的创建和初始化 数组是一组相同类型元素的集合。 数组…

UNIAPP实战项目笔记42 购物车页面新增收货地址

UNIAPP实战项目笔记42 购物车页面新增收货地址 设置新增收货地址页面布局和功能 具体内容图片自己替换哈&#xff0c;随便找了个图片的做示例 用到了vuex的状态机,具体位置见目录结构 代码 my-add-path.vue 页面部分 my-add-path.vue 设置页面布局 用到了vuex的状态机 <te…

steam搬砖副业,月入2万+,内含全套讲解

Steam平台是一款国外知名的数字游戏社交平台&#xff0c;steam游戏平台起初只是一个整合游戏的下载平台&#xff0c;随着软件的发展&#xff0c;逐渐演变为了游戏社交平台&#xff0c;steam是世界上目前最大的游戏平台之一&#xff0c;而「网易BUFF」是一款由网易公司推出&…

Unity3D简陋版跑酷游戏

目录 功能演示 功能简介 制作步骤 功能演示 链接&#xff1a;https://pan.baidu.com/s/1E_2JXWlVJNf3S5l-dH2UuQ提取码&#xff1a;dm5e 视频教学:Unity3D大作业 超级简陋版的跑酷游戏_哔哩哔哩_bilibili 功能简介 本次跑酷游戏主要从跑道&#xff0c;UI设计&#xff0c;…

[附源码]java毕业设计小区宠物管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

MyBatis--获取参数值

MyBatis获取参数值的两种方式 &#xff1a; ${} 和 #{} ${}的本质是字符串 &#xff0c;#{}的本质是占位符赋值 ${}使用字符串拼接的方式拼接sql &#xff0c;若为字符串类型或日期类型的字段进行赋值时&#xff0c;需要手动加单引号。 #{}使用占位符赋值的方式拼接sql &#x…

[附源码]java毕业设计小锅米线点餐管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Spring Cloud实战】Spring Cloud Bus消息总线

gitee地址&#xff1a;https://gitee.com/javaxiaobear/spring-cloud_study.git 在线阅读地址&#xff1a;https://javaxiaobear.gitee.io/ 1、概述 Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改&#xff08;例如配置更改&#xff09;或其…

15.PyQt5中的事件系统之事件(QEvent)简介

PyQt5中的事件系统 一、什么是Qt中的事件 事件&#xff08;event&#xff09;是由窗口系统或者Qt自身产生的事情或动作的通称。当用户按下或者松开键盘或鼠标的按键时&#xff0c;就可以产生一个键盘或者鼠标事件&#xff1b;当某个窗口第一次显示的时候&#xff0c;就会产生一…