Wiznet makers

Benjamin

Published August 21, 2026 © Apache License 2.0 (Apache-2.0)

153 UCC

11 WCC

18 VAR

0 Contests

0 Followers

2 Following

Original Link

How Does a Wires-First UART Combiner Move Four Serial Streams Over W55RP20 Ethernet?

An open KiCad board merges four serial lines into one Ethernet feed on a W55RP20, driving ioLibrary hardware sockets directly with no lwIP in the build.

COMPONENTS Hardware components

WIZnet - W55RP20-EVB-Pico

x 1

The only active module on the gateway board. gateway.kicad_pcb places footprint Module:WizNet_W55RP20_EVB_Pico with the WizNet_W55RP20_EVB_Pico.step model, and the firmware builds with BOARD_NAME W55R


PROJECT DESCRIPTION

A Home Automation Project That Rules Out Radio First

pcb-wires-first is a set of open KiCad boards published by devbotas, a GitHub account that carries 20 public repositories. Commits are authored as Simonas from a simon@devbot.lt address, 70 of the 71 commits across the hardware and firmware repositories behind this project, the one exception being an edit made through the GitHub web interface.

Most of the account's older repositories are C#, and several of the names point at Lithuania. One is a Homie Modbus to MQTT translator for the Domekt200 recuperator built by Komfovent, three carry the namespace of Light Conversion, whose own site titles itself "Light Conversion | Femtosecond Lasers", and another is described by its author as a "Control hub for my engineering shed (all the heaters, recuperators, solar inverters sit there)".

GitHub sums the repository up in five words, "A wires-first home automation controllers", and the README states the premise before any board appears. "Wireless IoT sucks," it opens, then gives the fix: "Put the analog wires first! So that light switches continue to operate even if smart features decide to stop working."

KiCad 3D render of the wires-first gateway board, a dark green carrier with four white JST connectors down the left edge, a W55RP20-EVB-Pico module mounted on top with its USB-C connector and RJ45 jack, and silkscreen text reading UART combiner v1.0 The gateway board with the W55RP20-EVB-Pico fitted. KiCad 3D viewer export from the repository, not a photograph.

One of the four board types in that repository carries a WIZnet part, and the README introduces it in a line: "This is a simple carrier board for WizNET W55RP20 development module." That is accurate and also modest, because the board and the firmware written for it add up to a four-channel serial to Ethernet combiner with no radio anywhere in the design.

The Silkscreen Still Calls It a UART Combiner

The gateway board joined the repository on 2026-07-27 in a commit titled "Adding gateway project", but the front silkscreen carries an older name. pcb/gateway/gateway.kicad_pcb holds exactly one free text object on the F.SilkS layer, reading UART combiner v1.0 (c) devbotas, and the KiCad project file kept the same older name inside itself: until commit 2141c927 on 2026-08-18, gateway.kicad_pro still recorded its own filename as uart-combiner.kicad_pro and its root sheet as uart-combiner.kicad_sch.

The parts list backs the older name up. The board places 27 footprints on a 47.4 by 77.4 mm outline: one Module:WizNet_W55RP20_EVB_Pico footprint with the matching WizNet_W55RP20_EVB_Pico.step model, four vertical JST PH 1x04 connectors, two JST SH 1x03 connectors marked SWD and DBG UART, seven 0603 LEDs with seven 2.2k resistors, four M3 mounting holes, a ground test point and one solder jumper.

Infographic pairing the gateway board render with a table that maps each silkscreen designator to its net and its firmware task, showing J1 on GPIO4 for receiver1, J3 on GPIO7 for receiver2, J2 on GPIO10 for receiver3, J4 on GPIO13 for receiver4, and LEDs D1 IP GOOD on GPIO2, D2 SERVER GOOD on GPIO3, D7 RUNNING on GPIO28 Nets read out of the KiCad board file, task arguments read out of the firmware. Board render: devbotas/pcb-wires-first.

