Droids Corporation http://www.droids-corp.org/ These aren't the droids you're looking for... en-us Thu, 26 Sep 2013 00:00:00 +0200 http://www.droids-corp.org/2013/09/26/a_simple_lost_rc_beacon__part_2_.html http://www.droids-corp.org/2013/09/26/a_simple_lost_rc_beacon__part_2_.html <![CDATA[A simple lost RC beacon (part 2)]]>

A simple lost RC beacon (part 2)

Following the previous article, I will continue to explain how our lost RC beacon works, especially the firmware of the receiver module. At the end of the post, a video shows how to find a lost RC model in real conditions.

Filtering noise on receiver module

Let’s recap the main design of the receiver module first. We use a DRA886RX that receives the signal transmitted by the TX beacon. The output of this chip is a digital signal that can for example be used to drive a buzzer through a transistor. But doing this is a punishment for our ears because if there is no radio signal, the receiver output can randomly be 0 or 1... as a result it will output an high level noise.

The first (bad) idea to avoid this is: “hmm let’s add a band-pass filter between the receiver and the buzzer calibrated on TX beacon frequency, so I will only ear the signal when we receive this frequency”. Wrong. By definition, noise contains all frequencies, and if we add a perfect band-pass filter, we will hear only one frequency instead of a noise. Worst, we may not be able to distinguish the signal.

Example with 2 audio files: noise + intermittent 500Hz signal and the same with a 500 Hz band-pass filter.

The second idea is to do a FFT on the received signal. The RX beacon is designed with a microcontroler between the radio receiver module and the buzzer, so we can do some processing on the received signal. Unfortunately a precise FFT is not really possible on a 8-bit microcontroler because it would consume a lot of resources, but we can do something quite similar.

Filter details

To detect a 500 Hz square signal (this is what the TX beacon sends), we 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 fundamental frequency.

If the signal is a noise, the output of the 3 filters will have the same mean power. If the signal is the 500Hz square signal, The power of the fundamental filter will be high, the power of the harmonic filter will be lower, and the power of the last filter (1000Hz) should be very low as this frequency should not be included in the signal.

Generation of filter parameters

To generate the 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 fir.py generates a graph of the filters. It assumes Fe=5Khz, Ffond=500hz (blue), Fharm1=1500hz (green), Fother=850hz (red) but this can be modified in the source. The order of the filter is 32. The filter is displayed in normalized frequencies: for instance, 0.2 means “0.2 * Fe/2”.

../../../_images/filter.png

Output of fir.py

Run the script as following:

python fir.py [filename]

The script also generates the code of a C function to be copied in the AVR program. People used to program on AVR may be surprised that the device has enough power to apply 3 different filters (order = 32) on a signal sampled at 5Khz. Indeed, this is usually a work for a DSP!

The trick here is that the input signal is 0 or 1. So we can completely remove the need of multiplication to apply the FIR filter:

out(n) = a0 * in(n) + a1 * in(n-1) + ... + ak(n-k)

We store the 32 previous sampled inputs in a 32bit integer, so the code is:

       if (bitfield & (1 << 0))
               out += a0
       if (bitfield & (1 << 1))
               out += a1
       if (bitfield & (1 << 2))
               out += a2
       ...

Moreover, we use some more optimizations in the code:
  • the loop is fully unrolled and all the filter parameters are directly in the code as constant to enhance speed and RAM consumption. The price is a large code in flash, but we don’t care.
  • the 3 filters are applied at the same time (the same “if” is used for the 3 filters)
  • the calculation is done on 16 bits without overflow or saturation because we know that the filter gain never exceed 1.

We will see later in the article that the simulator shows that we have enough CPU power.

Listen and view the result

The same code can be compiled for AVR but also for a linux host. Thanks to this, we can test the effect of the filter on a real audio input. Four WAV files have been generated. They are sampled at 5Khz 16 bits, and each sample is either -32768 or 32767, simulating a 1 bit sampling (like the output of the DRA886RX):

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 WAV 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.

