Last active
October 2, 2023 02:53
-
-
Save anecdata/7eb1cb2b6cece8c5b45c178e88cdfeac to your computer and use it in GitHub Desktop.
PicoW + WIZnet UDP Ouroboros
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SPDX-FileCopyrightText: 2023 anecdata | |
# | |
# SPDX-License-Identifier: MIT | |
import time, gc, random, board, busio, digitalio | |
from secrets import secrets | |
# for PicoW server: | |
import wifi, socketpool, ipaddress | |
# for WIZnet client: | |
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K | |
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket | |
__version__ = "0.0.2" | |
PORT = 5000 | |
SERVER_TIMEOUT = 5 | |
CLIENT_TIMEOUT = 5 | |
BACKLOG = 1 | |
INTERVAL = 5 | |
print(f"PicoW + WIZnet UDP Ouroboros Test") | |
# Connect to Wi-Fi | |
wifi.radio.connect(secrets['ssid'], secrets['password']) | |
time.sleep(0.1) # IP address can lag connect return by 10s of ms | |
print(f"PicoW Server IP Address: {wifi.radio.ipv4_address}") | |
# PicoW server address | |
HOST = str(wifi.radio.ipv4_address) | |
# PicoW socketpool | |
pool = socketpool.SocketPool(wifi.radio) | |
# WIZnet Ethernet Hat on Raspberry Pi Pico [W] | |
cs = digitalio.DigitalInOut(board.GP17) | |
spi = busio.SPI(board.GP18, MOSI=board.GP19, MISO=board.GP16) | |
eth = WIZNET5K(spi, cs) | |
eth_ip = eth.pretty_ip(eth.ip_address) | |
print(f"WIZnet Client IP Address: {eth_ip}") | |
# Set up PicoW server socket | |
print(f"Create PicoW server socket", (HOST, PORT)) | |
s_sock = pool.socket(pool.AF_INET, pool.SOCK_DGRAM) | |
s_sock.settimeout(SERVER_TIMEOUT) | |
s_sock.bind((HOST, PORT)) | |
# try to consume our own data w/o async... | |
orig = buf = bytearray() | |
buf_size = 1 | |
while True: | |
print("-"*25) | |
print(f"Available heap {gc.mem_free()} --> ", end="") | |
del(orig) | |
del(buf) | |
gc.collect() | |
print(f"{gc.mem_free()}") | |
orig = bytearray(''.join(random.choice("0123456789ABCDEF") for _ in range(buf_size))) | |
buf = bytearray(buf_size) | |
# WIZnet new client socket | |
print(f"Create WIZnet client socket") | |
c_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
c_sock.settimeout(CLIENT_TIMEOUT) | |
# WIZnet client sends data | |
addr = (HOST, PORT) | |
size = c_sock.sendto(orig, addr) | |
# print(f"Client sent {orig} {size} bytes") # WIZnet size always = None | |
print(f"Client sent {orig} {buf_size} bytes to {addr}") # fudge for now... | |
# PicoW server receives data | |
size, addr = s_sock.recvfrom_into(buf) | |
print(f"Server received {buf[:size]} {size} bytes from {addr}") | |
# PicoW server sends data back | |
size = s_sock.sendto(buf[:size], addr) | |
print(f"Server sent {buf[:size]} {size} bytes to {addr}") | |
# WIZnet client receives data back | |
size, addr = c_sock.recvfrom_into(buf) | |
print(f"Client received {buf[:size]} {size} bytes from {addr}") | |
# WIZnet client socket close | |
c_sock.close() | |
# grow the buffer only if it's still smaller than the low-level buffers | |
buf_size = 2 * buf_size if (size >= buf_size) else size | |
print(f"Next buffer size {buf_size}") | |
time.sleep(INTERVAL) |
1472 bytes = one packet 1500-byte MTU
• When >1472 bytes are sent to the Pico W UDP socket, the library reports only the first 1472 bytes received
• When >1472 bytes are sent to the WIZnet UDP socket, the library reports 0 bytes received (after a delay of several seconds)
WIZnet W5100S "Support 4 independent SOCKETs simultaneously" and has "Internal 16Kbytes Memory for TX/ RX Buffer"
https://www.wiznet.io/product-item/w5100s/
WIZnet W5500 "Supports 8 independent sockets simultaneously" and has "Internal 32Kbytes Memory for Tx/Rx Buffers"
https://www.wiznet.io/product-item/w5500/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using this hardware:

https://gist.github.com/anecdata/75ab1f977782008d33b5b3c6201e6dc1