基于ESP32+MicroPython实现联网并进行UDP通信

描述

    1. 官方文档
    1. 创建一个 STA 的基本流程
    1. 测试 udp 通信

使用 esp32 开发程序,非常重要的功能就是使用 wifi,下面我们就讲一下 esp32 连接 wifi 的方法。

在我们能接触的 WiFi 网络中,Wi-Fi设备通常处于以下两种角色中的一种:

  • 提供无线接入的设备,称之为 Access Point(AP) 无线接入点,家里常见的路由器就是结合 WiFi 和网络路由功能的 AP,AP 和 AP 可以相互连接。
  • 连接到 AP 的设备,称之为 Station(STA) 无线终端,像手机、电脑等需要联网的设备都处于 STA 模式,这个模式不允许其他设备接入。

说明:

一个设备可能既支持 AP 又支持 STA,但是一般设备同一时间,WiF 模块只能启用其中的一种模式,像手机既能连接外面的 WiFi,又能自己开热点让别的设备连接,但是每当开启热点,WiFi 就会自动关闭,这是因为手机在同一时间只能支持 AP 和 STA 一种。

1. 官方文档

官方文档对 esp32 实现wifi 功能的文档链接 ^[1]^ ,如下:

UDP

实现 WiFi 连接功能,需要使用到network模块:

不管是 STA 还是 AP 都是基于 network 的 WLAN,针对 LAN 我们以后再讲。

STA 的实现方法

import network

wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True)       # activate the interface
wlan.scan()             # scan for access points
wlan.isconnected()      # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
wlan.config('mac')      # get the interface's MAC address
wlan.ifconfig()         # get the interface's IP/netmask/gw/DNS addresses

ssid:就是需要链接的 WiFi 的名称。

key:就是需要链接的 WiFi 的密码。

说明:

现在的路由器都有 2.4g 和 5G 两个频段的信号,但是 esp32 只支持 2.4G 的信号。

官网提供了一个创建 STA 的 demo:

def do_connect():
    import network
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('ssid', 'key')
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())

AP 的实现方法

import network

ap = network.WLAN(network.AP_IF) # create access-point interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True)         # activate the interface

AP 功能用于让其他设备连接 esp32,这个功能不常用,我们以后会在补充里面介绍。

2. 创建一个 STA 的基本流程

esp32 不管是 UDP 还是 TCP 通信,都需要两个模块的支持。

network:用于连接 WiFi,获取 wifi 分配的 ip 等。

socket:用于设备之间的通信,当连接网络后,下一步就是建立和其他设备的通信。

下面我们创建一个 WiFi 类,实现 STA 连接:

import network
import time

class Wifi():
    """
    只实现了STA模式的WiFi链接封装
    """


    def __init__(self):
        self.wlan = network.WLAN(network.STA_IF)



    """
    复位WiFi模块
    """
    def Init_wifi(self):
        if  self.wlan.isconnected():
            self.wlan.active(False)
            print("wifi disconnect,please Reset Configuration ")

    """
    获取WiFi状态
    """
    def status(self):
        return self.wlan.status()


    """
    获取WiFi配置
    """
    def get_wifi_config(self):
        if self.wlan.isconnected():
            return self.wlan.ifconfig()


    """
    扫描WiFi列表
    """
    def wifi_scan(self):
        if wifi.status() != network.STAT_CONNECTING:
            self.wlan.active(True) # 开启WiFi
        return self.wlan.scan()


    """
    连接WiFi
    """
    def connet_wifi(self, ssid, password):
        count = 10 # 10秒内未连接到网络,则连接超时
        self.wlan.active(True) # 开启WiFi
        if not self.wlan.isconnected():
            self.wlan.connect(ssid,password)
            while not self.wlan.isconnected():
                print('connecting to network...')
                time.sleep(1)
                count -= 1
                if count == 0: # 连接超时
                    self.wlan.active(False) # 关闭WiFi
                    print("Connecting  Timeout,Please check the account password!")
                    break
        if self.wlan.isconnected():
            # 连接成功,则打印被分配的ip等信息
            print("ip:" ,self.wlan.ifconfig()[0])
            print("subnet:" ,self.wlan.ifconfig()[1])
            print("gateway:" ,self.wlan.ifconfig()[2])
            print("dns:" ,self.wlan.ifconfig()[3])
            return True
        else:
            # 未成功连接,则返回False
            return False


if __name__ == "__main__":
    wifi = Wifi() # 创建WiFi对象
    wifi_list = wifi.wifi_scan() # 扫描WiFi列表
    print(wifi_list)

    link_wifi = wifi.connet_wifi('K3', 'zhao0312') # 连接WiFi
    if(link_wifi == True):
        print("connet wifi is ok")

在调用 wlan.connect()之后,设备将在默认情况下永远重试连接,即使身份验证失败或范围内没有 AP,因此我们不需要重复 connect,只需要执行一次,自己设置一个等待超时就可以了。当然若不想这样也可以通过调 wlan.config(reconnects=n)来更改,其中 n 是所需的重新连接尝试次数(0 表示不会重试,-1 将恢复尝试永远重新连接的默认行为)。

wlan.isconnected()可以判断当前是否连接成功,当然也可以使用 wlan.status()将返回网络状态,调用 wlan.connect()之后,网络将处于 network.STAT_CONNECTING 表示正在连接状态,直到连接成功或接口被禁用状态才会改变。

一旦网络建立,我们可以通过 socket 模块像往常写 python 程序一样创建和使用 TCP/UDP 套接字,使用 urequests 模块可以方便的实现 HTTP 请求。

3. 测试 udp 通信

提示:

使用 micropython 开发 esp32,要求开发者要有 python 基础。

首先将电脑安装一个网络调试助手软件,这里推荐使用 NetAssist.exe。下载地址:下载链接 ^[2]^ ;

然后找一个能保证 PC 和 ESP32 都能正常连接的路由器,把电脑连接上路由器,然后在电脑的 cmd 控制台输入 ipconfig,看一下路由器分配的 ip 地址,如下:

UDP

这个 ip 地址将会在后面使用到。打开电脑上下载一个网络助手等待备用。

将上面连接 wifi 的程序封装成 wifi.py,然后创建一个 test_socket.py 文件,这时 esp 内目录如下:

UDP

然后将下面内容添加到 test_socket.py 文件中,内容如下:

from wifi import Wifi

from socket import *
import time

# 我电脑的ip
server_addr = "192.168.2.103"
# 随便选一个端口,建议端口范围2000~65535
server_port = 5000



def creation_udp_client():
    # 1. 创建udp套接字
    udp_socket = socket(AF_INET, SOCK_DGRAM)
    # 2. 准备服务器收方的地址
    dest_addr = (server_addr, server_port)

    # 3. 从键盘获取数据
    send_data = "hello world"
    # 4. 发送数据到指定的电脑上
    udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
    # 5. 关闭套接字
    udp_socket.close()


if __name__ == "__main__":
    wifi = Wifi() # 创建WiFi对象
    link_wifi = wifi.connet_wifi('K3', 'zhao0312') # 连接WiFi
    if(link_wifi == True):
        print("connet wifi is ok")
        while True:
            creation_udp_client()
            time.sleep(5)

点击 ide 上面的运行按钮,如下:

UDP

然后打开网络助手:

选择 ip 和端口号与 test_socket.py 文件设置的一致,就会收到由 esp32 发过来的消息,如下:

UDP

到此实验完成,若需要让程序开机运行,则只需要将 test_socket.py 内容 copy 到 boot.py 文件中即可。

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分