A place to drop the work coming off my bench: the Mustang firmware for the T41-EP software-defined transceiver, photos of the build, and the chassis system that holds it all together.
Mustang 2 overview
Mustang 2 V1.0.25 on the Pi Touch Display · 4 min 33 s · A look at the Raspberry Pi 5 secondary CPU running the radio’s screen: tuned to the FT8 calling frequency on 20 m with the live spectrum, waterfall, audio spectrum and Settings pane, and the toolbar and cascading Menu driven with a mouse. More on the Secondary CPU and Remote Access pages.
Mustang V1.0.39 · Mustang 2 V1.0.50 · Web Remote V1.0.87 · Mobile Remote V1.0.66 · as of 17 Oct 2026
Mustang Manual
The complete operating manual for the Mustang 2 station: the T41 radio itself, the Raspberry Pi 5 that drives its Touch Display, and the web and phone remotes that reach it over the home network. One chapter per piece – what it is, how to operate it, and every control it has.
Mustang Manual
Introduction
The Mustang 2 station is four pieces working together, and this manual has one chapter for each:
The T41 (Chapter 1) is the radio itself – a T41-EP SDR transceiver running the Mustang firmware. Every control that actually operates the radio lives here first: the tuning knobs, the Volume/Filter encoders, the front-panel buttons, and the Menu system that holds every setting the radio has, organized into 9 primary categories. Nothing downstream of the T41 can do anything the T41 itself can’t – the Pi and both remotes only ever send it the same button presses and knob turns the front panel would.
The Pi 5 (Chapter 2) is a Raspberry Pi 5 added alongside the Teensy 4.1 main board, driving a 7″ Raspberry Pi Touch Display 2 that mirrors the T41’s own screen and adds a mouse-driven toolbar in place of the Menu button. It talks to the Teensy over a serial link (PiLink), reading telemetry down and sending button presses and knob turns up – it is an add-on, not a dependency, and the radio works exactly the same with the Pi unplugged.
The Web Remote (Chapter 3) is a page the Pi serves to any browser on the home network, mirroring the same screen and sending the same commands as the Pi’s own toolbar, plus live receive audio, a virtual rotary dial for tuning/filter/volume, and keyboard control.
The Mobile Remote (Chapter 4), “Mustang Mobile,” is the phone-sized version of the same page, at /mobile: a denser toolbar grid, native phone pickers in place of dropdowns, and touch sliders standing in for the mouse wheel.
All four see and change the same radio at the same time, with no lock between them – a Menu pick from a phone shows up instantly on the T41’s own screen, the Pi, and every other open browser.
Chapter 1 · The T41
Overview
The T41 is a T41-EP SDR transceiver, built around a Teensy 4.1 doing all of the real-time audio, DSP and RF work. Every operating control – tuning, filtering, volume, mode, band, calibration, every Menu setting – lives on the Teensy and is reachable from its own front panel without anything else connected. The Pi 5 and the web/phone remotes (Chapters 2–4) are all just additional ways of sending the T41 the same button presses and knob turns its front panel sends; none of them add a capability the radio doesn’t already have on its own.
Front panel controls
Four encoder knobs do the moment-to-moment work of operating the radio:
Center Tune – the main VFO knob. Turning it moves the tuned frequency by the current Course Tune increment; pressing it steps through the available increments.
Fine Tune – a second tuning knob for small adjustments, at its own, smaller increment; pressing it steps through the fine-tune increments the same way.
Volume – turns whichever of Audio Volume, AGC threshold, Mic Gain or Sidetone Volume is currently selected (the Settings pane’s “Vol:” label shows which); pressing the Volume button (VOLUME_BUTTON) cycles to the next one of the four.
Filter – turns whichever edge of the receive filter is currently selected, Lo Cut or Hi Cut; pressing the Filter button (FILTER_BUTTON) toggles which edge that is. The same knob also drives a Menu setting’s value once a “Label: value” box is open, and (on the Audio Equalizer screen) a band’s level.
A row of dedicated buttons covers everything else: Band (up/down through the ham bands), Mode, Demod, Noise Reduction (cycles Off/Kim/Spectral/LMS), Zoom (spectrum/waterfall zoom, 1×–16×), Decode (CW decoder on/off), Select (confirms a Menu value or enters a highlighted item), Home and Spare (toggles between the primary 11-pane home layout and a secondary 5-pane one), plus the Menu button itself. PTT and the KEY jack (straight key or paddle, see CW Options) key the transmitter. In all, there are 22 front-panel buttons and the 4 encoders above; Menu > Front Panel Test (or the Diagnostics menu) lights up each button as it’s pressed and shows each encoder’s running turn count and direction – a quick way to check a front panel after reassembly without test equipment.
The Menu system
Press Menu to open it: the Filter knob’s left/right selects one of 9 primary categories, up/down selects an option within it, and the Volume/Filter knob (whichever the screen calls for) adjusts a selected “variable” option – one with a numeric or on/off value, shown in a red “Label: value” box with Select to confirm. A “function” option runs immediately when selected, with no value to adjust.
Mustang 2 uses the exact same menus, with a few additions, and the same Menu can also be opened from the Pi Touch Display and the web and phone remotes – see Chapter 2. Tags used below:
Mustang 2 only in the Mustang 2 firmware.
Pi & remotes only added by the Pi; only in the Pi Touch Display and web/phone remote menus, not on the radio itself.
Greyed out on Pi & remotes shown but not selectable from the Pi or the remotes for now, because that screen hasn’t been built for them yet. It still works normally from the radio’s front panel.
Also on Pi & remotes a screen that also opens on the Pi and the remotes.
Own dropdown on the Pi and the remotes this whole menu has its own toolbar button instead of sitting under Menu — see the Pi 5’s toolbar.
Receive gain applied in the DSP, for all bands. Range −5.0 to +20.0 dB in 0.5 dB steps; shown on the Settings pane as “DSP Gain:”. Raise it if weak signals barely rise above the noise on the spectrum.
Adjust Equalizers Also on Pi & remotes(back to tree)
Opens the receive and transmit audio equalizer screen: 14 bands from about 200 Hz to 4 kHz, levels 0–100. On the radio, button 15 switches RX/TX, the Volume knob picks the band, the Filter knob sets its level, button 16 changes the step (1 or 10) and Home saves and exits.
Mustang 2 From V1.0.26 the same screen opens full-screen on the Pi and the remotes, with Edit RX / Edit TX, Cell ◀ ▶, Level − / +, Incr, Exit and Save & Exit; tap a bar to pick it. From V1.0.27, Exit (button 14 on the radio) puts both equalizers back the way they were and leaves without saving.
Averages each point on the spectrum trace with this many neighboring bins on either side, smoothing the curve at the cost of frequency detail. 0 = off (raw trace); up to 10 (a 21-bin average).
Eases the live green trace's frame-to-frame movement instead of snapping instantly to every new reading, for a steadier-looking trace. 0 s = off (original instant-snap behavior); range 0–0.3 s.
Draws the radio’s spectrum trace filled in, graded green to yellow to red by signal strength. From V1.0.29 the radio always powers up with the fill off; pick this to turn it on until the next power-off.
Draws the spectrum as an outline only. On a very strong or wide signal the filled trace can take long enough to draw that the audio drops out; turn the fill off if audio ever gets choppy. This is the power-up default from V1.0.29.
Style of the frequency readout on the Pi and the remotes: Original, Nixie (glowing orange wire digits in glass tubes, with a tube for each decimal point), VFD (green seven-segment) or Dot Matrix (blue 5×7 dots). Doesn’t change the radio’s own screen.
On / Off (under PI Spectrum): turns the spectrum fill on or off on the Pi’s screen and the web and phone remotes together, separately from the radio’s own Spectrum fill setting above. Always starts Off when the Pi app starts.
2D / 3D (under PI Spectrum). 3D shows the newest spectrum row in front, with older rows stepping back — narrower and higher — and fading away, blue at the base up to yellow, orange and red on strong signals. With firmware V1.0.32 or later the 2D waterfall uses the radio’s own colour for every point, so the background noise is the same blue as on the T41.
PI Waterfall Speed Pi & remotes only(back to tree)
Fast / Medium / Slow / Very slow (under PI Spectrum): about 15, 7, 4 or 2 new waterfall rows a second, for both 2D and 3D. Short signals are never skipped at the slower speeds, and the spectrum trace above stays real-time.
Calibrates the S-meter/dBm reading, per band, against a known reference signal. Range −20 to +50. On the Pi and remotes it opens the usual value box (wheel or arrow keys, Select to confirm) with the S-meter still in view.
Starts the reference-frequency calibration routine: tune to a reference station (WWV, CHU) first, set the modulation to SAM, then adjust the Factor until the Error reads under 1. Mustang 2 From V1.0.30 the same screen opens on the Pi and the remotes, with Factor − / +, Incr, Modulation, Exit (leave without saving) and Save & Exit; the Pi version adds a live spectrum.
Starts the receive I/Q balance calibration routine (corrects phase/amplitude imbalance in the receiver). In Mustang 2 the same screen opens on the Pi and the web and phone remotes, with full control: amplitude and phase adjust, step size, auto-tune, band cycling and Save & Exit. The Pi screen also has Stop (ends an Auto sweep early) and Exit (leave without saving).
Starts the transmit I/Q balance calibration routine (minimises the opposite sideband). Mustang 2 From V1.0.30 the same screen opens on the Pi and the remotes, with IRR / dBc, the current-band values, the all-bands table and buttons for Amp, Phase, Atten, Incr, Auto, Stop (ends an Auto run and releases PTT), Band, Exit and Save & Exit. Key the radio with its own PTT to transmit; Auto keys it automatically, as on the radio.
Starts the transmit power-amplifier calibration routine. Mustang 2 From V1.0.30 the same screen opens on the Pi and the remotes, with the step list (✓ done, ▶ current), Attenuation, measured and target power, the Psat / k / Gain table and buttons for Record (Select), Atten, Power, Incr, Units W/dBm, PA 20/100W, Next step, Reset, Band, Exit and Save & Exit. V1.0.30 also fixes the radio’s own “Transmit:” line, which always read Off.
Runs a built-in-test screen checking the I2C-connected hardware: PASS or FAIL for the front panel, BPF, RF, RF SI5351 and K9HZ LPF boards. In Mustang 2 the results screen also opens on the Pi and the remotes, with a Home button to leave it.
Restore receive EQ Greyed out on Pi & remotes(back to tree)
Resets all receive equalizer bands back to their flat/default values. Greyed out on the Pi and remotes for now; use the front panel.
Buffer print Greyed out on Pi & remotes(back to tree)
Prints diagnostic buffer contents, for debugging. Greyed out on the Pi and remotes for now; use the front panel.
Menu > Network on the Pi’s touch screen opens a full-screen Wi-Fi page: the current network (SSID), 2.4 or 5 GHz, signal and IP address; a list of the networks the Pi can see (signal, band, secured/open, connected/saved); and Rescan, Connect, Forget and Close. Picking a secured network that isn’t saved yet opens a password box with an on-screen keyboard (Shift, ?123 for numbers and symbols, Show/Hide). It isn’t on the web remotes, because switching networks from a browser on the current one would cut it off. After a switch the Pi has a new address, shown on the page. More in Chapter 2.
Settings Pane
The normal on-screen status/readout box (Page 1), shown whenever CW Decode is off. A fixed top row, then a two-column grid, then two full-width bottom rows.
Shows whichever parameter the main Volume/adjust encoder currently controls - the label itself changes to match: Audio Volume (“Vol:”), AGC threshold (“AGC:” - not the AGC mode indicator on the right), Mic Gain (“Mic:”), or Sidetone Volume (“STn:”). Pi & remotes there, Vol: (audio volume) is shown in the Settings pane.
Transmit attenuation actually in effect right now: the CW-mode attenuation value while receiving CW, 0 while in SSB/digital receive (digital transmit uses the SSB path), otherwise the previous reading is held.
Zoom narrows the spectrum/waterfall display around the tuned frequency: at each step up, the displayed bandwidth is cut in half. The rule is simply displayed bandwidth = sample rate ÷ zoom factor, centered on the tuned frequency (half above, half below).
DSP loop CPU load, as a percentage, sampled once per second. Mustang 2 From V1.0.27 it measures only the signal processing; earlier versions also counted time spent waiting for the audio output, which made it read 60–79% after power-up and drop to about 20% once DATA mode restarted the audio.
The firmware version string, right-aligned in red at the bottom of the pane.
CW Settings Pane
Replaces the Settings pane above, in the exact same screen area, whenever CW Decode is turned on (Menu > CW Options / the Decode button). Several rows are read-only reflections of CW Options menu settings; the last four (Dit(ms):, Upd Age:, AvgD/D:, Coeff:) are hardware-testing diagnostics for the CW speed tracker, not user controls.
Mustang 2 From V1.0.34 the Pi and the web and phone remotes switch to this page at the same time as the radio (without Vol: and AGC:, which are on their readout line already), and the decoded text shows on a line under the waterfall on the Pi and in a strip along the bottom of the waterfall on the remotes — with “CW” in green once the decoder locks and the decoded WPM. The radio only keeps its last 15 characters; the Pi keeps a much longer line.
On/Off, with a small colored box next to it: green once the decoder has confidently locked onto a signal, red while on but not locked, hidden while Off.
Auto or Manual - a live, read-only reflection of Menu > CW Options > “CW Manual Mode”: Auto lets CW auto-tune track the signal on its own, Manual hands tuning fully to the operator.
Diagnostic: the raw dit length (ms) currently driving CW decode timing - the number to watch directly (independent of the 1200/x WPM conversion) when investigating whether the speed tracker is responding.
Diagnostic: seconds since the CW speed tracker last updated its dit-length estimate. Should stay at or below about 5s while receiving continuously; climbs without bound while CW Manual Mode has the tracker paused.
Diagnostic: smoothed, exponentially-averaged dit and dah lengths (ms), shown side by side as “dit/dah” - an alternate speed estimate that reacts faster to a genuine speed change than Dit(ms):/WPM:, for comparing against them.
Diagnostic: the raw combinedCoeff correlation value driving CW decode/lock (10 × average correlation × 100 × Goertzel magnitude). Compare by eye against the two thresholds used internally: 50 (must be cleared to feed the character decoder at all) and 120 (must be cleared for the Decoder: lock indicator and WPM:/SNR: to trust the signal).
Same firmware version string as the Settings pane.
Chapter 2 · The Pi 5
Overview
A Raspberry Pi 5 sits alongside the Teensy 4.1, driving a 7″ Raspberry Pi Touch Display 2 (720×1280, rotated to landscape). The Teensy keeps doing everything it has always done – all the real-time audio, DSP and RF control; the Pi only draws the screen and handles the mouse (and touch). The two talk over a serial link called PiLink: the Teensy sends frequency, mode, settings, S-meter and spectrum data down to the Pi, and the Pi sends clicks and wheel turns back up as ordinary front-panel button presses and knob turns – nothing it does is a capability the T41 doesn’t already have (Chapter 1). The Pi is an add-on, not a dependency: the physical front panel stays wired straight to the Teensy, and if the Pi is unplugged or crashes, the radio keeps working exactly as it does now.
The Touch Display screen
A full mirror of the Teensy’s own display, scaled up and in the same layout: VFO, frequency/band/mode, spectrum and waterfall (with the Teensy’s own colors and frequency ruler), S-meter, REC/XMT, SWR/power, audio spectrum, the Settings pane and a clock badge. When the front panel switches to the secondary (“Toggle Layout”/Spare) home screen, the Pi follows. A readout strip above the spectrum adds Vol, AGC, Scale, Floor, Zoom, TI (tune increment), FT (fine-tune increment) and Noise at a glance, and the Pi’s own network address sits next to the clock, with Local Time and UTC readouts beside it. A blue highlight over the spectrum marks the receive passband, just like the tuning bar on the Teensy’s own screen.
Toolbar & Menu
In place of the radio’s own Menu button, the Pi (and both remotes in Chapters 3–4) reaches every control through a mouse-driven toolbar, built straight from the firmware’s own tables. Every pick sends the radio exactly the same button press or knob turn the front panel would; with firmware V1.0.28 or later a dropdown pick jumps straight to the item instead of stepping through every entry on the way.
Button
What it does
Menu
RF Options, EEPROM, Calibration, Diagnostics and Sample Rate, plus Network on the Pi screen.
Display
The Display menu, grouped: Spectrum floor ▸ Auto / Manual / Spectrum floor · Spectrum scale, smoothing, decay, trace smoothing · Spectrum shadow ▸ On / Off · Spectrum fill ▸ On / Off · Brightness ▸ 25–100% · Freq Font ▸ · PI Spectrum ▸ PI Spectrum Fill, PI Waterfall, PI Waterfall Speed.
A plain button: sets the radio’s Volume knob back to audio volume (from AGC / Mic / Sidetone if needed) and points the mouse wheel and arrow keys at it. Mic gain, sidetone and AGC are under Mic, CW and Audio.
Band, Mode, Demod, Course, Fine, Zoom, Filter, Noise, Decode, Home
The same as the matching front-panel buttons. Filter picks Lo Cut or Hi Cut and points the wheel at it.
CW KeyPi screen only
On the Pi’s third toolbar row, next to Wheel, and only in CW mode. Hold it to key down (it turns red and reads “CW KEY”), let go for key up, like a straight key in the KEY jack. Needs firmware V1.0.35. Not on the web or phone remote.
Current choice highlighted: on any menu with two or more choices the current (or last-picked) one is marked — bold green with a dot on the Pi, a green check on the web. It follows the radio, so front-panel changes show too.
The mouse wheel works the knobs it adjusts a Menu setting while the red parameter box is showing (with a “Select >” to confirm, like the real SELECT button), or Volume/AGC/Mic/Sidetone or the filter after picking them from Vol or Filter. A “Wheel:” indicator shows what the wheel controls; click it to hand the wheel back to tuning.
Readout line above the spectrum: AGC, DSP (RX DSP gain), Scale, Floor, Zoom, CT (course tune step), FT (fine tune step), Noise. Vol (audio volume) is in the Settings pane.
Pi-only settings (Brightness, Freq Font, PI Spectrum Fill, PI Waterfall, PI Waterfall Speed) are shared by the Pi and every open remote, and the Pi remembers them across restarts.
Desktop icons on the Pi’s own screen start the radio app and shut the Pi down cleanly, with a confirmation first.
Calibration & test screens
Every Menu > Calibration item (S meter level, Frequency, Receive IQ, Transmit IQ, Power), the Audio Equalizer and Menu > Diagnostics > I2C BIT test open full-screen on the Pi (and both remotes) – see each one’s own entry in Chapter 1’s Calibration section for exactly what it offers. A few Menu items without a Pi screen yet (Diagnostics > Restore receive EQ/Buffer print, EEPROM > Print data to Serial) are greyed out for now; they still work from the radio’s own front panel. Front Panel Test (Menu > Front Panel Test, or the Diagnostics menu) lights up each of the 22 front-panel buttons on the Pi and both remotes as it’s pressed on the radio, and shows each of the 4 encoders’ (Volume, Filter, Center tune, Fine tune) running turn count and direction.
CW operation
With Decode on, the decoded text runs along a line under the waterfall – green “CW” once locked, with the decoded WPM – and the Settings pane switches to the radio’s own CW settings page (Chapter 1). A CW Key button on the Pi’s third toolbar row, shown only in CW mode, acts as a straight key in the KEY jack: hold it to key down, let go for key up. While held, the Pi re-sends key-down every 300 ms and lets go after 30 s or if the mode leaves CW; the radio releases the key itself if the Pi goes quiet for 1 s. This button is Pi-screen only – neither web remote has it.
Digital (FT8/FT4) operation
Reached from Menu, the Pi decodes and transmits FT8/FT4 itself – no PC or WSJT-X needed. The screen has band buttons, a UTC clock with a period-position bar and sync check, a colour-coded decode list (tap a line to answer it) with CQ-tries/Answer-tries limits and a Dist/Brg (distance and bearing) column once Setup has your grid set, a QSO panel (CQ, Enable TX, Halt, Auto, Tune, Log QSO), an SWR/power meter, and a waterfall you can tap to move your TX offset. Auto-sequencing works like WSJT-X and logs completed QSOs to ~/mustang_digital.adi (ADIF); a View Log button opens a smaller read-only window listing what’s already logged (newest first: date, UTC time, call, grid, band, mode, RST sent/rcvd), with Name/Country columns, a Lookup QRZ backfill button, Refresh, CSV/PDF/ADIF export, and checkbox-select + Delete for removing a bad QSO. Needs the Serial + MIDI + Audio firmware build and the Teensy USB cable into the Pi, since it switches DATA mode, frequency and PTT over the Teensy’s own CAT port. Both web remotes have the identical screen, reflowed to stack vertically on the phone page (Chapters 3–4), with full transmit control – the Pi’s screen and any number of browsers all drive and watch the same QSO at once, with no lock between them.
Pi-only settings
Menu > Settings (Global Settings) holds app-wide values that live on the Pi, not the radio: Call Sign (the name badge on the Pi’s own screen), Local Time Zone (quick-pick US zones or any IANA zone, used only for the Local Time readout, independent of the Pi OS’s own system clock so FT8 timing can stay on UTC), and Pi Display Timeout (blanks the screen Off/1–30 min after no mouse/touch activity; any movement brings it right back). Saved to the Pi and effective immediately. Menu > Network, Pi-screen only, is covered in Chapter 1.
What’s different about the Pi’s own screen
Three toolbar rows (the web remote fits the same controls into two), with REC and SWR at the right edge.
CW Key and Menu > Network are Pi-screen only – neither appears on a web or phone browser.
The hidden Pi OS top panel (for restarting the app or shutting down) opens by hovering the very top edge of the fullscreen touchscreen for 3 s, to keep a stray touch from popping it open by accident.
Chapter 3 · Web Remote
Connecting
The web remote is served directly by the Pi 5 – no separate web server, app or account needed. On any computer, tablet or phone on the same home network as the radio, open a browser and go to:
http://<pi-hostname>:8765/
Replace <pi-hostname> with the Pi’s network name (for example mustang.local) or its IP address. The page asks for a passkey before it connects – set in the Pi’s config.py, separate from the home network’s own Wi-Fi password. Once logged in, the page starts mirroring the radio immediately. Any modern desktop browser works – Chrome, Firefox, Edge and Safari have all been used with it – with no plugins, extensions or app install needed. On a phone, use Chapter 4’s page instead; the two share the same URL and passkey, just /mobile on the end.
Layout & panes
The page mirrors the same panes as the radio’s own screen and the Pi’s Touch Display (Chapter 2), arranged the same way: VFO/frequency readout with band/mode and REC/XMT across the top, the toolbar just under it, the S-meter at 20 Hz, the spectrum and waterfall (2D or 3D, picked under Display > PI Spectrum) with the blue passband highlight and a red-marked frequency ruler, the audio spectrum with passband and CW filter markers, the readout strip (AGC, DSP, Scale, Floor, Zoom, CT, FT, Noise), SWR/PWR, and the Settings pane (switching to the CW settings page when Decode is on).
Controls: toolbar & Menu
Every toolbar control works exactly as described for the Pi in Chapter 2 – the same Menu, Display, Audio, Mic, CW, Vol, Band/Mode/Demod/Course/Fine/Zoom/Filter/Noise/Decode/Home, and the same Calibration and test screens, with one exception: CW Key and Menu > Network are Pi-screen only and don’t appear here. What’s different on the web page is how you drive it:
Click instead of tap/mouse-on-touchscreen; the cascading Menu opens and flies out the same way.
A “Wheel:” status pill shows what the mouse wheel currently controls — Tune only, Volume, or Filter. Clicking Vol, or picking Hi Cut/Lo Cut from Filter, claims the wheel (and the arrow keys) for that knob; click the pill to release it back to tuning-only.
Mute sits with the other toolbar controls and turns red while muted (see Audio & Mute below).
Tuning
Three ways to move the VFO (or adjust Filter/Volume) from this page:
Mouse wheel over the frequency readout or the spectrum turns the main tuning knob; hold Shift while scrolling for fine tuning. This works independently of whatever the wheel is currently claimed for (Volume or Filter, via the “Wheel:” pill above) — the knobs don’t interfere with each other.
A USB rotary encoder, configured (in its own software or a keyboard-emulation mode) to send arrow or page keys, drives the VFO the same way regardless of where the mouse pointer is.
The virtual rotary dial – a draggable dial that floats over the page without blocking it, for Tune/Fine-tune, Filter, and Volume. “Freq Dial” opens a Course/Fine dial that sends the same tune/fine-tune clicks the mouse wheel does, driven by drag angle; “Filter Dial” and “Vol Dial” work the same way for the filter edge and the volume knob. Each dial’s center shows its live value and can be tapped to close it or held to drag it anywhere on screen. Menu > Rotary Dial sets each dial’s size (Small/Medium/Large) and on-screen position, saved per-browser; a Layout choice there picks Both (every dial independent, the default) or Single (one shared dial that Freq Dial/Filter Dial/Vol Dial retarget instead of each opening its own), with automatic collision-avoidance so open dials don’t overlap.
The rotary dial at its Large size, centeredSized down and moved to the lower-right corner — out of the way while still reachableMenu → Rotary Dial: pick its size and where it sits, saved per-browser
Keyboard: Up/Down tune (Shift = fine). Left/Right adjust Filter Lo/Hi Cut or Volume after picking it; after Vol all four arrows change the volume. In a Menu value box every arrow changes the value; on the Equalizer screen Left/Right pick the band and Up/Down its level. A trackpad scroll moves one step per short swipe and ignores sideways movement.
Audio & Mute
When the Teensy’s USB audio is wired to the Pi, the web remote streams live receive audio to every logged-in browser – uncompressed, over the same connection as everything else, with no codec or plugin to install. Playback starts automatically once logged in (browsers require a user click before audio can start, which logging in already provides). The Mute button in the toolbar turns red while muted and is local to your browser tab only: it doesn’t stop the Pi from sending audio, and has no effect on the radio, the Pi’s own speaker, or any other viewer’s audio. If nothing is heard: the Teensy’s USB audio cable to the Pi may be unplugged, or the Pi’s audio software isn’t installed – either way nothing else on the page is affected.
Security
LAN onlyThe web remote has no encryption — it’s plain ws://, not wss://. Don’t forward port 8765 through your router to reach it from outside your home network. The passkey stops casual access on the LAN; it isn’t a substitute for TLS against a hostile network.
Reaching the radio from outside the home would need real encryption and a stronger passkey, or a VPN back into the home network – never a plain port-forward. See the Secondary CPU project page for this as a future item.
Troubleshooting
Page won’t load
Confirm the computer is on the same network as the Pi, and that radio_ui.py is running on the Pi (it also runs the web server). Double-check the hostname/IP and that :8765 is included in the URL.
A recent change doesn’t seem to show up
Browsers can cache the page. Do a hard refresh instead of an ordinary reload: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac), or open the browser’s developer tools and enable “Disable cache” while the page is open.
Login asks again every time
Normal – the passkey isn’t stored between sessions on purpose.
Menu pick jumps back to Home
Fixed in firmware V1.0.15, which sends the Menu’s real position to the Pi. Check the Settings pane’s firmware version; reflash the Teensy if it’s older.
No audio
See Audio & Mute above – usually a disconnected USB audio cable or missing Pi-side audio software, not a browser problem.
CW page shows “--”
WPM and SNR fill in once the decoder locks, and Dit, AvgD/D, Upd Age and Coeff only while in CW receive with Decode on – the same as on the radio.
Spectrum/waterfall frozen
Check the Pi’s own screen first – if it’s frozen too, the issue is the PiLink link or radio_ui.py itself, not the browser page.
Known limits
State of Health isn’t on the web page yet.
A few Menu items are greyed out until they get their own remote screen (see Chapter 1).
No PTT time-out or screen/browser lock – two people driving it at once (or the Pi’s own screen and a browser) can conflict. This includes the Digital/FT8 screen, which deliberately has full transmit control from a browser with no lock against the Pi’s own screen.
No general voice/CW transmitting from a browser – the on-screen CW Key is Pi-screen only. The Digital (FT8/FT4) screen is the one exception, with full transmit control from either web remote.
LAN only, as above – no remote access from outside the home network.
Chapter 4 · Mobile Remote
Connecting
The phone page, Mustang Mobile, is the same web remote server as Chapter 3, at a different path:
http://<pi-hostname>:8765/mobile
Same host, same passkey as the desktop page. It’s built for a phone or small tablet screen; a laptop or desktop browser should use /remote instead.
Layout differences
The page mirrors the same panes described in Chapter 3 – frequency, toolbar, S-meter, spectrum/waterfall with the readout strip, audio spectrum, Settings pane – reflowed for a narrow screen:
The toolbar becomes a six-column grid of buttons (four columns on some screens) instead of the desktop’s two dropdown rows.
Dropdowns open as the phone’s own native pickers (an iOS wheel picker, for example) instead of an in-page popup list – Band, Mode, Demod, Course Inc and the rest all work this way.
The Menu’s cascading flyouts open with a tap, the same categories and options as Chapter 1; the Display menu specifically opens as an accordion (its sub-groups expand inline) so four levels of nesting still fit a phone screen.
The on-screen version label reads Mustang Mobile and its own version number, separate from the desktop page’s.
Mustang Mobile, with the touch sliders at the bottomMenu → Display, as an inline accordionBand as a native iPhone pickerCourse Inc tuning step, also a native picker
Touch sliders
In place of the desktop page’s mouse wheel and rotary dial, four touch sliders sit at the bottom of the screen: Tune, Fine Tune, Volume and Filter. Drag one away from the center to turn that knob – further for faster – and it springs back to the center when you let go. The Volume slider’s label shows which of Vol/AGC/Mic/Sidetone it will change, and the Filter slider’s label shows Hi Cut, Lo Cut, or “Menu” while a Menu setting box is open. Tuning with these always works independently of whatever the toolbar’s Vol/Filter picks have claimed, the same non-interference rule as the desktop wheel in Chapter 3.
Menu & toolbar
Every control behaves exactly as described for the Pi in Chapter 2 and the web remote in Chapter 3 – same Menu categories, same Calibration/test screens, same Mute button (red while muted, local to this browser only) – just reached through the six-column grid and native pickers above instead of dropdowns. CW Key and Menu > Network remain Pi-screen only and don’t appear here either.
CW and Digital (FT8/FT4) on mobile
CW decode and the CW settings page work the same as described in Chapter 2 and Chapter 1 (without the Pi-only on-screen CW Key). The Digital (FT8/FT4) screen from Chapter 2 is identical here too, with full transmit control, reflowed to stack its band buttons, decode list, QSO panel and waterfall vertically for a phone screen instead of the Pi’s/desktop’s side-by-side layout.
The 3D waterfall and touch sliders together on Mustang Mobile
Differences from the desktop web remote
No virtual rotary dial (Chapter 3) – the touch sliders above do that job on a phone.
No USB rotary encoder or keyboard shortcuts – there’s no keyboard to wire one to.
No CW Key or Menu > Network, same as the desktop page (both remain Pi-screen only).
Everything else – Security, Troubleshooting and Known limits from Chapter 3 – applies here unchanged: LAN only, no encryption, same passkey, same lack of a PTT time-out or screen lock.
Mustang is my build of the Phoenix T41-EP SDT firmware, with changes to the display, spectrum and CW decoding. Mustang 2 adds PiLink, the link to the Raspberry Pi 5 Secondary CPU, which brings the Pi Touch Display and remote access from a browser or phone. Download the current releases below, or read what changed in each version.
Firmware .hex: ready to flash with Teensy Loader — see Flashing the .hex. Both are built for the Teensy 4.1; pick one:
With digital mode (USB Type “Serial + MIDI + Audio”). The radio appears on your computer as a USB sound card, “Teensy MIDI/Audio”, for WSJT-X and other digital-mode programs. Press Mode until the display shows DATA. CAT control shares the single USB serial port.
Dual Serial. No digital (USB audio) mode; CAT control gets its own second USB serial port.
In digital mode, set the level sent to the computer with Menu > Microphone > “USB RX level” and the transmit audio level with “USB drive”. DATA mode switches the radio to the 176.4 ksps sample rate.
Source ZIP: the complete Arduino sketch (the MustangSketch folder). Like the Phoenix firmware it’s based on, Mustang is released under the GNU GPL v3.
Mustang 2 is Mustang plus PiLink: the Teensy sends its display data to a Raspberry Pi 5 over a serial link and takes button presses and knob turns back from it. That’s what drives the Pi Touch Display and the web and phone remote. The radio works exactly as before without the Pi connected.
With digital mode is the one to pick for remote access: the web and phone remote get their live receive audio from the Teensy’s USB audio, over a USB cable to the Pi. It’s also the build for FT8 / WSJT-X.
Dual Serial runs the Pi display and remote control, but without live audio in the browser.
Source ZIP: the Teensy sketch (Mustang2Sketch), the Pi software including the web and phone remote pages (PiDisplay), the build documents and the changelogs. The Arduino libraries aren’t included; install the same ones listed under Building from source. Released under the GNU GPL v3, like Mustang.
The digital-mode build powers up in DATA mode (set STARTUP_MODE_DATA in Config.h to change that when building from source), with the radio’s spectrum fill off. After flashing, the Settings pane should read “Mustang 2 V1.0.49”. Flash the Teensy and copy the matching PiDisplay folder to the Pi together — the two have to match, or the Pi’s Settings pane stops updating (a Pi running ahead of the Teensy now degrades gracefully instead: the STATUS fields it doesn’t recognize yet just read as 0/hidden). See the Secondary CPU page for the Pi side.
Flashing the .hex
The .hex file is the finished firmware with every library already built in, so you don’t need the Arduino IDE or any libraries — just PJRC’s Teensy Loader and a USB cable.
Save your settings first. On the radio, use Menu > EEPROM > “Save data to storage” to back up your settings to the SD card.
Get Teensy Loader. It installs with Teensyduino, or download it on its own from PJRC. The Arduino IDE itself can’t open a .hex file; Teensy Loader is the tool that flashes it.
Connect the Teensy 4.1 to your computer with a USB data cable.
Open the file. In Teensy Loader choose File > Open HEX File and pick the Mustang .hex.
Program it. Press the small pushbutton on the Teensy. Teensy Loader erases, programs and reboots it; this takes a few seconds.
Check the version. The version string at the bottom of the Settings pane should read the new version (for example “Mustang V1.0.39” or “Mustang 2 V1.0.34”).
A .hex is built for one board and one set of Tools options (USB Type, CPU Speed). If you need different options, build from source below.
Building from source
Install the Arduino IDE 2 and add Teensy support: in Settings, add https://www.pjrc.com/teensy/package_teensy_index.json to Additional boards manager URLs, then install “Teensy” in Boards Manager.
Install the libraries listed below. Library Manager covers the Adafruit ones and ArduinoJson; copy OpenAudio into your Arduino libraries folder.
Open the sketch. Unzip the source and open MustangSketch/MustangSketch.ino (for Mustang 2, Mustang2Sketch/Mustang2Sketch.ino).
Set Tools options. Board: Teensy 4.1. USB Type: Serial + MIDI + Audio if you want digital (USB audio) mode, or Dual Serial if you don’t. CAT control works with either.
Upload with the radio’s Teensy connected, or use Sketch > Export Compiled Binary to make your own .hex.
Included with Teensyduino, nothing to install: Audio, SD, SPI, Wire, SerialFlash, LittleFS, Time (TimeLib), RA8875 and the Arm CMSIS-DSP math library.
Release Notes
Newest first. Versions not listed had no user-visible changes.
Mustang V1.0.39
V1.0.39 Current
Digital mode now works: fixed a crash that made builds with USB Type “Serial + MIDI + Audio” restart every few seconds at the startup screen. The spectrum zoom used 16 KB of temporary memory on the stack, which overflowed once USB audio was added; that memory now lives in the Teensy’s second RAM bank, which also frees stack space in every build.
First release with a digital-mode (USB audio) firmware download.
V1.0.37 – V1.0.38
Fixed the spectrum at 1x zoom: the frequency scale under the spectrum read 48 kHz high (44.1 kHz at 176.4 ksps), and signals showed up offset from the tuning marker. The tuned frequency is now centered, with the scale and marker matching the signals, at every zoom level.
V1.0.36
Spectrum colors now change at the intended heights: the green → yellow → red breakpoints are measured from the trace’s visible baseline instead of the bottom of the pane.
V1.0.35
Spectrum color breakpoints moved to 1/4 (green → yellow) and 1/2 (yellow → red) of the trace height.
V1.0.34
Spectrum color fill now fades in bands instead of recoloring the whole column.
Light yellow and light red changed to solid yellow and red.
Fixed Menu > EEPROM > “Save data to storage”, which broke saving to and loading from the SD card.
V1.0.33
Spectrum trace is colored by signal strength: green, then yellow, then red.
V1.0.32
Spectrum display settings (floor mode, scale, smoothing, decay, trace smoothing and shadow) are now saved per band instead of globally. Settings files from earlier versions still load.
V1.0.31 Renamed to Mustang
Firmware renamed from K2RRL to Mustang.
New Pane row on the secondary screen uses the same font size as the Settings pane, and adds TI:, FT: and Noise: fields.
V1.0.29
Smaller spectrum trace area on the secondary screen, with a new row below LO Freq.
Fixed a display-corruption bug on that screen.
V1.0.28
REC/XMT indicator moved above the S-Meter on the secondary screen.
New Menu > Display > “Spectrum trace smoothing” setting (0–0.3 s).
Spectrum Scale extended to 17 steps (0–16) with more half-steps.
V1.0.27
New Menu > Display > “Spectrum shadow on/off” option.
V1.0.22 – V1.0.26
Fast Course Tune spins: the frequency readout, spectrum and waterfall now keep up with the knob, at full refresh rate.
The blue shadow trace no longer lags behind the live trace after a fast retune.
V1.0.21
Half-step (0.5 dB/division) presets added to Spectrum Scale.
V1.0.20
New blue “shadow” (peak-decay) trace behind the live green spectrum trace.
V1.0.15 – V1.0.16
Pressing the Course Tune encoder steps through the tuning increments.
Pressing the Fine Tune encoder steps through the fine-tune increments.
V1.0.1 – V1.0.5
CW auto-tune no longer drifts or hunts while the decoder is locked, and waits through normal pauses in the code.
The “Decoder:” lock indicator no longer sticks on green after the signal is lost, and a weak or noisy signal no longer shows a false lock and a stuck WPM reading.
New Menu > CW Options > “AT Grace (s)” setting for how long auto-tune waits before searching again.
V1.0.0 First release (as K2RRL)
Based on the Phoenix (Phx V1.4.0) T41-EP SDT firmware.
Settings pane adds Temp(F) (Teensy CPU temperature, updated every 5 s) and Load (DSP CPU load); the version string shows right-aligned in red.
A clock replaces the Name Badge pane, and pauses while a menu setting is being adjusted.
Key Type shows “STR Key”; the dB/division label moved next to Mode/Demod; the filter Lo/Hi readout was removed from the spectrum pane.
New CW auto-tune, which peaks the fine-tune frequency on the CW signal, and a live decoded-WPM readout.
Mustang 2 V1.0.49
Teensy firmware changes only; each one needs a reflash. Changes that only touch the Pi are under Remote Access and on the Secondary CPU page.
V1.0.49 Current download
I/Q transmit VU meter sent to the Pi (same spot used for the retired State of Health pane): two bars, I and Q, with the same green/yellow (raised IMD)/red (clipping) thresholds as the T41’s own bars — shown while the mic is keyed in SSB/DATA, handy for setting mic gain from the Pi.
V1.0.48
Fixed a crash a few minutes into streaming DATA-mode USB audio (web remote or the Digital/FT8 screen): the on-screen Diagnostics board tests added in V1.0.39–41 now build into the Dual Serial firmware only, not the Serial + MIDI + Audio (digital-mode) build, which had been landing just enough extra code to tip the digital-mode audio timing margin over.
Reverted a front-panel encoder change (V1.0.45) meant to stop a full-board reboot under fast knob spinning — on real hardware, the earlier unbounded-loop behaviour didn’t reboot and tracked fast turns better.
V1.0.42 – V1.0.47
New read-only DA; CAT command reporting the USB audio under/overrun counts, for diagnosing audio dropouts.
The rest of this range was debugging for the crash and reboot issues resolved in V1.0.48 above (a boot-loop-causing diagnostic print, tried and backed out twice; a front-panel I²C speed test) — no lasting user-visible change.
V1.0.41
Front panel board test on the Pi: a knob-count update could be skipped if the serial link was busy that instant, making the Pi lag the T41’s own count under fast turning — fixed to retry on the next pass.
BPF board test: Row ▲/▼ hidden (that page has only the one row).
V1.0.40
Board tests (BPF, LPF, RF, Front panel, Board test/USB serial) added to the Pi’s Menu > Diagnostics, mirroring the T41’s own test screens with the same rows and live readings.
V1.0.39
On-screen board tests (BPF, LPF, RF, Front panel, Board test over USB serial) added to the T41 itself under Menu > Diagnostics.
4 M removed everywhere (the T41 has no 4 m hardware): skipped by Band Up/Down and Auto calibration, and gone from the RX/TX IQ tables and the Pi/web Band dropdowns.
Calibration screens’ Instructions box lists the Stop/Exit buttons added since V1.0.24.
Power calibration screen’s band table trimmed to 160M–6M so it fits the T41’s screen again.
V1.0.38
Tune button (CW modes only) on the Pi and both remotes: tap for a steady carrier at the current CW power, tap again to stop; ends by itself after 60 s.
Power calibration: each step’s target now starts from a quarter of what you actually just recorded, instead of dividing a built-in 10 W guess. Pressing Select while still holding PTT now records the point instead of silently dropping it.
V1.0.37
Experimental TX IQ calibration now works on single-VFO radios (one RF board, one BPF board), sharing the RX IQ loopback path.
Auto no longer looks “stuck on GEN” when it finishes — it returns to the band it started from and shows Running/Done/Stopped beside the title.
V1.0.36
New Calibration > Experimental submenu: EVE RX/TX IQ calibration, a search routine ported from the T41EVE project, as an alternative to the normal Receive IQ / Transmit IQ Auto run.
V1.0.35
For the Pi’s on-screen CW Key: a new Pi-to-Teensy message keys the radio exactly like a straight key in the KEY jack, so the radio does its own T/R switching and sidetone. It only keys in CW, on a ham band, and the radio lets go by itself if the Pi stops sending for 1 s.
V1.0.34
CW settings page values sent to the Pi, so the Pi and the remotes switch to the radio’s CW settings page (Decoder with its lock box, AT Grace, Mode, Key Type, WPM, SNR, Dit, AvgD/D, Upd Age, Coeff) whenever Decode is on.
Includes everything from V1.0.26 to V1.0.33 below.
V1.0.33
Decoded CW text sent to the Pi, so it shows under the waterfall on the Pi and along the bottom of the waterfall on the remotes, with the decoded WPM.
V1.0.32
The radio’s own waterfall colours are sent to the Pi, so the Pi and remote waterfalls (including the noise blue) match the T41 exactly.
V1.0.31
Powers up in DATA mode (digital-mode build); set with STARTUP_MODE_DATA in Config.h.
V1.0.30
Calibration > Transmit IQ, Frequency and Power screens on the Pi and both remotes, with full control; S meter level enabled there too.
New Exit (leave without saving) on those three screens and Stop for the Transmit IQ Auto run.
Receive IQ Stop fixes: a Stop pressed while idle no longer cancels the next Auto run, and stopping before GEN no longer jumps to GEN.
Power calibration’s “Transmit:” line now shows On while transmitting.
V1.0.29
The radio’s spectrum fill is off at every power-up; Menu > Display > Spectrum fill turns it on.
V1.0.28
Menu picks from the Pi and the remotes jump straight to the item instead of visibly stepping through every menu entry on the way (new PiLink menu-select message; ignored unless the radio is on its Home screen and not transmitting).
V1.0.27
Audio Equalizer: button 14 is now Exit — puts both equalizers back the way they were when the screen opened and returns Home without saving (Home still saves and exits).
“Load:” now measures only the signal processing. It used to include time spent waiting for the audio output, so it read 60–79% after power-up and dropped to about 20% once DATA mode restarted the audio.
V1.0.26
Audio Equalizer screen data sent to the Pi, so Audio > Adjust Equalizers works on the Pi and both remotes.
“TI:” readout renamed “CT:” (course tune step).
V1.0.25
I2C BIT test results (pass/fail per board: front panel, BPF, RF, RF SI5351, K9HZ LPF) sent to the Pi, so the BIT screen works on the Pi and both web remotes.
Menu items that don’t have a Pi or web screen yet are greyed out on the Pi and remotes (they still work from the front panel).
V1.0.24
Receive IQ calibration: Stop (ends an Auto sweep early) and Exit (leave without saving) buttons on the Pi screen.
V1.0.23
Receive IQ calibration screen on the Pi and both web remotes, with full control: amplitude/phase adjust, step size, auto-tune, band cycling, Save & Exit.
V1.0.22
Sends the T41’s Spectrum fill on/off setting to the Pi.
V1.0.21
Choppy audio fixed. On a strong or wide signal the filled spectrum trace could take long enough to draw that audio blocks were dropped, on the radio’s own speaker as well as the remotes.
New Menu > Display > Spectrum fill on / Spectrum fill off, so the fill can be turned off if it ever comes back. Default on (off from V1.0.29).
V1.0.19 – V1.0.20
RX DSP gain is now worked out once instead of on every audio block; V1.0.20 was a test build used to track down the choppy audio.
V1.0.18
Sends the spectrum floor (manual value or Auto) for a new “Floor:” readout on the Pi and remotes.
V1.0.17
New Menu > RF Options > RX DSP Gain, −5 to +20 dB in 0.5 dB steps (it was already live, with no menu entry to change it).
Sends the spectrum scale for a new “Scale:” readout on the Pi and remotes.
V1.0.16
New button-repeat message: jumping several steps in a dropdown (Zoom, Band, Mode, Demod, Noise, Course/Fine Inc, Vol, BW) now happens almost instantly instead of stepping through each level.
V1.0.15
The Teensy now sends the Menu’s real position to the Pi, so choosing a Menu item from the Pi screen or the remote always lands on the right setting instead of sometimes jumping back to Home.
V1.0.14
The main tuning and fine-tuning knobs can now be turned from the Pi and the remote (new Tune and Fine-tune virtual encoders).
V1.0.13
Sends the visible spectrum span and the band’s legal limits, for the frequency ruler (with out-of-band ticks in red) under the Pi’s spectrum.
V1.0.12
Sends the volume level and which home layout is showing, so the Pi follows the secondary (“Toggle Layout”) screen.
V1.0.11
Fixed: Menu → Display spectrum scale and floor now change the Pi’s spectrum as well as the Teensy’s.
V1.0.10
The Volume knob can be turned from the Pi (the virtual encoder message now carries which knob to turn).
V1.0.9
Sends the red “Label: value” box while a Menu setting is being adjusted, so the Pi can show it and change the value with the mouse wheel.
V1.0.8
New virtual encoder message, so the Pi can turn the Filter knob to pick Menu items. Adds the Decode on/off state.
V1.0.7
Fixed: REC/XMT could show XMT while receiving; it now follows the radio’s own transmit state.
V1.0.6
Sends everything on the Settings pane, including the firmware version, twice a second.
V1.0.5
Sends the live audio-spectrum bars.
V1.0.3 – V1.0.4
Fixed: the spectrum sent to the Pi was a flat line, then missing entirely (a bigger serial transmit buffer).
V1.0.2 and earlier First release
PiLink added: frequency, band, mode, S-meter and spectrum to the Pi, and button presses back from it.
Remote Access
The browser pages run on the Pi, so these updates need no reflash: copy the new files to the Pi and hard-refresh the browser.
/remote — web (laptop / desktop) V1.0.34
V1.0.34 Current download
Calibration > Transmit IQ, Frequency and Power screens, and S meter level (with firmware V1.0.30).
Decoded CW strip along the bottom of the waterfall, and the CW settings page in the Settings box while Decode is on (with firmware V1.0.33 / V1.0.34).
Waterfall in the radio’s own colours (with firmware V1.0.32); brighter blues, and a brighter 3D waterfall.
PI Spectrum Fill starts off; the calibration overlay has a solid background.
V1.0.28
New toolbar: Display, Audio, Mic and CW dropdowns (copies of the radio’s own menus) next to Menu; Vol is now a plain button that points the wheel and arrow keys at the volume.
Display menu grouped (Spectrum floor, Spectrum shadow, Spectrum fill, PI Spectrum), plus new Freq Font (Original / Nixie / VFD / Dot Matrix), PI Waterfall 2D / 3D and PI Waterfall Speed.
Menus highlight the current choice; menu picks jump straight to the item (with firmware V1.0.28).
Audio Equalizer screen with Edit RX / Edit TX, Exit and Save & Exit (with firmware V1.0.26 / V1.0.27).
DSP: added to the readout line, Vol: moved to the Settings pane, TI: renamed CT:.
Trackpad fix (filter edges no longer jump around); arrow keys adjust Filter or Volume after picking them, and tune otherwise.
The S-meter’s “−XXX.X dBm” reading is no longer cut off on the right.
V1.0.25
I2C BIT test results screen; Menu items without a remote screen yet are greyed out.
Receive IQ calibration screen with Stop and Exit buttons and on-screen instructions.
SWR/PWR readout added; the “(USB)” demod name shows again.
Fixed choppy audio caused by playing the stream back at the wrong sample rate.
Spectrum trace made shorter so the waterfall gets more room, with the readout strip (Vol, AGC, Scale, Floor, Zoom, TI, FT, Noise) moved above it.
New Menu > Display > Brightness (Pi screen backlight) and PI Spectrum Fill on/off; Scale: and Floor: readouts.
Brighter spectrum green and a smoother green-to-red fill; larger audio-filter labels.
V1.0.15
Vol, AGC, Zoom, TI, FT and Noise always show across the top of the spectrum; Filter moved into the audio spectrum pane and Power into the Settings pane.
Toolbar buttons keep fixed labels (Course, Fine, Zoom, Filter and so on) instead of showing the current value.
Fixed: S-meter labels cut off at the top, and the frequency ruler running into the waterfall.
Menu selections land on the right setting (with firmware V1.0.15).
V1.0.14 First release
Browser remote on the home network at http://<pi-hostname>:8765/, with a passkey.
Mirrors the frequency, toolbar, S-meter, spectrum and waterfall, audio spectrum, Settings pane and the Menu parameter box.
Mouse-wheel tuning (Shift for fine) and USB rotary encoder support; cascading Menu; BW dropdown and “Wheel:” indicator.
Live receive audio with a Mute button; blue filter-bandwidth highlight on the spectrum.
/mobile — phone (Mustang Mobile) V1.0.55
V1.0.47 – V1.0.55 Current download
Calibration > Transmit IQ, Frequency and Power screens (two buttons a row), and S meter level (with firmware V1.0.30).
Decoded CW strip along the bottom of the waterfall, and a compact CW settings page in the Settings box while Decode is on (with firmware V1.0.33 / V1.0.34).
Waterfall in the radio’s own colours (with firmware V1.0.32); brighter blues, and a brighter 3D waterfall.
PI Spectrum Fill starts off.
V1.0.34 – V1.0.46
New toolbar: Display, Audio, Mic and CW dropdowns (copies of the radio’s own menus) next to Menu; Vol is now a plain button that points the wheel and arrow keys at the volume.
Display menu grouped (Spectrum floor, Spectrum shadow, Spectrum fill, PI Spectrum), plus new Freq Font (Original / Nixie / VFD / Dot Matrix), PI Waterfall 2D / 3D and PI Waterfall Speed.
Menus highlight the current choice; menu picks jump straight to the item (with firmware V1.0.28).
Audio Equalizer screen with Edit RX / Edit TX, Exit and Save & Exit (with firmware V1.0.26 / V1.0.27).
DSP: added to the readout line, Vol: moved to the Settings pane, TI: renamed CT:.
Trackpad fix (filter edges no longer jump around); arrow keys adjust Filter or Volume after picking them, and tune otherwise.
Toolbar is a 6-column grid and the readout line fits on one row, so all four jog sliders (including Filter) stay on screen; the styled frequency fonts don’t push the page down.
V1.0.33
I2C BIT test results screen; Menu items without a remote screen yet are greyed out.
V1.0.31 – V1.0.32
Receive IQ calibration screen, then Stop/Exit buttons and on-screen instructions.
V1.0.30
SWR/PWR readout added; the “(USB)” demod name shows again.
V1.0.27 – V1.0.29
Spectrum fill on/off in the Display menu, then a separate PI Spectrum Fill on/off for the Pi and remotes.
V1.0.26
Fixed choppy audio caused by playing the stream back at the wrong sample rate.
V1.0.23 – V1.0.24
Smaller readout strip font; spectrum trace made shorter with the readout strip moved above it.
V1.0.18 – V1.0.22
Scale: and Floor: readouts, RX DSP Gain in RF Options, and Display > Brightness for the Pi screen’s backlight.
V1.0.14 – V1.0.17
Spectrum fill matched to the waterfall colours; S-meter dBm and audio-filter labels no longer clipped; “Power: 20W”.
V1.0.13
Fixed: the waterfall disappeared after the ruler fix; the trace and waterfall now share the space.
V1.0.12
Fixed: frequency ruler labels running into the waterfall.
V1.0.9 – V1.0.11
REC and “connected” no longer cut off at the top of the screen; REC shows in green.
V1.0.8
Fixed: toolbar buttons shrinking into a corner on the phone.
V1.0.6 – V1.0.7
Toolbar buttons keep fixed labels instead of showing the current value; S-meter labels no longer cut off.
V1.0.3 – V1.0.5
The page fits the phone’s real visible height, so the Filter slider at the bottom is reachable and drags reliably.
V1.0.2
Split into its own phone page at /mobile, so the laptop page stays unchanged.
V1.0.1 First release
Tune, Fine Tune, Volume and Filter touch sliders; four-column button grid; S-meter sized to the screen.
Chassis installed in the case, radio running (top panel off)Fully assembled chassis out of the caseRadio turned over: lining up the outside bolts with the case holesBase plate with side extension, topBase plate, undersidePCB mounts, from abovePCB mounts, from the sideChassis handleUpdated handle's flat plate, with the Pi 5 power supply Velcroed onBPF toroid retainers: bottom tray (6–20 m) left, top tray (30–160 m) rightBPF toroid retainers, side viewBPF toroid retainers, edge viewDisplay shield: printed shield, outsideDisplay shield: printed shield, insideDisplay shield: covered in copper tape and mounted over the displayDisplay shield: installed; the green wire grounds the copper tape to the chassisSecondary CPU: Pi display, T41, iPhone and laptop all running Mustang 2Secondary CPU: web remote, Pi Touch Display 2 and T41 all running Mustang 2Secondary CPU: the web remote in a browserSecondary CPU: Menu in the web remoteSecondary CPU: Mustang Mobile phone page with touch slidersSecondary CPU: phone page – Menu → DisplaySecondary CPU: phone page – Band as a native iPhone pickerSecondary CPU: phone page – Course Inc tuning stepSecondary CPU: 3D waterfall in the web remote, FT8 on 20 mSecondary CPU: 3D waterfall on the phone pageSecondary CPU: Mustang 2 on the Pi Touch Display 2Secondary CPU: Menu with cascading submenuSecondary CPU: the Digital (FT8/FT4) screen working FT8 on 40 mSecondary CPU: UART wires on the T41 main boardSecondary CPU: UART wires on the Pi 5 GPIO header
I built this chassis system to solve a few problems I encountered. I have the metal case from Justin (AI6YM Store — T41-EP SDT), and I wanted an easier way to connect all the ribbon cables, power cables, RF cables, etc. Placing the PCBs in the case and then trying to connect everything was a nightmare, and having to pull the PCBs out for troubleshooting was cumbersome.
Once the PCBs and all the cabling are attached, removing or inserting the chassis requires (in my case) connecting or disconnecting the main power from the power distribution, the RF cables from the 20 W PA, the USB connection on the Teensy, the case fan from the power distribution, and the display and front panel cables — a total of 6 connections. Once that’s done, I can place the chassis into or remove it from the case. It only takes a minute and it’s ready to go. With the handles in place, it still has about 10 mm of clearance when the top panel is on.
This also makes troubleshooting much easier: I can place the chassis outside the case, connect the power, display, front panel, etc., and have access to all the PCBs at once, from all sides.
PCB Mount
The PCB mount can be used with or without the main chassis base plate.
PCB mounts, from abovePCB mounts, from the side
Chassis Base System
The chassis base plate comes in two versions: one with a side extension that you can attach a power distribution board (or anything else) to, and one without it, for cases that are too narrow for the extension.
The PCB mounts and handles attach to the base plate with 3 mm bolts and washers. The handles are optional, but they make it much easier to lift the chassis system in and out of the case.
Use longer bolts in the outside slots — long enough to pass through the handles or PCB mounts and reach through the case. On the bottom, the outside slots are recessed so the washers and nuts sit in place without raising the chassis base system off the case once it’s installed.
In the “radio turned over” photo, the radio is upside down so I can adjust the outside bolts to line them up with the holes in the case. I used wing nuts on the bottom to make the chassis base system easier to remove.
Base plate with side extension, topBase plate, undersideFully assembled chassis out of the case, power distribution on the side extensionRadio turned over: lining up the outside bolts with the case holesChassis installed in the case, radio running (top panel off)
Chassis Handles
The chassis handles make it much easier to move the system in and out of the case. You can also use them to tie-wrap loose cables and wiring.
Chassis handle
Chassis Handle — Flat Plate (V1)
An updated handle with a solid flat plate across the middle, built stronger than the original handle so it can carry some weight. You can mount just about anything to it — in the photo it's holding the Raspberry Pi 5's power supply converter board (with its own small cooling fan), stuck down with Velcro rather than bolted. Same slotted mounting rails on each end as the original handle, so it bolts to the base plate the same way.
Updated handle's flat plate, with the Pi 5 power supply Velcroed on
Parts list
I printed the parts in PETG, but I’m sure PLA will also work, as the radio doesn’t get that hot. If the parts are too long for your printer, use your slicer to cut them with connectors.
Printed parts
PETG (PLA should also work), 0.4 mm nozzle, basic filament settings — nothing special
Threaded inserts
M3 × 4 × 5 metric threaded inserts
PCB mounts
3 mm × 8 mm bolts with washers
Chassis to case
3 mm × 16 mm bolts with washers and wing nuts, in the four corners
Downloads
3D-printable files for the chassis parts. Print settings and hardware are in the Parts list above.
A two-piece 3D-printed retainer, a bottom tray and a top tray, for the toroids on the band-pass filter (BPF) board.
Overview
I wanted to make sure that when working in the radio I didn’t bump or move the toroids, and also to have a way to re-tune or replace them.
Photos
Both retainers fitted on the T41 BPF board: bottom tray (6–20 m) on the left, top tray (30–160 m) on the rightSide view: the trays clip onto the boardEdge view: toroids held in the tray, visible through the openings
Printing
I printed them in PETG, but PLA will also work. I used a 0.4 mm nozzle and standard printer settings.
Downloads
3D-printable files for the two trays. The top tray covers the 30–160 m toroids and the bottom tray the 6–20 m toroids.
A 3D-printed shield for the video display, covered in copper tape and grounded to the chassis.
Overview
This is a 3D-printed shield for the video display. I covered it with copper tape and grounded it to the chassis. This cut down on the noise considerably.
Photos
Printed shield, outsidePrinted shield, insideCovered in copper tape and mounted over the displayInstalled; the green wire grounds the copper tape to the chassis
Mounting
The shield mounts on 3 mm × 20 mm bolts that come up through the case: nuts hold the display board, and the shield sits above it, held by another nut.
Hardware: 3 mm × 20 mm bolts, nuts and washers.
Mounting sketch: 3 mm × 20 mm bolt through the case, with nuts holding the display board and the shield
Downloads
3D-printable file for the shield. Cover it with copper tape and ground it to the chassis after printing.
Hardware · software · Mustang 2 V1.0.50 · as of 12 Oct 2026
Secondary CPU
A Raspberry Pi 5 added alongside the Teensy 4.1 to drive the graphics on a Raspberry Pi Touch Display 2, now with a mouse-driven toolbar and a browser remote, with live audio, on the home network.
Overview
This project is to add a secondary CPU, in this case a Raspberry Pi 5, to handle all the graphics to the Raspberry Pi Touch Display 2 screen. Future additions to this will be changing to dropdown menus using a mouse and also a remote control website.
Status
RunningStill growing
The Pi 5 and Teensy are talking on the bench, running Mustang 2 V1.0.50. The Pi’s screen mirrors every pane of the Teensy’s own display, the toolbar dropdowns and mouse wheel control the radio, and a browser on the home network, including a phone, can see it, control it and play its receive audio. Every Calibration screen, the Audio Equalizer, the I2C BIT test and a Front Panel Test now work from the Pi and the remotes too, and in CW the decoded text and the CW settings page show there as well, with an on-screen CW Key to transmit. Digital modes are no longer a future item: the Pi decodes and transmits FT8/FT4 itself, no PC or WSJT-X needed, with full transmit control from either web remote too — see it running on 40 m below. Most recently: a Menu > Settings page, an FT8 log viewer, and the new Front Panel Test for the front-panel buttons and encoders.
All four running Mustang 2 together: the Pi 5 on the Touch Display 2 (left), the T41’s own screen (back), the phone page on an iPhone (center) and the web remote on a laptop (right)
How it works
The Teensy 4.1 keeps doing everything it does today: all the real-time audio, DSP and RF control. The Pi 5 only draws the screen and handles the mouse. The two boards talk over a simple serial (UART) link called PiLink: the Teensy sends frequency, mode, settings, S-meter and spectrum data down to the Pi, and the Pi sends clicks and wheel turns back up as ordinary front-panel button presses and knob turns.
The Pi is an add-on, not a dependency. The physical front panel (buttons, encoders, key, PTT) stays wired straight to the Teensy. If the Pi is unplugged or crashes, the radio keeps working exactly as it does now.
powerdata / video
What it does
On the Pi’s own screen
A full mirror of the Teensy’s display in the same layout, scaled from 800×480 to 1280×720: VFO, frequency/band/mode, spectrum and waterfall (with the Teensy’s own colors and frequency ruler), S-meter, REC/XMT, SWR/power, audio spectrum, the Settings pane and the clock badge. When the front panel switches to the secondary (“Toggle Layout”) screen, the Pi follows.
Toolbar dropdowns, each built from the real firmware tables: Menu (with cascading flyouts, like a desktop app), Vol, Band, Mode, Demod, Course Inc, Fine Inc, Zoom, BW, Noise, Decode and Home.
The mouse wheel works the knobs. It adjusts a Menu setting while the red parameter box is showing (with a “Select >” to confirm, like the real SELECT button), or Volume/AGC/Mic/Sidetone or the filter after you pick them from the Vol or BW dropdown. A “Wheel:” indicator shows what the wheel controls; click it to hand the wheel back to tuning.
Blue filter highlight on the spectrum showing the receive passband, like the Teensy’s own tuning bar.
Desktop icons to start the radio app and to shut the Pi down cleanly (with a confirmation first).
Calibration and test screens: every Menu > Calibration item (S meter level, Frequency, Receive IQ, Transmit IQ, Power), the Audio Equalizer and Menu > Diagnostics > I2C BIT test open on the Pi and the remotes. The few Menu items without a Pi screen yet are greyed out there; they still work from the front panel. See the Mustang Manual for which ones.
CW: with Decode on, the decoded text runs along a line under the waterfall (green “CW” once locked, with the decoded WPM), and the Settings pane switches to the radio’s CW settings page, just like the T41. A CW Key button also appears on the third toolbar row in CW mode: hold it to key down, like a straight key in the KEY jack (needs firmware V1.0.35). While held, the Pi re-sends key-down every 300 ms and lets go after 30 s or if the mode leaves CW, and the radio releases the key itself if the Pi goes quiet for 1 s.
Digital (FT8/FT4) screen, reached from Menu: the Pi decodes and transmits FT8/FT4 itself, with no PC or WSJT-X needed — band buttons, a colour-coded decode list with CQ-tries/Answer-tries limits and distance/bearing, a QSO panel (CQ, Enable TX, Auto, Tune, Log QSO), an SWR/power meter, a waterfall you can tap to set your TX offset, and a View Log button that opens a smaller read-only window over the screen listing what’s already in the FT8 log (newest first: date, UTC time, call, grid, band, mode, RST sent/rcvd). Needs the Serial + MIDI + Audio build and the Teensy USB cable into the Pi. See the Changelog for the full rundown.
Menu > Settings (Global Settings): Call Sign, Local Time Zone and Pi Display Timeout (screen-blanking), with room for more; saved to the Pi and effective immediately.
Pi-only extras: a readout strip above the spectrum (Vol, AGC, Scale, Floor, Zoom, TI, FT, Noise), the Pi’s network address next to the clock with Local Time and UTC readouts, Menu > Display > Brightness for the touchscreen, and PI Spectrum Fill on/off for the Pi and remotes.
Mustang 2 running on the Pi Touch Display 2, tuned to 14.076.450 on 20 mChoosing from the Menu with the mouse: Display and its cascading submenuThe Digital (FT8/FT4) screen working FT8 on 40 m
From a browser on the home network
Open http://<pi-hostname>:8765/ on any computer on the same network. The page mirrors the VFO, toolbar, band/mode, REC/XMT, S-meter, spectrum and waterfall, audio spectrum, Settings pane and the Menu parameter box, and sends exactly the same commands the Pi’s own screen does.
Tune with the mouse wheel over the frequency or spectrum (hold Shift for fine tuning), or with a USB rotary encoder set up to send arrow or page keys.
Live receive audio plays in the browser, with a Mute button for that browser only. It comes from the Teensy’s own USB audio, over a USB cable to the Pi.
A phone page, Mustang Mobile, at http://<pi-hostname>:8765/mobile: the toolbar becomes a six-column grid of buttons that open as the phone’s own pickers, and four touch sliders at the bottom (Tune, Fine Tune, Volume and Filter) stand in for the mouse wheel. Drag a slider away from the center to turn that knob, further for faster; it springs back when you let go. The Volume and Filter labels show what they’re set to adjust (for example AGC, Lo Cut, or a Menu setting).
It asks for a passkey, which you set in config.py. Change it from the default.
For how to connect, what every control does and troubleshooting, see the Remote Access guide.
The 3D waterfall in the web remote: FT8 on 20 m at 14.074.400, zoomed 16×The same 3D view on Mustang Mobile V1.0.55
The web remote in a browser, reaching the radio through the Pi 5Choosing from the Menu in the browser: Microphone and its submenu
Mustang Mobile, with the touch sliders at the bottomMenu → DisplayBand as a native iPhone pickerCourse Inc tuning step
LAN onlyThe web remote has no encryption. Don’t forward port 8765 through your router to reach it from outside your home network.
Hardware
Secondary CPU
Raspberry Pi 5, 2 GB
Display
Raspberry Pi Touch Display 2, 7″ (720 × 1280, portrait native, rotated to landscape), DSI, using the “Standard – Mini” Touch Display cable (22-way on the Pi 5, 15-way on the display)
Power
Geekworm RPI5-5V5A-PD (terminal-block version) fed from its own fused branch off the 12 V distribution block, 5 A ATO fuse. It does real USB-C PD, so the Pi 5 runs at full performance with its overvoltage protection intact. Mean Well SD-25A-5 / SD-15A-05 GPIO-powered alternates are in the Integration Procedure
Display power
The display’s own power cable: red to Pi pin 2 (5 V), black to Pi pin 6 (GND)
UART link
Pi pin 8 (GPIO14 TXD) → Teensy pin 0 (RX1); Pi pin 10 (GPIO15 RXD) → Teensy pin 1 (TX1); plus a GND wire between the boards
USB audio
A USB cable from the Teensy’s own USB port to a Pi 5 USB-A port, with the firmware built as “Serial + MIDI + Audio”. Check that the Teensy’s VUSB–VIN link is cut first, so the Pi can’t back-feed 5 V into the main board
Mouse
Any wired USB mouse; a USB rotary encoder is optional for the web remote
Cooling
Official Raspberry Pi 5 Active Cooler, fitted (12 Oct 2026)
CheckTeensy pins 0/1 are only free if your main board uses the Voltage reversal prevention power option. The alternate Shutdown routine activation option (ATtiny85) uses the same two pins, and every other Teensy hardware UART is already taken on this board.
Never tie the Pi’s 5 V to the Teensy board’s own 5 V regulator. The two share a ground only.
UART connections
On the T41 main board: the PiLink wires plug into the empty ATtiny85 socket in the unused “Shutdown activation” section, which is wired to Teensy pins 0 and 1On the Pi 5 (on the bench, on the back of the Touch Display 2): UART wires and the display’s red/black power leads on the GPIO header, and the Touch Display ribbon
Main board schematic
T41 Main Board schematic V012.6 (select to open the PDF)
UART link
921,600 baud on the Teensy’s Serial1, with a 1 KB transmit buffer so a whole spectrum frame fits.
Teensy → Pi
Message
Rate
Carries
STATUS
10 Hz
Frequency, band, mode, TX/RX, power, filter and passband edges, keyer WPM, SAM offset, the visible spectrum span, the band’s legal limits and (V1.0.15) where the Menu is
SMETER
20 Hz
Signal level in 0.1 dB steps
SPECTRUM
~15 fps
512 bins, one byte each, scaled with the Teensy’s own spectrum scale and floor settings
AUDIO_SPECTRUM
~15 fps
The live audio-FFT bars
SETTINGS
2 Hz
Everything on the Settings pane, the firmware version, Decode on/off, which home layout is showing, and the spectrum scale, floor and fill settings
PARAMETER
10 Hz
The red “Label: value” box, only while a Menu setting is being adjusted
RXIQ_CAL
10 Hz
The Receive IQ calibration screen, while it’s open
BIT_RESULTS
2 Hz
I2C BIT test pass/fail per board, while that screen is open
EQUALIZER
10 Hz
The Audio Equalizer screen (V1.0.26)
TXIQ_CAL / FREQ_CAL / POWER_CAL
10 Hz on screen, 2 Hz off
The Transmit IQ, Frequency and Power calibration screens (V1.0.30)
WATERFALL
~15 fps
The radio’s own colour for every waterfall point, so the Pi’s waterfall matches the T41 (V1.0.32)
CW_DECODE
10 Hz decoding, 2 Hz off
Decoded CW text, WPM and the CW settings page values (V1.0.33 / V1.0.34)
Pi → Teensy
Message
Carries
Purpose
VIRTUAL_BUTTON
One button id
A click, fed into the same button queue as the front panel
VIRTUAL_ENCODER
Knob + direction
One click of the Filter, Volume, Tune or Fine-tune knob, exactly like turning the real encoder
VIRTUAL_BUTTON_REPEAT
Button id + count
Presses the same button several times in one go, so jumping several steps in a dropdown is near-instant
MENU_SELECT
Menu category + item
Jumps straight to a Menu item (V1.0.28)
HEARTBEAT
—
Lets the Teensy notice when the Pi goes away
VIRTUAL_KEY
Key down / key up
The Pi’s on-screen CW Key, handled like a straight key. Re-sent every 300 ms while held; the Teensy lets go after 1 s without one (V1.0.35)
A bad CRC drops the frame and the receiver scans ahead for the next 0x7E 0xA5. The Teensy parses one byte at a time so it never holds up the main loop.
Software
Teensy:PiLink.h / PiLink.cpp in the Mustang 2 sketch, started from InitializePiLink() and polled every pass of the main loop.
Pi: Raspberry Pi OS (64-bit, with desktop) running radio_ui.py, a full-screen Tkinter app, with pilink_client.py handling the protocol web_relay.py serving the browser remote and audio_relay.py passing the receive audio to it. It starts at boot as a user systemd service, and the SD card runs read-only so the Pi survives the radio’s power being switched off abruptly.
Firmware changes need the Teensy reflashed; Pi-only changes just need the PiDisplay folder copied to the Pi and radio_ui.py restarted. The full wiring, OS setup and test checklist are in the Integration Procedure below.
Changelog
Mustang 2 firmware and Pi display, newest first. The version on the Teensy’s Settings pane is what’s actually running.
Mustang 2 V1.0.50, 12 Oct 2026 Current download
Front Panel Test (Menu > Front Panel Test, or from the T41’s own Diagnostics menu/front panel): every one of the 22 front-panel buttons lights up on the Pi and both web remotes as it’s pressed on the radio, and the 4 encoders (Volume, Filter, Center tune, Fine tune) show their running turn count and direction — a quick way to check a front panel after reassembly without an oscilloscope.
The other four Diagnostics board tests (BPF, LPF, RF, USB serial) are now no-ops on this firmware build: they briefly touched the BPF/LPF/RF board drivers, I2C reads and the SWR bridge in a way that reintroduced the USB-audio timing glitch this firmware exists to avoid, so they’ve been pulled rather than risk that regression. The new Front Panel Test is pure display with no hardware access, so it didn’t have that problem and could stay real.
Pi, 12 Oct 2026 Current
Menu > Settings: a Global Settings window for app-wide values — Call Sign (the name badge on the Pi’s own screen), Local Time Zone (quick-pick US zones or type any IANA zone, used only for the Local Time readout below, independent of the Pi OS’s own system clock so FT8 timing can stay on UTC), and Pi Display Timeout (blanks the screen Off/1–30 min after no mouse/touch; any movement brings it right back). Saved to the Pi and effective immediately; room for more settings as the project grows.
The bottom-of-screen status strip next to the IP address now also reads Local Time: HH:MM and UTC: HH:MM.
View Log button on the Digital (FT8/FT4) screen — Pi touchscreen and both web remotes — opens a smaller read-only window listing what Log QSO (and auto-sequencing) have already written to the FT8 log (~/mustang_digital.adi, ADIF), newest first: Date, UTC time, Call, Grid, Band, Mode, RST sent/rcvd.
Fixed: on the web remotes’ Digital screen, Setup had been landing next to the clock instead of next to Back — a CSS spacing rule meant for the pair of them was on the wrong one of the two.
Pi, 12 Oct 2026
Digital (FT8/FT4) screen on both web remotes (/remote and /mobile), with full transmit control: a browser can call CQ, answer, and key the transmitter exactly as the Pi’s own screen can — same FT8/FT4 toggle, band buttons, clock, decode list, QSO panel and waterfall as the Pi’s screen below, reflowed to stack vertically on the phone page. The Pi’s screen and any number of browsers all drive and watch the same QSO at once; there is no lock between them, by the same design as every other control on these pages.
The hidden Pi OS top panel (revealed by hovering the very top edge of the fullscreen touchscreen) now only opens after the pointer has stayed in that hot zone for 3 s, instead of instantly — a quick accidental touch no longer pops it open.
Fixed: on firmware not yet reflashed to V1.0.49, the frequency/Band/Mode/Filter readout, the spectrum’s frequency ruler and filter-bandwidth highlight, and picking the right band/mode/demod from a dropdown had all gone dark/wrong, because the STATUS message grew by 2 fields in V1.0.49 and the Pi was rejecting the shorter pre-V1.0.49 frame outright. Both sizes are accepted now, so an updated Pi no longer has to wait on a reflash to work correctly.
V1.0.49
I/Q transmit VU meter on the Pi, in the same spot used for the retired State of Health pane — two bars, I and Q, with the same green/yellow/red thresholds as the T41’s own bars. Needs this reflash; until then the pane stays hidden, same as if the mic were never keyed.
Pi, 11 Oct 2026
CQ tries and Answer tries boxes on the Digital screen: how many times CQ repeats, or a QSO step repeats, before Auto gives up (0 = no limit; defaults 0 and 6).
SWR / power meter added below the Digital screen’s button grid, so it’s visible without needing the radio’s own display while running FT8/FT4; text turns red while transmitting, like the main screen.
Decode list gets a Dist Brg column: distance and bearing from your own grid to a CQ caller’s, once Setup has your grid set.
Pi, 11 Oct 2026
Digital (FT8/FT4) screen, reached from Menu: the Pi decodes and transmits FT8/FT4 itself, no PC or WSJT-X needed, using the same free decoder library (ft8_lib) the sBitx uses. UTC clock with a period-position bar and a clock-sync check, band buttons, a colour-coded decode list (tap a line to answer it), a QSO panel with CQ/Enable TX/Halt/Auto/Tune/Log QSO, and a waterfall you can tap to move your TX offset. Auto-sequencing works like WSJT-X and logs completed QSOs to ~/mustang_digital.adi (ADIF).
Needs the Serial + MIDI + Audio firmware build and the Teensy USB cable into the Pi (the same cable the web remote’s audio uses) — it switches DATA mode, frequency and PTT over the Teensy’s own CAT port.
RTC: an Adafruit DS3231 real-time clock keeps the Pi’s time accurate away from the internet, which FT8 needs within about a second.
See it running on 40 m below.
The Digital (FT8/FT4) screen working FT8 on 40 m
V1.0.39 – V1.0.41
Board tests (BPF, LPF, RF, Front panel, Board test/USB serial) added under Menu > Diagnostics on the T41 itself, then mirrored on the Pi with the same rows, live readings and Row ▲/▼ / −/+ / Select / Exit controls.
4 M removed everywhere (no transmit hardware on this radio); Power calibration’s band table trimmed to 160M–6M so it fits the screen again.
V1.0.36 – V1.0.38
Tune button (CW modes) on the Pi and both remotes for a steady carrier, up to 60 s. Power calibration target/Select-while-PTT fixes.
Calibration > Experimental: T41EVE IQ calibration, and Experimental TX IQ working on single-VFO radios. Auto no longer looks stuck on GEN when it finishes.
V1.0.35
On-screen CW Key on the Pi’s third toolbar row, shown only in CW mode: hold to key down (it turns red and reads “CW KEY”), let go for key up.
V1.0.29 – V1.0.34
Calibration > Transmit IQ, Frequency, Power and S meter level on the Pi and both remotes, with Exit and (Transmit IQ) Stop.
CW: decoded text under the waterfall and the radio’s CW settings page while Decode is on.
Waterfall in the radio’s own colours; brighter 2D and 3D blues; the frequency readout no longer shows through full-screen pages.
Powers up in DATA mode; the radio’s spectrum fill and PI Spectrum Fill both start off.
V1.0.26 – V1.0.28
Audio Equalizer screen on the Pi and both remotes (Edit RX / Edit TX, Exit, Save & Exit); menu picks jump straight to the item; “Load:” reading fixed.
New toolbar: Display, Audio, Mic and CW dropdowns; Vol is a button; three toolbar rows on the Pi with REC and SWR at the right edge; menus highlight the current choice.
Smooth 3D waterfall with 2D / 3D and speed settings; Freq Font styles (Nixie, VFD, Dot Matrix); Pi settings remembered across restarts.
Menu > Network on the Pi screen: change Wi-Fi networks, with an on-screen keyboard for the password.
DSP: on the readout line, Vol: in the Settings pane, TI: renamed CT:; arrow-key control of tuning, Filter and Volume.
V1.0.25
I2C BIT test screen on the Pi and both remotes; Menu items without a Pi/remote screen are greyed out there for now.
V1.0.23 – V1.0.24
Receive IQ calibration screen on the Pi and both remotes, with full control; the Pi screen adds Stop and Exit.
V1.0.21 – V1.0.22
Choppy audio fixed: the filled spectrum trace could stall the audio. New Menu > Display > Spectrum fill on/off on the radio, and a separate PI Spectrum Fill for the Pi and remotes.
V1.0.17 – V1.0.20
New Menu > RF Options > RX DSP Gain; Scale: and Floor: readouts; readout strip moved above a shorter spectrum trace; Menu > Display > Brightness for the Pi touchscreen; SWR/PWR on both web remotes.
V1.0.16
Jumping several steps in a dropdown (Zoom, Band, Mode and so on) is now near-instant.
Mustang Mobile phone page at /mobile with Tune / Fine Tune / Volume / Filter touch sliders.
V1.0.15
The Teensy now sends the Menu’s real position, so choosing a Menu item from the Pi or the browser always lands on the right setting instead of sometimes jumping back to Home (reflash needed).
V1.0.14
Live receive audio in the browser remote, with a Mute button.
Blue filter-bandwidth highlight on the spectrum, on the Pi and in the browser.
Desktop icons to start the radio app and shut down the Pi.
Browser remote control on the home network, with passkey, mouse-wheel tuning and USB rotary encoder support.
Tune and Fine-tune knobs can now be turned from the Pi or the browser (reflash needed).
Browser remote gains the audio spectrum, Settings pane and a real cascading Menu.
New BW (filter) dropdown, and a “Wheel:” indicator that hands the wheel back to tuning.
V1.0.13
Frequency ruler under the spectrum, with out-of-band ticks in red, like the Teensy’s own screen (reflash needed).
V1.0.12
“Select >” button on the Menu parameter box to confirm a value.
The Pi follows the Teensy’s secondary (“Toggle Layout”) home screen.
V1.0.11
Fixed: Menu → Display spectrum scale and floor now change the Pi’s spectrum too.
V1.0.10
Vol dropdown (Vol / AGC / Mic / Sidetone), with the mouse wheel adjusting whichever is selected.
Toolbar rearranged into two rows.
V1.0.9
Red “Label: value” box when adjusting a Menu setting, with the mouse wheel changing the value.
V1.0.8
Band dropdown replaces BAND +/−, plus Mode, Demod, Noise, Course Inc, Fine Inc, Decode, Home and a two-level Menu, all built from the firmware’s own tables.
Menu opens with cascading flyouts; larger touch targets.
V1.0.7
Fixed: REC/XMT could show XMT while receiving.
Spectrum fill and waterfall now use the Teensy’s own colors; Settings pane restyled to match.
V1.0.6
Settings pane now shows everything the Teensy’s does; the desktop panel appears when the mouse touches the top edge.
V1.0.5
Live audio-spectrum bars.
V1.0.3 – V1.0.4
Fixed: spectrum was a flat line, then empty (bigger serial buffer).
Waterfall now scrolls top to bottom like the Teensy’s.
V1.0.2 and earlier Baseline
The original PiLink link, S-meter and SWR/power panes.
Future
Already done since this page first went up: the hardware checkout, dropdown menus with the mouse, sending settings back to the Teensy (through button presses and knob turns), the rest of the Home screen, band and mode names, real button ids, the browser remote on the home network and live audio to it, matching the firmware source to the Pi software, a self-contained Digital (FT8/FT4) screen on the Pi — no PC or WSJT-X needed, a Front Panel Test, and fitting the Pi 5 Active Cooler — see the Changelog above. Still to come:
Finish the browser remote Planned
State of Health isn’t on the web page yet. The Digital (FT8/FT4) screen already gives the browser full transmit control (12 Oct 2026), deliberately without a PTT time-out or a lock against the Pi’s own screen — still worth adding, now for a real transmitting feature rather than a hypothetical one. Voice/CW transmit from the browser (beyond the on-screen CW Key, Pi-only) remains undone. Check the rules for remote operation of your station before relying on any of this away from the shack.
Port the remaining Menu screens Planned
Diagnostics > Restore receive EQ and Buffer print, and EEPROM > Print data to Serial, are greyed out on the Pi and remotes until each gets its own screen. (The Calibration screens were done in V1.0.30.)
Remote access from outside the home Idea
Only with encryption (TLS) and a stronger passkey, or through a VPN, never by simply forwarding the port.
Accurate time for FT8 Idea
FT8 needs the clock within about a second. NTP works on the home network; for portable use, add the Pi 5’s RTC battery or a small GPS.
Saving Pi settings
Menu > Settings (12 Oct 2026) gave the Pi its own small settings file (call sign, local time zone, display timeout), written on Save. Still open: the Pi’s SD card is read-only so an abrupt power-off can’t corrupt it, and these writes go around that — EEPROM → “Save data to storage” on the Teensy could instead tell the Pi to save, through a new commit-settings message and a read-only setup that can be briefly unlocked without a reboot.
Version check between the boards
The Pi shows the firmware version, but nothing stops a mismatch. A short hello message with a protocol version would let the Pi warn clearly when its code doesn’t match the Teensy firmware.
Ethernet, if the UART runs out Option
The link has grown to fourteen downlink messages. If it ever gets tight, the Teensy 4.1’s Ethernet header (PJRC Ethernet kit + QNEthernet) straight to the Pi’s Ethernet port is the upgrade path. It replaces the whole link, so it’s a project of its own.
RF noise check
The Pi 5 and a second display are new noise sources right next to the receiver. Listen for birdies on every band with the Pi running, and plan for ferrites on the USB, DSI and power leads and a shield like the Display Shield.
Mounting in the case
The Pi 5 Active Cooler is fitted and running (12 Oct 2026). Still to publish: the Pi mount and touchscreen adapter plate STLs here, once they’re fit-checked.
User guide · Mustang 2 V1.0.50 · /remote V1.0.76 · /mobile V1.0.66 · as of 15 Oct 2026
Remote Access
How to reach the radio from a browser on the home network, log in, and drive it: what every control does, tuning with a mouse wheel or a USB rotary encoder, live audio and the Mute button, and what to try if something looks stuck.
The same radio from four places at once: the Pi Touch Display (left), the T41’s own screen (back), /mobile on an iPhone (center) and /remote in a laptop browser (right)
Connecting
The web remote is served directly by the Raspberry Pi 5 — no separate web server, app or account needed. On any computer, tablet or phone connected to the same home network as the radio, open a browser and go to:
http://<pi-hostname>:8765/
Replace <pi-hostname> with the Pi’s network name (for example mustang.local) or its IP address. The page asks for a passkey before it connects — this is set in the Pi’s config.py and is separate from any home network Wi-Fi password. Once you’re logged in, the page starts mirroring the radio immediately.
The web remote (V1.0.15) at 14.074.360 on 20 m, zoomed to 16× on the FT8 signals — readout strip across the top of the spectrum, blue filter highlight, live waterfall
On a phone: use the phone page, Mustang Mobile, at http://<pi-hostname>:8765/mobile. The toolbar becomes a six-column grid of buttons that open as the phone’s own pickers, the Menu flyouts open with a tap, and four touch sliders at the bottom replace the mouse wheel (see Tuning).
Mustang Mobile, with the touch sliders at the bottomMenu → DisplayBand as a native iPhone pickerCourse Inc tuning step
Browser support: any modern desktop or mobile browser works — Chrome, Firefox, Edge and Safari have all been used with it. No plugins, extensions or app install are needed.
Layout & panes
The page mirrors the same panes as the radio’s own screen and the Pi’s Touch Display, arranged the same way:
VFO / frequency readout across the top, with band and mode next to it and REC/XMT showing which state the radio is in.
Toolbar of dropdown controls just under the frequency (see below).
S-meter, live at 20 Hz.
Spectrum & waterfall: the live trace fills green through yellow to red by signal strength, the receive passband is highlighted in blue, and a frequency ruler runs underneath with out-of-band edges marked in red. The waterfall can be flat (2D) or a 3D view where each new line rolls back into the distance and strong signals stand up as ridges: pick it under Display > PI Spectrum > PI Waterfall, and set how fast it moves with PI Waterfall Speed.
Audio spectrum: the live audio-FFT bars with the passband edges and CW filter markers.
Readout strip just above the spectrum: AGC, DSP, Scale, Floor, Zoom, CT (course tune increment), FT (fine-tune increment) and Noise.
SWR / PWR readout next to REC/XMT.
Settings pane: RX/TX Atten, AutoNotch, Vol, Antenna, Rate, Temp, Load and Power, plus the firmware version. With CW Decode on it switches to the radio’s CW settings page, and the decoded text runs in a strip along the bottom of the waterfall. The audio spectrum pane shows the current Filter width.
/remote on a laptop with the 3D waterfall: FT8 on 20 m at 14.074.400, zoomed 16×, the signals standing up as orange and red ridges inside the blue filter highlight/mobile V1.0.55 with the same 3D waterfall
Toolbar & Menu
Every toolbar dropdown drives the radio exactly as if you’d pressed the matching front-panel button or turned the matching knob — there’s no separate remote-only logic to learn.
Display, Audio, Mic, CW — copies of the radio’s own Display, Audio Options, Microphone and CW Options menus, next to Menu.
Vol — a button: click it and the mouse wheel and all four arrow keys change the volume.
Filter — Hi Cut / Lo Cut; once picked, the mouse wheel and the Left/Right arrow keys move that edge.
Band, Mode, Demod, Course Inc, Fine Inc, Zoom, Noise, Decode, Home — one click each, built from the firmware’s own tables so the choices always match what’s actually loaded on the radio.
Menu — a cascading popup like a desktop app: click Menu, then a category, and its options fly out to the side. Picking a setting opens the same red “Label: value” box the radio’s own screen shows, with the mouse wheel changing the value and a “Select >” to confirm.
Calibration and test screens — every Menu > Calibration item, the Audio Equalizer and Menu > Diagnostics > I2C BIT test open right in the page; arrow keys adjust the main values on the calibration screens. The few items that don’t have a remote screen yet are greyed out and can’t be picked for now; they still work from the radio’s front panel (the Mustang Manual marks which ones).
Mute — sits with the other dropdowns and turns red while muted. It only silences audio in your own browser tab; it doesn’t touch the Pi’s own speaker, other people viewing the page, or what the radio is actually receiving.
A “Wheel:” status pill shows what the mouse wheel currently controls — Tune only, Volume, or Filter. Clicking Vol, or picking Hi Cut / Lo Cut from Filter, claims the wheel (and the arrow keys) for that knob; click the pill to release it back to tuning-only.
The cascading Menu: pick a category, then an option from its flyout — Display and its Spectrum submenu shown here
Tuning
Two ways to move the VFO from a browser:
Mouse wheel over the frequency readout or the spectrum — turns the main tuning knob. Hold Shift while scrolling for fine tuning.
A USB rotary encoder, configured (in its own software or a keyboard-emulation mode) to send arrow or page keys — drives the VFO the same way regardless of where the mouse pointer is.
On the phone page, use the four sliders at the bottom: Tune, Fine Tune, Volume and Filter. Drag one away from the center to turn that knob, further for faster; it springs back to the center when you let go. The Volume label shows which of Vol/AGC/Mic/Sidetone it will change, and the Filter label shows Hi Cut, Lo Cut, or “Menu” while a Menu setting box is open.
Tuning always works this way, independent of whatever the plain mouse wheel is currently claimed for (Volume or Filter) — the two knobs don’t interfere with each other.
The rotary dial at its Large size, centeredSized down and moved to the lower-right corner — out of the way while still reachableMenu → Rotary Dial: pick its size and where it sits, saved per-browser
Audio & Mute
When the Teensy’s USB audio is wired to the Pi, the web remote streams live receive audio to every logged-in browser — uncompressed, over the same connection as everything else, with no codec or plugin to install. Playback starts automatically once you’re logged in (browsers require a user click before audio can start, which logging in already provides).
The Mute button in the toolbar turns red while muted. It is local to your browser tab only: it doesn’t stop the Pi from sending audio, and has no effect on the radio, the Pi’s own speaker, or any other viewer’s audio.
If you don’t hear anything: the Teensy’s USB audio cable to the Pi may not be connected, or the Pi’s audio software isn’t installed. Either way, nothing else on the page is affected — video/telemetry keeps working normally.
Security
LAN onlyThe web remote has no encryption — it’s plain ws://, not wss://. Don’t forward port 8765 through your router to reach it from outside your home network. The passkey stops casual access on the LAN; it isn’t a substitute for TLS against a hostile network.
Reaching the radio from outside the home would need real encryption and a stronger passkey, or a VPN back into the home network — never a plain port-forward. This is tracked as a future item on the Secondary CPU page.
Troubleshooting
Page won’t load
Confirm the computer is on the same network as the Pi, and that radio_ui.py is running on the Pi (it also runs the web server). Double-check the hostname/IP and that :8765 is included in the URL.
A recent change doesn’t seem to show up
Browsers can cache the page. Do a hard refresh instead of an ordinary reload: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac), or open the browser’s developer tools and enable “Disable cache” while the page is open.
Login asks again every time
Normal — the passkey isn’t stored between sessions on purpose.
Menu pick jumps back to Home
Fixed in V1.0.15, which sends the Menu’s real position to the Pi. Check that the Settings pane shows Mustang 2 V1.0.15 or later (currently V1.0.34); if not, reflash the Teensy.
No audio
See Audio & Mute — usually a disconnected USB audio cable or missing Pi-side audio software, not a browser problem.
CW page shows “--”
WPM and SNR fill in once the decoder locks, and Dit, AvgD/D, Upd Age and Coeff only while in CW receive with Decode on — the same as on the radio. If AT Grace, Mode and Key Type also show “--”, the radio needs firmware V1.0.34.
Spectrum/waterfall frozen
Check the Pi’s own screen first — if it’s frozen too, the issue is the PiLink link or radio_ui.py itself, not the browser page.
Known limits
State of Health isn’t on the web page yet.
A few Menu items are greyed out until they get their own remote screen (Diagnostics > Restore receive EQ, Buffer print; EEPROM > Print data to Serial).
No PTT time-out or screen/browser lock yet — two people driving it (or the Pi’s own screen and a browser) at once can conflict. This now applies to the Digital/FT8 screen too, which deliberately has full transmit control from a browser (12 Oct 2026) with no lock against the Pi’s own screen.
No general voice/CW transmitting from a browser: the on-screen CW Key (firmware V1.0.35) is on the Pi’s own screen only. The Digital (FT8/FT4) screen is the one exception — full transmit control from either web remote, added 12 Oct 2026.
LAN only, as above — no remote access from outside the home network.
See the Secondary CPU project page for what’s planned next.
Web Remote Changelog
The desktop/laptop page (/remote), newest first. This page has no on-screen version label of its own — check Menu > About for its current version, which now reads Mustang Remote V1.0.76. Unless noted otherwise, every entry here needs only a re-sync of PiDisplay/ and a hard refresh of the browser — no Pi restart or Teensy reflash.
V1.0.76, 15 Oct 2026 Current
The small version number in the corner of the Settings box is now this page’s own hardcoded version, not the T41’s live firmware version. It used to show the Teensy’s own version there, unlabeled — easy to mistake for the page’s own version, especially since the phone page dropped that same field back in September in favor of its own label. The T41’s firmware version is still available in Menu > About.
V1.0.75, 15 Oct 2026
Touch +/− for Menu parameters. On a phone or tablet with no keyboard or mouse, a Menu setting like Spectrum scale could be opened (“Select >”) but never actually changed — the value itself only moved with the mouse wheel or arrow keys. New −/+ buttons sit right next to “Select >” and send the same adjustment, the same idea as the Equalizer screen’s existing Level −/+ buttons. Fixes every Menu parameter that uses this box, not just Spectrum scale.
V1.0.74, 15 Oct 2026
Display dropdown cleaned up. Spectrum smoothing, decay, trace smoothing and shadow on/off removed — none of them are carried over PiLink to the Pi, so they only ever affected the T41’s own screen and did nothing here. Spectrum floor, Spectrum scale, Spectrum fill, Brightness, Freq Font and the PI Spectrum group remain, since those do reach the Pi or are Pi-specific already. The firmware items themselves are untouched and still reachable from the T41’s own front panel.
V1.0.73, 15 Oct 2026
CT:/FT: now shows the tuning increment, not the frequency. The rotary dial’s center readout reads what Course Tune/Fine Tune is actually set to (“CT: 100 kHz”, “FT: 250 Hz”), pulled straight from the same Course Inc/Fine Inc selectors the toolbar uses, so it can’t drift out of sync no matter which control changed it. The live frequency keeps its own line just below.
V1.0.71 – V1.0.72, 15 Oct 2026
Two fixes to the rotary dial added in V1.0.70: the CT/FT mode pills lived inside the tap-to-close center circle, so every tap on them closed the dial instead of switching mode — moved onto two full-size Course/Fine buttons below the dial instead. The center readout’s text also wrapped and lost its centering at small/medium dial sizes on a wide frequency string; split into two independently-centered lines that fixed it at every size.
V1.0.70, 15 Oct 2026
Virtual rotary dial added for Tune/Fine-tune on this page. A new “Dial” toolbar button opens a draggable rotary dial that floats over the page (not a modal — the rest of the page stays usable). Dragging it sends the same tune/fine-tune clicks the mouse wheel already does, just driven by drag angle. A new Menu > Rotary Dial settings page picks its size (Small/Medium/Large) and on-screen position, saved per-browser since it’s a display preference, not a radio setting.
V1.0.69, 15 Oct 2026
Log viewer: checkbox select + Delete, for removing a bad QSO. The digital (FT8/FT4) log table’s first column is now a checkbox per row, with a Delete button next to Lookup QRZ that removes every checked contact (after a confirmation) and refreshes the log on every connected screen, not just the one that pressed Delete.
V1.0.68, 14 Oct 2026
New About entry under Menu, showing the T41’s live firmware version alongside the Pi’s and both web remotes’ own versions, plus a link to boblance.net for downloads.
Digital (FT8/FT4) moved off the Menu dropdown and into the bottom of the Mode dropdown; the greyed-out, never-enabled Menu > Tune entry was removed (the Tune toolbar button is the only Tune control now).
V1.0.67, 14 Oct 2026
The digital log viewer gained Name/Country columns, a Lookup QRZ button for backfilling older contacts, a Refresh button, and CSV/PDF/ADIF export links — matching the Pi’s own screen.
V1.0.61 – V1.0.66, 9–11 Oct 2026
4M removed from the Band dropdown and calibration tables (the T41 has no 4 m hardware); a new Tune toolbar button gives a steady carrier in CW modes for up to 60 s; the Receive/Transmit IQ calibration screens show their Auto status (running/done/stopped); Menu > Calibration gained an Experimental flyout for the six T41EVE IQ routines; the CW settings page dropped its now-redundant Vol:/AGC: fields.
V1.0.55 – V1.0.60, 4 Oct 2026
Menu > Calibration’s S meter level, Frequency, Transmit IQ and Power screens enabled; the waterfall switched to the T41’s own live colors and got several brightness passes to match the Pi’s screen; CW receive with Decode on shows a scrolling decoded-text strip along the bottom of the waterfall, with WPM.
V1.0.45 – V1.0.54, 2–3 Oct 2026
New Audio, Mic and CW toolbar dropdowns (copies of the T41’s own menus); Vol became a plain button pointing the mouse wheel/arrow keys at Volume; a trackpad bug that made Filter Hi/Lo Cut jump around was fixed; arrow keys were wired up to reach the Filter knob; the Nixie-tube frequency font was redrawn to look like real tubes; and the Menu/Display items started marking the current selection with a green check.
V1.0.37 – V1.0.44, 30 Sep – 2 Oct 2026
A full-screen Receive IQ calibration screen was added, with Stop/Exit controls; the SWR/PWR readout and the missing “(USB)” demod suffix were fixed; the spectrum pane was shrunk and its readout strip moved above it; Menu > Display gained a 3D waterfall option with an adjustable speed, and was regrouped into sub-menus (Spectrum floor, scale, shadow, fill, Brightness, PI Spectrum) without changing any of the T41’s own menu indices.
V1.0.21 – V1.0.36, 26–30 Sep 2026
A mis-clocked audio playback rate that caused choppy sound was tracked down and fixed; the readout strip above the spectrum grew Scale:, Floor: and RX DSP Gain entries; toolbar dropdowns stopped overwriting their own fixed labels with the current selection; S-meter clipping and frequency-ruler/waterfall layout bugs were fixed; the spectrum trace’s fill color was matched exactly to the waterfall’s own gradient; and a full-screen Audio Equalizer overlay and the Menu > Diagnostics > I2C BIT test screen were added.
V1.0.14 – V1.0.20, 25–26 Sep 2026 Baseline
The original LAN-only browser remote: mouse-wheel/USB-encoder tuning, the live audio spectrum, a Settings pane, a cascading Menu, live RX audio with a local Mute button, and the blue filter-bandwidth highlight over the spectrum — gated by a passkey set in the Pi’s config.py. The phone-specific layout that grew alongside this page was split out into its own file, remote_mobile.html (see the Mobile Remote changelog below), once it became clear a media-query alone couldn’t reliably tell a phone from a laptop.
The phone/tablet page (/mobile, “Mustang Mobile”), newest first. This page carries its own on-screen version label, currently Mustang Mobile V1.0.66. Unless noted otherwise, every entry here needs only a re-sync of PiDisplay/ and a hard refresh of the phone’s browser — no Pi restart or Teensy reflash.
V1.0.66, 15 Oct 2026 Current
Same fix as the desktop remote’s V1.0.75: −/+ buttons added next to “Select >” in the Menu parameter box, so a value like Spectrum scale can be changed by tapping instead of needing a mouse wheel or arrow keys.
V1.0.65, 15 Oct 2026
Same Display-dropdown cleanup as the desktop remote’s V1.0.74: Spectrum smoothing, decay, trace smoothing and shadow on/off removed — no PiLink-transmitted equivalent, so they never did anything here.
V1.0.64, 15 Oct 2026
Same log viewer checkbox select + Delete as the desktop remote’s V1.0.69, for removing a bad QSO from the digital (FT8/FT4) log.
V1.0.63, 14 Oct 2026
New About entry under Menu, same as the desktop remote’s V1.0.68; Digital (FT8/FT4) moved into the Mode dropdown; the greyed-out Tune entry removed from Menu.
V1.0.61, 14 Oct 2026
The digital log viewer gained Name/Country columns, a Lookup QRZ button, a Refresh button, and CSV/PDF/ADIF export links, matching the Pi’s own screen.
V1.0.55 – V1.0.59, 9–11 Oct 2026
4M removed from the Band dropdown and calibration tables; a new Tune button for a steady CW carrier; calibration Auto status and the Experimental IQ flyout; the CW settings page dropped its redundant Vol:/AGC: fields.
V1.0.46 – V1.0.54, 3–4 Oct 2026
A round of phone-specific layout fixes after the new Audio/Mic/CW dropdowns made the page taller than the screen — the toolbar became a 6-column grid and the Filter slider became usable again; Menu > Calibration’s screens were enabled, sized for a phone; the waterfall switched to the T41’s own live colors with several brightness passes; and CW receive with Decode on gained the scrolling decoded-text strip.
V1.0.39 – V1.0.45, 2–3 Oct 2026
New Audio, Mic and CW toolbar dropdowns and a plain Vol button, matching the desktop remote; arrow keys wired up to reach the Filter knob; the Nixie-tube frequency font redrawn; Menu/Display items started marking the current selection; and Display got its own toolbar dropdown, built as an accordion so its sub-menus fit a phone screen.
V1.0.27 – V1.0.38, 30 Sep – 2 Oct 2026
The Menu > Diagnostics > I2C BIT test screen and a full-screen Receive IQ calibration screen were added; the SWR/PWR readout and the missing “(USB)” demod suffix were fixed; a mis-clocked audio playback rate that caused choppy sound (more reliably hit on phones than on the desktop page) was tracked down and fixed; the spectrum pane was shrunk and its readout strip moved into its own row; and Menu > Display was regrouped into sub-menus, opening inline (accordion-style) so four levels of nesting still fit a phone screen.
V1.0.18 – V1.0.26, 30 Sep 2026
The readout strip above the spectrum grew Scale:, Floor: and RX DSP Gain entries, its font reduced to fit a phone width; Brightness became a single flyout instead of four flat entries; the spectrum trace’s fill color was matched to the waterfall’s own gradient; and the Audio Equalizer screen was added.
V1.0.6 – V1.0.17, 26–27 Sep 2026
A run of phone-only layout fixes: toolbar dropdowns no longer overwrote their own fixed labels with the current value, the toolbar grid was rebuilt after it broke on an actual phone, the S-meter’s dBm reading and the frequency-scale ruler were fixed for real screen sizes, the on-screen version label stopped colliding with the Teensy’s own version readout (which was then dropped from this page entirely, see the Baseline entry below), and the page gained proper top/bottom safe-area padding for phones with a notch or home indicator.
V1.0.1 – V1.0.5 and earlier, 26 Sep 2026 and before Baseline
The phone experience started as @media (pointer: coarse) rules bolted onto the desktop page — touch jog sliders for Tune/Fine Tune/Volume/Filter, a reordered status block, and a 4-column toolbar grid — until that media query turned out to also match the user’s own laptop trackpad and reflow the desktop page by mistake. The phone experience became its own file, remote_mobile.html, served at /mobile, with its own version label starting at V1.0.1. The desktop page (remote.html) was reverted back to a plain, pointer-detection-free layout the same day.
Step-by-step setup instructions and procedures for the radio and its secondary CPU, collected here as they’re written. More will be added as the project goes on.
RTC Setup (DS3231)
How to add a battery-backed real-time clock to the Mustang 2’s Raspberry Pi 5, so it keeps accurate time in the field with no internet connection — needed for FT8, which requires the Pi’s clock to be within about 1 second of correct. Covers wiring an Adafruit PiRTC DS3231 breakout to the Pi’s GPIO header, including how its six unlabeled pins were identified, plus the setup script that keeps the clock synced.
Onboard RTC vs. DS3231: the Pi 5 has its own built-in real-time clock, but it only survives a power-off if a battery is added to its J5 connector — a small rechargeable cell (such as a LIR2032), not a plain coin cell. That cell self-discharges fairly quickly, holding time for only days to a few weeks unpowered. The DS3231’s own replaceable CR1220 coin cell holds accurate time for months to years unpowered instead, which matters more for a radio that sits unused between trips. If the radio gets powered up often enough to keep the Pi’s own battery topped off, the onboard RTC alone is simpler and needs none of the wiring or setup below.
How to wire an Adafruit TS3USB30 breakout and a DPDT toggle so the Teensy’s single Micro-USB port can be handed off between the Raspberry Pi and a programming cable with one flip — no unplugging cables inside the case. Covers the board’s actual silkscreened pinout (PORT1/USBHOST/PORT2), why VBUS needs its own switch pole instead of the board’s built-in pass-through, and the full wire-by-wire connection table.
How to build a simple 2-input, 1-output 3.5 mm SPDT audio selector switch, so the T41’s front-panel MIC jack can be fed by either a real handheld mic or a Pi 5 USB audio adapter’s output, one at a time. Covers why a passive Y-splitter doesn’t work for this (it wires both sources together permanently, loading each other and risking the jack’s own mic-bias voltage backfeeding into the Pi’s sound card), the parts list, a wiring diagram, and step-by-step build and continuity-check instructions.
Feasibility review and wiring plan for mirroring the N7DDC ATU-100 Extended Board’s OLED readout (PWR, SWR, L, C) onto the Pi 5’s own screen and both web remotes, via a passive tap on the ATU-100’s existing I2C display bus — no changes to the ATU-100’s PIC firmware. Covers why the bus’s slow bit-banged timing and the firmware’s known font table make true text decoding realistic (not just a pixel mirror), the mandatory 5V→3.3V level shifter, why the board needs 12V straight from the T41’s existing rail rather than a 5V supply, the parts list, a wiring diagram, and the recommended build order.