Wiznet makers

TheoIm

Published August 28, 2026 ©

123 UCC

30 WCC

7 VAR

0 Contests

0 Followers

0 Following

Original Link

protective-stop

protective-stop

COMPONENTS Hardware components

WIZnet - W5500

x 1


PROJECT DESCRIPTION

📌 A Protective-Stop Remote That Treats Silence as STOP

Polymath Robotics' protective-stop repository documents an open-hardware remote for robots and automation. A PoE- or USB-powered ESP32-S3 monitors a physical stop switch and reports its state to machine-side pstop logic. Its preferred wired network path uses the WIZnet W5500 on a Waveshare ESP32-S3-ETH carrier board.

The finished unit uses an NKK FF0126BBCAEA01 twist-release button. In the PoE configuration, the Ethernet connection can carry both network traffic and power.

 

  The remote continuously reports its state while its sensing channels and communication path remain valid. According to the README, pressing the switch sends STOP, while a wiring fault, a stalled task, or loss of all network paths prevents normal transmission. In those documented cases, the machine-side silence timeout requests STOP.

Protective Stop, Not Emergency Stop

The README states: "This is a protective stop, not an emergency stop." It also explains that the project does not replace any required emergency-stop function, including hardwired power removal where applicable.

This project implements the protective-stop function and explicitly leaves any required emergency-stop function outside its scope.

Two Cores, Two Loops, One memcmp

The README describes a switch with two normally closed contacts. Each contact is wired to a separate GPIO loop and read by one ESP32-S3 CPU core. Each core independently builds a complete pstop message, and transmission proceeds only when the two encoded messages match.

 Generated technical diagram of the lockstep path in firmware/main/main.c and estop_verdict.c.

 

Every 100 ms tick, each core drives its output pin high, reads the echo, drives it low, and reads again. A healthy loop conducts as driven, returning 1 on the high phase and 0 on the low phase, so sampling both phases catches a pin stuck high as surely as a wire that has fallen off.

The unusual part is what the cores do with that reading. Core 0 picks the codeword by arithmetic, indexing a two-entry table with ((rb_hi ^ 1) | rb_lo) & 1. Core 1 reaches the same result with a plain boolean, (rb_hi == 1) && (rb_lo == 0). The comment in estop_verdict.c explains that the two expressions are logically equivalent when correct but intentionally implemented differently. This diversity is intended to reduce the chance that one implementation error affects both channels identically; it does not eliminate common-cause risks from the shared toolchain, processor, or
 surrounding code.

Each core builds its own 48-byte pstop message, as defined by PSTOP_MESSAGE_SIZE in pstop_c/pstop/include/pstop/config.h. A comparator task checks all 48 bytes, including the CRC-16 field, and transmits only when the two encoded messages match byte for byte. The project documents this architecture as 2oo2 to run and 1oo2D to stop.  The arrangement is designed to turn the following six documented situations into a STOP request at the machine:

  • The operator presses the button, both poles open, both cores agree on STOP, and a STOP message goes out.
  • One loop wire breaks, the cores disagree, and the comparator sends nothing.
  • A core task stalls past its 80 ms publish deadline, and the tick counts as a mismatch.
  • A sense pin loses its pull-down, and a pad-configuration read-back running about once a second latches a sticky fault.
  • The cores stop advancing their liveness signals relative to each other for 500 ms, and a cross-check latches a fault.
  • For a Tailscale-configured peer, loss of the VPN causes the tunnel-bound transmission to fail instead of falling back to plaintext.

Inside the Side Pod: The W5500 Carrier and Four Loop Wires

The bill of materials in hardware/README.md names the board without hedging: "Waveshare ESP32-S3-ETH | The W5500 Ethernet carrier board this design is built around. For PoE-powered units order the ESP32-S3-POE-ETH variant on the same page; it includes the PoE Module (B) that mounts on the board." Waveshare's product page describes the same part as an "Onboard W5500 Ethernet chip for extending 10/100Mbps network port through SPI interface".

 Assembly step 3. The white and yellow pairs form the two stop-switch sensing loops, and the RJ45 faces out of the pod. Photo: Polymath Robotics, CC-BY-4.0.

 