../../../_images/tone.png

Filtering the pure tone

../../../_images/lownoise.png

Filtering the tone with some noise

../../../_images/highnoise.png

Filtering the tone wich a lot of noise

../../../_images/noise.png

Filtering pure noise

The code that decides if the signal is detected is a bit empirical. We first filter the mean power of each filter. Then we compare their values as in the code below. When the variable cpt_filter is above a threshold, we consider that the signal is detected.

if ((pow_fond/3) > (pow_harm1/2) &&
    (pow_fond/2) > pow_other &&
    cpt_filter < MAX_CPT_FILTER)
      cpt_filter += 2;
else if (cpt_filter > 0)
      cpt_filter--;

Performance Test

We can check that the program will run correctly on an AVR by using a simulator. We simulates an ATmega128 because the ATtiny45 is not supported by simulavr:

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 we 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! Indeed, the AVR runs at 8Mhz, so the loop frequency is 10Khz in the worst case.

The receiver in action

The receiver can work in 2 modes:

  • bypass mode: in this case, the input (from the radio receiver) is copied on the output (the buzzer) by the microcontroler, there is no filtering.
  • filter mode: the microcontroler will apply the filters described above 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.

In both modes, the LED is switched on when the signal is detected.

See the real-life video.

Thanks to serpilliere and will who helped me on this project.

]]>
Thu, 26 Sep 2013 00:00:00 +0200
http://www.droids-corp.org/2013/07/14/a_simple_lost_rc_beacon__part_1_.html http://www.droids-corp.org/2013/07/14/a_simple_lost_rc_beacon__part_1_.html <![CDATA[A simple lost RC beacon (part 1)]]>

A simple lost RC beacon (part 1)

With some friends, we play with RC planes, especially FPV (First Person Viewer): the RC model has a camera that transmits the video over radio, received and displayed in goggles, as if we were in the plane! But this hobby can be risky, we sometimes crash the plane, and unfortunately it can be crashed far, at an unknown location. So the question is: how can we find it easily?

To solve this issue, there are several solutions. The easiest one is to put an audio beeper on the plane (we already do that), but it doesn’t help if the plane is too far. Another common solution is to embed a GPS on the plane and transmit the position to the ground station. This is probably a good solution but it requires some quite complex electronics: the GPS board, a microcontroler to decode data, and a radio transmitter. Moreover, you need another GPS device that to get your current position and determine the relative position of the RC plane.

Although this solution is probably a good one, we wanted to design the simplest board with the following constraints:

  • cheap: no GPS, small uC
  • long autonomy: embeds its own battery
  • reliable: implies simple, board is protected by a box, embeds its own battery (again)
  • “long” range (500m)
  • fun ;) ...it is probably not the best design, but at least it is a not so bad one that works

Our system is composed of 2 boards: a transmitter and a receiver. The transmitter sends beeps over radio (433 Mhz), and the receiver module is connected to a buzzer that emits sound when the signal is received. To detect the direction of the transmitter, we use a directional antenna (yagi).

Here are the final version of the boards:

../../../_images/beacons.jpg

We decided to use the Dorji DRA886RX (receiver) and the Dorji DRA887TX (transmitter) as they are referenced by two (interesting) documents:

The datasheets of these modules are very poor, but they are easy to use. The radio power depends on the voltage. When using the maximum voltage, the range of these modules can be quite high, but we should take care to conform to legal constraints.

We were able to build a simple prototype in a couple of hours:

../../../_images/beacons-proto.jpg

Description of the transmitter

The transmitter board contains:

  • the radio TX (DRA887TX)
  • an audio buzzer to find the RC plane when distance is < 50m
  • a push button, for user interaction
  • a LED
  • a microcontroler (AVR ATtiny13) that will generate the radio and audio signals, and handle the button
  • an adjustable power for the TX, that can be switched off by the microcontroler

