Martin Wu
Résumé

Embedded and software engineer

I'm a second-year Computer Engineering student at UBC. I write firmware for UBC Solar's race car and build web apps on the side, including Songless, a song-guessing game with over 100,000 visits.

Looking for an internship starting January or May 2027

The RTD breakout being plugged into UBC Solar's Motor Drive Interface board
  • RTD breakoutA PT1000 sensor read by a MAX31865
  • SPI headerWhere my driver talks to the converter
  • STM32Runs the board's firmware: CAN, ADC, faults
UBC Solar's Motor Drive Interface board with the RTD breakout plugged in. The labelled parts run my firmware.
Songless on a phone: difficulty buttons, the clue bar at 0.1 seconds, and a search suggesting Bohemian Rhapsody
  • Five difficulties804 songs to guess
  • Clue stagesFrom 0.01 s up to 15 s
  • SearchTitles, aliases and artists
Songless on a phone, mid-round.

Projects

Songless mid-round: difficulty buttons, the clue bar, a play button and a search box

Songless

Song-guessing game · 100k+ visits

My version of Songless: you hear the first 0.01 seconds of a song and try to name it, and each skip plays a bit more, up to 15 seconds. There are 804 songs across five difficulties. Behind it is a pipeline that pulls each track, checks it's the right version with an audible opening, and uploads the clips to Cloudflare R2.

React, TypeScript, Vite, Cloudflare R2

NutriTracker's daily view: energy against need, macronutrient bars and nutrients that need attention

NutriTracker

Nutrition tracker · in progress

Most nutrition apps stop at calories and macros. This one tracks 59 nutrients against your own daily targets, and you'll log meals by taking a photo. The AI only names the food; every number comes from the USDA's food database, so a bad guess shows up as the wrong food instead of a made-up value. The nutrient reference and the interface are built; accounts and real logging are next.

Next.js, TypeScript, Drizzle, Postgres, Vitest

Us gameplay inside the Molly Tea shop: a barista with an exclamation-mark prompt and the order and pickup counters

Us

Pixel-art story game

A short story game in the style of the Gen 3 Pokémon games, built on Phaser 4. It has 15+ scenes with saving, fast travel and dialogue you can rewind. To test it, I wrote Playwright scripts that play through the routes and check lighting and collisions.

Phaser 4, TypeScript, Playwright

Useful Tool Hub's home page listing its tools

Useful Tool Hub

Browser tools

A dozen small tools in one site: file conversion, OCR, transcription, PDF signing. Almost everything runs in your browser, so your files stay on your device; only the downloaders use a small Python backend. Jest runs in CI.

JavaScript, Python, Jest, Vercel

Math Quiz's new-quiz screen: four game modes, presets, difficulty and question sliders

Math Quiz

Quiz app

A math quiz with four modes, including a daily challenge that gives everyone the same questions. It tracks XP, levels and 18 achievements.

React, styled-components

Haar wavelet compressor

Desktop app

Image compression with the Haar wavelet transform, written as matrix operations in NumPy. A small desktop app lets you change the threshold and depth and compare the result with the original.

Python, NumPy, CustomTkinter

Motor temperature over CAN

I proposed adding motor temperature sensing to UBC Solar's car with a PT1000 RTD, then wrote the firmware for it, from a breadboard prototype to the driver on the Motor Drive Interface board.

  1. PT1000 RTDPlatinum sensor on the motor
  2. MAX31865Turns resistance into a reading
  3. STM32 on the MDIMy driver and fault debounce
  4. 0x502, once a secondSuccess, °C, fault flags
  5. GrafanaThe pit crew's dashboard

The tricky part was failures that look like data. If the MAX31865 is missing, SPI reads still succeed and return about −259 °C, which looks like a real temperature, so the driver checks the chip's config register before every conversion. A fault also has to persist for five reads before the flag is set, so one noisy reading doesn't raise an alarm.

Try unplugging the sensor in the table. It follows the same rules as the firmware. The last photo below is a real capture from the board with the sensor pulled.

CAN-IDLengthDataMeans
0x500400 00 00 00up 0 s
0x501100no flags
0x502601 18 00 00 00 00read ok, 24 °C
Reading. Fault count 0 of 5
A MAX31865 breakout on a breadboard wired to an RTD probe, next to a laptop
The first prototype on a breadboard
The Motor Drive Interface board with the RTD breakout fitted and a green LED lit
On the Motor Drive Interface, Rev 2.0
The heat-gun test bench: a heat gun on the probe, a thermocouple meter and a laptop
Heat-gun test on the bench
Thermal camera, same test
The Motor Drive Interface board with a PCAN-USB adapter and a J-Link attached
PCAN-USB and a J-Link on the board
PCAN-View showing three frames: D5 00 00 00, 08, and 00 00 00 00 00 80
The real capture: fault bit 08 set

Experience

Sep 2025 – now · Vancouver

Embedded Systems Developer

UBC Solar

  • Brought up the Motor Drive Interface firmware on STM32: pin setup, a CAN driver with a hardware filter for motor commands, and ADC readings of board voltage and temperature.
  • Made motor commands expire after 100 ms of CAN silence, so a stale command can't keep driving the motor; confirmed it on the car by cutting the command stream.
  • Proposed and built PT1000 motor-temperature sensing, then the external-lights tasks and the steering-wheel speed display.

C, STM32 HAL, FreeRTOS, CAN, SPI, Grafana

Oct 2025 – now · Vancouver

Co-founder, Software Engineer

A stealth AI infrastructure startup

  • Wrote a Go test harness whose in-memory adapters drive reads, idempotent replays, identity denials and adapter panics through the team's 11-step dispatcher without Docker.
  • Rebuilt the live product demo, where AI agents query Postgres through access policies, human approvals and an audit trail.
  • Ran the technical review for the first enterprise deal.

Go, Postgres, Docker

Education

BASc Computer Engineering, University of British Columbia, expected May 2029. Average A-.

Computer Systems (SystemVerilog, FPGA, RISC-V), Software Construction (Java).

Awards

  • CSMC Top 0.5% in Canada, 71st
  • AIME Qualified twice
  • Euclid Top 2%, 85 of 100

Skills

Martin and teammates in the UBC Solar bay on a motor installation night, seen through the car's canopy
Motor installation night in the UBC Solar bay. I'm the one in the grey beanie.

Web and apps

TypeScript, JavaScript, React, Next.js, Vite, Tailwind, styled-components, Phaser, Drizzle, Postgres, Playwright, Jest, Vitest, Cloudflare R2, Vercel

Systems and backend

Go, Python, NumPy, Java, SystemVerilog, Docker, Linux, Git

Embedded and bench

C, STM32 HAL, FreeRTOS, CAN, SPI, ADC, CMake, oscilloscope, PCAN, J-Link, ST-Link, Grafana

Hiring an intern for 2027?

I'm looking for a software or embedded internship starting January or May 2027, for 4, 8 or 12 months. I'd like to work in the US and I'm happy to relocate. Email is the fastest way to reach me.

martinwu500@gmail.com