Beacon RX ========= Main design ----------- We use a DRA886RX that receives the signal transmitted by the TX beacon. The output of this component is a digital signal that could be used to drive a buzze through a transistor. Doing this will be a punishment for our ears because if there is no signal, we will output a digital noise. To detect the presence of the signal, we will use a microcontroler. It will have 2 modes: - bypass mode: in this case, the input is copied on the output, there is no filtering. - filter mode: the microcontroler will apply some filters on the input signal and detect the square signal sent by the TX beacon. If it is detected, a pure square signal is transmitted on the output, else the output port stays to 0. Filter details -------------- To detect a 500 Hz square signal, we could use a FFT... but the AVR is clearly too slow to do this in real time. So we decided to use 3 filters (FIR) running in parallel on specific frequencies. We know from its Fourier decomposition that a square signal is composed of odd-integer harmonic frequencies (of the form 2π(2k-1)f). The power of the first harmonic (n=3) is one third of the power of the fondamental frequency. :: +----------+ +----------+ | | | | +-----> fondamen.+-------> mean +---------+ | | bandpass | | filter | | | | | | | | | +----------+ +----------+ | | | | v | +----------+ +----------+ +----------+ | | | | | | is it the| +------+-----> harm1 +-------> mean +-------> signal we| | | bandpass | | fiter | | are looking | | | | | | for ? | | +----------+ +----------+ +----------+ | ^ | | | +----------+ +----------+ | | | | | | | +-----> otherfreq+-------> mean +---------+ | bandpass | | filter | | | | | +----------+ +----------+ Generation of filter parameters ------------------------------- We use a python script and the pylab module. This module contains a function to generate the parameters of a simple low pass FIR from its cutoff frequency and its order. We added some code done by Matti Pastell found on the Internet to calculate the parameters of a bandpass filter. The script is ``fir.py``. It generates a graph of the filters, and a function to be copied in the AVR code. This function has the loop unrolled and all parameters in the code to enhance speed and memory consumption. .. figure:: filter.png :width: 75% Output of fir.py The script assumes Fe=5Khz, Ffond=500hz, Fharm1=1500hz, Fother=850hz but this can be modified. The order of the filter is 32. Run the script as following:: python fir.py [filename] Listen and view the result -------------------------- The code can be compiled on a host. Thanks to this, we can try the effect of the filter on a real audio input. Four wav files have been generated. They are sampled at 5Khz 16 bits, but each sample is either -32768 or 32767, simulating a 1 bit sampling (like the output of the DRA886RX): - tone.wav: the perfect tone at 500 hz - tone-lownoise.wav: the tone plus some noise - tone-highnoise.wav: the tone plus a lot of noise - noise.wav: only noise These files are our reference test inputs. Depending on how the code is compiled, it will use one of these files:: make H=1 WAV=WAV_TONE make H=1 WAV=WAV_TONE_LOWNOISE make H=1 WAV=WAV_TONE_HIGHNOISE make H=1 WAV=WAV_NOISE A script ``output_to_audio.py`` is used to display the result, and save the output of each filter (fond, harm1 and other) in a separate wave file. In the figures below, the top graph represents the output power of each filter. In blue "fond1", in green "harm1" and in red "other". The bottom graph displays the output of the "signal detector". When the green line is 500, the signal is detected. To generate the images, start ``gen-img.sh``. .. figure:: tone.png :width: 75% Filtering the pure tone .. figure:: lownoise.png :width: 75% Filtering the tone with some noise .. figure:: highnoise.png :width: 75% Filtering the tone wich a lot of noise .. figure:: noise.png :width: 75% Filtering pure noise Performance Test ---------------- We can check that the program will run correctly on an AVR by using a simulator. We use an atmega128 on the simulator because ATtiny45 is not supported:: make simulavr -g -p 1234 -d atmega128 -F binary main.bin Then launch gdb:: avr-gdb main.elf (gdb) target remote 127.0.0.1:1234 Remote debugging using 127.0.0.1:1234 0x00000000 in __vectors () (gdb) b main (gdb) c Continuing. Breakpoint 1, main () at /home/zer0/projects/zavr/projects/fir/main.c:371 371 if ((pow_fond/3) > (pow_harm1/2) && Then add a breakpoint somewhere in the loop, and do several "cont". The simulator displays the cycle value each time we go in a breakpoint. We measure between 450 and 750 cycles for one loop iteration, so it's large enough to have Fe=5Khz !