Here is the schematic:

../../../_images/beacon-tx-sch.png

Here is the PCB:

../../../_images/beacon-tx-pcb.png

Eagle files (including part list) are available on our git: http://git.droids-corp.org/?p=protos/xbee-elec.git;a=tree;f=beacon-tx;h=35ff6facfb31ee73fdde580f25aca327b1a5446d;hb=HEAD

The program in the ATtiny13 is very basic. It transmits a beep on the radio every second, and an audio beep every 2 seconds. If the button is pressed, the audio is mutted during one minute. A future evolution could be to add a servo input and monitor activity on it to mute the audio or radio, as it is done by this guy.

The program is available on our git: http://git.droids-corp.org/?p=beacon-tx-433.git;a=summary

Description of the receiver

The receiver board contains:

  • the radio RX (DRA886RX)
  • an audio buzzer to hear the output of the receiver and a trimmer to modify the volume
  • a push button, for user interaction
  • 2 LEDs (one for power, one for status)
  • a microcontroler (AVR ATtiny45) that will filter the received signal

Here is the schematic:

../../../_images/beacon-rx-sch.png

Here is the PCB:

../../../_images/beacon-rx-pcb.png

Eagle files (including part list) are available on our git:

http://git.droids-corp.org/?p=protos/xbee-elec.git;a=tree;f=beacon-rx;h=35ff6facfb31ee73fdde580f25aca327b1a5446d;hb=HEAD

]]>
Sun, 14 Jul 2013 00:00:00 +0200
http://www.droids-corp.org/2013/06/03/marker_beacon_new_album.html http://www.droids-corp.org/2013/06/03/marker_beacon_new_album.html <![CDATA[New album of Marker Beacon]]>

New album of Marker Beacon

A small post to talk about my heavy metal band Marker Beacon: we just released our first album today called “Dead Frequencies”, and it is licenced under the Creative Commons licence (BY-SA 3.0).

../../../_images/Marker-Beacon_Dead-Frequencies_Front_small.jpg

Feel free to download it and drop us a message on the guestbook if you like it !

]]>
Mon, 03 Jun 2013 00:00:00 +0200
http://www.droids-corp.org/2013/05/14/olimex_avr_isp_mk2.html http://www.droids-corp.org/2013/05/14/olimex_avr_isp_mk2.html <![CDATA[Olimex AVR-ISP-MK2 under Debian linux]]>

Olimex AVR-ISP-MK2 under Debian linux

For more than ten years now, I use AVR microcontrolers for many projects: Aversive and Microb Technology robots until 2010, and now for some other projects related to FPV.

To program the device, I was mainly using a home-made bootloader or a STK500-like programmer, connected to a parallel port... but we are in 2013, and we can now be sure that this connector is not the future of computers.

So I finally decided to buy an Olimex AVR-ISP-MK2 programmer, which is not so expensive and seems to support many protocols (ISP, PDI, TPI) so I should be able to use it for xmega too.

../../../_images/AVR-ISP-MK2-02.jpg

It nearly works out of the box on my Debian, it just requires some configuration that is easy to do once you know what you have to do.

Flash the firmware

The Olimex AVR-ISP-MK2 programmer is shipped with a firmware that is designed to work with AVR Studio under Windows. But Olimex provides an alternative firmware that can be used with avrdude under Linux.

To update the firmware, we need to put it in DFU mode. Before that, we will update the udev configuration to have the correct permissions (from steve.kargs.net).

Create a new file /etc/udev/rules.d/99-avrisp.rules, and add this in it:

# Atmel Corp. JTAG ICE mkII
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2103", MODE="660", GROUP="uucp"
# Atmel Corp. AVRISP mkII
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2104", MODE="660", GROUP="uucp"
# Atmel Corp. Dragon
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2107", MODE="660", GROUP="uucp"

We need to be a member of uucp group:

adduser my_user_name uucp

