February 15, 2026 in Embedded5 minutes
Capture and decode 433 MHz domotic beeper signals using SDR
Most domotic beepers operate in the 433.92 MHz ISM band, a license-free frequency widely used for short-range wireless devices. These remotes typically use On-Off Keying (OOK), a simple form of Amplitude Shift Keying (ASK) where the carrier signal is either transmitted or not to represent binary 1s and 0s.
In this article, we’ll use the BladeRF xA4 to capture the signal emitted by a domotic beeper, visualize it in GQRX, and decode the underlying data using signal analysis tools. This is a great exercise to understand how basic RF communication works at the physical layer.
Prerequisites:
Tuning to 433.92 MHz in GQRX and pressing the remote button, we can observe the signal on the waterfall display. Each button press produces a series of short bursts at a fixed frequency. The carrier appears and disappears abruptly, which is characteristic of OOK (On-Off Keying) modulation: the transmitter is either fully on or fully off, with no frequency shift.

The spectrum view (top part of GQRX) confirms the OOK modulation. When the remote button is pressed, a sharp peak appears at 433.92 MHz, rising well above the noise floor. When the button is released, the peak vanishes entirely. There is no frequency deviation, only an on/off pattern, a clear indicator of OOK rather than FSK modulation.

To go further, we can use rtl_433 in analysis mode to automatically detect the modulation and decode the signal:
rtl_433 -d soapy=0,driver=bladerf -f 433920000 -g 60 -A -S 2MOutput:
*** Saving signal to file g009_433.92M_250k.cs16 (232505 samples, 1048576 bytes)
Detected OOK package
Analyzing pulses...
Total count: 54, width: 1141.52 ms (285380 S)
Pulse width distribution:
[ 0] count: 1, width: 38912 us [38912;38912] (9728 S)
[ 1] count: 29, width: 13092 us [13064;13172] (3273 S)
[ 2] count: 23, width: 6592 us [6556;6620] (1648 S)
[ 3] count: 1, width: 0 us [0;0] ( 0 S)
Gap width distribution:
[ 0] count: 29, width: 6536 us [6500;6580] (1634 S)
[ 1] count: 23, width: 13048 us [13024;13100] (3262 S)
[ 2] count: 1, width: 81476 us [81476;81476] (20369 S)
Level estimates [high, low]: 12508, 5446
RSSI: -2.3 dB SNR: 7.2 dB Noise: -9.6 dB
Frequency offsets [F1, F2]: -1302, 0 (-5.0 kHz, +0.0 kHz)
Guessing modulation: Pulse Width Modulation with sync/delimiter
Attempting demodulation... short_width: 6592, long_width: 13092, reset_limit: 81480, sync_width: 38912
Use a flex decoder with -X 'n=name,m=OOK_PWM,s=6592,l=13092,r=81480,g=0,t=0,y=38912'
codes : {52}[REDACTED]rtl_433 confirms OOK modulation with Pulse Width Modulation (PWM) encoding. The analysis reveals two distinct pulse widths (~6.6 ms and ~13 ms) representing binary 0 and 1, with a sync delimiter of ~39 ms marking the start of each frame.
Using the -S 2M flag, rtl_433 saves each detected signal as a .cs16 file (complex signed 16-bit IQ samples). The files are numbered sequentially (g001, g002, …, g118), preserving the chronological order of capture:
g001_433.92M_250k.cs16 g002_433.92M_250k.cs16 ... g118_433.92M_250k.cs16We can replay all captured files and count occurrences of each decoded frame:
for f in *.cs16; do rtl_433 -r "$f" -A 2>/dev/null; done \
| grep "^codes" | sort | uniq -c | sort -rn 17 codes : {52}[REDACTED]
13 codes : {52}[REDACTED]
13 codes : {52}[REDACTED]
11 codes : {52}[REDACTED]
9 codes : {52}[REDACTED]
3 codes : {63}[REDACTED]
2 codes : {62}[REDACTED]
2 codes : {61}[REDACTED]
1 codes : {63}[REDACTED]
1 codes : {63}[REDACTED]
1 codes : {62}[REDACTED]
1 codes : {61}[REDACTED]
1 codes : {52}[REDACTED]
1 codes : {52}[REDACTED]
1 codes : {26}[REDACTED]
1 codes : {24}[REDACTED]The analysis reveals several patterns:
rtl_433 missed the beginning or end of the transmission.Since the files are ordered chronologically, we can extract only the valid 52-bit codes in capture order and remove consecutive duplicates:
for f in $(ls -1 *.cs16 | sort); do rtl_433 -r "$f" -A 2>/dev/null | grep "^codes.*{52}"; done | awk '!seen[$0]++'Duplicates are expected: RF remotes intentionally repeat the same frame several times per button press to improve reliability, as any individual transmission may be corrupted by noise or interference. By filtering duplicates with awk, we keep only one code per button press, revealing the actual sequence of buttons pressed during the capture session.
This analysis shows that this remote uses a fixed code: pressing the same button always transmits the same data. This is the simplest (and least secure) approach to RF remote control. More modern systems use rolling codes, where the transmitted value changes with every button press, making simple replay attacks ineffective.
We saw how to analyze a 433 MHz domotic beeper signal, identify the modulation type (OOK), and extract the key length and frame structure. Tools like rtl_433 make this process relatively straightforward by automating modulation detection and decoding. Without such tools, manually demodulating and interpreting raw IQ samples would be significantly more complex.
This is however an important skill to develop, as a wide range of devices operate in the 433 MHz ISM band: domotic remotes, weather stations, tire pressure sensors, wireless thermometers, and many other IoT sensors. Being able to capture and decode these signals opens the door to understanding, debugging, or reverse-engineering a large portion of the low-power wireless ecosystem.