So I decided to build a quadcopter recently, which turned out to be almost as much fun as flying it, and I got to get reacquainted with the smell of burning solder flux. A key component of a quadcopter (or any multirotor) is the “flight controller”, which takes the inputs from the receiver along with the readings from the onboard gyroscope and accelerometer and determines the correct speed for each of the motors to be running at in order to keep the craft stable in the air. The more fancy flight controllers have things like GPS and compasses to remove even more work from the pilot.
It turns out that a lot of the flight controllers about are based on the Atmel AVR series of microcontrollers, the same ones used by Arduinos. As always, “the community” has been keen to come out with improved and alternative firmware for the various controllers. I chose the KK2.1.5 for my build, which was no exception to this rule.
The 1.6 version of the firmware that it shipped with was apparently rubbish compared to the later updates by steveis. So always wanting to have the latest and greatest, I set about trying to get the newest firmware onto my KK2.1 board.
Flashing the Firmware
AVR chips can be programmed using the AVR ISP tool from Atmel, or alternatively the USBasp or one of its many clones. These connect to a 6-pin header on the board with the AVR chip at one end (or I suppose can be wired in directly to the chip one way or another) and into your computer via USB at the other. Then it’s just a case of running an appropriate tool like
avrdude to write the firmware to the chip’s flash memory.
So I ordered my USBasp from a reputable looking seller on ebay and waited. Unfortunately this was on Thursday, and Easter was happening. That meant I wouldn’t get it until this coming Tuesday; an unacceptably long wait.
Doing a bit of research into these AVR programmers revealed that they use an interface called SPI to talk to the chip. The main parts of this are the
MOSI signals. The
SS (slave select) signal isn’t present on the programmer, presumably because there’s only ever one slave. The other two pins are a
RESET, a 5V line to provide power and the ever present
It occurred to me that SPI sounds like something that a Raspberry Pi would have on a few of its many pins, and it turned out I was right.
Other people have written about programming AVR chips, or more specifically Arduino boards using a Raspberry Pi, but they seem to be using special builds of
avrdude or GPIO for the whole thing instead of the built-in SPI hardware. Luckily for me time seems to have passed and it turned out to be much more straight forward in 2016.
Setting up the Raspberry Pi
The first thing I did was to grab the latest build of Raspbian Jessie and pop it onto an SD card. Once I’d got the basics set up (
apt-get install vim, we’re doing serious work here) I just installed the latest
apt-get because it has all the patches I needed already.
SPI isn’t enabled by default, but enabling it is as simple as editing
/boot/config.txt and finding this section:
# Uncomment some or all of these to enable the optional hardware interfaces
I just had to remove the hash on that last line and reboot.
To connect the Pi to my KK2.1 I repurposed some servo cables I had left over from the build, carefully removing the plastic plugs with some tweezers. Here’s a nice diagram of the Raspberry Pi pins. The
MOSI are pins 23, 21 and 19 on the Pi.
RESET isn’t part of SPI, but
avrdude is configured to use GPIO 25 for this by default, which corresponds to pin 22. For
GND I just used pin 20.
Now, USBasp provides 5V to power the chip it’s programming (maybe this is just because that’s what it gets over USB), and the KK2.1 normally runs off 5V (maybe just because that’s what’s standard in the RC world). But the Raspberry Pi doesn’t like to get 5V on any of it’s GPIO pins and it’ll probably break a little inside if it does. It much prefers the taste of 3.3V. The datasheet for the ATmega644PA used in the KK2.1 says it’ll run off anything between 1.8V and 5.5V, so I reckoned it’d be fine with 3.3V and just hooked it up to pin 17 on the Pi. And what do you know, it worked!
Note: I connected this all up one by one while the Pi was running and connected the power last. This may or may not have been a good idea, but I was careful not to let anything short while I was doing it as that tends to end in disappointment.
Once all that was done, all I had to do was download the firmware image onto the Pi and run the following command:
$ sudo avrdude -c linuxspi -P /dev/spidev0.0 -p m644p -e -U flash:w:KK2V1_1V19S1Pro.hex:i
The options here are:
-c linuxspiwe’re using the built-in SPI drivers and hardware here, as opposed to
usbaspor any of the dozens of other possibilities
-P /dev/spidev0.0this is where the actual SPI device appears. If this isn’t present then SPI hasn’t been enabled properly
-p m644puses the correct settings for the ATmega644PA chip we’re flashing
-eerases everything on the chip before writing anything. I don’t know the exact reasons for this, but the
manpage says it’s required
avrdudeto write the contents of the
.hexfile to the flash memory of the chip
This took about 30s to write and then verify the image. Once done I disconnected the KK2.1 and plugged it back into the quadcopter…
Everything started up as expected and it all seemed to be working. I did a factory reset and did all the calibrations and it all looked good.
So did it fly any better? Well, I don’t really know for two reasons:
1. It’s been stormy all weekend. Even when it’s not been raining or thundering it’s been far too windy to fly
2. I’m really not very good at flying the quadcopter yet, so it’s quite hard to tell
I was able to do just enough hovering indoors to get the PI settings roughly right, but I can’t say whether there’s been an improvement yet. I’ll just have to wait until the weather gets better ¯\_(ツ)_/¯.