KC2KVY · Firmware project · In progress

UV Pager

Two-tone fire/EMS paging for the Quansheng UV-K5 V3 and UV-K1, with a trial build for the older UV-K5 V1. Mark a memory channel as a pager channel, and the radio decodes Quick Call II pages in the background and alerts on the departments you watch. There is no app to launch.

Radios UV-K5 V3 · UV-K1 · V1 (trial)Base F4HWN (armel)Config CHIRPUpdated 2026-10-21

Status: built and bench-tested on a PC, not yet run on a radio. The firmware compiles, and its decoder reports the same pages as the reference model on 149 test inputs. The CHIRP driver round-trips the watch list byte for byte.

A trial build for the V1 radios (UV-K5, UV-K5(8)) also compiles. It uses the radio chip's own tone detector and has had no testing at all; its first real pages on air are the test (section 06).

Input level, low-tone response, and the alert beeps during receive can only be checked on hardware. The test builds in section 07 are for trying exactly that: use them at your own risk, and back up your radio first.

01What it does

Each memory channel gets a pager mode, set in CHIRP:

Off

A normal channel. Nothing is decoded.

Alert

The channel is heard as usual. A page for a watched department adds the alert on top.

Silent

The channel stays quiet. A watched page opens the speaker so the dispatch is heard. It stays open for the monitor time (60 s by default), and longer while the channel is busy.

On a watched page:

  • the backlight comes on;
  • the department's name is shown, inverted, over the main screen until EXIT;
  • the green LED blinks;
  • three beeps sound once the tones are over.

The beeps wait because stacked pages follow at once, and a beep in the middle would cut off the next department's A tone. EXIT acknowledges the page and returns a Silent channel to quiet.

The watch list holds up to 150 departments. Each one has a name, an A tone, a B tone (or a single long tone), minimum lengths and a tolerance.

A tone B tone page recognised A ≥ 0.6 s, then B ≥ 0.6 s beeps dispatch heard Silent: speaker opens here 0 s1 s4 s
A typical Quick Call II page. The match fires once B has lasted its minimum. The alert follows when the tones end.

02Which radios

RadioMCU / RFCan the firmware hear audio?Pager
UV-K5 V3, UV-K1PY32F071 / BK4829Yes: RX audio reaches PA4, which is read on ADC channel 4Supported
UV-K5, UV-K5(8), UV-K6, 5R Plus (V1)DP32G030 / BK4819No: there is no audio path to an ADC pin, and the BK4819 only reports levelsTrial build, using the chip's tone detector
On V1, the BK4819's built-in SelCall tone detector does the decoding instead (section 06). Firmware for one revision does not run on the other.

Sellers mislabel these radios. Look for "V3" or "UV-K1" in the listing. Listings that say "UV-K5(8)" or "K5(99)" are usually the older V1 board.

03How it decodes

While a pager channel is receiving, a hardware timer samples the receive audio at 9.6 kHz. The audio is picked up before the speaker amplifier, so a Silent channel can be decoded with the speaker off. When the channel isn't receiving, the sampler is stopped and the radio's power saving is unchanged.

  1. Zero crossings. The decoder times rising zero crossings to 1/256 of a sample, using hysteresis and linear interpolation. Only rising-to-rising periods count, so CTCSS under the tone and DC offsets cancel out.
  2. 40 ms blocks. A block counts as a tone when its periods agree to within a quarter period and its level clears a gate. Its frequency is periods ÷ time.
  3. Segments. Consecutive blocks within 1.5% of each other join a segment. Averaging them gives the precision, and a segment survives one bad block.
  4. Matching. A page is an A segment of at least its minimum length, followed straight away by a B segment of at least its minimum, each within tolerance (2%). A long tone is a single long segment. A tone that completed one page can't also be the A of the next, which avoids false pages when pages are stacked.

All the arithmetic is 32-bit integer. The whole feature adds about 2.9 KB of flash and 128 bytes of RAM to the firmware, and the watch list is read from flash.

04Bench results

TestResult
Frequency errorWorst 0.11%, median 0.01%, at 15 dB SNR across 186 distinct tones from 102 to 2875 Hz. The tolerance is 2%.
Pages foundAll of them at 20 dB SNR and above, about 80% at 12 dB, and none at 8 dB. This covers short (0.65 s) and long (1 s + 3 s) tones, with and without CTCSS, and ±1% transmitter error.
Wrong departmentNone in any test run
False pagesNone in 2.9 hours of recorded dispatch traffic. Every page it reported there was a real one, confirmed by FFT.
Firmware vs modelThe same pages on all 149 test inputs
The tests used synthetic pages built from 726 real A/B pairs, plus recorded traffic. Weak signals are the known gap. Departments whose tones lie within 2% of each other match together.

