Hi! This is the first of a series of posts about the avrgirl project that I'm working on. If you'd like to follow along, subscribe to my RSS feed!
In my personal time, I work with microcontrollers a lot. I like to use them in fun, educational or just downright silly projects. Check out my Meow Shoes or P.U.R.R. bracelet for a couple of examples and you get the idea.
But what is a microcontroller? Simply put, it's a tiny computer, much simpler than your desktop PC or laptop. Microcontrollers consist of a processor, some memory and a collection of programmable peripherals to be used as inputs and outputs. They're ideal for use in low power situations. These days you'll find them in everything from kitchen appliances, to your car, to your computer keyboard.
Below you can see what a microcontroller can look like:
"ATmega8 01 Pengo" by Pengo - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons
See the rows of pins that look like legs? They are the input/output peripherals that you can connect things up to! What sort of things? Lights, sensors, motors, you name it. Heard of Arduino? An Arduino has an Atmel microcontroller similar to the one above as the brains of the board.
Below illustrates a simple example circuit you can set up with a microcontroller chip:
You can see a microcontroller in the middle of the breadboard. This is an ATMEGA84V-10PU, produced by Atmel. It has 8KB of program memory, 512B of EEPROM space, and 512B of SRAM.
The greenish white circle above the microcontroller is an LED, or Light Emitting Diode. A mini light, similar to what you'd see in appliances that have an 'on' or 'off' light indicator. The LED is currently shining bright, because I uploaded some software written in C to the microcontroller. This software contains the instructions needed to tell the microcontroller to send power to the pin our LED is connected to. When electricity is allowed to flow to the LED (via the orange wire!), it turns that energy into light. There's a resistor between the microcontroller pin and the LED, to limit the amperage so we don't blow up our delicate little LED. Nice!
The microcontroller uses external power (such as the battery pictured) to run itself and also anything connected to one of its pins. In order for this to be, the black and white wires you see in the picture are actually connected to the ground (black, top) and power (red, bottom) wires of the battery. This circuit is one of the simplest, more visual demonstrations of how a microcontroller works.
But hang on, I hear you say. How did you upload the software to the microcontroller chip? I don't see any USB ports!
Good question! So the answer is - it depends.
In the example above, I connected some extra wires to some special pins on the microcontroller, with the other ends then plugged into what's called a programmer. A programmer is a device that can take software from your computer, then translates and 'uploads' it to the microcontroller. We'll go into this in more detail in future posts in this series.
My programmer of choice is the AVR ISP mkII. It's made by Atmel specifically for their AVR microcontrollers, which I almost exclusively use. Here is what it looks like:
The box looks pretty sweet too:
Sorta wish the programmer actually looked like that rainbow shooting robot though. Can't be helped.
There is a USB port at one end so you can connect a cable from your computer. The other end features 6 little slots for plugging wires into for connecting to some specific microcontroller pins. I used this programmer to 'flash' or upload software to the chip above. Once programmed, we can remove the wires and the circuit can function without the main computer or programmer connected to it.
Other microcontrollers are integrated into circuits with USB sockets alongside them. Probably the most well known example of this is any Arduino:
These setups make it way easier to upload software to the chip, as there is no extra external device that has to act as a middleperson. Pretty neat stuff. Fun fact: you can also use an Arduino as a programmer to program other chips, and even other Arduino's! Woooaah, we'll cover this at a later stage in the series. Hold tight!
We're missing one step last though. What is the software running on the computer that helps upload the pre-compiled program to the microcontroller? That, dear reader, is getting to the meat of the avrgirl project.
Atmel offers free official IDE software that allows you to program, debug and upload to any Atmel chip. It's called Atmel Studio.
The catch? It only runs on Windows. Alternative software packages out there range in price from $150 - $1500. Ouch.
If you're just fiddling with Arduino's, the free Arduino IDE will suit most needs nicely.
Which brings us to a free upload tool that programs Atmel AVR chips very effectively - AVRDUDE, or AVRDownloader/UploaDEr.
AVRDUDE is great for a number of reasons. Firstly, it's very solid (it was written over a decade ago by Brian S. Dean), available on all operating systems, and again, free. Secondly, the Arduino IDE uses AVRDUDE for their uploading functionality which I think says good things.
AVRDUDE works as a command line (CLI) software tool that you run in the terminal/shell. An example command would look something like this:
avrdude -v -P usb -c avrispmkii -p attiny45 -U eeprom:w:myeeprom.hex:i
Here is a sample of its output when run:
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e9206 avrdude: safemode: lfuse reads as 62 avrdude: safemode: hfuse reads as DF avrdude: safemode: efuse reads as FF avrdude: reading input file "./tests/eeprom.hex" avrdude: writing eeprom (32 bytes): Writing | ################################################## | 100% 0.06s avrdude: 32 bytes of eeprom written avrdude: verifying eeprom memory against ./tests/eeprom.hex: avrdude: load data eeprom data from input file ./tests/eeprom.hex: avrdude: input file ./tests/eeprom.hex contains 32 bytes avrdude: reading on-chip eeprom data: Reading | ################################################## | 100% 0.03s avrdude: verifying ... avrdude: 32 bytes of eeprom verified avrdude: safemode: lfuse reads as 62 avrdude: safemode: hfuse reads as DF avrdude: safemode: efuse reads as FF avrdude: safemode: Fuses OK (E:FF, H:DF, L:62) avrdude done. Thank you.
Pretty cool. And widely used by both hobbyists and professionals alike. In fact, I used it to upload the program of our simple LED circuit from earlier.
I also used it recently to create some software for the lovely Public Radio project by Zach Dunham and Spencer Wright. The radio was available for a short time as a kit to be soldered and assembled. The last step of the kit was to flash the (Atmel ATtiny45) chip on the circuit board with some custom settings, such as the radio station you'd like your Public Radio to be tuned to when you turn it on.
I set up a Python GUI (Tkinter) with some inputs for the kit maker to enter in, before clicking a 'Flash' button to program their radio with their entered parameters. The programming step was taken care of by making a hidden call to AVRDUDE.
This is what it looked like (note the very 'Python UI lib' look and feel):
The Python GUI worked quite well, as I could package it up for all platforms in a single executable file with the help of Pyinstaller.
There were a few caveats to this approach of using AVRDUDE though. In order to not fiddle around with shipping whole binaries or libraries (except for Python modules), we had to set and document a requirement that AVRDUDE was downloaded and installed prior to using the GUI program. This is okay, but not super optimal. I like a great out-of-the-box experience, and it made me a little sad. Another issue is that AVRDUDE is command line only. It then becomes necessary to run it within a child process, introducing complexity such as piping stderr around, and checking exit codes upon close of the child process.
I do a lot of hardware projects in NodeJS, using anything from just bare node-serialport, to the fabulous johnny-five library. This has eventually led me to wishing for an AVRDUDE-like NodeJS library that supports all of the Atmel chips, Arduino boards, and most of the modern programmers out there.
I got a cheeky but warranted nudge from an engineer while at a conference earlier this year, after complaining about not having a NodeJS AVRDUDE alternative. "Someone should just write this for the NodeJS hardware community," I lamented. "Yes, SOMEONE," (with a chuckle and a meaningful look) was what I got in response.
And so avrgirl was born. Well, it's currently a work in progress. Here's what I'm aiming to produce out of this:
- Above all, a NodeJS alternative to AVRDUDE for programming Atmel chips
- NOT a direct replacement or port. Software diversity and having more choices is a good thing.
- Break the project into small, standalone parts to avoid a monolith
- Support for both scripted and CLI use
- Easy to install and require in your project
- Support most modern, commonly available USB programmers (skipping the very old non USB models)
- Support all common Arduino boards
- Support all Atmel chips for custom PCB project needs
And the name avrgirl? It stands for General Isp pRogramming tooL. It's pretty tongue-in-cheek, but I like it.