The goal
Decode OOK from rtl_fm raw outputUsability
You don't need to analyze OOK audio manually.Hardware
- any rtl-sdr dongle
Description
While working on my software for my CC1101 atmega32u dongle, I was making tests with doorbell transmitter. To check if my code decodes it properly I needed to record "sound of OOK", then using Audacity look into the wave and manually count all long and short pulses. I've started to wondering if this could automated, because signal I was looking on was pretty good with very low noise.
I've started to google and found this http://stackoverflow.com/questions/15112964/digitizing-an-analog-signal, based on jleahy's answer I created this simple script below.
The script
Command below will start listening on ISM band: 433.92Mhz with AM modulation and 38400 sampling rate. Output will be written to ook.raw file. Almost in the same time will be played by your sound card. Thanks to this you can easily tell if something was send over air.
rtl_fm -M am -s 38400 -f 433.92M -g 0 | tee ook.raw | play -t raw -r 38400 -es -b 16 -c 1 -V1 -Gain of rtl-sdr device is set to 0, because I was checking doorbell transmitter that I had in my hand. Thanks to low gain I've got quite large signal/noise separation. Sample rate 38400 = 4 * 9600, which is the proper speed for analyze_ook function that uses regular expressions to decode OOK signal. I could use of course some lower sampling rate, but with bigger one audio is smoother. If you'll decide to change it to something else, remember to change downsample line.
Rf_analyzer module, you can find in source code section of CC1101 Atmega32u USB dongle + python = RFkitten post.
#!/usr/bin/python from numpy import memmap, where, trim_zeros, char, mean, max from scipy.signal import medfilt from re import split from sys import argv import rf_analyzer # load raw audio file with uint16 encoding and # 38400 sample rate data = memmap(argv[1], dtype='uint16', mode='r') # "calculate" noise level from begining of a file noise = max(data[0:1000]) # Sample rate was set to 38400, which is 4 * 9600 # now downsample it 4 times by reading every 4-th integer data = data[0::4] # set baudrate for OOK analyzer, it will calculate original # signal baudrate baud = 9600 # create median vector median = medfilt(data) # every signal above will be set to 1, every below to 0 # use additional noise floor normalized = where(median > mean(median) + noise, 1, 0) # trim trailing and leading zeros normalized_no_zeros = trim_zeros(normalized) # convert above [1,1, ... , 0, 0, ... , 1,1] to string 11...00...11 bin_str = char.mod('%d', normalized_no_zeros).tostring() # split string into packets separted by high count of '0', 20 is enought for # 2400 to 9600 data rate for splitted in split('0{20,}', bin_str): if (len(splitted) > 0): # make sure that we've got some zeroes at the end for regexp splitted+="0" * 20 # analyze and print rf_analyzer.analyze_ook(splitted, baud, bin_input=True)Here is the result:
$ ./af.py ook.raw Packet len: 52 speed: 2400 OOK decoded: 10001011111110100000010 key: doorbell_button_1_first Original: 11111111111111000011111000000000000011111000000000000011111000000000000011111111111111000011111000000000000011111111111110000011111111111110000011111111111110000011111111111110000011111111111110000011111111111110000011111111111110000011110000000000000111111111111110000111110000000000000111110000000000000111110000000000000111110000000000000111110000000000000111110000000000000111111111111100000111100000000000000000000 Packet len: 54 speed: 2400 OOK decoded: 110001011111110101010010 key: doorbell_button_1 Original: 11111111111110000011111111111110000011110000000000000011110000000000000011110000000000000111111111111110000111110000000000000111111111111110000111111111111110000111111111111110000111111111111110000111111111111110000111111111111110000111111111111110000111110000000000000111111111111100000111110000000000000111111111111100000111100000000000000111111111111100000111100000000000000111100000000000000111111111111100000111100000000000000000000 Packet len: 54 speed: 2400 OOK decoded: 110001011111110101010010 key: doorbell_button_1 Original: 11111111111110000011111111111110000011110000000000000111110000000000000111110000000000000111111111111110000111110000000000000111111111111110000111111111111110000111111111111110000111111111111110000111111111111110000111111111111100000111111111111100000111100000000000000111111111111100000111100000000000000111111111111100000111100000000000000111111111111100000111100000000000000111100000000000000111111111111100001111100000000000000000000and so on ...
No comments:
Post a Comment