Skip to content

Instantly share code, notes, and snippets.

@anecdata
Last active October 2, 2023 02:53
Show Gist options
  • Save anecdata/7eb1cb2b6cece8c5b45c178e88cdfeac to your computer and use it in GitHub Desktop.
Save anecdata/7eb1cb2b6cece8c5b45c178e88cdfeac to your computer and use it in GitHub Desktop.
PicoW + WIZnet UDP Ouroboros
# 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)
@anecdata
Copy link
Author

anecdata commented Jan 14, 2023

@anecdata
Copy link
Author

anecdata commented Jan 14, 2023

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