ESP32嵌入式人工智能:WiFi功能与远程控制LED详解
1、WiFi简介
ESP32的最大优点就是集成了wifi与蓝牙,有了这2个无线模块就可以实现物联网智能控制了,尤其适合无线控制的场景,弥补了STM32处理器在无线Wifi上的缺憾。
WiFi是一种无线网络技术,全称为无线保真网络(Wireless Fidelity)。它允许电子设备(如电脑、智能手机、平板电脑等)通过无线方式连接到互联网或局域网,使用户可以无需使用有线连接就能够访问网络。
WiFi使用了射频信号来传输数据。它基于IEEE 802.11标准,通过无线接入点(无线路由器)将有线网络信号转换为无线信号,并将其传播到设备附近的范围内。当设备连接到WiFi网络时,它会通过认证和加密等过程与无线接入点建立安全的连接。
有了WiFi,后期我们就可以部署Web Server,通过手机、电脑通过互联网远程控制各类智能设备,实现真正的万物互联。
2、WIFI 的六种工作模式
WIFI配置具体的模式主要有以下这几种:STA模式、AccessPoint模式、Monitor模式、Ad-hoc(IBSS)模式、WDS模式、Mesh模式。
在ESP32主要有2种工作模式,即STA模式、AccessPoint模式。
第一种:STA模式
任何一种无线网卡都可以运行在此模式下,这种模式也可以称为默认模式。在此模式下,无线网卡发送连接与认证消息给热点,热点接收到后完成认证后,发回成功认证消息,此网卡接入无线网络。这种模式下,wifi工作于从模式。
第二种:AccessPoint模式
在一个无线网络环境中,无线热点是作为一个主设备,工作于主模式(Master mode)。通过管理控制可控制的STA,从而组成无线网络,也有相应的安全控制策略。由AP形成的网络,由AP的MAC地址唯一识别。热点完成创建后,会由热点创建一个被别的设备可识别的名称,称为SSID。在Linux下,要使用AP模式,必须使系统支持hostapd。
3、ESP3的2种工作模式的设置
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
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
4、ESP32通过WiFI连接路由器
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())
将ssid与key替换成本地路由器的SSID和密码。
获取ESP32连接的配置情况 (IP地址,子网掩码,网管与互联网公网IP)
5、通过WiFi与PC交互数据
在PC上打开网络调试助手,注意设置正确的本机IP。
(1)发送‘hello world’
(2)接收数据 recvfrom
注意3点:第一,发送和接收所创建的SOCKET要是一个,不能重新创建,不然接收不到数据,所以要把第一个发送函数的创建套接字放到函数外,关闭套接字语句去掉。第二网络调试助手要注意设置套接字,一般选最后一个。第三发送的utf-8的中文是bytes字节流的形式,需要用utf-8进行解码decode.
def Wifi_Send(IPAddr,Port,send_data):
# 准备接收方的地址与端口号
dest_addr = (IPAddr, Port)
# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
# 5. 关闭套接字
# udp_socket.close()
def Wifi_Receive():
recv_data = udp_socket.recvfrom(1024)
return recv_data
do_connect()
IPAddr = '192.168.1.101'
Port = 8080
send_data = "hello world"
# 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)
Wifi_Send(IPAddr,Port,send_data)
while True:
recv_data = Wifi_Receive()
print(recv_data[0])
print(type(recv_data[0]))
print(recv_data[0].decode('utf-8'))
注意选择59963的最后一个SOCKET连接,接收到的数据类型为元组类型数据。
6、通过PC远程控制LED灯
我们独立按键与流水灯模块接了4个灯0-3,上电后让所有的LED默认关闭,通过指令里面的数字和ON/OFF 来控制LED灯的亮灭。.
import socket
import time
import network
from machine import Pin
import re
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('TP-LINK_40302', 'wang1982')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
def start_udp():
# 启动网络功能(UDP)
# 1.创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定本地信息
udp_socket.bind(("0.0.0.0", 5678))
return udp_socket
def GPIO_Init():
P0 = Pin(19, Pin.OUT)
P1 = Pin(18, Pin.OUT)
P2 = Pin(5, Pin.OUT)
P3 = Pin(17, Pin.OUT)
global LED_List
LED_List = [P0,P1,P2,P3]
for i in LED_List:
i.value(1)
def Led_ctrl(num,state):
LED_List[num].value(state)
def main():
global state
GPIO_Init()
#链接wifi
do_connect()
#创建UDP
udp_socket = start_udp()
# 接收网络数据
while True:
recv_data, sender_info = udp_socket.recvfrom(1024)
print("{}发送{}".format(sender_info, recv_data))
recv_data_str = recv_data.decode("utf-8")
try:
print(recv_data_str)
except Exception as ret:
print("error:", ret)
# 5. 处理接收的数据
match = re.search(r'\d',recv_data_str)
if match:
num = int(match.group(0))
if "on" in recv_data_str:
state=0
Led_ctrl(num,state)
elif "off" in recv_data_str:
state=1
Led_ctrl(num,state)
if __name__ == "__main__":
main()
通过正则表达式获取要控制的LED灯的ID,这里得到的match变量的类型是正则表达式的匹配对象,需要将其转化成int型变量,传递到函数led_ctrl里,作为列表的索引值。
match = re.search(r'\d',recv_data_str)
if match:
num = int(match.group(0))
上图有一个ESP32的扩展板,最好买一个,由于ESP32扩展板尺寸较大,插上之前的面包板有一列引脚无法引出,如果用2块面包板一起使用也可以不用这个扩展板。
作者:u010152658