Each JST PH connector is wired identically: ground on pin 1, two neighbouring GPIOs on pins 2 and 3, and the module's 3V3 rail on pin 4. That symmetry is why the README warns that "It cannot do much by itself - maybe blink some LEDs. Real functionality (and also power) should come from the JST PH headers."

The two smaller JST SH connectors serve the bench rather than the field. J5 carries GPIO0 and GPIO1 for the debug console that app/mppt_combiner.c opens with initialize_uart0_for_debug_output(115200), and J6 carries SWCLK and SWDIO for the picoprobe adapter named in openocd-rp2040-cmsis-dap.cfg.

Four Solar Chargers, Four PIO State Machines

A second repository, fw-victron-mppt-combiner, gives the gateway board its job. Created 2026-08-05 and last pushed 2026-08-11, it describes itself as software that "Combines multiple Victron SmartSolar/BlueSolar MPPTs and mimicks them over ethernet", and names its hardware plainly: "At it's heart there's a Wiznet W55RP20 chip, which integrates Raspberry Pi Pico RP2040 with Wiznet W5500 ethernet module into one package."

The application problem is narrow and physical. A Victron MultiPlus-II GX inverter has one VE.Direct port, already occupied, and the manufacturer's USB hub workaround fails because "once invcerter starts inverting, USB devices disconnect almost immendiatelly". Ethernet is the port that remains, and the README gives the reason in the author's own words: "ehternet is known for being not that susceptable to electromagnetic problems (at least nowhere near as much as USB is)".

VE.Direct is Victron's plain text serial protocol, tab separated key and value lines at 19200 baud with a checksum byte closing each frame. The firmware receives four of those streams at once, and the receiver tasks in app/mppt_combiner.c line up one for one with the connectors on the board.

ConnectorSilkscreenRP2040 pinReceiver taskChannel LEDDevice instance
J1UART1/I2C0GPIO4receiver1D3 on GPIO6260
J3unlabelledGPIO7receiver2D4 on GPIO9261
J2I2C1GPIO10receiver3D5 on GPIO12262
J4unlabelledGPIO13receiver4D6 on GPIO15263

None of the four inputs uses an RP2040 hardware UART. Each receiver claims a PIO state machine running the Raspberry Pi uart_rx program at 19200 baud, and all four are pinned to PIO0. The reason sits in a commit message from 2026-08-10 rather than in any source comment: "Forcing serial monitors to PIO0, just in case, because WizNET SPI uses PIO1."

Generated technical diagram of the five stage data path: four MPPT text streams at 19200 baud on GPIO4, 7, 10 and 13, then a frame checksum that must sum to zero, then a key value to JSON conversion for device instances 260 to 263, then W55RP20 socket 2 running socket, connect, send, recv, disconnect and close, then an HTTP PUT to a monitor script at 172.16.7.1 port 8090 Generated technical diagram traced through run_serial_pio_monitor_task.c, parse_serial_data_task.c, push_to_inverter_task.c and rest_client.c.

Validation happens before any network work. run_serial_pio_monitor_task.c accepts a frame only when the sum of all its bytes is zero, which is how Victron builds the checksum, and a rejected frame resets both buffers and drops the channel LED. That gate earned its place the hard way, judging by a commit on 2026-08-10: "Fell for the rookie trap. MPPT is sometimes injecting binary data into the stream, which overflew parsing buffers."

The two RP2040 cores are split along the same line. The four serial receivers sit on core 1, with a comment in app/mppt_combiner.c explaining why: "These go to a dedicated Core 1, because I'm not sure how big is serial-PIO buffer, if it exists at all." Core 0 keeps the network monitor at priority 8, the parsers at priority 2 and the REST pusher at priority 1.

The Network Path Runs Straight Into Hardware Sockets

