Note: This article is the 2nd in a series of posts about electronics.
In my previous post I mentioned that I identified microcontrollers and microcontroller programming as one of the key disciplines that I needed to study up on. I have been programming in one way or another for about 20 years now, so I have done so on a pretty wide range of computers, but aside from some tinkering with a PIC microcontroller, I never really did anything with these amazing and tiny computers. This post will take a look at the hardware side of the microcontroller picture.
A microcontroller is, more or less, a very tiny and (often) self-contained computer. While compared to the past, modern microcontrollers are extremely advanced, run at very high speeds, and have huge amounts of program storage and RAM, compared to modern PCs, they seem incredibly primitive.
A modern PC such as the one I’m writing this on may have a 2.4GHz processor, 4GB of RAM, and a 320GB hard drive. Comparatively, an Atmel ATmega644 has a 20MHz processor, 4KB of RAM, and 64KB of program storage (flash)—incredibly slow and with a tiny amount of memory and storage—and it’s one of the higher end microcontrollers. So why are they useful? For a few reasons:
- Size — If you’re looking to build something small, you can still give it a lot of brain power with a modern microcontroller, and it will fit in the palm of your hand.
- Power consumption — The power consumption of microcontrollers is usually measured in micro-amps (ÂµA). PCs, even very simple ones, can’t even come close, especially once you make use of some of the power saving features on the microcontroller.
- Durability — Vibration, heat, dust, etc. aren’t really a big problem for most microcontrollers.
- The sheer number of internal peripherals such as timers, serial interfaces (UART [TTL serial], I2C, SPI, and even USB), analog-to-digital converters (ADCs), pulse-width modulation (PWM), and of course tons of general purpose IO (GPIO) pins. Many of these peripherals can even be used in interrupt-driven background modes, making more processor cycles available to your main program.
- Speed — While 20MHz (or less!) might not seem like much to us desensitized by modern multi-GHz PCs, when you don’t have the overhead of 12 layers of operating system, and when your tasks are very simple, a few MHz is more than enough; it will be far more responsive than a PC ever could be.
- Price — Atmel AVR microcontrollers run from less than a dollar up to a few tens of dollars each depending on capacities and features. Most of the ones I use are around $8.
The Atmel AVR series
When I was first looking at trying my hand at microcontroller programming, I more or less chose the Atmel AVR series by accident: some sites that I respected (like Sparkfun) had many projects based on it, and I noticed the avr-gcc (merged into gcc proper) and avr-libc projects seemed to be very well maintained. I knew about the Arduino platform (which is based on the Atmel ATmega328), but I really wanted to get into the internals of everything, and I already know C and low-level systems programming pretty well, so I figured it would be easy. I believe, especially now, that I made the right choice.
The Atmel AVR ATmega and ATtiny series’ of microcontrollers are 8-bit RISC architecture processors combined with a variable amount of erasable flash memory for program storage, static RAM (SRAM) memory for working data, non-volatile EEPROM memory for persistent data, and a bunch of peripherals, but usually a couple of timers, a UART, a few ADCs, and a few PWMs, an I2C bus, an SPI bus, and some GPIOs. They are typically programmed over their SPI bus, and can even be reprogrammed in-circuit. All of that for just a few dollars each.
The Atmel ATmega644
I decided to do most of my microcontroller work on the Atmel ATmega644 (including ATmega644P and ATmega644PA revisions). It has enough flash that I don’t need to worry about running out of space (except by accident, heh) and enough SRAM that most anything I want to do is possible. While it’s kind of chunky in PDIP package, it’s certainly petite enough for my needs in TQFP and QFN packages.
It’s specs are:
- Processor speed: Up to 20MHz (8MHz internal oscillator)
- Flash: 64KB
- SRAM: 4KB (4096 bytes)
- EEPROM: 2KB (2048 bytes)
- Timers: 2x 8-bit and 1x 16-bit
- PWM: 6x
- ADC: 8x 10-bit
- Interfaces: 1x USART, 1x SPI, 1x I2C
- Packages: PDIP 40, TQFP 44 (12.00mm), QFN 44 (7.00mm)
In order to get started with any Atmel ATmega (or ATtiny) series, there are a few must-haves:
- Breadboard — These are pretty standard, but you’ll want a few good ones so you don’t have to unplug everything to try something new or test something.
- Programmer — I got the AVR Dragon, but there are dozens of different programmers out there. It just needs to support the 6/10 pin ICSP programming mode for AVRs. (If you get the AVR Dragon, also get a 40-pin ZIF socket and a bunch of DIP headers to populate its empty through-hole positions. The AVR Dragon with a ZIF socket is very useful if you need to “rescue” a badly programmed microcontroller using its parallel programming (PP) mode, and many cheaper programmers only do ICSP, not PP.)
- USB serial adapter — Sparkfun sells several based on the FTDI FT232RL serial interface chip (5V and 3.3V), and they work very very well on all operating systems.
- Crimped jumper wires — These are awesome for making quick and easy connections between boards, for making custom programming cables, etc. I use a ton of them. You will want M-M, M-F, and F-F, and a good selection of crimp connector housings; I find the most useful ones are 1×1 (jumpering), 1×2 (power etc.), 1×3 (I2C, serial, etc), 1×4, 1×6 (ICSP), and 2×3 (ICSP).
- Pre-cut jumper wires — These are critical for making short connections on the breadboard. Pololu has a good selection of them.
Then of course, you’ll want to get a few actual microcontrollers:
- Atmel ATmega644PA PDIP 40 — Good for all sorts of hackery, but quite big in PDIP package. Currently $7.50 each individually.
- Atmel ATmega168 or ATmega328 — These are cheaper, smaller, and less capable. They are great once you’ve written something and want to deploy it at a larger scale for cheaper. They are also great if you want to use the Arduino bootloader. Atmel is having all kinds of supply issues with them right now (welcome to the world of hardware!), so good luck finding them.
This is how my desk usually looks when I’m prototyping something on the breadboard:
My desk during prototyping. A breadboard with ATmega644PA, the AVR Dragon, and a Sparkfun FT232 breakout.
A few cautions
Read the datasheets!
While it may seem incredibly boring, you will learn a lot by reading the datasheets for the parts you’re buying. After having worked in the software industry for 12 years, I am very impressed by the sheer level of accurate documentation in the hardware world. It will save you a lot of time if you at least skim the datasheet for every part you intend to use before you break it out (or even before you buy it).
Don’t mix 5V and 3.3V
You will probably want to choose whether you want to work at 5V or 3.3V. The electronics world is currently fractured between those two voltages pretty evenly (as well as some lower voltages such as 1.8V). Many things are not compatible between the two, so always check the voltage very carefully before you buy something. You do not want to be working out level conversion issues while you’re just trying to learn and get things working. It doesn’t matter which you choose (although arguably more hobbyist stuff is 5V) but everything you buy should be the same voltage unless you have a large budget.
Be careful with fuses
I’ll get into how fuses (basically, non-volatile configuration switches) work in a later blog entry, but suffice it to say, if you see stuff about fuses and setting them, be extremely careful. If you set the fuses incorrectly you can easily get your AVR into a state where it can’t be serially programmed and you’ll need to trash it or rescue it with parallel programming. (See above about why AVR Dragon with a ZIF socket is nice.) I have done this a few times, and it’s not fun to fix them, but at least it’s possible with my setup.