Seven connections leave the board, fixed in firmware rather than in configuration.

Board pinGoes toWire color
VBUSLED ring 5Vred
GNDLED ring GNDblack
IO17LED ring data ingreen
IO39Button terminal 11, pole Awhite
IO40Button terminal 12, pole Awhite
IO41Button terminal 21, pole Byellow
IO42Button terminal 22, pole Byellow

The internal pull-downs allow an open sensing loop, including a broken wire, to be detected as a STOP condition. In the words of hardware/README.md, "the firmware drives one GPIO and reads the echo on another, once per pole, so a broken wire reads the same as a pressed button (STOP)."

⚙️ Why Ethernet Ranks First in the Firmware

The W5500 sits on SPI2 at 20 MHz, with MOSI on GPIO11, MISO on GPIO12, SCLK on GPIO13, chip select on GPIO14, interrupt on GPIO10 and reset on GPIO9. The firmware enables it with CONFIG_ETH_SPI_ETHERNET_W5500=y in firmware/sdkconfig.defaults and brings it up in dcs_eth.c before any other interface.

 Generated technical diagram of the route priorities set in dcs_eth.c, ml_dev_tether.c and dcs_net_supervisor.c.

  • Fault Detection
    • Check whether the W5500 registers respond correctly over SPI.
    • Verify that actual network responses are being received.
  • Software Recovery
    • Restart the Ethernet driver.
    • If the problem remains, reinitialize the W5500 and rebuild the network interface.
  • Hardware Recovery
    • As a final step, toggle the W5500 RESET pin to force a hardware reset.

The route preference is explicit: Ethernet uses route_prio 128, USB-CDC-NCM uses 110, and Wi-Fi STA uses 100. A supervisor selects the highest-priority interface with a usable IP address and allows Ethernet to reclaim the default route when it returns. Lower-priority interfaces are brought up as needed; all three are not necessarily active at the
 same time.

One Cable for Power and the Safety Link

The reference assembly installs the Waveshare PoE Module (B), allowing a PoE-configured unit to use one Ethernet cable for power and networking. The repository also supports USB-powered operation, so PoE is not required for every configuration.

 Assembly step 4. The PoE Module (B) mounts on top of the carrier board, after which the RJ45 carries both power and the safety link. Photo: Polymath Robotics, CC-BY-4.0.

 

Assembling one unit takes about 15 minutes, and the enclosure prints as a two-unit plate in roughly 4.5 hours using 144 g of filament. The FreeCAD source is included, so the mechanical design is reproducible rather than merely visible.

When the W5500 Itself Wedges

The most transferable engineering in the repository, for anyone else building on this chip, is a watchdog that assumes the Ethernet controller can fail quietly. The comment in dcs_eth.c names the failure it was written for: "the W5500 can black-hole with NO ETHERNET_EVENT_DISCONNECTED and the netif still reporting UP with a valid lease", which leaves the route supervisor pinning a dead path.

 Generated technical diagram of the detection and recovery logic in firmware/components/dcs_support/src/dcs_eth.c.

 

Detection uses two signals, both polled at 1 Hz and both required to persist three consecutive ticks. One is a read-only PHY register read of PHYCFGR at 0x002E, which forces a real SPI transaction and so surfaces a wedged bus as a failed ioctl. The other is a black-hole test: link up and lease valid, yet no peer has replied for 8 seconds and the uplink gateway is silent too. That cross-check separates a local W5500 problem from a peer that is simply unreachable.

Recovery then climbs three rungs, each given 8 seconds to restore the link. The first stops and starts the driver. The second rebuilds driver and netif, re-running the W5500 software reset and the VERSIONR check. The third asserts a hardware reset on GPIO9 for 1 ms against the datasheet minimum of 500 us, then waits 5 ms for the PLL against a 1 ms maximum, citing W5500 datasheet v1.1.0 section 5.5.1 in the source comment. During the documented recovery sequence, the communication path remains silent and the machine-side logic is intended to remain in STOP. Ethernet recovery restores network availability rather than authorizing motion.

