0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

嵌入式开发爱好者 来源:嵌入式开发爱好者 作者:嵌入式开发爱好者 2022-11-22 09:19 次阅读

大家好,我是ST!

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

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

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

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

fa01dd48-69b2-11ed-8abf-dac502259ad0.png

fa2131ac-69b2-11ed-8abf-dac502259ad0.png

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

fa4b4258-69b2-11ed-8abf-dac502259ad0.png

点击【新建项目】

fa659306-69b2-11ed-8abf-dac502259ad0.png

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

fa808238-69b2-11ed-8abf-dac502259ad0.png

点击刚新建的项目

fa9d933c-69b2-11ed-8abf-dac502259ad0.png

点击【新建产品】

fabbe166-69b2-11ed-8abf-dac502259ad0.png

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

facd8fa6-69b2-11ed-8abf-dac502259ad0.png

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

faea64f0-69b2-11ed-8abf-dac502259ad0.png

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

fb05daaa-69b2-11ed-8abf-dac502259ad0.png

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

fb21b2a2-69b2-11ed-8abf-dac502259ad0.png

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

fb48045c-69b2-11ed-8abf-dac502259ad0.png

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

fb682142-69b2-11ed-8abf-dac502259ad0.png

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

fb81d38a-69b2-11ed-8abf-dac502259ad0.png

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

fb9a39de-69b2-11ed-8abf-dac502259ad0.png

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

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

fbae5eb4-69b2-11ed-8abf-dac502259ad0.png

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

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

点击【下一步】

fbc7d736-69b2-11ed-8abf-dac502259ad0.png

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

fbe236ee-69b2-11ed-8abf-dac502259ad0.png

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

fbf197ce-69b2-11ed-8abf-dac502259ad0.png

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

第二步:生成Username和Password

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

fc0899f6-69b2-11ed-8abf-dac502259ad0.png

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

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

fc2786e0-69b2-11ed-8abf-dac502259ad0.png

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

fc422d10-69b2-11ed-8abf-dac502259ad0.png

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

fc5cc5f8-69b2-11ed-8abf-dac502259ad0.png

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

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

fc7551cc-69b2-11ed-8abf-dac502259ad0.png

【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】

fcbcdae2-69b2-11ed-8abf-dac502259ad0.png

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

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

【Password】:cd6c31a3d4cfdba2759deab02fb831a0f672e008;hmacsha1

点击【OK】保存

fcdcad04-69b2-11ed-8abf-dac502259ad0.png

点击【Connect】连接腾讯云

fcf675fe-69b2-11ed-8abf-dac502259ad0.png

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

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

fd0f312a-69b2-11ed-8abf-dac502259ad0.png

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

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

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

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

fd24163a-69b2-11ed-8abf-dac502259ad0.png

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

fd4101fa-69b2-11ed-8abf-dac502259ad0.png

第四步、编写程序代码

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

import usocket as socket
import ustruct as struct
from ubinascii import hexlify




class MQTTException(Exception):
    pass




class 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")
        msg = bytearray(b"x04MQTTx04x02")


        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")
        self.sock.close()


    def ping(self):
        self.sock.write(b"xc0")


    def publish(self, topic, msg, retain=False, qos=0):
        pkt = bytearray(b"x30")
        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")
        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"x40x02")
            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 time
import network
from umqttsimple import MQTTClient
from machine import Pin,Timer


def 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. 创建mqt
c = 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()

fd57451e-69b2-11ed-8abf-dac502259ad0.png

点击编译,编译成功如下

fd76b6f6-69b2-11ed-8abf-dac502259ad0.png

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

fd94977a-69b2-11ed-8abf-dac502259ad0.png

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

fdb7937e-69b2-11ed-8abf-dac502259ad0.png

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

fdd28e04-69b2-11ed-8abf-dac502259ad0.png

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 远程控制
    +关注

    关注

    4

    文章

    546

    浏览量

    34511
  • 腾讯云
    +关注

    关注

    0

    文章

    190

    浏览量

    16617
  • MQTT
    +关注

    关注

    5

    文章

    537

    浏览量

    21975
  • ESP32
    +关注

    关注

    13

    文章

    896

    浏览量

    15810

