After firming up the animations that I wanted to do, I got two things accomplished in the last few days.
First, I build the "ring" part. I had bought a 5' piece of pvc electrical conduit to use as a form, and my plan was to bend it into a circle by heating it with a heat gun.
Initial results were disappointing. The circle that I got was about as circular as the ones I drew when I was in kindergarten, so I decided I needed a form.
And there, sitting in a box because of my laziness at not putting them away, was a set of spare wheels for my bicycle. A little experimentation showed me three things:
- Using the wheel as a form was workable
- The piece of conduit I had wasn't long enough
- It was sort of bunged up for my first attempt
A quick trip to Lowes and another 30 minutes with the heat gun, and I had a nice hoop (size 700c) completed.
After digging out my development board (I use the Atmel STK500) and buying a copy of the CodeWarrior AVR C compiler, I was ready to get started. Well, not quite - I had to set up my work area since we're getting ready to gut and redo our office. My main tools are:
- A nice 20MHz dual-trace Tektronix oscilloscope that I bought on the internets a few years ago.
- A benchtop power supply (+5V, +12V, -12V, and 0-20V)
- A Fluke multimeter
- A Weller temperature-controlled soldering station
- My 8 fingers and 2 thumbs
I don't really need the power supply as I'm using a wall wart to power the development board, but it looks nice under the scope. The multimeter is useful to look at LED currents, and because I'm using PWM to control the brightness of the LEDs, the scope is invaluable for debugging. If you don't want a full-sized scope, there are some decent PC-based solutions, but keep in mind that the precision electronics required for 'scopes are never cheap. I like having the real buttons and knobs rather than having to use a UI on the laptop to do things, though I would really like a TDS1000B.
I've often advocated that developers should learn multiple languages because knowing languages effects how you approach problems. If you are fluent in Perl, you're much more likely to know when to use a nice regex in C#.
Similarly, it's good for your skills to spend some time working on a seriously constrained machine like a microcontroller. The 861 I'm using has a whopping 512 *bytes* of memory, which sounds pretty tiny until you note that the 261 only has 128, and some of the 8-pin versions only have 64 bytes. Trying to structure your algorithms and code to use that amount of memory and the 8K of flash for the program memory will stretch your mind in ways that writing C# code won't.
I'm undecided on the benefits of writing in assembler. I can be a learning experience, but I'm not sure if the pain of remembering how indexed address mode works transfers over to more rational languages.
My first order of business was to get the chip in the board, make sure I could burn it, and get a skeleton program running. Getting the chip on the board was trivial, but I had real problems getting it to program (which is done with a PC program that sends the code over a serial cable to the board). After a lot of trial and error - mostly error - a kind soul on avrfreaks.net pointed out that the connections on the STK500 were wrong for my chip, and things started working correctly then.
Codewarrior is a nice product. Microcontrollers require a lot of configuration up front - you need to set how you are using each of the pins, what interrupts you want, and 35 other things. You do this by writing code that stuffs particular values in specific registers on the chips. Something like:
Where you found that by careful reading of the 227 page user's guide for the chip. It's pretty tedious, but CodeWarrior provides a "get started wizard" where you specify what chip you're using and then go through a dialog and choose what options you want and then it generates all the initialization code that is needed for your chip. It's a huge timesaver.
After tracking down one problem that was keeping my interrupts from firing (traced to missing a bit in one of the interrupt configuration registers), my main loop woke up and started operating. I did a bit more debugging and then ported one of my animations over from C# to C.
It looked okay on the scope (minus a few glitches), but it seemed slow. Plugging in the leds on the STK500 to 8 of the output bits I'm using showed that a) the animation was working, but very slowly and ii) the LEDs were flickering like nobody's business.
As I suspectected, the 861 running at 8 MHz doesn't have enough horsepower to handle 256 levels of dimming. I'm not getting the 100 Hz that I need to keep the leds from flickering, and there's not enough free time after the interrupts to do the animation at any reasonable speed.
I'll spend a little time seeing if I can't speed up the interrupt routine, but the real fix is going to be to reduce the number of dimming levels down to 16, which should give me enough time for everything to run smoothly.
Then, it will be time to start attaching components to the ring