What the Project Publishes and What It Does Not

The integrity target is SIL 3 under IEC 61508 with an equivalent PL e track under ISO 13849, and the README describes both as targets the project is pursuing rather than ratings it holds. The safety case under docs/safety/ includes a system definition, a HARA, an FMEA and FMEDA, a traceability matrix, and an open-items file tracking the gaps toward a quantified claim. A MISRA C:2012 review dated 2026-07-21, run with the free cppcheck misra addon, cut findings in firmware/components/dcs_support from 513 to 273 and in main.c from 30 to 16, with the residue recorded as a deviation register.

The project records a 6 hour 11 minute fleet soak on August 3, 2026, with zero reboots, zero lockstep mismatches and zero spurious stops across 2,864 collected samples. These are project-authored engineering test results rather than functional-safety certification evidence. Separately, the Protective Stop v1.2 hardware design received OSHWA open- source hardware certification as US002846 on August 27, 2026. OSHWA certification covers the openness and
 documentation of the hardware design; it is not functional-safety certification. The repository provides source code and build instructions rather than a ready-to-flash firmware binary. Its hardware uses an off-the-shelf Waveshare carrier, switch, and LED ring instead of a custom PCB. Some managed check-in and OTA workflows depend on external infrastructure that is not included, while deprecated ROS 2 packages under archive/ are retained for reference only.

Related WIZnet Maker Projects

Crane Emergency Stop is the closest neighbour on this site, an ESP32-S3 with a W5500 module built to stop a bridge crane remotely. The problem is the same, a person outside a heavy machine who needs it to halt, but the direction of trust is opposite: that design sends an explicit emergency_stop command into a CANopen gateway, while the Polymath remote treats the absence of a message as the stop. Read together they contrast command-driven with liveness-driven safety.

OneTouch: W5100S-Based Ethernet Motor Control and Robotics Messaging Stack shares the robotics context and the watchdog instinct, linking Jetson control to ODrive motors through a W5100S bridge. It places the wired link inside the robot rather than between robot and operator, so the two cover opposite halves of a wired control path.

ESP32-S3-ETH OPC UA Gateway runs on the same Waveshare carrier board but in Rust, serving industrial data instead of a safety signal. It shows how differently the same W5500 SPI path can be used when the application changes from industrial data service to fail-silent protective-stop communication.

Smart Home Energy Management Controller with the Waveshare ESP32-S3-POE-ETH uses the PoE variant of the same board through ESPHome, and answers the same one-cable powering question in a building rather than on a machine.

❓ FAQ

Q. What does this project use the W5500 for? The W5500 is the wired Ethernet controller on the Waveshare ESP32-S3-ETH board and is driven over SPI2 at 20 MHz through the ESP-IDF esp_eth driver. It carries pstop UDP traffic over the wired network at the highest interface priority. Direct LAN peers can bypass Tailscale, while Tailscale peers use WireGuard and may fall back to a DERP relay.

Q. Is this an emergency stop? No. The README explicitly identifies it as a protective stop and states that it does not replace any required emergency-stop function, including hardwired power removal where applicable.

Q. What happens if one of the two stop-switch loop wires breaks? The core owning the broken loop reads it as open and produces a STOP codeword while the other core still produces OK, so the encodings differ and the comparator transmits nothing. The machine stops on heartbeat silence, about 2.0 seconds with the repository's default configuration of a 400 ms heartbeat and five missed windows.

Q. Do I need the PoE version of the board? The bill of materials tells builders to order the ESP32-S3-POE-ETH variant for PoE-powered units, and the assembly guide says every unit gets the PoE Module (B). A unit can also run on USB power, in which case the RJ45 carries the network only.

Q. Is this certified to SIL 3? No. SIL 3 under IEC 61508 and PL e under ISO 13849 are engineering targets, not current functional-safety certifications. The published safety case and remaining evidence gaps are available under docs/safety/. The hardware design has OSHWA open-source hardware certification, but that certification does not establish functional-safety compliance.

Documents
Comments Write