Four firmwares, one table each: what they do, how each one handles 17 different corruptions of the network chip, how they recover when the link, the gateway or the receiver fails, how many network-standard requirements they meet, and how they behave day to day. Everything was measured on the same real EPS box with the same pre-registered tools; where a version wasn't tested, the table says so.
På dansk: Alle versioner sammenlignet · Hvorfor v3.3 (kort)
v3.3 is the most robust of the four on every measurement we have, and it is the one we recommend as official. v2.2 needs a power cycle after most network faults; v3.1 recovers from many but dies on four chip faults including the one that matches the field symptom; v3.2 recovers from those but is dead on a PHY held in reset and its receiver check stops testing anything once the gateway has answered once. v3.3 recovers from all 17 faults, really tests its receiver every minute, and records the supply voltage at every chip fault. None of them is field-proven yet, and the leading field trigger (a supply sag) is still to be tested by hand.
Pins, outputs, sequence timing, inputs, the LED, the TCP control protocol and the stored settings are the same in all four; only the network layer differs. v3.1 → v3.2 → v3.3 are small steps on the same rewritten driver.
| Area | v2.2 (field) | v3.1 | v3.2 | v3.3 |
|---|---|---|---|---|
| Network driver | Arduino Ethernet 2.0.2 | own W5500 driver | same | same |
| Connections | 4 sockets shared by everything, one held by the keepalive; idle or half-open connections never closed | 8 sockets, fixed per service; idle web connections closed after 5 s, oldest control connection evicted | same | same |
| Web page output | one TCP segment per byte (~3,600 per view) | buffered, 2–3 segments | same | same |
| DHCP | library: blocks up to 60 s, strands on its fallback | RFC 2131, never blocks, keeps asking | same | same |
| Address conflict detection | none | RFC 5227 | same | same |
| TCP give-up time | 18.4 s (library writes the W5100 register addresses) | 102 s (RFC 1122) | same | same |
| Chip self-check every 5 s | none | version, IP, MAC, mask, gateway | + mode, retry, PHY config bits | + PHY reset bit |
| PHY stops with the link down | never recovered | never recovered | only if a config bit changed | PHY reset after 30 s, backing off to ~32 min |
| Receiver goes deaf (link up, hears nothing) | never detected | gateway probe, only if the gateway answered since the last link-up | same | gateway or last client; survives a link-up; counts only when nothing at all is heard |
| ARP requests to a gateway that is gone | 9 every 30 s | 20 in 4 s, every minute | same | 1 per minute (RFC 1122) |
| Over-long web request | no answer | 400 | 400 | 414 (RFC 9112) |
| Event log (survives power cuts) | none | 96 events | same | + supply voltage at every chip re-init |
| Supply and brown-out readout | none | none | none | VCC, VCC_MIN, BOD in NET_STATUS |
| Syslog | none | RFC 5424, optional | same | same |
| Flash used (of 32,256 B) / RAM globals (of 2,048 B) | 29,876 / 736 | 31,120 / 1,364 | 31,238 / 1,364 | 32,094 / 1,407 |
Why each change was made: why v3.3 · why v3.2 · mechanisms (findings) · full report
Each fault is written into the real box's own W5500 by the firmware (test builds only); the PC sends only ping, a control command and a web request, and watches every service for 120 s. Three trials per fault and firmware, pre-registered criteria. F1–F14 for v2.2/v3.1/v3.2 were run on 2026-10-11; F15–F17 and all of v3.3 on the night of 2026-10-12.
| Fault (one W5500 register) | v2.2 | v3.1 | v3.2 | v3.3 |
|---|---|---|---|---|
| F1 Chip soft reset (all settings lost) | dead 3/3 | ok 2/3, tail 1/3 (6–10 s) | ok 2/3, tail 1/3 (6–10 s) | recovered (4–10 s) 3/3 |
| F2 IP address changed | dead 3/3 | ok 2/3, tail 1/3 (10 s) | recovered (5–10 s) 3/3 | recovered (3–5 s) 3/3 |
| F3 MAC changed | latent 3/3 | ok 2/3, tail 1/3 (5–10 s) | recovered (6–10 s) 3/3 | recovered (4–6 s) 3/3 |
| F4 Gateway changed | tail 2/3, latent 1/3 | recovered (6 s) 3/3 | recovered (3–7 s) 3/3 | recovered (6–7 s) 3/3 |
| F5 Mask changed | dead 3/3 | recovered (4–7 s) 3/3 | ok 1/3, tail 2/3 (5 s) | recovered (3–7 s) 3/3 |
| F6 Ping block (mode register) | dead 3/3 | dead 3/3 | ok 2/3, tail 1/3 (4–7 s) | recovered (3–7 s) 3/3 |
| F7 PHY power-down (field match) | dead 3/3 | dead 3/3 | ok 2/3, tail 1/3 (11–12 s) | recovered (4–6 s) 3/3 |
| F8 PHY forced 10 Mbps half | latent 3/3 | latent 3/3 | recovered (4–10 s) 3/3 | recovered (6–10 s) 3/3 |
| F9 Retry count 0 | dead 3/3 | dead 3/3 | recovered (3–5 s) 3/3 | ok 2/3, tail 1/3 (10 s) |
| F10 Control listeners closed | no effect 3/3 | no effect 3/3 | ok 1/3, tail 2/3 | no effect 3/3 |
| F11 Control listen port changed | dead 3/3 | no effect 3/3 | no effect 3/3 | no effect 3/3 |
| F12 Web listeners closed | ok 2/3, tail 1/3 | no effect 3/3 | ok 2/3, tail 1/3 | ok 2/3, tail 1/3 |
| F13 Web listen port changed | dead 3/3 | ok 2/3, tail 1/3 | no effect 3/3 | ok 2/3, tail 1/3 |
| F14 Control RX buffer 0 | no effect 3/3 | no effect 3/3 | no effect 3/3 | no effect 3/3 |
| F15 PHY held in reset (new) | dead 3/3 | dead 3/3 | dead 3/3 | recovered (3–6 s) 3/3 |
| F17 PHY power-down written once (new) | tail 1/3, latent 2/3 | tail 2/3, latent 1/3 | ok 2/3, tail 1/3 (5–26 s) | ok 2/3, tail 1/3 (6–7 s) |
| F16 F15 with only the link-down recovery (v3.3 build without the bit-7 check) | — | — | — | recovered (40 s) 3/3 |
| Scenario | v2.2 | v3.1 | v3.2 | v3.3 |
|---|---|---|---|---|
| Network chip loses all its settings (chip reset by command) | dead until power cycle (4/4) | recovered 2–7 s, outputs kept (30/30) | recovered (fault matrix F1, 3/3) | recovered 2–8 s (38/40); twice the chip came back deaf for 38 s / ~3.5 min, cleared by itself |
| DHCP server away during a renewal | stranded until power cycle | keeps asking, recovers by itself | as v3.1 | DHCP sequence A–E passed |
| PHY held in reset (link down, new fault F15) | dead 3/3 | dead 3/3 | dead 3/3 | recovered 3–6 s (3/3) |
| PHY stuck with the link down, registers look right (F16) | no recovery (code) | no recovery (code) | no recovery (code) | PHY reset after 30 s: back at 40 s (3/3) |
| Gateway disappears (router reboot), 12 min watched | keepalive uses the cached address: no ARP after it vanished (no recovery logic to trigger) | same as v3.2: 1 ARP while present, none after; the check keeps "succeeding" | no ARP after it vanished: the check keeps "succeeding" on a cached address | 1 ARP request per check; no false PHY reset |
| Receiver goes deaf with the link up | never detected | not detectable once the gateway answered (cached address), nor without a gateway | same as v3.1 | 3 silent checks → PHY reset (emulated: once, at 6 min); two real episodes after re-inits cleared by themselves first (38 s, ~3.5 min) |
| Link down 180 s (cable or switch side) | back when the link returns (switch port flaps, 10-09) | back when the link returns (16/16 link drops, 10-11) | not run | back 8.3–8.6 s after the link returns (2/2); 2 harmless PHY resets per outage |
| Main-loop hang | watchdog restart (outputs off) | watchdog restart ~25 s (3/3) | as v3.1 | watchdog restart 25 s (3/3 outside the outage) |
| Start-up after a USB reset (resets the network chip too) | 200/200 | 200/200 | not run | 50/50, median 9.2 s |
Details: DHCP strand · code analysis and v3.3 · full report §5.20–5.26
Pass criteria written down before any firmware was run; same tool, same box. A standard passes only if all its requirements pass. v3.2 was not run through the suite: its only change from v3.1 is the health check, which nothing in the suite measures, so its column repeats v3.1's.
| Standard | v2.2 | v3.1 | v3.2 | v3.3 |
|---|---|---|---|---|
| IEEE 802.3 Ethernet | pass | pass | pass (as v3.1) | pass |
| IEEE 802 MAC addressing | pass | pass | pass (as v3.1) | pass |
| RFC 826 ARP | pass | pass | pass (as v3.1) | pass |
| IEEE 802.1D/Q end station | pass | pass | pass (as v3.1) | pass |
| RFC 5227 address conflict detection | fail: 6 items | pass | pass (as v3.1) | pass (2 not verifiable without forged traffic) |
| RFC 5424/5426 syslog | not available | pass | pass (as v3.1) | pass |
| RFC 2131/2132 DHCP client | fail: 7 items | fail: 1 item | fail: 1 item (as v3.1) | fail: 1 item (kept: asks from its fallback address) |
| HTTP (RFC 9110/9112) | fail: 7 items | fail: 3 items | fail: 3 items (as v3.1) | fail: 2 items (kept: GET switching, no Host check) |
| TCP (RFC 9293/1122) | fail: 2 items | fail: 1 item | fail: 1 item (as v3.1) | fail: 1 item (kept: 2-s send timeout) |
| RFC 1122 host requirements | fail: 3 items | fail: 3 items | fail: 3 items (as v3.1) | fail: 2 items, both chip limits (ARP rate fixed) |
| Requirements passed, of 56 | 26 | 46 | 46 | 48 |
Per requirement: findings · executive summary
| Test | v2.2 | v3.1 | v3.2 | v3.3 |
|---|---|---|---|---|
| Power and output sequence (21 checks) | reference behaviour | 21/21 | as v3.1 | 21/21 |
| Load test, short (idle connections, then Companion + eXcontrol + browser) | control port dead with 2 idle web connections (1 of 30 answered) | 541/541 | as v3.1 | 541/541 |
| Idle connections held open, up to 5 per port | control port dead from 2 | 800/800 answered | as v3.1 | all answered |
| Persistent controller connections | not supported | 6/6 | as v3.1 | 6/6 |
| Junk and malformed input | — | 16/16 | as v3.1 | 16/16 |
| HTTP methods and malformed requests | every method served as GET | 21/21 | as v3.1 | 21/21, plus 414 |
| DHCP sequence (no server, lease, server gone, address in use) | strands after an outage, restarts at renewals | pass | as v3.1 | pass |
| 10 Mbps half duplex | — | pass (load 543/544) | as v3.1 | pass (load 543/543) |
| millis() rollover at 49.7 days (simulated) | — | pass | as v3.1 | pass |
| Lowest free stack seen | ~0.45 KB (computed) | 243 B | as v3.1 | 190 B |