Once a frame is parsed, push_to_inverter_task.c builds a 512 byte JSON body carrying product id, firmware version, serial number, battery voltage and current, panel voltage and power, today's yield, load state and uptime, then hands it to rest_put. From that point app/rest_client/rest_client.c talks to the W55RP20 itself rather than to a stack.

/* app/rest_client/rest_client.c */
int8_t opened_socket_number = socket(socket_number, Sn_MR_TCP, 0, 0);
if (opened_socket_number != socket_number) { response_code = REST_NO_SOCKETS; goto error; }

uint8_t connect_result = connect(socket_number, ip, port);
if (connect_result != SOCK_OK) { response_code = REST_NO_CONNECTION_TO_SERVER; goto error; }

uint8_t send_result = send(socket_number, (uint8_t*)request, strlen(request));
/* ... recv() loop until SOCKERR_SOCKCLOSED ... */

disconnect(socket_number);
close(socket_number);

The socket number is not requested from anywhere. network.h reserves socket 0 for DHCP with #define SOCKET_DHCP 0, rest_get() passes socket 1, and rest_post() and rest_put() both pass socket 2, so three of the eight hardware sockets in the W5500 core are budgeted by hand and the rest stay idle.

Generated technical diagram showing socket 0 assigned to DHCP, socket 1 to HTTP GET, socket 2 to HTTP POST and PUT and sockets 3 to 7 unused, beside a build stack listing the author code, ioLibrary_Driver, the W55RP20 TCP/IP core, and lwIP struck out as not present in the repository Generated technical diagram. Socket numbers read from network.h and rest_client.c, link targets from libraries/CMakeLists.txt.

No software TCP/IP stack is present. .gitmodules pulls three submodules, Wiznet/ioLibrary_Driver, raspberrypi/FreeRTOS-Kernel and raspberrypi/pico-sdk, and app/CMakeLists.txt links only ETHERNET_FILES, IOLIBRARY_FILES, DHCP_FILES, DNS_FILES and TIMER_FILES. The single occurrence of the string lwip anywhere in the tree, checked on 2026-08-21, is a leftover comment on line 64 of FreeRTOSConfig.h.

Cable Events, DHCP Restarts and Three Status LEDs

In the combiner firmware, monitor_network_task.c polls wizphy_getphylink() every 100 ms and treats link changes as events. A drop to PHY_LINK_OFF calls DHCP_stop(), clears the address flag and turns off the LED on GPIO2, while a return to PHY_LINK_ON calls initialize_dhcp(), waits a second and resets a retry counter capped at five.

The link transitions are readable on the board itself. The schematic gives D1 the value IP GOOD on GPIO2, D2 the value SERVER GOOD on GPIO3 and D7 the value RUNNING on GPIO28, and the firmware drives exactly those pins from the network task, the REST pusher and a heartbeat blinker, so three LEDs report the lease, the last PUT and the scheduler.

What the W55RP20-EVB-Pico Leaves the Carrier to Use

The root CMakeLists.txt of the combiner firmware names the target board and the chip in its opening statements.

# CMakeLists.txt, top of file, comments and blank lines removed
set(BOARD_NAME W55RP20_EVB_PICO)
set(WIZCHIP_SPI_SCLK_SPEED 43)
add_definitions(-D_WIZCHIP_SPI_SCLK_SPEED=${WIZCHIP_SPI_SCLK_SPEED})
set(WIZNET_CHIP W5500)
add_definitions(-D_WIZCHIP_=W5500)
add_definitions(-DDEVICE_BOARD_NAME=W55RP20_EVB_PICO)

Under that board name, port/ioLibrary_Driver/inc/wizchip_spi.h enables the PIO SPI path and fixes six pins: CS on GPIO20, SCK 21, MISO 22, MOSI 23, INT 24 and RST 25. The system clock is 133 MHz in app/system/system.h, and the 43 MHz SPI request is the number the driver converts into its PIO divider.

