esp8266 NodeMCU v3 实现wifi远程 mqtt 通信

在这里插入图片描述

》》》》》》》》》》
这块板子的淘宝链接
》》》》》》》》》》

一.移植MicroPython

1.用microusb 数据线连接到电脑上,找到对应的串口号 这里是52,找不到端口的下载并安装串口驱动
2.

  1. 使用flash_download_tools烧录microPython 固件 文件下载
    在这里插入图片描述
    在这里插入图片描述
  2. 使用thonny IDE进行开发 下载安装包
    在这里插入图片描述
    选择esp8266的端口
    在这里插入图片描述
    测试microPython
    在这里插入图片描述
    打开文件系统
    在这里插入图片描述
    到此环境准备完毕
    在这里插入图片描述

二. 连接wifi 案例

新建一个main.py 的文件

import network,time
from machine import I2C,Pin

#初始化相关模块
i2c = I2C(sda=Pin(13), scl=Pin(14))


#WIFI连接函数
def WIFI_Connect():

    WIFI_LED=Pin(2, Pin.OUT, value=1) #初始化WIFI指示灯

    wlan = network.WLAN(network.STA_IF) #STA模式
    wlan.active(True)                   #激活接口
    start_time=time.time()              #记录时间做超时判断

    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('Xiaomi_3D6D', '!!!!tl820808') #输入WIFI账号密码

        while not wlan.isconnected():

            #LED闪烁提示
            WIFI_LED.value(0)
            time.sleep_ms(300)
            WIFI_LED.value(1)
            time.sleep_ms(300)

            #超时判断,15秒没连接成功判定为超时
            if time.time()-start_time > 15 :
                print('WIFI Connected Timeout!')
                break

    if wlan.isconnected():
        #LED点亮
        WIFI_LED.value(0)

        #串口打印信息
        print('network information:', wlan.ifconfig())

        

#执行WIFI连接函数
WIFI_Connect()


在这里插入图片描述

显示成功连接到wifi,灯光从闪烁变为常亮,ip为192.168.31.70。

三.进行mqtt 双向通信

1. 使用免费公告mqtt服务器

broker-cn.emqx.io

关于不同端口
tcp:1883
tls: 8883
WebSocket: 8083,8084

我们esp8266用的tcp 所以一定要1883端口

扫描二维码关注公众号,回复: 14936963 查看本文章

2.使用esp8266 发布订阅信息

需要新建两个文件

main.py

import network,time
from simple import MQTTClient #导入MQTT板块
from machine import I2C,Pin,Timer

#初始化相关模块
i2c = I2C(sda=Pin(13), scl=Pin(14))


#WIFI连接函数
def WIFI_Connect():

    WIFI_LED=Pin(2, Pin.OUT, value=1) #初始化WIFI指示灯

    wlan = network.WLAN(network.STA_IF) #STA模式
    wlan.active(True)                   #激活接口
    start_time=time.time()              #记录时间做超时判断

    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('Xiaomi_3D6D', '!!!!tl820808') #输入WIFI账号密码

        while not wlan.isconnected():

            #LED闪烁提示
            WIFI_LED.value(0)
            time.sleep_ms(300)
            WIFI_LED.value(1)
            time.sleep_ms(300)

            #超时判断,15秒没连接成功判定为超时
            if time.time()-start_time > 60 :
                print('WIFI Connected Timeout!')
                break

    if wlan.isconnected():
        #LED点亮
        WIFI_LED.value(0)

        #串口打印信息
        print('network information:', wlan.ifconfig())
        return True

    else:
        return False
#接收数据任务
def MQTT_Rev():
    client.check_msg()
#发布数据任务
def MQTT_Send():
    client.publish(TOPICSEND, 'Hello esp8266')
#设置MQTT回调函数,有信息时候执行
def MQTT_callback(topic, msg):
    print('topic: {}'.format(topic))
    print('msg: {}'.format(msg))
# 定时任务
def task(tim):
    MQTT_Rev()
    MQTT_Send()
#执行WIFI连接函数并判断是否已经连接成功
if WIFI_Connect():

    SERVER = 'broker-cn.emqx.io'
    PORT = 1883
    CLIENT_ID = 'xxxx' # 客户端ID
    TOPICREV = 'testtopic/1' # 发送节点
    TOPICSEND = 'testtopic/2' # 接收节点
    
    client = MQTTClient(CLIENT_ID, SERVER, PORT)
    client.set_callback(MQTT_callback)  #配置回调函数
    client.connect()
    client.subscribe(TOPICREV) #订阅主题

    #开启RTOS定时器,编号为-1,周期1000ms,执行socket通信接收任务
    tim = Timer(-1)
    tim.init(period=1000, mode=Timer.PERIODIC,callback=task)


以下代码保存为 simple.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\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()


将 main.py 里面的wifi换成自己的
在这里插入图片描述

修改mqtt id, topic 可以自己设置一个 类似 test/1
在这里插入图片描述

然后上传到开发板里面
在这里插入图片描述

然后直接运行脚本
在这里插入图片描述

3.使用python 发布订阅消息

安装mqtt

pip install paho-mqtt

新建文件mqtt.py

#!/usr/bin/ python
# -*- encoding: utf-8 -*-
'''
@文件    :mqtt.py
@说明    :
@时间    :2022/05/02 19:12:54
@作者    :刘子沫
@邮箱    :[email protected]
@版本    :1.0
'''


import paho.mqtt.client as mqtt
from threading import Thread
import json
import time

HOST = "broker-cn.emqx.io"
PORT = 1883
client_id = "mqttx_d13434c"                     # 客户端ID

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("testtopic/2")         # 订阅消息


def on_message(client, userdata, msg):
    print("主题:"+msg.topic+" 消息:"+str(msg.payload.decode('utf-8')))


def on_subscribe(client, userdata, mid, granted_qos):
    print("On Subscribed: qos = %d" % granted_qos)


def on_disconnect(client, userdata, rc):
    if rc != 0:
        print("Unexpected disconnection %s" % rc)

def send_message():
    for i in range(10000):
        client.publish("testtopic/1", "Hello, World!")
        time.sleep(1)

client = mqtt.Client(client_id)
client.username_pw_set("xxxxxx", "xxxxxx")
client.on_connect = on_connect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.on_disconnect = on_disconnect
client.connect(HOST, PORT, 60)
Thread(target=send_message).start()
client.loop_forever()




修改里面的id
在这里插入图片描述
运行
python 收到esp8266 发过来的信息
在这里插入图片描述
esp8266 收到python 主机发过来 的信息
在这里插入图片描述

需要嵌入式软件定制开发进群

686070107

猜你喜欢

转载自blog.csdn.net/qq_26696715/article/details/124533758