How to Send Wheel Encoder Counts with W5500 on Raspberry Pi Pico 2?
This project turns a Raspberry Pi Pico 2 into a networked wheel encoder node.
Summary
This project turns a Raspberry Pi Pico 2 into a networked wheel encoder node. Two IR sensors watch wheel spokes, the firmware determines signed motion counts and debug RPM, and a WIZnet W5500 provides the wired Ethernet path that sends those counts as UDP packets to the motor-control side of the system.
What the Project Does
The repository implements a small measurement-and-reporting pipeline for a vehicle project. Two digital IR sensors are arranged so the firmware can infer direction from edge timing, count forward or reverse spoke events, and package the result into a 4-byte signed integer. That payload is then sent over UDP to a receiver listening on port 10111, where a Python script decodes the first four bytes back into a signed count.
The timing model is simple and explicit in the code. A repeating timer polls both sensors every 1 ms, tracks when sensor B last went high, and on each rising edge of sensor A increments or decrements the shared spoke counter depending on whether B led A within a configured direction window. Every 100 ms, the main loop snapshots the count, clears it, computes RPM for serial debug, and sends the packed count over the network.
Where WIZnet Fits
The WIZnet part here is the W5500, used as the Ethernet interface for the Pico 2 node. In this architecture it does not measure the wheel and it does not decide direction; it gives the encoder firmware a wired UDP endpoint so the node can publish motion data to the rest of the vehicle over Ethernet. The README names a “W5500 WizNet” and a “WizNet Ethernet HAT,” and the firmware uses the Arduino Ethernet and EthernetUDP APIs to bring up the interface and send packets.
That is a practical fit for a control-oriented embedded node. W5500 is a hardwired TCP/IP Ethernet controller with an embedded MAC/PHY, SPI host interface up to 80 MHz, 32 KB internal buffer memory, and 8 hardware sockets. In a project like this, those traits let the Pico stay focused on edge timing and count generation while the Ethernet side is handled by a dedicated network chip rather than a larger software networking burden on the MCU.
Implementation Notes
One part of the firmware is the network bring-up path in wiznet.ino around lines 642–664, where the board selects the W5500 chip-select pin, requests an address over DHCP, and opens the local UDP socket. That matters because it establishes the encoder board as a network participant before any wheel data is sent.
Ethernet.init(csPin);
if (Ethernet.begin(mac) == 0) { ... }
Udp.begin(LOCAL_PORT_NUMBER);wiznet.ino around lines 683–704. The code converts the signed spoke count into a fixed 4-byte big-endian payload and sends it to the remote motor-control IP and port. That matters because it keeps the application protocol extremely small and easy to parse on the receiver side.pack_be_int32(payload, count);
Udp.beginPacket(remoteIP, REMOTE_PORT_NUMBER);
Udp.write(payload, 4);
Udp.endPacket();wiznet_demo.ino, where the W5500 setup block is commented out. That makes the design intent clear: wiznet.ino is the Ethernet-enabled path, while the demo sketch is a local tachometer/debug variant without active network transmission.Practical Tips / Pitfalls
- Resolve the wiring mismatch before building. The README lists sensor B as GP14 / physical pin 10, but
wiznet.inodefinesIR_SENSOR_B_PIN 10, which is GPIO 10, not GP14. - The project depends on DHCP in the main sketch. On an isolated bench network, bring-up will stall if no DHCP server is present, so a static-IP fallback would make deployment easier.
- The UDP payload is only four bytes. That is efficient, but it has no sequence number or timestamp, so packet loss or reordering will be hard to diagnose from receiver logs alone.
- The sampling method is polling-based at 1 ms, not interrupt capture. That is fine for moderate spoke rates, but very high wheel speeds may need tighter timing or validation against missed edges.
- The code uses only one UDP flow even though W5500 supports multiple hardware sockets. That is appropriate here because the application is a single-purpose sensor publisher, but it also means telemetry expansion should be planned deliberately.
FAQ
Q: Why use W5500 here?
A: This node only needs to count wheel motion and publish it reliably over Ethernet. W5500 gives the Pico 2 a dedicated hardwired Ethernet/TCP/IP controller with MAC/PHY and hardware sockets, so the firmware can stay focused on sensor timing and UDP publication instead of carrying a larger software networking burden on the MCU.
Q: How does W5500 connect to the platform?
A: The project uses a WIZnet Ethernet HAT on the Raspberry Pi Pico 2. In the firmware, the important board-specific signal exposed by the sketch is the W5500 chip-select on GP17, while the Ethernet library handles the rest of the SPI/Ethernet interface expected by the HAT.
Q: What role does W5500 play in this project specifically?
A: It is the transport layer between the encoder firmware and the motor-control receiver. The Pico measures motion locally, packs the signed spoke count into four bytes, and the W5500-backed Ethernet stack sends that count over UDP to the remote listener on port 10111.
Q: Can beginners follow this project?
A: Yes, with some embedded basics. The setup is Arduino IDE–based, the required hardware list is short, and the receiver is a small Python script, but you should already be comfortable with Pico board setup, digital sensor wiring, and basic Ethernet networking.
Q: How does this compare with using Wi-Fi instead of W5500 Ethernet?
A: For this design, W5500 keeps the node wired and simple: fixed hardware Ethernet, a very small UDP payload, and no radio association layer in the application path. A Wi-Fi design could work, but it would change the integration assumptions and likely add more software and network-state handling around a sensor node whose main job is deterministic counting and reporting.