Then as root restart udev:

service udev restart

After that, you will need to relogin or you can su my_user_name in the terminal.

When we plug the programmer, it is identified by the kernel (in dmesg) as:

usb 2-2.2: new full-speed USB device number 8 using ehci_hcd
usb 2-2.2: New USB device found, idVendor=03eb, idProduct=2104
usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-2.2: Product: AVRISP mkII
usb 2-2.2: Manufacturer: ATMEL
usb 2-2.2: SerialNumber: 000200012345

To change the firmware, we need to reset it in dfu mode. For that, push the “upgrade” button with a paper clip. In dmesg, we should something like:

usb 2-2.2: new full-speed USB device number 9 using ehci_hcd
usb 2-2.2: unable to get BOS descriptor
usb 2-2.2: New USB device found, idVendor=03eb, idProduct=2ffa
usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-2.2: Product: AT90USB162 DFU
usb 2-2.2: Manufacturer: ATMEL
usb 2-2.2: SerialNumber: 1.0.0

Install the package dfu-programmer:

apt-get install dfu-programmer

Flash the firmware (the hex file of the firmware is available in the archive):

dfu-programmer at90usb162 flash libUSB-AVRISP-MKII.hex

Program a device

We need to add some other udev rules (for instance in /etc/udev/rules.d/99-avr-isp.rules):

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ffa", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ffa", MODE="660", GROUP="uucp"

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ffb", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ffb", MODE="660", GROUP="uucp"

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff9", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff9", MODE="660", GROUP="uucp"

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff7", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff7", MODE="660", GROUP="uucp"

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff4", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff4", MODE="660", GROUP="uucp"

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff3", MODE="660", GROUP="uucp", SYMLINK+="at90usb-%k"
ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="2ff3", MODE="660", GROUP="uucp"

Then as root restart udev again:

service udev restart

Now, we can unplug and replug the programmer. In dmesg, there is no difference before and after the firmware update:

usb 2-2.2: new full-speed USB device number 8 using ehci_hcd
usb 2-2.2: New USB device found, idVendor=03eb, idProduct=2104
usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-2.2: Product: AVRISP mkII
usb 2-2.2: Manufacturer: ATMEL
usb 2-2.2: SerialNumber: 000200012345

And now, to program our hex file on my ATtiny13, we just need:

avrdude -p t13 -P usb -c avrispmkii -e -U flash:w:main.hex

That’s hit ! In a future post, I will describe our new little project: a lost RC radio beacon. It can be used to find a crashed plane with a directional antenna.

]]>
Tue, 14 May 2013 00:00:00 +0200
http://www.droids-corp.org/2013/04/11/diff2html_py_version_1_0_is_released.html http://www.droids-corp.org/2013/04/11/diff2html_py_version_1_0_is_released.html <![CDATA[diff2html.py version 1.0 is released]]>

diff2html.py version 1.0 is released

Three months after the last commit, I decided to release the first stable version of diff2html-1.0. I started to write this quick script in 2009, and I made it available on the droids-corp website.

I was very happy to see that it was used by other people and some of them contributed to it. Thanks to Alan De Smet, Sergey Satskiy and Scito for their contribution !

../../../_images/diff2html.jpg

Screenshot

You can download the script here: diff2html-v1.0

]]>
Thu, 11 Apr 2013 00:00:00 +0200
http://www.droids-corp.org/2013/02/19/welcome_on_the_new_droids_corp_website__.html http://www.droids-corp.org/2013/02/19/welcome_on_the_new_droids_corp_website__.html <![CDATA[Welcome on the new Droids Corp website !]]>

Welcome on the new Droids Corp website !

We are happy to open this new blog, based on Tinkerer. The old wiki has been converted in static html pages and is currently available at http://wiki.droids-corp.org or http://microb-technology.org as before. We will progressively merge the old content in this new site.

]]>
Tue, 19 Feb 2013 00:00:00 +0100