05Setting it up

  1. Flash the Pager build with UV Studio (web-based; works in Chrome or Edge over the programming cable). Back up your calibration first: UV Studio does that too.
  2. In CHIRP, use File → Load Module to load the Pager driver. The radio model is UV-K1 & UV-K5 V3 (F4HWN Pager).
  3. Download from the radio. In the Pager tab, set the monitor time, beeps on or off, and up to 150 departments.
  4. On the dispatch channel's memory, set Extra → Pager to Alert or Silent, then upload.

If you keep your departments in tones.cfg files (INI sections with atone, btone, lengths, tolerance and description), a script copies them into a saved CHIRP image. It reads only the tone fields:

python3 cfg2pager.py radio.img tones.cfg --match "Delmar|Elsmere" --list   # preview
python3 cfg2pager.py radio.img tones.cfg --match "Delmar|Elsmere"          # write, then upload in CHIRP

The watch list is stored with the radio's other settings, so it moves with the firmware's multiboot config banks. A radio without the Pager edition simply ignores it.

06The V1 trial build

The V1 radios (UV-K5, UV-K5(8), UV-K6, 5R Plus) can't sample audio, so this build hands the job to the BK4819 chip. Its SelCall detector holds 16 programmable tones and reports which one it heard. The firmware times those reports and matches them to the watch list with the same A-then-B rules. The build fits in the V1's 60 KB by leaving out the spectrum analyzer, FM radio, AirCopy and screenshots.

  • Marking channels. V1 has no spare channel bits, so the channel name decides: a name starting with * is an Alert channel and one starting with ! is a Silent channel. That works with stock CHIRP or on the radio.
  • Watch list. It is built into the firmware and limited to 16 distinct tones, which is enough for several departments.
  • Accuracy. The chip places each tone with an 8-bit coefficient. Above about 600 Hz that is fine, but below it neighbouring QC2 tones look the same to the chip: 349.0 and 368.5 Hz differ by one step. Its bandwidth is undocumented, so neighbouring departments may be confused. The table generator warns about tones it can't separate.
  • Timing. The chip says which tone it heard but not when the tone ends, so the B and long-tone lengths are measured from the first detection. The beeps wait until the transmission ends.
  • On-air readout. On a pager channel, the bottom of the screen shows each detection, for example PG 707.3 x3. The first real pages will show how the chip behaves.

Flash it with uvtools (web-based; Chrome or Edge), after backing up the EEPROM and calibration. If the detector proves too coarse, the fallbacks are a small hardware audio tap to a spare ADC pin, or the V3 radio.

07Downloads (test builds)

Untested on any radio. These builds compile and pass the PC tests, nothing more. Flashing custom firmware can leave a radio needing recovery, so back up first. The radio's bootloader is not touched, so a bad build can be replaced by flashing again.

FileForFlash or use with
uvpager-v3-k1-20261021.binUV-K5 V3, UV-K1UV Studio. Dump the calibration first.
uvpager-v1-trial-20261021.packed.binUV-K5, UV-K5(8), UV-K6, 5R Plus (V1)uvtools. Back up the EEPROM and calibration first.
f4hwn_pager.chirp.pyV3 / K1 buildCHIRP: File → Load Module
cfg2pager.pyV3 / K1 buildPython 3: tones.cfg files into a CHIRP image
SHA256SUMS.txtAllsha256sum -c SHA256SUMS.txt
Built 2026-10-21. Put the radio in bootloader mode by holding PTT while turning it on. The V1 build carries a placeholder watch list of Albany County departments, and its channels are marked by name (section 06). It does not use the CHIRP driver.

08Still to check on hardware

  • Input level. In normal receive, the audio level reaching the ADC follows the volume setting, so the level gate may need tuning.
  • Low tones. The radio's 300 Hz high-pass stays on in this edition, so QC2 tones between 321 and 433 Hz arrive weaker. The decoder doesn't depend on level, but this is unconfirmed.
  • Beeps during receive. The radio has to come back to receive cleanly afterwards.
  • V1 detector. Whether it reports a tone once or repeatedly, how selective it is, and its threshold.
  • Battery saver and dual watch. Either can make the radio miss the start of an A tone. Turning them off on a pager channel may be the answer.