Created
August 30, 2025 05:27
-
-
Save anecdata/875e47c041452b28cb4cdbaf9705fba4 to your computer and use it in GitHub Desktop.
CircuitPython Wi-Fi + Ethernet with PoE
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: 2025 anecdata | |
# SPDX-License-Identifier: MIT | |
# Pimoroni Pico Plus 2W | |
# connected via Adafruit Proto Doubler PiCowbell to | |
# WIZnet W5500-EVB-Pico2 with WIZPOE-P1 | |
# https://fosstodon.org/@anecdata/115115735846073971 | |
# code is a simplified version of https://gist.github.com/anecdata/456524f8e38c207931afd0dedf6bec89 | |
import time | |
import os | |
import traceback | |
import board | |
import busio | |
import digitalio | |
import wifi | |
import ssl | |
import adafruit_connection_manager | |
import adafruit_requests | |
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K | |
URLS = ( | |
"http://wifitest.adafruit.com/testwifi/index.html", | |
"https://httpbin.org/get", | |
) | |
# wifi (native) | |
def connect_native(radio): | |
while not radio.connected: | |
try: | |
radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD")) | |
except Exception as ex: | |
traceback.print_exception(ex, ex, ex.__traceback__) | |
time.sleep(1) | |
return radio.ipv4_address | |
# WIZnet | |
wiz_pins = ( | |
( | |
digitalio.DigitalInOut(board.GP17), | |
digitalio.DigitalInOut(board.GP20), | |
), | |
) | |
def connect_eth(radio): | |
return radio.pretty_ip(radio.ip_address) | |
# General | |
def connect(radio): | |
if radio.__class__.__name__ == "Radio": | |
ipv4_str = connect_native(radio) | |
elif radio.__class__.__name__ == "WIZNET5K": | |
ipv4_str = connect_eth(radio) | |
elif radio.__class__.__name__ == "ESP_SPIcontrol": | |
ipv4_str = connect_esp(radio) | |
return ipv4_str | |
time.sleep(3) # wait for serial | |
# LED | |
led = digitalio.DigitalInOut(board.LED) | |
led.switch_to_output(value=False) | |
radios = [] | |
pools = [] | |
ssl_contexts = [] | |
requestss = [] | |
connection_managers = [] | |
# spi = board.SPI() | |
spi = busio.SPI(clock=board.GP18, MOSI=board.GP19, MISO=board.GP16) | |
# wifi (native) | |
print(f'Initializing native wifi...') | |
radios.append(wifi.radio) | |
# WIZnet | |
print(f'Initializing ethernets...') | |
for eth in range(0, len(wiz_pins)): | |
print(f'#{eth}') | |
cs = wiz_pins[eth][0] | |
rst = wiz_pins[eth][1] | |
mac = f'de:ad:be:ef:fe:{(251 + eth):02x}' # avoid DHCP collisions | |
while True: | |
try: | |
radio = WIZNET5K(spi, cs, rst, mac=mac, debug=False) | |
print(f'{mac} {radio.pretty_ip(radio.ip_address)}') | |
radios.append(radio) | |
break | |
except Exception as ex: | |
traceback.print_exception(ex, ex, ex.__traceback__) | |
# set up the socketpools and requests | |
print(f'Set up socketpools and requests...') | |
for radio_num in range(0, len(radios)): | |
pools.append(adafruit_connection_manager.get_radio_socketpool(radios[radio_num])) | |
ssl_contexts.append(adafruit_connection_manager.get_radio_ssl_context(radios[radio_num])) | |
requestss.append(adafruit_requests.Session(pools[radio_num], ssl_contexts[radio_num])) | |
connection_managers.append(adafruit_connection_manager.get_connection_manager(pools[radio_num])) | |
# requests on all the radios | |
while True: | |
print(f'{"="*25}') | |
for radio_num in range(0, len(radios)): | |
print(f'{"-"*25}') | |
for url in URLS: | |
print(f"Fetching from {url} via {radios[radio_num].__class__.__name__} #{radio_num} {pools[radio_num]} {connection_managers[radio_num]}") | |
print(f"{connect(radios[radio_num])}") | |
try: | |
with requestss[radio_num].get(url) as resp: | |
print(f'{resp.status_code} {resp.reason.decode()}') | |
except Exception as ex: | |
traceback.print_exception(ex, ex, ex.__traceback__) | |
led.value = not led.value | |
time.sleep(1) |
dual-code.mov
🔌 USB power on both boards is protected with a Schottky diode upstream of VSYS. PoE power is similarly protected with a Schottky diode upstream of VSYS. I've left the 3V3 pins unconnected between the two boards, to keep the two LDO outputs separate. I've also left the VBUS (5V) pins unconnected between the two boards. If any of the three power sources are connected (PoE, or either USB-C), both boards will be powered via VSYS.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code is running independently on the WIZnet W5500-EVB-Pico2:
Power over Ethernet supplies power to both microcontrollers. One or both USB connections can be made to a host to edit code, view serial output, etc.