Three crops from WIZnet's own W55RP20-EVB-Pico schematic, the first showing the W55RP20 LQFP68 symbol with the Ethernet PHY signals TXP, TXN, RXP and RXN on its left edge, the second showing header J2 breaking out GPIO0 to GPIO15, and the third the title block reading W55RP20-EVB-Pico_V200.SchDoc, Revision 1.0, Date 2024-07-10, Drawn By: Alan, WIZnet Co., Ltd. The repository keeps WIZnet's own module schematic next to the KiCad project. Drawing: WIZnet Co., Ltd., crops arranged for this article.

The reserved pin range also shapes the carrier. pcb/gateway/schematics-w55rp20-evb-pico.png is not the author's drawing: its title block reads W55RP20-EVB-Pico_V200.SchDoc, Revision 1.0, Date 2024-07-10, Drawn By: Alan, WIZnet Co., Ltd., and it is the module reference the board is designed against. In the KiCad symbol taken from that reference, the header positions that would be GP16 through GP22 on a Pico strip are marked NC, so the carrier works entirely within GPIO0 to GPIO15 plus GPIO28, and every one of those pins lands on a connector or an LED.

The Rest of the Wires-First Set

The gateway shares its repository with three board types that explain the project name. A voltage converter takes 12 to 24 V and produces the 3.3 V that arrives on pin 4 of the gateway's connectors, and a switcher drives one 12 or 24 V output rated at 4 A around a Renesas SLG47115, wired so that its ON, OFF and TGL lines can go straight to a physical wall switch.

Four KiCad 3D renders arranged side by side: the gateway carrier with its four JST connectors, the voltage converter with 12-24V silkscreen, the switcher with ON OFF TGL terminals around an SLG47115, and a blank Holey mounting plate covered in a grid of 3.2 mm holes The four board types published in the repository, all KiCad 3D viewer exports, arranged for this article.

The Holey boards are blank mounting plates with 3.2 mm holes on a 5 mm grid, carrying 135, 285 and 589 holes in the three sizes. The README lists them as 160x100, 100x80 and 80x40 mm, although holey-s.kicad_pcb draws the small plate at 80 by 50 mm with a 15 by 9 grid, which is what makes two of them fit one medium plate exactly as the README describes.

What the Repository Does Not Publish

The pcb-wires-first and fw-victron-mppt-combiner repositories are both recent and small, so it is worth being precise about what a reader can rebuild from them as of 2026-08-21.

  • Gerbers exist for the Holey plates only; the gateway ships KiCad sources with no fabrication output and no BOM.
  • No photograph of an assembled board appears in either repository. The four board images are KiCad 3D viewer exports that still carry the exporter's logicalX, logicalY and subGeometryList chunks, and the fifth image in the tree is WIZnet's module schematic.
  • Neither repository has a GitHub release, an open issue or a fork, and both sit at zero stars. The hardware repository carries one git tag, Versions/0.1.0, placed on 2026-05-11 with the message "Doing a draft release."
  • The server address is compiled in as 172.16.7.1 port 8090, and the API token ships as the literal string change-me.
  • The Venus OS monitor script that receives the PUT is described in the README but is not part of either repository.
  • Commit messages are the only sign that hardware was built: "Debugging on a real board" on 2026-07-07, which added the switcher's Renesas configuration file, and "Adding issues after live testing and soldering" on 2026-08-20, which touched pcb/switcher alone. Neither commit touches the gateway.

The licences are unusually clear for a personal project. The hardware repository carries the full CERN Open Hardware Licence Version 2 Strongly Reciprocal text, so derived boards inherit the same terms, while the firmware is Apache-2.0 and credits its origin: "This repo was originally based on WizNET's getting started repo. I removed the examples and replaces with my app."

Related WIZnet Maker Projects

W55RP20 Ethernet Bring-Up for a VSCP NFC Lock starts from the same WIZnet FreeRTOS C example and reaches the point where DHCP and the socket layer come up. That project stops at bring-up before the lock logic exists, while the combiner carries a finished payload and its own PCB, so the pair shows both ends of one starter tree.

