Firmware Tone Generation
Edit on GitHubHow the firmware produces Morse tones on the buzzer and audio jack, with timing from the Morse standard.
Firmware Tone Generation
Every beep the beacon makes, on the buzzer and through the audio jack, is generated by the firmware using the ESP32’s LEDC PWM peripheral.
Why PWM, not tone()
The Arduino tone() function uses one of the timer channels and blocks other uses of that timer. The LEDC peripheral produces a square wave on any GPIO pin without CPU involvement once configured, so the main loop keeps running while a tone plays.
Tone parameters
The firmware configures three values:
| Parameter | Typical value | Notes |
|---|---|---|
| Frequency | 700 Hz | Audible through snow and layers, easy to decode by ear |
| Duty cycle | 50% | Square wave, maximum loudness |
| Duration | Per Morse timing | 1 unit for a dot, 3 units for a dash |
Morse timing
The timing follows the ITU standard with a base unit derived from the configured WPM:
- Dot: 1 unit on
- Dash: 3 units on
- Intra-character gap: 1 unit off
- Inter-character gap: 3 units off
- Word gap: 7 units off
At 12 WPM the unit is 100 ms; at 20 WPM it is 60 ms. The firmware computes the unit from the WPM setting at runtime, so changing the setting changes the tone speed immediately.
Audio jack path
When an audio cable is plugged into the jack, the same square wave drives the tip. The jack isolates the internal buzzer through a diode so both can coexist: the buzzer stays audible while the jack feeds a recording device or a handheld radio for longer-range tests.
Volume and limiting
There is no volume control in the firmware; the 3.3 V square wave is the output. If the tone is too loud for the buzzer, add a series resistor. For the audio jack, keep levels below 0 dBm when connecting to a transceiver microphone input.
Related pages
- Audio Tone Details for the exact frequencies
- Morse Code Engine for the encoding logic
- Audio Jack Wiring for the hardware path