原文标题:使用ESP32连接腾讯云实现远程控制

文章出处:【微信号:嵌入式开发爱好者,微信公众号:嵌入式开发爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    远程控制方法

    想问问单片机远程控制的思路,使用esp8266弄机智必须在同一个网络下才行,这也就限制了距离,所以想问假如我想实现异地控制,使用什么模组?
    发表于 10-04 22:11

    STM32F103C8T6连接阿里物联网平台

    STM32F103C8T6连接阿里物联网平台(1)—阿里lot Studio控制Web开发分享一下自己使用stm32f103c8t6通过ESP
    发表于 08-11 09:33

    请问esp8266如何通过mqtt协议建立连接实现小车的远程控制

    请问esp8266如何通过mqtt协议建立连接实现小车的远程控制
    发表于 11-01 06:32

    为什么ESP32腾讯ASR平台会出现偶发性的签名错误问题呢

    为什么ESP32腾讯ASR平台会出现偶发性的签名错误问题呢?怎样去解决这个问题?
    发表于 12-23 09:24

    如何使用Arduino IDE开发让ESP32连接wifi?

    如何使用Arduino IDE开发让ESP32连接wifi?
    发表于 01-14 07:09

    如何利用ESP32实现远程图传?

    如何利用ESP32实现远程图传?
    发表于 01-19 07:36

    使用esp32连接mpu6050读取角度数据

    使用esp32连接mpu6050,读取角度(这里只是读取角度,其他的自行去查阅,很多厂家都有例程的)。这边使用的是维特一家厂家的(他们的技术服务很好),看了官方的arduino例程,发现他们
    发表于 02-10 07:11

    使用OneNET平台远程控制风扇的方法

    联网的平台,实现控制开发板上面的灯。暑假期间,参加竞赛之余,实现云端控制继电器,进而实现
    发表于 02-21 06:12

    ESP8266开发板+机智IoT+远程控制的智能风扇

    智能小风扇本案例为机智开发平台初级基础应用开发实例,开发者通过使用机智Aiot开发平台和ESP8266,实现对USB风扇的远程APP
    发表于 06-14 13:24

    esp32c3连接wifi和tcp服务器速度能否加快,esp8266 速度在5-7s左右,esp32c3能否加快?

    esp8266 80ma左右?esp32c3是否能在40mhz运行,功耗是多少?》2:esp32c3连接wifi和tcp服务器速度能否加快,esp
    发表于 02-17 06:44

    有没有例程通过esp32连接AWS IOT平台?如何连接到AWSiot平台?

    有没有例程通过esp32连接AWS IOT平台??如何连接到AWSiot平台?百度找的一些博客都说在乐鑫SDK esp-idf的例程esp-
    发表于 02-20 06:00

    使用esp8266连接阿里进行OTA升级提示错误咋办?

    使用esp8266连接阿里进行OTA升级提示no memory recive buffer
    发表于 02-24 14:25

    请问能提供一份release版本的ESP32腾讯AT固件吗?

    请问能提供一份 release 版本的 ESP32 腾讯 AT 固件吗? 我们在 ESP-AT 仓库编译出来的固件在验证 ota 时候有问题: 发现显示 207 报错,经查文档这个
    发表于 04-24 09:16

    想通过ESP8266连接阿里,固件哪里有?

    想用新唐的板子,通过esp8266连接阿里 有没有测试好的esp8266的固件? 还是说,这个固件要自己修改,自己写?
    发表于 06-27 07:40

    使用ESP32、Python和javascript的远程控制继电器

    电子发烧友网站提供《使用ESP32、Python和javascript的远程控制继电器.zip》资料免费下载
    发表于 11-10 10:27 0次下载
    使用<b class='flag-5'>ESP32</b>、Python和javascript的<b class='flag-5'>远程控制</b>继电器