- 2024-03-04
-
发表了主题帖:
【得捷Follow me第4期】项目总结
[localvideo]75a4b91c996f6d1fd951a4b0b5082c81[/localvideo]
前言
第四期报名后一直没有收到邮件,因为之前参加感觉都是名额制,都忘记是否有写申请理由了,过了时间问了下确实没有中标。
几日后有人退出,机会又回到我头上,这次板子+屏幕已经近300了,没有参与早期讨论不知屏幕可以自己发挥,很快下了单,凑了个数据线
焊了排针,并连接后如下图:
入门任务:开发环境搭建
这里选择CircuitPython作为本次测试的基本软件平台。
固件下载:W5500-EVB-Pico Download (circuitpython.org)
下载完成后,按住bootselect插入usb,会识别一个u盘,把下载的固件拷贝进去,拷贝完成后自动重启,一个python的板子就完成了。
下面需要安装lib ,下载 地址 Libraries (circuitpython.org)
选择部分需要的库即可,毕竟空间是真的小。
我使用这个插件打开识别的设备,不过这次不知为何不能识别 ,只能当个编辑器用。
然后用串口打开设备,查看输出
点灯闪烁和显示屏最终代码如下:
# 入门任务
import time
import board
import busio
import digitalio
import adafruit_sharpmemorydisplay
def led_flash():
led.value = not led.value
time.sleep(0.5)
def clear_disp():
# Clear the display. Always call show after changing pixels to make the display
# update visible!
display.fill(1)
display.show()
def disp_helloworld():
print("hello world")
display.fill(1)
display.text("I have a dream!", 30, 50, 0)
display.show()
if __name__ == '__main__':
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
# Initialize SPI bus and control pins
spi = busio.SPI(board.GP14, MOSI=board.GP15)
scs = digitalio.DigitalInOut(board.GP13) # inverted chip select
display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
clear_disp()
disp_helloworld()
while True:
led_flash()
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
两条命令初始化了blink的IO引脚
spi = busio.SPI(board.GP14, MOSI=board.GP15)
scs = digitalio.DigitalInOut(board.GP13) # inverted chip select
display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
这三行初始化了屏幕,这么小的屏幕有144x168像素,还是很“视网膜”的。
显示效果如下图:
闪烁见视频吧。
基础任务1 Ping及wireshark
板子带以太网模块,这也是它的诱人之处,将它连到局域网里,使用静态ip实现了ping并抓取了数据包。
总体代码如下:
import time
import board
import busio
import digitalio
import array
import struct
import adafruit_sharpmemorydisplay
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
IP_ADDRESS = (192, 168, 68, 100)
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 68, 1)
DNS_SERVER = (218, 203, 59, 116)
def init():
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
# Initialize SPI bus and control pins
spi = busio.SPI(board.GP14, MOSI=board.GP15)
scs = digitalio.DigitalInOut(board.GP13) # inverted chip select
# pass in the display size, width and height, as well
display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
return led,display
def led_flush():
led.value = not led.value
time.sleep(0.5)
def clear_disp():
# Clear the display. Always call show after changing pixels to make the display
# update visible!
display.fill(1)
display.show()
def init_w5500(ip, subnet, gateway, dns):
##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
##reset
W5x00_RSTn = board.GP20
print("Wiznet5k Ping Test (no DHCP)")
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False)
# Set network configuration
eth.ifconfig = (ip, subnet, gateway, dns)
print("Chip Version:", eth.chip)
print("My IP address is:", eth.pretty_ip(eth.ip_address))
return eth
def disp_w5500():
clear_disp()
display.fill(1)
cst = "chip version:" + eth.chip
display.text(cst, 0, 0, 0)
cst = "ip:" + eth.pretty_ip(eth.ip_address)
display.text(cst, 0, 10, 0)
cst = "mac:" + eth.pretty_mac(eth.mac_address)
display.text(cst, 0, 20, 0)
display.show()
if __name__ == '__main__':
# 初始化led和显示模块
led,display = init()
#静态初始化w5500
eth = init_w5500(IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
disp_w5500()
while True:
led_flush()
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
分别初始化w5500的各引脚,5500接在板子的SPI0上。
eth = WIZNET5K(spi_bus, cs, is_dhcp=False)
# Set network configuration
eth.ifconfig = (ip, subnet, gateway, dns)
这两行配置网络模块的IP等参数,网络初始化成功如下图:
在pc上发送ping命令并抓取数据如下图:
基础任务二:TCP服务器和UDP服务器
程序如下:
# 测试基础任务二
import time
import board
import busio
import digitalio
import array
import struct
import adafruit_sharpmemorydisplay
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
IP_ADDRESS = (192, 168, 68, 100)
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 68, 1)
DNS_SERVER = (218, 203, 59, 116)
def init():
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
# Initialize SPI bus and control pins
spi = busio.SPI(board.GP14, MOSI=board.GP15)
scs = digitalio.DigitalInOut(board.GP13) # inverted chip select
# pass in the display size, width and height, as well
# display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 96, 96)
display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
return led,display
def led_flush():
led.value = not led.value
time.sleep(0.5)
def clear_disp():
# Clear the display. Always call show after changing pixels to make the display
# update visible!
display.fill(1)
display.show()
def disp_helloworld():
print("hello world")
display.fill(1)
display.text(" hello world!", 30, 50, 0)
display.show()
def init_w5500(ip, subnet, gateway, dns):
##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
##reset
W5x00_RSTn = board.GP20
print("Wiznet5k Ping Test (no DHCP)")
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False)
# Set network configuration
eth.ifconfig = (ip, subnet, gateway, dns)
print("Chip Version:", eth.chip)
print("My IP address is:", eth.pretty_ip(eth.ip_address))
return eth
def disp_w5500():
clear_disp()
display.fill(1)
cst = "chip version:" + eth.chip
display.text(cst, 0, 0, 0)
cst = "ip:" + eth.pretty_ip(eth.ip_address)
display.text(cst, 0, 10, 0)
cst = "mac:" + eth.pretty_mac(eth.mac_address)
display.text(cst, 0, 20, 0)
display.show()
def disp_str(s, addr):
display.fill_rect(0,addr,144,10,1)
display.text(s, 0, addr, 0)
display.show()
def inCksum(packet):
if len(packet) & 1:
packet = packet + '\0'
words = array.array('h', packet)
sum = 0
for word in words:
sum += (word & 0xffff)
sum = (sum>>16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return (~sum) & 0xffff
def create_tcpserver(port):
# Initialize a socket for our server
socket.set_interface(eth)
sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Allocate socket for the server
sc_ip = None # IP address of server
sc_port = port # Port to listen on
sc.bind((sc_ip, sc_port)) # Bind to IP and Port
sc.listen() # Begin listening for incoming clients
return sc
def create_udpserver(port):
# Initialize a socket for our server
socket.set_interface(eth)
sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Allocate socket for the server
# sc_ip = None # IP address of server
sc_port = port # Port to listen on
sc.bind((eth.pretty_ip(eth.ip_address), sc_port)) # Bind to IP and Port
return sc
if __name__ == '__main__':
# 初始化led和显示模块
led,display = init()
clear_disp()
#静态初始化w5500
eth = init_w5500(IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
disp_w5500()
# 创建一个tcp服务器
server = create_tcpserver(40001)
# 创建一个udp服务器
#server = create_udpserver(40001)
conn, addr = server.accept() # Wait for a connection from a client.
print("socket connected")
# print(addr)
disp_str("UDP Server TEST", 30)
disp_str("socket connected", 40)
# disp_str('cli:'+addr[0]+','+str(addr[1]), 50)
disp_str('receive:', 60)
linenum = 70
while True:
led_flush()
with server:
while True:
data = conn.recv(20)
# data,addr = server.recvfrom(20)
#disp_str('cli:'+addr[0]+','+str(addr[1]), 50)
if data:
print(data)
disp_str(data.decode('utf-8'),linenum)
linenum += 10
if linenum > 150:
linenum = 70
conn.send(data) # Echo message back to client
首先调用init()函数初始化LED和显示模块,并调用init_w5500()函数初始化Wiznet5k以太网模块。然后调用disp_w5500()函数在显示模块上显示Wiznet5k的信息。
创建了一个TCP服务器,调用create_tcpserver()函数指定端口号,并调用accept()方法等待客户端的连接。
进入主循环,不断接收客户端发送的数据并回显给客户端。在循环中,调用recv()方法接收数据,然后使用decode()方法将接收到的字节数据解码为字符串。将解码后的数据显示在显示模块上,并调用send()方法将数据回发给客户端
pc端使用下面的工具发送和接收数据
EEWORLDIMGTK10
进阶任务 从NTP服务器同步时间并在显示屏幕上显示
1.连接NTP服务器需要解析域名,所以一定要配置DNS服务器
2.连接NTP服务器需要micropython的ntp库
实现代码如下:
# 测试进阶任务
import time
import board
import busio
import digitalio
import array
import struct
import adafruit_requests as requests
import adafruit_sharpmemorydisplay
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
#from adafruit_wiznet5k.adafruit_wiznet5k_ntp import NTP
import adafruit_ntp
import adafruit_wiznet5k.adafruit_wiznet5k_dns as dns
days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
IP_ADDRESS = (192, 168, 68, 100)
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 68, 1)
DNS_SERVER = (114, 114, 114, 114)
def init():
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
# Initialize SPI bus and control pins
spi = busio.SPI(board.GP14, MOSI=board.GP15)
scs = digitalio.DigitalInOut(board.GP13) # inverted chip select
# pass in the display size, width and height, as well
# display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 96, 96)
display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
return led,display
def led_flush():
led.value = not led.value
time.sleep(0.5)
def clear_disp():
# Clear the display. Always call show after changing pixels to make the display
# update visible!
display.fill(1)
display.show()
def disp_helloworld():
print("hello world")
display.fill(1)
display.text(" hello world!", 30, 50, 0)
display.show()
def init_w5500(ip, subnet, gateway, dns):
##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
##reset
W5x00_RSTn = board.GP20
print("Wiznet5k Ping Test (no DHCP)")
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
#Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False)
# Set network configuration
eth.ifconfig = (ip, subnet, gateway, dns)
print("Chip Version:", eth.chip)
print("My IP address is:", eth.pretty_ip(eth.ip_address))
return eth
def init_w5500_dhcp():
##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
##reset
W5x00_RSTn = board.GP20
print("Wiznet5k Ping Test (DHCP)")
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=True)
# Set network configuration
# eth.ifconfig = (ip, subnet, gateway, dns)
print("Chip Version:", eth.chip)
print("My IP address is:", eth.pretty_ip(eth.ip_address))
return eth
def disp_w5500():
clear_disp()
display.fill(1)
cst = "chip version:" + eth.chip
display.text(cst, 0, 0, 0)
cst = "ip:" + eth.pretty_ip(eth.ip_address)
display.text(cst, 0, 10, 0)
cst = "mac:" + eth.pretty_mac(eth.mac_address)
display.text(cst, 0, 20, 0)
display.show()
def disp_str(s, addr):
display.fill_rect(0,addr,144,10,1)
display.text(s, 0, addr, 0)
display.show()
def disp_sntp_time(sntp_server):
ntpserver_ip = eth.pretty_ip(eth.get_host_by_name(sntp_server))
print("NTP : %s" % ntpserver_ip) #DNS Domain
#ntp = NTP(iface = eth, ntp_address =ntpserver_ip ,utc=8)
socket.set_interface(eth)
ntp = adafruit_ntp.NTP(socket, tz_offset=8)
cal = ntp.datetime
disp_str("date:", 40)
disp_str("time:", 60)
str_date = "%s %d/%d/%d" %(days[cal.tm_wday], cal.tm_mday,cal.tm_mon,cal.tm_year)
print(str_date)
disp_str(str_date, 50)
str_date = "%d:%02d:%02d" %(cal.tm_hour,cal.tm_min,cal.tm_sec)
print(str_date)
disp_str(str_date, 70)
if __name__ == '__main__':
# 初始化led和显示模块
led,display = init()
clear_disp()
#静态初始化w5500
eth = init_w5500(IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
#初始化w5500 dhcp
# eth = init_w5500_dhcp()
disp_w5500()
time.sleep(1)
disp_str("SNTP TEST", 30)
# ntp.aliyun.com 阿里云授时服务器
disp_sntp_time("ntp.aliyun.com")
while True:
led_flush()
定义了一个名为disp_sntp_time()的函数,该函数接受一个SNTP服务器地址作为参数。
使用eth.get_host_by_name()函数将SNTP服务器的域名解析为IP地址,并将其存储在ntpserver_ip变量中。
创建了一个NTP对象,并传入初始化时的网络接口和NTP服务器的IP地址。通过ntp.datetime属性获取当前的日期和时间,并将其存储在cal变量中。
在显示模块上显示日期和时间的相关信息。使用disp_str()函数将"date:"和"time:"显示在特定的位置上,然后根据cal变量中的日期和时间信息,将日期和时间分别显示在显示模块上的相应位置。
在代码的主循环中,调用了disp_sntp_time()函数,并传入了SNTP服务器的地址"ntp.aliyun.com"。从阿里云的NTP服务器获取当前的日期和时间,并在显示模块上显示出来。
为了使用NTP功能,代码中引入了adafruit_ntp库,并在disp_sntp_time()函数中创建了NTP对象。此使用了adafruit_wiznet5k.adafruit_wiznet5k_socket库中的set_interface()函数来设置NTP对象的网络接口,以便与Wiznet5k以太网模块进行通信。
终极任务二 ftp服务器
查阅python资料发现使用micropython是无法使用片内存储的,而我又没有sd模块,所幸开发板不只支持python还有c的sdk,且c语言sdk中有ftp的示例。
需要安装C语言的sdk,查找下载地址如下:
https://github.com/raspberrypi/pico-setup-windows/releases/tag/v1.5.1
安装windows一体的的开发环境。
测试结果如下:
四、总结
这次的任务总体感觉上比之前的还要难一些,一方面是讲解视频与之前不同了,并没有完全符合和我的预期,参考其它大牛的任务也完成了主要的任务,通过几次followme活动同在对mircopython理解更加深入了,未来可能会基于follow me的板子和这些组件做点有趣的东西,感谢EEWORLD,感谢digikey
代码:
- 2024-03-03
-
加入了学习《follow me4 视频》,观看 followme4 视频
-
回复了主题帖:
【得捷电子Follow me第4期】基础任务二:TCP服务器和UDP服务器
Jacktang 发表于 2024-2-7 09:08
一下子搭建两个服务器,不知道这俩TCP服务器和UDP服务器的区别
socket.SOCK_STREAM socket.SOCK_DGRAM 这两个参数不同
- 2024-02-27
-
回复了主题帖:
【得捷电子Follow me第2期】扫描式传感器支架
秦天qintian0303 发表于 2023-11-7 12:05
没看到是如何连接的啊?最后实现了吗?
超声的驱动没研究好,扫描完成了,自制激光雷达嘿嘿,超声模块得自己写个驱动
- 2024-02-26
-
回复了主题帖:
得捷电子Follow me第4期】进阶任务:从NTP服务器获取时间并显示
没有找到ntp的库
-
回复了主题帖:
【得捷电子Follow me第4期】入门任务
向大佬致敬
- 2024-02-25
-
加入了学习《 【得捷电子Follow me第4期】》,观看 【得捷Follow me第4期】综合实践之智能家居控制器
- 2024-02-24
-
加入了学习《 【得捷电子Follow me第4期】》,观看 【得捷Follow me第4期】入门任务:开发环境搭建
- 2024-02-01
-
加入了学习《直播回放: FollowMe 4 W5500-EVB-Pico 使用入门》,观看 W5500-EVB-Pico 使用入门