【得捷电子Follow me第2期】 任务2:网络功能使用
[复制链接]
【得捷电子Follow me第2期】 任务2:网络功能使用
完成网络功能的使用,能够创建热点和连接到WiFi
接线:
无
编程语言和环境用CircuitPython:
开发板:
Adafruit Feather ESP32-S3 TFT
运行环境:
Adafruit CircuitPython 8.2.3 on 2023-08-11
编辑器:
mu-editor
用到的模块:
无
需要在code.py同目录下创建一个secrets.py,存放要连接的wifi名称跟密码。
代码解析:
以下是secrets.py文件完整代码:(相应位置要改成自己的wifi名称跟密码,其他几个暂时没用上)
secrets={
"ssid":"要连接的wifi名称",
"password":"要连接的wifi密码",
'aio_username' : 'adafruit io账号',# 暂时用不上
'aio_key' : 'adafruit io API key',# 暂时用不上
'timezone' : "America/New_York", # http://worldtimeapi.org/timezones
}
以下是code.py文件完整代码:
import wifi
import socketpool
import struct
import time
import rtc
import ipaddress
import digitalio
import board
try:
from secrets import secrets
except ImportError:
print("need secrets.py, please add them!")
raise
#NTP_ADDR = "ntp.ntsc.ac.cn"
NTP_ADDR = "ntp.tencent.com"
#NTP_ADDR = "ntp3.aliyun.com"
NTP_PORT = 123
UTC = 8
HOT_POINT_SSID = "MY-ESP32-S3"
HOT_POINT_PASSWORD = "12345678"
HOT_POINT_IP = "192.168.111.1"
#扫描wifi,这里用不上,只是展示一下。
for network in wifi.radio.start_scanning_networks():
print("\t%s\t\tRSSI: %d\tChannel: %d"%(str(network.ssid, "utf-8"), network.rssi, network.channel))
wifi.radio.stop_scanning_networks()
print("wifi conneting...")
#连接secrets里面指定的wifi
wifi.radio.connect(secrets["ssid"],secrets["password"])
pool = socketpool.SocketPool(wifi.radio)
def getNTPTime(pool):
print("getting network time...")
sc = pool.socket(socketpool.SocketPool.AF_INET, socketpool.SocketPool.SOCK_DGRAM)
sc.settimeout(3)
#网上抄的NTP请求包
#data = struct.pack("!BBBBIIIQQQQ",3<<6|3<<3|3,1,10,1,1,10,0,0,0,0,0)
data = struct.pack("!BBBBIIIQQQQ",0x1b,0,0,0,0,0,0,0,0,0,0)
buf=bytearray(48)
print("ntp recving...")
sc.sendto(data, (NTP_ADDR, NTP_PORT))
t0=time.time()
n,addr=sc.recvfrom_into(buf)
sc.close()
print("recv: ",n,addr)
TIME1970 = 0x83aa7e80
t = struct.unpack("!12I", buf)[10]
t1=time.time()
print("used: ",t1-t0)
t -= TIME1970
t = time.localtime(t)
return t
def startHotPoint():
print("wifi hot point starting...")
ip=ipaddress.IPv4Address(HOT_POINT_IP)
mask=ipaddress.IPv4Address("255.255.255.0")
gateway=wifi.radio.ipv4_gateway
wifi.radio.set_ipv4_address_ap(ipv4=ip, netmask=mask, gateway=gateway)
wifi.radio.start_ap(HOT_POINT_SSID, HOT_POINT_PASSWORD)
print("Hot Point: ", wifi.radio.ap_active)
print("SSID: ", HOT_POINT_SSID)
print("Password: ", HOT_POINT_PASSWORD)
print("ap gateway: ", wifi.radio.ipv4_gateway_ap)
print("ap subnet: ", wifi.radio.ipv4_subnet_ap)
print("ap ipv4: ", wifi.radio.ipv4_address_ap)
t = getNTPTime(pool)
rtc.RTC().datetime=t
t0 = time.localtime(time.time())
btn=digitalio.DigitalInOut(board.BOOT0)
btn.switch_to_input(digitalio.Pull.UP)
isHotPointStarted = False
while True:
if not btn.value:
if not isHotPointStarted:
startHotPoint()
isHotPointStarted=True
else:
wifi.radio.stop_ap()
isHotPointStarted=False
print("Hot point stopped!")
time.sleep(1)
t1 = time.localtime(time.time())
if t1.tm_sec!=t0.tm_sec:
t0=t1
print("%d-%02d-%02d %02d:%02d:%02d"%(t1.tm_year, t1.tm_mon, t1.tm_mday, t1.tm_hour + UTC, t1.tm_min, t1.tm_sec))
time.sleep(0.2)
如果只是单纯的完成任务代码其实可以很简单:
连接wifi的功能只要这一句代码:wifi.radio.connect(secrets["ssid"],secrets["password"])
创建wifi热点的功能只要这一句代码:wifi.radio.start_ap(HOT_POINT_SSID, HOT_POINT_PASSWORD)
扫描wifi可以用这一句:wifi.radio.start_scanning_networks()
东西太少没法水时长,所以顺便把获取网络时间也写上去了。
我这里是创建UDP类型的socket,发送NTP报文,请求网络标准时间,端口号是123,
比TCP通过http请求速度应该是要快的,流量也少。
data = struct.pack("!BBBBIIIQQQQ",0x1b,0,0,0,0,0,0,0,0,0,0)
这句就是ntp协议的请求报文,通过udp发出去,
就可以收到NTP服务器返回48字节的时间数据,当然还要解析一下数据的:
t = struct.unpack("!12I", buf)[10]
获取到时间后通过RTC模块,更新esp32的系统时间。
rtc.RTC().datetime=t
任务视频演示
任务源码
活动的心得体会:
CircuitPython的wifi没法做到网络共享,就是不能通过它的热点来上网,有点可惜。
不过有个wifi.radio.Monitor可以用来监控网络数据的,试了一下,没深入研究。
|