rtl_433
The decoder for the 433/868/915 MHz sensor world. It reads a live SDR or a recorded IQ file, slices bursts into bits, runs 200-odd device decoders over them, and when none of them fits it tells you the pulse timings so you can write your own.
rtl_433 is the standard open-source decoder for the sub-GHz ISM bands. Despite the name it is not tied to an RTL-SDR or to 433 MHz: it takes samples from any supported SDR, or from a file, and it covers 315, 433.92, 868 and 915 MHz devices. Weather stations, tyre pressure sensors, door contacts, energy meters, remotes and doorbells are all in its decoder list.
What it is
The pipeline is fixed and worth knowing, because each stage is where a different mistake shows up. It detects a burst against the noise floor, demodulates it as OOK by amplitude or as FSK by frequency, reduces it to a list of pulse and gap durations, hands those to a slicer (PWM, PPM, PCM, Manchester and others) that turns timings into bits, and finally offers the bits to every registered device decoder in turn.
rtl_433 -f 433.92M # listen live
rtl_433 -f 433.92M -S all # record every burst to .cu8 files
rtl_433 -r capture_433.92M_250k.cu8 # replay a recording through the decoders
rtl_433 -r capture.cu8 -A # analyse the pulses of an unknown device
rtl_433 -r capture.cu8 -R 0 -X 'n=x,m=OOK_PWM,s=204,l=600,r=9000,y=312'
Recordings are raw interleaved samples with no header, so the parameters live in the filename by convention: name_<centre frequency>_<sample rate>.cu8 for unsigned 8-bit IQ, .cs16 for signed 16-bit. Getting that name right is what lets the tool replay a file with the correct rate.
Why it matters
Two reasons, and the second is the one that gets underrated.
First, for a device that is already supported you are done in one command: it prints model, id, channel, battery and readings as text, JSON or CSV, and that is often the whole job.
Second, for a device nobody has written a decoder for, -A is a proper reverse engineering tool. It prints the distribution of pulse widths, gap widths and periods, guesses the modulation, and then prints the exact -X flex decoder line for what it just measured. Running that line gives you the raw bit rows for every burst in the file. You have skipped straight past the DSP and are looking at bits, which is where the actual protocol work starts.
Pitfalls
- The file extension is the format. Feed a
.csvor a text log to-rand rtl_433 will happily read it as samples and report noise. A tool test that "found nothing" against the wrong format proves nothing at all. - Which pulse is a one is a convention. The PWM slicer calls the short pulse a one, and plenty of real devices do the opposite, so a row that looks like nonsense is often the exact complement of the frame. Check both before rewriting your decoder.
- Bit order inside a byte is another convention. Cheap encoder chips shift bytes out least significant bit first, and rtl_433 prints them in the order they arrived. If a field that should count does not, reflect the bytes.
- The reset limit sets the frame boundary. Too small and one transmission is split into several rows, too large and several repeats merge into one. It is the
r=in a flex decoder line and it is the first thing to adjust. -Astops at analysis. It is deliberately not a decoder. The bits it prints still need the framing, the field layout and the checksum worked out by hand.