We are Formula Gades, the Formula Student team of the University of Cádiz, in the south of Spain. Every season we design and build a single-seater and take it racing against other university teams. I am on the electronics side, and I joined the team in April 2025.
This post is about the telemetry unit we ran this year. It is the first working telemetry in the eight-year history of our team, and it is also the first PCB I have designed, soldered and debugged from start to finish, which is the only reason I feel like writing about it.
The project
Until this season our team drove blind. Whatever the engine was doing stayed inside the car until it rolled back into the pits and somebody plugged in a laptop. If something went wrong out on track, the best we had was the driver’s description of it.
The goal was simple to state and less simple to build: get the ECU data off the car and onto a screen at the pit wall while the car is still moving, and never lose a session even if the radio link drops.
Electronics and design
The board is a central telemetry unit built around an ESP32-WROOM-32UE. It reads our ECU, a Link G4X, over CAN at 500 kbit/s, writes everything to a microSD card, and streams the same data over WiFi to a TP-Link CPE210 access point at the pit wall.
Splitting it across three paths was deliberate. CAN does the acquisition because it is deterministic and it does not particularly care about the electrical noise inside a race car. The SD card means we never lose a session if the radio link drops, which it does. WiFi exists for one reason only: so we can see the car while it is still out there.
Some of the choices behind it:
Switchable 120 Ω CAN termination. A DIP switch instead of a fixed resistor. Our bus topology changes depending on which nodes are fitted for a given test, and I did not want to be reworking a board in the paddock at seven in the morning. Quick sanity check before every session: with two terminated nodes on the bus you should measure 60 Ω between CANH and CANL. If you read 120, one of your terminations is not where you think it is.
A GND pin on the CAN connectors. This one is small and it saved me an enormous amount of time. It lets me power the board from the UART header on the bench while it receives real CAN traffic from another node, with a common ground between them. I can develop and test the whole acquisition path sitting at a desk, without dragging the car’s battery into the room. If you are designing anything that talks on a differential bus, give yourself a ground reference on that connector.
Wide input converter, 6 to 36 V. Battery voltage on a car is not 12 V. It sags while cranking and comes back with transients, and I wanted the board to shrug at both. In front of it there is an input fuse, reverse polarity and transient protection, an LC filter and bulk capacitance before the switcher.
External antenna connector. The UE variant of the module exists for exactly this situation. A chassis is a metal box, and a PCB antenna inside a metal box is decoration.
Boot and reset buttons plus a UART header on the board. I added them thinking they would be a convenience. They turned out to be the only way I could flash the thing for weeks (see below).
Four things that went wrong
A damaged via in the power stage. I tore it while desoldering the buck converter, so the input rail was simply not connected any more. I found it with a multimeter, one point at a time, working backwards from the load until the continuity stopped making sense. Our electronics section chief repaired it with a flying wire.
A CAN transceiver soldered 180° out. Instead of the ~2.5 V recessive level I expected on CANH and CANL, I measured 0 V. Entirely my fault, and completely obvious afterwards, which is the most irritating category of mistake.
A reset capacitor larger than the manufacturer recommends. This is my favourite mistake of the whole project. I put a bigger cap on the EN line than Espressif specifies, reasoning that a cleaner reset could only help. It does not: the EN pin now discharges too slowly, the automatic bootloader entry via DTR/RTS stops working, and every flash needs the manual sequence of holding BOOT, pressing and releasing RESET, then releasing BOOT. The board works perfectly. It is just slightly worse to live with, every single time, because I second-guessed a number in a datasheet.
A network that simply refused to come up. I lost an evening to that one before it occurred to me that nothing on an isolated link is handing out IP addresses. The CPE210 in access point mode with no router behind it has no DHCP server. No lease, no connection. Everything runs on static IPs now.
What the pit wall sees
The interface refreshes at 20 Hz: engine speed, gear, throttle position, coolant and oil temperature, oil and fuel pressure, lambda, MAP and battery voltage, with the last ten seconds of history and configurable alarm thresholds per channel. The session in the screenshot: 2,840 packets received, 2 with errors.
I have looked at that error counter far more often than is reasonable.
Range
We measured a stable link at around 400 metres with the car at full throttle, which is more than enough to cover our pit area and a long stretch of track. Worth saying that this figure is conservative: during that test the CPE210 was mounted on the far side of the pit box pointing upwards, not at the circuit. The CPE210 is directional, with a 9 dBi antenna, so most of its gain was going into the sky and we still got 400 m out of it.
The car ran with all of this at Formula Student Spain, and it is at Alpe Adria this week.
Tips, tricks & offers
Things I would tell myself twelve months ago, in case they are useful to somebody else:
- Do not “improve” the reset capacitor on an ESP32. Use the value the manufacturer gives you. A larger cap on EN slows the discharge and breaks automatic bootloader entry, and you will pay for it on every single flash for the rest of the project’s life.
- Check pin 1 against the datasheet, not against what the footprint looks like. My CAN transceiver went on rotated because I trusted the silkscreen in my head instead of the drawing on the page.
- Put a ground pin on your bus connectors. Being able to power the board from UART while it receives real CAN frames from another node turns bench debugging from an ordeal into an afternoon.
- Put the termination on a switch, and measure 60 Ω across the pair before you trust the bus.
- On an isolated network, nothing assigns addresses. Obvious once you say it out loud. Static IPs from the start.
- Two CPE210 settings that cost me a whole afternoon: MAXtream has to be disabled, because it blocks non-Pharos clients from associating, and the encryption has to be set explicitly to WPA2-PSK with AES. Leaving it on “Auto” gave me association failures with no useful error anywhere.
- The SD card is slower than you want it to be. Ours needed SPI clocked down to 1 MHz to be reliable. We flush to the card once a second, which is the right trade for us: our engine keeps running for a few seconds after a session ends, so there is always margin to get the last block written before power disappears.
- Debug backwards from the load. Continuity checks point by point found a torn via that no amount of staring at the layout would have.
Happy to help if anyone is doing something similar: getting custom CAN streams out of a Link G4X, reading them on an ESP32, setting up a CPE210 as a trackside link, or the general shape of a pit-wall dashboard fed over WiFi. Ask in the comments and I will answer as best I can.
Where I could use help
We are now adding strain gauges and load cells to instrument the suspension, so that we can check our simulations against what the car actually does. That is where I am currently out of my depth, and where this community probably knows things I do not:
- Strain gauge conditioning on a vibrating, electrically noisy chassis. Recommendations for amplifiers or integrated conditioners, and how you handle temperature drift and calibration on a car rather than on a bench.
- Radio coverage for a full lap. 400 m gets us the pit straight. Covering a whole circuit is a different problem, and I am not sure whether the answer is a better-aimed directional link, several access points, or leaving WiFi behind entirely for the non-critical channels. If you have taken a link like this further, I would like to hear how.
- Surviving vibration. Conformal coating, connector choice and mounting strategy for a board that lives on a car with a combustion engine a few centimetres away.
Thanks to Aisler for manufacturing this one. Seeing your first design come back as real hardware, and then watching it bolted into a car and sending numbers, is a strange and very good feeling.
And thanks to my team. The PCB is a small part of something a lot of people built.