WIZnet Success Stories: SNMP-based Environmental Monitoring Converter Using W55RP20 solves the same problem from the product side. FLS ships a converter that speaks SNMP to a monitoring system, while the combiner speaks one hardcoded HTTP PUT to one script, which brackets the same job at the commercial and the one-person ends.

Building a VCP, a virtual serial port, on the W55RP20-EVB-Pico puts a serial line on the network with the same module, written in Japanese. A virtual COM port keeps the byte stream transparent end to end, while the combiner parses VE.Direct frames, verifies the Victron checksum and emits JSON, which is the trade between a generic bridge and a protocol-aware one.

How to Build an Industrial Geiger-Mueller Datalogger with W55RP20-EVB-PICO places the same module at the centre of a fixed wired installation, a radiation monitoring station from Signal Elektronik. One stream instead of four and a vendor instead of an individual, with the same conclusion about where the module fits: unattended equipment that has to keep reporting over a cable.

FAQ

Q. What does this project use the W55RP20 for? The W55RP20 supplies both the RP2040 that runs the firmware and the W5500 TCP/IP core that carries every HTTP request, so one package replaces a separate microcontroller and Ethernet controller on a 47.4 by 77.4 mm board.

Q. Does the firmware use lwIP or any software TCP/IP stack? No. app/CMakeLists.txt links only the ioLibrary Ethernet, DHCP, DNS and timer targets, and rest_client.c calls socket(), connect(), send(), recv() and close() on hardware sockets 1 and 2, with DHCP on socket 0.

Q. Can the gateway board be built from what is published? The KiCad schematic and board files are published under CERN-OHL-S-2.0, so the design can be reproduced, but no gerbers, BOM or assembly photographs are included for the gateway, unlike the Holey mounting plates which do ship gerber archives.

Q. Why are the serial inputs handled by PIO instead of the RP2040 hardware UARTs? Four simultaneous receivers exceed the two hardware UARTs an RP2040 provides, so each channel runs a PIO soft UART at 19200 baud, and the author's commit message states that all four are forced onto PIO0 because the WIZnet SPI driver occupies PIO1.

Q. Can this be reused for something other than solar chargers? The board is protocol-agnostic: four JST PH connectors carrying ground, two GPIOs and 3.3 V each, plus SWD and a debug UART. Replacing the parser and the JSON body leaves the PIO receivers, the checksum gate and the socket code intact.

Documents
  • pcb-wires-first repository

    The hardware project. Four KiCad board types under CERN-OHL-S-2.0, default branch Development, last push 2026-08-20.

  • Gateway KiCad project

    Schematic, board and project files for the W55RP20-EVB-Pico carrier, plus WIZnet's own module reference schematic. Added 2026-07-27.

  • fw-victron-mppt-combiner firmware

    Apache-2.0 firmware that reads four VE.Direct serial streams at 19200 baud and pushes JSON over Ethernet. Created 2026-08-05, last push 2026-08-11.

  • rest_client.c, the hardware socket path

    socket(Sn_MR_TCP), connect, send, recv, disconnect, close on manually assigned socket numbers, with no software TCP/IP stack in the build.

  • WIZnet-PICO-FREERTOS-C (upstream project)

    The WIZnet FreeRTOS example this firmware started from. The author keeps a fork of it at devbotas/WIZnet-PICO-FREERTOS-C, and the firmware README credits the example directly.

  • WIZnet ioLibrary_Driver

    Submodule providing socket.c, wizchip_conf.c, w5500.c, dhcp.c and dns.c, the only network code linked into the build.

  • WIZnet W55RP20 product documentation

    Official page for the RP2040 plus W5500 package used here, including the eight hardware sockets the firmware allocates by hand.

  • WIZnet W55RP20-EVB-Pico

    The development module the carrier board is built around, and the source of the reference schematic kept in pcb/gateway.

Comments Write