The Ravenna Ultra-Low-Altitude Vehicle is a treehouse equipped to explore the lower frontier of the troposphere.
Read: in chronological order newest entries first Read about: All entries Jon's build log Jeremy's electronics log Grandma Jan's flight suit |
|
Fixed TWI Sunday, March 14, 2010 -- jelson
I have a pile of other plans, including getting the rocket to work. Which I did. The rocket works. I'm 99% certain if you go to the back yard and reprogram it, it'll work.Jon: Well, my friend, I'll take those odds, because you're right! Woohoo! I'm sitting in the R-ULAV right now. svn up, make, attach cables while making, and everything just works, right out of the repository.Jeremy: The photo shows the test rig I used to get the rocket to today's glorious state. Center: sender and receiver boards running twitest. Left: My new TWI bus board (v2!), with extra headers for test probes and even a power light. Back: the Rigol scope and USBee logic analyzer. Center: two programming boards.
Got TWI working! Sunday, February 21, 2010 -- jelson
I just checked in a big pile of code. I refactored the network stack so that network.c is strictly packet-oriented, and the framing code is separated (but not working) in a separate file called framing.c, used for underlying physical interfaces that are byte-oriented. I'm confident enough in this that I'm going to bring CPU1 in tomorrow so Jon can install it.
Getting TWI working Tuesday, February 16, 2010 -- jelson
I started working through this, luckily with my trusty logic analyzer which has I2C bus decoding logic built-in. (This task would have been impossible without it.) There were a bunch of hard-to-track-down software bugs to work out, but the biggest problem turned out to be an electrical one. For bus sharing, TWI bus members are "open collector" -- that is, the bus needs pull-up resistors so that it is defined as being high if no one has seized the bus. Each TWI bus member can drive the bus low, but the only way to make it high is to disengage the drivers and let the pullup resistor bring the line high again. The issue was that the resistor had to be small enough that it could "charge" the bus back to Vcc in a timely manner. The definition of "timely" is a combination of the configured bit rate (i.e., how quickly the edge needs to reach its intended value) and the total bus capacitance (larger caps need more current to charge in that time). I arbitrarily picked a 10k resistor, since that's more or less the "usual" value of a pullup resistor, but things were acting very strangely. Out of desperation I searched the internet for advice on how to pick a TWI pullup resistor value, and found conflicting answers. One source said "I've seen values from 1k to 48k". Another said "4.7k is the standard value." Really, how much of a difference could it make to go to 4.7k to 10k? Out of desperation, I tried it anyway. Watching the logic analyzer's signals go by, things seemed to work for the first time! Then they stopped. Then they started again. I finally decided to get out my new analog scope -- the one we used to diagnose the problems on our other bus -- and there it was, clear as day (image above). This is a picture of the bus with 4.7k resistors. Wow. Those "square" waves aren't very square. It takes so long to charge the bus that the line isn't even getting all the way up to Vcc before it's time to discharge again for the next clock cycle -- it's about a volt shy. 10k resistors probably were, in fact, right on the edge: just a little bit slower, they charged the bus just a little less -- less than the detection threshold.
I fixed this in two ways. First, I changed the resistors to 2k resistors.
Second, I reduced the bus speed from 500KHz to 100Khz (which is the TWI
standard anyway). And now, voila!
We're reaching Vc and staying there for a while before it's time to discharge again. Now everything works -- here's the logic analyzer snooping on my first "hello" message from one CPU to another. You can't quite see it at this scale but there's acking of each byte. The first block ("02 Write") means the master is saying "I want to send a message to node 2". The sliver after that is node 2 acking that it's ready to receive. Then, the master sends a series of bytes, each of which is individually acked by the receiver. Finally the master sends an end-of-message signal and releases the bus. Yay! I haven't pulled the TWI all the way through into the networking stack yet but, that's tomorrow's project.
EPB on a real scope Saturday, February 6, 2010 -- jelson
Yup, apparently violating all thirteen rules of capacitative and inductive coupling has resulted in a measurable amount of coupling. Notice also that even the valid signals are wandering -2V to +7.5V, on a system with only a 5V power supply. Jeremy snipped the strobe line in preparation for replacing with a shielded wire. He measured the effect again -- and we saw 2V of coupling just from the nine inches of ribbon cable leading out of the CPU0 board. But what really freaked Jeremy out was this: When he measured the strobe line on a board that wasn't plugged into the CPU, it was still coupled! The only coupling was through the power supply: the meteoric slew rate on the signal lines was enough to swing the power supply voltage almost a volt. Ouch. Our plan is to first install the shielded conductor for the strobe signal, which should reduce the wire-to-wire coupling back down to 2V, which while ridiculous, will probably get the rocket working again. If it doesn't, I'll rebuild the buffer board a third time with JD's proposed resistors to damp the slew rate to something finite, which should clean everything up quite a bit. Here's hoping!
All boards assembled Thursday, December 17, 2009 -- jelson
Final Power Board Wednesday, December 9, 2009 -- jelson
On the far left is the input section. We'll terminate the Romex cable coming through the conduit from Jon's house with a couple of ring terminals that will attach to the board with screws. The input is 12V; a green LED shows that house power is on. Lower left is a 3-pin terminal where we'll attach the master power switch. That will feed power to both of the output sections: 12V and 5V. The 12V output section is just the raw house power, switched but unregulated. It will feed the cockpit lights and the HPAM -- which, in turn, switches power to the thrusters and paint shaker. Power for the 5V output is generated by a switching power regulator and will be used for all the avionics panels. Both output sections have red LEDs showing they're active. Right now the 5V output section only has 5 connectors, but that's just because I ran out of connectors. There's room for 18. The photos on the right both show the new power board. The second photo shows the new board powering the mission clock panel and was taken with the lights off making the LEDs more clearly visible. Wow, those hundreths-of-a-second LEDs are ridiculously bright! Good thing we moved them from my office wall (where they're distracting) to the rocket (where they're just pure awesome).
The Power Board Sunday, December 6, 2009 -- jelson
Yesterday, I went to Jon's house to help him pull wires through the trench he'd built between the rocket and the basement. The trench will carry compressed air and water for the thrusters, power for the boards, and data between the house and the rocket. (The rocket has more utilities coming into it than my apartment!) We realized that the next step on the critical path was building a board that would distribute power from the house supply out to all the various panels. We'd planned on having such a board from the beginning -- I ordered the necessary components from Digi-Key 3 months ago -- but hadn't needed to put them together until today. I had a busy weekend, so only had an hour or so for board-building time. I thought for a while about the best way to construct the power board, drew a schematic, threw it out, drew a 2nd one, and then prototyped it on a breadboard. It'll have a big red power switch, two indicator LEDs, 12 5.5V outputs and 3 12V outputs, with room for future expansion. Some evening this week I'll build the real board.
Planning the final panel Monday, October 26, 2009 -- jelson
I used PowerPoint to draw a dozen different proposed panel modules. Then, one evening after work, Jon and I clambered into the newly risen rocket with a dozen correct-scale printouts of a rocket panel. We cut each module out and pasted the ones we liked all around us. I have to say, seeing all those displays up in the rocket, even though they were just paper, was pretty exciting.
Tonight, I started the process of building all the final boards --
labelling each one with its intended function, and taping all the
right colors and sizes of LEDs into it. It feels like we're almost there!
Joysticks controlling thrusters -- it works! Sunday, October 25, 2009 -- jelson
I don't think I really appreciated how complex this project had become until I sat down yesterday to make this all work. I was shocked to discover that there are no less than 6 separate components that must be chained together in a long line:
The past two days were mostly spent building all the special cables to connect the components to each other and writing software. ADC-read voltage values from the joystick are converted into positions assuming the hyperbolic resistance-to-voltage curve shown in the joystick entry. I settled on 40k resistors. The positions are scaled to a value from -99 to +99, with 0 at center. Hysteresis is used to threshold the joystick positions; +/-50 triggers, and +/- 30 releases. Depending on the joystick direction, one of the three thrusters is fired. It all works! Here's a video showing the whole system:
Monday, October 19, 2009 -- jelson
Of course, having written a time-sync dissertation, this clock would need to be accurate. My original plan was to signal the start of each second using a single GPIO line, but Jon convinced me to use a full-fledged serial port to send complete time messages. After some resistance (I was afraid the serial port would be too complex) I agreed. The first step was to establish a data link between my PC and the board. I bought some MAX-232's, which are chips that convert the voltage used by a PC serial port to the voltage used by typical microcontroller. I prototyped an interface board that would take a PC serial port, short-circuit the flow control lines like a null-modem does, and put the 2 data lines into the MAX-232. I wrote code on the controller to configure the UART, accept serial port interrupts, timestamp them with high precision, and enqueue the characters. As a first test, I wrote a simple program that would just read characters and display them. It was surprisingly cool: I could type on my PC keyboard, and see messages scroll across the 7-segment LEDs! Next, using my newfound power to get messages from the PC to the board, I set out to get my clock to tick correctly. I wrote a small program that runs on the PC which sends a message to the serial port once every minute, precisely at the beginning of the minute, telling the board what time it is. (The PC's clock is synchronized using NTP, via the Internet.) The clock board lets the clock run free in between the messages; when it gets one, it both sets the time and trains its oscillator so that the length of coming free-running minute will be accurate. It annoys me that most time-sync software doesn't do this; usually, they just jump the clock to the right value every few minutes, giving you a clock with a sawtooth pattern. Finally, I built a permanent pair of small connector boards so I'd be able to feed both power and serial data into a single 4-conductor cable to run from my office PC to the clock. If this sounds like a project that consists mostly of a hundred tiny little details, you're right. But the result is awesome, and I'd estimate remains accurate to within 20ms of the PC's clock throughout the entire minute between pulses:
It's now hanging on the wall outside my office. If you're ever at Microsoft, stop by 99/2374 and take a look at it!
Saturday, October 10, 2009 -- jelson
The v1.1 boards were more evolutionary than anything else, as you might know if you've read the rest of the entries in painstaking detail. Perhaps the most visible change is that it now supports larger LEDs (0.56", vs the original that only supported 0.39"). Through some clever routing, a single board can take either size of LED, or a combination. v1.1 also have some convenience features: mounting holes, a reset button, more analog-to-digital converter pins now available, a joystick port (a single header with 2 ADC inputs, plus a GPIO input for the trigger button), and so forth. To the right is a picture I took of the first v1.1 board with LEDs soldered in, showing that both the larger (green) and smaller (orange) LEDs work together. This v1.1 board doesn't have a processor yet; it's being controlled via the data bus by one of the older v1.0 boards. I also have a glamour shot of my "signature" on the new PCBs. By v1.1 I'd figured out how to add custom silkscreening so I put my name on it.
Reading a joystick Thursday, October 8, 2009 -- jelson
After some research, we discovered that old-style PC joysticks are actually just two potentiometers, one for the vertical and horizontal directions. Joystick buttons are just plain old pushbuttons that ground their inputs. This should make it easy to attach a joystick to a microcontroller. In theory. Step one was finding a joystick. Modern joysticks are digital monstrosities with USB interfaces. We needed a 1990's era joystick, and they were surprisingly hard to find. No one uses them any more. Finally, one popped up on Craigslist for $1 nearby in Redmond, so I biked over there after work one afternoon a couple of weeks ago and picked it up. The 5-year-old previous owner was excited to hear his old toy was going into a rocket ship. I promised him a ride once it was finished!
Tonight I sat down to see if I could get the microcontroller to read the joystick's position. I thought it would be easy; I assumed that the top and bottom of the joystick's pot would be attached to +5V and GND, meaning the output would be some voltage in between, linearly mapped to the joystick's position, that could be easily read by the ADC. But... surprise! It turns out that for some reason, joysticks don't attach the bottom of the pot to GND, they just let it float. They just vary their resistance, as shown in the diagram to the right. The resistance varies between 0 and 100k ohms; 50k is center.
Wait, what am I talking about? Random stray circuit boards scattered around the rocket will just make it better! Sunday, October 4, 2009 -- jelson
Today's main project was building a small board that would let the main rocket panel actuate the rocket's "engine" and "thrusters". As Jon briefly describes in his todo list, he's going to run compressed air to the rocket from his garage air compressor. This will power both the rocket's "engines" (actually a paint shaker that will vibrate the rocket for "takeoff"!) and its "maneuvering thrusters" (actually pneumatic engine cleaning guns). Jon's original plan was to rig up some kind of mechanical valve to let the pilot turn these systems on and off from the cockpit, but I convinced him to buy some $18 solenoid air valves I found on EBay. That gives us the flexibility to have the thrusters controlled both from software and manually by the pilot We're going to write some sort of "launch sequence" program that will fire up the engines and thrusters; once in orbit, the pilot will be able actuate the thrusters using a joystick. Jon was resistant to the idea at first, but as soon as the valves arrived and he saw one turn on his paint shaker, he was glad the rocket's electrical and pneumatic systems would be working as a team! From my point of view, the plan was to choose one of the eight identical display boards as the controller, leave off one of its LEDs, and use the 8 unused latch outputs as control signals for 8 valves. Unfortunately, the latches can only source 25 milliamps at 5 volts, but the valves need 500 milliamps at 12 volts. The solution: a small board with power MOSFETs, using 5v control signals to switch the larger 12v valve power. More for fun than anything else, I also put LEDs on the board that light up every time one of the channels is active.
Since we only needed one or two of these boards, I just made them by
hand rather than getting PCBs professionally manufactured. And,
to really give the thing that 50's Fictional Space Program feel,
we gave the board a ridiculous name: the High Power Auxiliary
Module.
The end result, I must say, is super cool. Here's a video clip of
Liesl playing with the button box. Each button press lights up an
LED. I also attached a test solenoid to Channel 3; if you turn up the
sound you can hear it clicking when she pushes Button 3.
I'm heading to Jon's place tomorrow to try it with a solenoid that has
real air running through it .... how exciting!
Thursday, September 24, 2009 -- jelson
I also added a reset button, some nice silkscreened labels on everything, and more generous clearance between pads and vias to make the boards easier to solder without accidentally shorting two nets. Ever the eternal optimist, I ordered 20 of these boards -- enough for two full stacks, plus a couple of extra for development, or just hanging on my office wall. Why not, they're less than $3 each (plus $90 setup fee and shipping). They should be here October 5 -- something to look forward to after the NSDI deadline has passed!
Here's the final schematic and board layout. Note the schematic
is much cleaner once I learned how to attach remote nets just by
giving them the same name; the ugly and not-very-informative
blue bus no longer snakes its way through the center. Plus,
the bus connector's pins are all assigned to a logical name,
rather than a microcontroller pin: exactly how it should be,
since from revision to revision, we want the mapping of the
logical function (e.g., segment select) to position on the bus header
to
remain consistent, but we don't really care which microcontroller pin
is being used to drive the bus.
Wednesday, September 23, 2009 -- jelson
I have been spending most of my days lately writing a paper for a work deadline coming up, but my thoughts occasionally drifted back to the problem of driving a gauge. A few minutes searching both Digi-Key and Google revealed that, for some reason, high-current digital pots just don't exist. No one makes them. People on the Internet ask where to find them and they're answered with "They don't exist." I don't understand why. I started to think about taking a different approach. Really, why does the gauge want to see variable resistance? Presumably because it's measuring the resultant current. So, what if I found some other way to vary the current, other than varying the resistance? Transistors are current amplifiers ... might I use one? People often use transistors as simple switches, because there is such high gain between what you put in the control pin (the "base current") and what flows through the high-current pin (the "collector current"). Put in any reasonable base current, and the collector current gets driven up to the transistor's maximum. This is called "saturating" the transistor. But there's a range of base currents, before saturation, for which small increases in base current give proportional increases in the collector current. I wondered -- could I try using a transistor in this way? Yesterday, I measured the maximum current draw required by the gauge at 250ma for full deflection. (0 current gives 0 deflection.) It so happens I have some Darlington transistors here that have a current gain ("Hfe") of 20,000. So if I want 250ma of collector current, I'd need 250ma/20,000 = 12.5 microamps of base current. So I need a resistor on the base that gives me 12.5 micromps. Assume base voltage is 5v, transistor's forward voltage drop is 2v. That leaves 3 volts visible to the resistor. 3v / 12.5ua = 240Kohms. I attached a 200k ohm resistor to the base of my transistor, and sure enough, my gauge's needle went to full deflection and drew about 250ma. Now, on to gradually reducing this current all the way to zero, so the gauge goes through its range of deflections. The easiest way to do this (rather than hugely increasing the base resistance) is to reduce the base voltage, using a pot configured as a voltage divider. That is, 5v and gnd on the top and bottom, of the pot and the base resistor attached to the wiper, as shown in the diagram to the right. I hooked up one of my mechanical pots and, sure enough, turning the pot got the gauge to gradually move between its two extremes!! Sep 21st's entry showed a gauge moving when I had a mechnical pot attached, too. But there's an exciting difference here. Today's pot is only passing 12 microamps, not 250ma as before. In fact, I attached an ammeter in series with the pot, and it couldn't even measure the current flowing through it (its resolution was 1 milliamp). A dozen microamps is so small that I should be able to pass it through my digital pot, which is rated up to 1 milliamp, without melting it. I'll try attaching that tomorrow and see if it works! This is so exciting: another tool in my toolbox!
Monday, September 21, 2009 -- jelson
It's not too hard to find cheap used car gauges on Ebay. A couple of months ago, I paid all of $0.99 (shipping included!) for really cool-looking electroluminescent oil temperature and RPM gauges. We thought they'd be perfect for the rocket's control panel. Unfortunately, we couldn't figure out how to get them to do anything. They'd power up when attached to a 12V supply, but we couldn't figure out what kind of signal to put on the sense line to get the needle to move. I learned that car part manufacturers don't document their interfaces as meticulously as most other electronics components. If you go onto Digi-Key and buy so much as a 7 cent LED, it'll come with 8 pages of documentation, exhaustively describing its electrical and mechanical properties. Car gauges seem to come with nothing more than a flyer that says "Put 'er in your car! Then go get a cigarette! Yee haw!" After hours of web research I found a catalog page for a 3rd party fuel-tank sensor that said "Attaches to standard gauge (60 ohm full - 600 ohm empty)." At last, some data! Apparently you vary the resistance on that signal wire. I tried attaching our fancy gauges to a pot with the proper range but the needle still didn't budge. Finally, I speculated that perhaps the gauges were broken and that's why they cost $0.99. Jon took me on my first trip to a junkyard, charmingly named Pull-a-Part, and I paintakingly extricated a couple of gauges out of the dash of an Oldsmobile (I think). Hooked that up to a mechanical pot, and when I adjusted it with a screwdriver, the needle moved. Hooray! It's too bad those gauges are so ugly. The broken EL gauges looked rocket-y; the ones that work just scream "80s sedan". That brings us to today. How do you get a microcontroller to provide variable resistance? I discovered a clever device called a digital pot that does exactly that: every time you strobe one of its pins, it increases (or decreases, your choice) its resistance among 100 pre-set values. Easy, right? I ordered a few of them last week, and today tried to get one working.
First try: breadboarded a prototype, using buttons to strobe the
inputs, and measuring the outputs with an ohmmeter. Seemed to work,
but jumped forward a lot every time I pushed the button. My little
oscilloscope confirmed that button bounce was my problem (right).
Fourth try: the microcontroller and pot were powered off different halves of my power supply; maybe their grounds are floating relative to each other? I tied the two grounds together, and, success! I can now get the pot to increase its resistance by 10 ohms at a time. Fifth try: I hooked the pot up to the actual gauge rather than an ohmmeter. Everything broke; when I put the ohmmeter back, the resistance was 10 kohm (even though the pot is only rated to go up to a max of 1 kohm!). Tried with a 2nd digital pot; worked with the ohmmeter, then broke when attached to a gauge. I took another look at the datasheet, and realized that the pot was only rated for 5v across its terminals at a max of 1 milliamp. What the hell use is that to anyone? The gauge has 12v from its its sense line to ground and when I hooked it up to an ammeter, it was pushing 250ma through it. Obviously I was just destroying the digital pots. So ends the saga for now. I need to order some beefier digital pots and try again. Everything has been working so well on this project up until now, I guess I was due for some failure!
September 20, 2009 Sunday, September 20, 2009 -- jelson
Bang!
Saturday, September 19, 2009 -- jelson
There it is, hot off the Chinese presses -- v1 of the Rocket Panel Printed Circuit Board! I soldered all the components on, loaded the digit-identifying program onto a new microcontroller, popped it in, and turned it on. It worked on the first try! Isn't it beautiful?
But wait, there's more! I soldered half of a second board together (alas, I had only 4 LEDs left) and put together a 16-pin ribbon cable a few inches long. I connected the two bus connectors and -- voila! Both boards are being controlled by a single processor! As if that wasn't all cool enough, the programming header works, too! I was able to put new code on the microcontroller in place by just running a cable from the programming kit board to the programming header on my PCB. Total success! There was one minor board bug I discovered even before receiving the boards: a wire I was supposed to connect, but didn't, that's needed to read from analog dials. But that's easy to manually fix. Despite the fact that (amazingly) these boards work, I think I'm still going to order the v1.1 boards. They have lots of nice features, such as mounting holes, support for larger LEDs, support for 6 dials rather than just 2 (important because of our joystick, as I described on Sep 16th), and some other odds and ends. Still on the To-Do list:
Can you believe I'm running out of solder? That's like running out of baking soda. I think I've had my current spool of solder since I was in college.
September 16, 2009 Wednesday, September 16, 2009 -- jelson
One motivation for doing this is that Jon I were scheming today a way to attach a joystick (which is basically 2 pots attached to a lever) to the microcontroller. As the pilot moves the joystick, the microcontroller outputs will electrically control the solenoid air valves that actuate the thrusters and paint-shaker. I'll write more on this once we flesh it out. I'd hoped that the 2nd batch of PCBs would have only tiny revisions compared to the first, to minimize the chance of introducing new bugs. But the changes are pretty substantial at this point. Oh well! Tuesday, September 15, 2009 -- jelson
One feature I added to the PCB at the last minute was a couple of headers for analog inputs. Each header has 3 wires: power, ground, and a line back to one of the controllers' ADC inputs. I hoped that by attaching those three leads to a potentiometer, I'd be able to read the position of a dial. Unfortunately I didn't actually get a chance to test this before sending the PCBs out to be produced. I ordered a bunch of panel-mount 50k pots that arrived yesterday, and scrounged a rocket-looking knob out of the hardware lab at work. This evening I tried hooking them up to my proto-board, and wrote a few lines of code that would read the analog input once every 50msec, scale it to a value from 0 to 99, and display that value on the two LEDs on my protoboard. Amazingly, it worked (almost) without a hitch! (The only hitch: the ADC input I was using is the same pin as one of the general purpose input/output pins. I had set all I/O pins as output pins, so a low value was being asserted on the same pin the ADC was trying to read, and always returned 0 -- except when the pot was at such a high value that it overcame the internal resistance of the output pin. When I reconfigured the GPIO as an input pin, everything worked.)
A Simulator Saturday, September 12, 2009 -- jelson
Sure, the hardware's not here yet. But, since when is a lack of completed hardware an excuse not to work on the software? I spent an hour or two writing a little Rocket Panel Simulator that runs on the console under Linux. It's essentially just a display module that I can link against the same code that goes on the real rocket. When the code is compiled in simulator mode, the functions that assert real I/O pins are replaced with functions that interact with my simulator module. To the right is a screenshot of the simulator, configured to display 6 8-digit numbers, running the digit-identification program. I also made some minor updates to the schematic and board layout yesterday. Primarily, I corrected the footprint of the dial connectors. Since the real footprints are smaller, there was also space to add a 3rd one. I also found the connectors at DigiKey that match the templates I used on the v1 boards. If the boards actually work, I may as well just buy the connectors that fit on the boards instead of doing something hacky.
PCB Layout v1.1 Thursday, September 10, 2009 -- jelson
The biggest difference in v1.1 is that the board now supports two different sizes of 7-segment LED displays. The original board only supported 0.39" high digits, because they're cheapest. But there are a couple of models of cheap 0.56" high digits too, which, being bigger, are naturally cooler. For maximum coolness, we really wanted to be able to mix up the sizes -- have a wall with digits in a variety of colors and sizes. But, for simplicity, we only wanted a single board, so our idea was to have a board that has two sets of mounting holes (and associated traces), fitting both sizes. This version of the board now has this feature. It mainly required learning how to extend the parts library in my PCB design software, since this particular type of 7-segment display wasn't in its pre-defined library. And, hats off to Lite-On, the manufacturer of these LEDs. Their pin layouts really makes board design a lot easier. One, their two anode pins are 3 and 8, which are the middle pins in both rows. This means two good things: first, the supply line can run horizontally all the way across the board, without any turns. Second, you can mount LEDs upside-down, which is useful to make a clock (mounting every other digit upside-down gives you a series of colons, rather than decimal points). Also, even though their 0.56" LEDs have horizontal rows of pins, rather than vertical as in the 0.39" version, the segments are controlled by pins in the same quadrant, making the superimposition I was trying to do quite easy. And the supply lines end up being simple vertical tendrils off the long horizontal supply line for the smaller LEDs. The extra traces were all quite short and didn't intersect with each other. At right is a screenshot of two adjacent digit positions, each of which is a 0.39" and 0.56" LED superimposed so that either can be mounted. I learned lots of other new features of my schematic editor, which let me do other cool things:
I also blew another $75 at DigiKey today, getting enough ICs to build 3 fully-populated 8-LED boards (when the v1.0 PCBs arrive), and some other odds and ends. In particular, 4 electronic potentiometers so that the microcontroller can control the needle on a car gauge, and some manual knob potentiometers so the kids can twirl some knobs. I have a board design in mind to support the gauges, but that'll have to wait for another post. Here's the latest schematic and board layout, both with and without the traces visible.
Sunday, September 6, 2009 -- jelson
The next step was to try getting a board manufactured. I redrew my schematic using different software, Eagle, that made it easier to go from a schematic to a physical board. I also added a few other features:
I learned that it takes a lot of tweaking to get the board nice and compact. Early versions were way too spread out. Partly this was because Eagle's default minimum clearance between traces (i.e., the number of "wires" you can pack into a space) was conservative: 1/20'' (50 "mils") between traces. But, the board manufacturers I found claimed they could make boards down to 8 mils; the board got much smaller when I switched Eagle to using a 10 mil routing grid. I also tried to keep the wires from crossing where I had freedom. For example, the resistor ICs are symmetrical; you can go in on the left and come out on the right, or vice-versa. I had each wire enter the resistor on the same side as it exited the latch. Finally, I ended up with a nice, compact board! Exciting stuff! I sent this off to a PCB manufacturer in China called OurPCB and should have the boards back in two weeks or so. I'm getting 10 boards for $110. There's a $50 setup fee and $40 shipping; the boards themselves only cost about $2.50 each! Of course, if there were no shipping or setup fee, I'd make one board, see if it needs a correction, then get more. But since the boards themselves are such a small part of the overall cost, it's more cost-efficient to just order them all up-front if there's even a small chance they'll work. So I ordered 10. Keep your fingers crossed!
Adding a Keypad Monday, June 1, 2009 -- jelson
Of course, as soon as he said this, I realized he was right. So I added another new feature: a 16-key membrane keypad, pictured below, that I bought on Ebay for $3 directly from some random electronics house in China. In fact, I bought two of them, since shipping was $4 no matter how many you buy. I'm not sure yet exactly how the toy will actually work; maybe if you push "A" and then punch in a number, a row of digits labelled "A" takes on that value and starts counting up or down. Or something. But, hey, the Apollo missions flew to the Moon using just a keypad and some rows of 7-segment LEDs so I'm sure I can do something at least as awesome.
So, the procedure for scanning the keypad is
The connector for this keypad had a single-row, 8-pin interface with standard (0.1'') spacing. It so happened that I'd already decided to make the board-to-board control bus a 2-row (16-pin) connector of the same spacing. So I thought I'd do something clever: try to save pins and connectors by plugging the keypad right into the bus connector. Unfortnately, I made a mistake. The assignment of signal pins to positions on the bus connector is arbitrary. I reasoned that if I assigned the pins carefully, I could just plug the keypad right into the bus connector, and not even use any extra GPIO lines on the microcontroller. I assigned 8 address lines to the first row, and made sure the Enable pin was on the second row. I figured that as long as I kept the Enable pin un-asserted, I would be able to twiddle the other output pins in order to scan the keypad without affecting the state of the latches. I thought this was a clever way to conserve microcontroller IO pins.
To fix this, I updated the schematic to bring 4 dedicated input pins out to the first row of the bus connector, and move four of the outputs to the second row. Of course, there was no way I was going to update the physical wiring to test this...the test will have to wait until the prototype PCB arrives. In the meantime, to test the scanning procedure, I changed the software to display the key pressed for 3 seconds after the key is released. That is, I could press "5" (the display failed while the key is pressed), and after releasing the key see "5" appear on the display for 3 seconds. Yay!
The Second Prototype Monday, May 25, 2009 -- jelson
The first step was to draw a real schematic; this was starting to get too complicated to keep everything in my head reliably. Next I laid out all the components on the protoboard to get a sense for how they'd all fit together. This required working out a bunch more details, like finding a DIP switch, power connector, a connector for the control bus (and mating ribbon cable and socket), and a socket for the microcontroller (so I could swap it in and out, instead of soldering it permanently). I also switched from the individual wire-lead resistors to IC-shaped resistor chips -- basically just 8 resistors in a 16-pin package. I soldered the components in, and, following my schematic, started to painstakingly make all the electrical connections. The process of cutting a wire to the right length, stripping the ends, and soldering it in is surprisingly time-consuming. It took many hours over several evenings, after which I'd only fully connected 2 LEDs. I decided there was no point in continuing. A board with 2 digits was complete enough to test what I wanted to test. I'd test with a 2-digit board and let a PCB manufacturer do the hard work of running every wire to a fully populated board. I turned the thing on and was sad to discover it didn't work. After a while with a voltmeter, I concluded the driver wasn't working properly. Of course, the real problem was that I didn't understand how it was supposed to work. I'd thought that if you put a voltage in (low or high), the same voltage would come out. Not so: it's what's called an "open collector" driver. That means if you put in a low voltage, a low voltage comes out, but if you put in a high voltage, nothing comes out; the circuit is open, and whatever's on the other end just floats. The fix ended up being easy: I attached a pull-up resistor to each of the four outputs of the driver. Then it worked! Next, I wrote a test program that commands all 64 LEDs in the entire board stack to identify themselves once per second. For example, LED digit 3 on board 5 is told to display "b...5...d...3". This test served two purposes. First, it let me test the board-select circuitry. As seen in the video below, if use the DIP switch to configure the board as Board 2, the right most digit says "b2d0". Then, if I change it to Board 4, it starts to display "b4d0". Cool -- it worked! The test was also useful because it shows the microcontroller (running at 1MHz) has plenty of time to individually program all 512 segments (8 segments x 64 digits) with no visible delay.
Tuesday, May 12, 2009 -- jelson
The last time I'd tried to use an LED was when I was about 15 years old. I was really into electronics back then, but didn't have any good reference texts. One day, I saw a 7-segment LED in Radio Shack and thought "Wow, that would be cool to use!". It seemed simple enough: 7 individual power pins, one for each segment, and one common ground pin. I figured if I just attached a battery across the two, it would light up. I took it home and, unfortunately, couldn't get it to do anything. 20 years later, I started reading about LEDs and learned my problem: I had assumed that an LED was a resistive load, just like a light bulb. It turns out, diodes are magical things that cause a voltage drop but don't provide resistance. If you attach a battery directly across a diode, it's no better than a short circuit: the diode will immediately burn out. The right design is to add a resistor, chosen so that the current flowing through it, taking into account the voltage drop inherent to the diode, is no more than what the diode says it can take. My plan was to run the system at 5V. The LED data sheet said that the diode drop was 2V. That leaves 3V "visible" to the resistor. My target was about 10 mA per segment so I picked a 300 ohm resistor (actually, 270: the closest value I had in stock).
My first test was simply to attach an LED segment to a 5V power
supply and a resistor, to see if it would light up: Wow! This was exciting. I'd already done way better than 15-year-old Jeremy! Next I decided to try out a latch. I attached two segments of the LED to two of the latch's outputs (with resistors in between). Then I attached three buttons to the latch: one to the data input pin, one to the lowest bit of the "segment select" address line, and one to the Enable pin. And I finally learned just how to use pull-up/down resistors: you attach a high-value resistor to, say, a pin and ground. Then, on the pin side of the resistor, attach a push-button tied to Vcc. When the button is not pressed, the resistor (with no current flowing) keeps the pin at ground. When you push it, you tie it to Vcc instead; the resistor is so strong that the connection to ground is overcome. If I pushed Enable without pushing Data, the segment would go out. If I hold down Data and then push Enable, it lights up. If I did all of this while holding down the Segment Select line, it would happen to segment #2. I couldn't believe this was all working! I decided the next step was to get the microcontroller to flip the lines automatically, rather than me doing it manually with buttons. I hooked up all 7 segments to resistors and to the latch, and figured out how to use my new microcontroller programming kit. I made a table defining which of the seven segments should be lit up for each number 0-9, and each letter A-Z. (Some letters, like W, X, and Z, can't actually be represented by these displays.) Then I wrote a program having the controller cycle my LED through the all the numbers and letters. It worked! Next I added a second digit and a second latch, and a first demultiplexor that would let me select which of the two digits I was controlling. The circuit was really starting to take shape now: I had a real data bus, and real segment-select bus, even though there were only two devices on each bus.
Thursday, April 2, 2009 -- jelson
Luckily, I ran this plan past my friend Lew before going any further. He knows electronics pretty well, and suggested what I needed were some latches. A '259-model latch is a basic memory device; it can remember 8 bits, and asserts those values on 8 output pins. To change them, you twiddle 5 inputs: first, assert 3 address lines, to tell it which of the 8 outputs you're trying to change; then, assert 1 data line, to tell it what value that output should take; then, "strobe" (i.e., go through an asserted/unasserted cycle) the Enable line. So, by attaching each of the 8 segments of an LED digit (including decimal point) to the outputs of a latch, it's possible to control all 8 segments using just 5 control lines -- the latch's inputs -- instead of 8. But, more exciting is that this scheme scales well. If I want 24 digits instead of one, I need only 28 GPIO pins: the three address lines and one data line can run on a common bus, shared by every latch. 24 GPIO lines are then needed for each latch's Enable pin, letting us specify which latch we're actually talking to; the rest ignore the address and data lines because they're not being strobed. That is, we can program a latch by asserting the segment number on the three shared address lines (which I'll now call segment select), asserting the value of that segment on the shared data line, and then strobe the one (out of 24) Enable lines corresponding to the digit we're trying to change. But wait! We can do even better! Another clever device, called a demultiplexer, can reduce our pin requirements even further. '138 series demultiplexers take 3 address lines and one Enable line as input, and have 8 outputs. Unlike a latch, a demux only asserts one of its outputs at a time. When we strobe its Enable line, it strobes whichever of the 8 output lines we've selected using its 3 address inputs. Now, controlling 24 LEDs requires even fewer control lines: we can attach each LED to a '259 latch, with a common bus for the 1-bit data channel and 3-bit segment select, then attach each of the latch's Enable pins to one of the outputs of a demultiplexer. For 24 digits, we'd need 3 demultiplexers, 8 latches on each. Of course, the addressing input lines of the demultiplexers can also be shared. I will now call these shared address lines digit select. Then, connect each of those 3 demux's Enable lines back to the microcontroller. Now we can control each of the 8 segments of 24 LEDs using only 13 GPIO pins: 1 data line, 3 segment select lines, 3 digit select lines, and 3 pins that lead back to the Enable pins of the 3 demultiplexors. But wait! We're still not done! Now we can add a 2nd layer of demultiplexors. In other words, have one "top-level" demux, and attach each of its 8 outputs to the Enable lines of 8 more demux's. I will call the 3 address lines of this top-level demux the bank select lines. Each of the 2nd-level demux's can control 8 digits, so this is now a total of 64 digits, each with 8 segments (or a total of 512 segments) that can be individually controlled with only 11 output lines on the microcontroller: 1 data lineAwesome! And suddenly I more deeply understand how a computer's memory bus works. Unfortunately we're not quite done. When I showed this plan to my friend and colleague JD, he pointed out a problem. The data and segment-select lines have a rather large fanout: the microcontroller asserts just one data line and it is taken as input to all 64 latches. Most parts are spec'd for a maximum fan-out of 10 or 15. So, we also have to add drivers -- basically amplifiers -- one for each of the 8 banks. That is, the microcontroller asserts data and segment-select lines to 8 drivers; each driver re-asserts it to 8 latches. While the design seemed reasonable, the idea of assembling such a beast did not. Such a board would have hundreds of signal lines and close to 5,000 tiny holes that would need precise drilling. It didn't seem reasonable to try and fabricate it myself. I'd have to learn another new skill: how to draw a schematic and have a PCB professionally manufactured from it. Board manufacturers charge by the square inch. We wanted the rows of digits to be spread out (leaving room in between for things like labels, dials, etc.), so I added one final feature to the design. Instead of one huge board with all 64 digits on it, I'd make 8 smaller, identical boards, with their 11 magical lines all connected to each other using a ribbon cable. I'd give each board a DIP switch that would let me tell it which "bank number" it was. I should then be able to put a microcontroller on one of the boards -- it doesn't matter which -- and let the ribbon cable distribute its 11 outputs to all the others. Then, we'd be able to manufacture smaller boards in larger quantities, rather than one huge board. Plus, it has the significant advantage of letting us spread the numbers out in the rocket ship a bit more. With all this decided, I drew up a basic block diagram showing what each board would look like. I was so excited: the project was already paying for itself in teaching me new things! The diagram above shows the latches, but doesn't depict the LED or resistors attached to each latch. Also, it shows my cheesy board-select method: each output of the first-layer demux is attached to one switch in a bank of 8 DIP switches. Then all the outputs are bussed together. So, to select (say) board 4, you turn on switch 4, and turn all the others off. With some more complex logic, I could have made it work in binary (allowing you to select 256 boards), but this thing was already complex enough and other aspects of the design limited us to 8 boards per stack anyway. My next task was to pick a microcontroller. The first sub-task was to pick a brand of microcontroller. My only past experience with them was tinkering with some PICs with my friend Guy back almost 15 years ago. (Aside: We'd tried to build a board we could install in his apartment's front-door intercom so it would unlock the downstairs door if someone pushed the buzzer with a secret morse-code pattern. We hacked together an assembly-code program that seemed to do the right thing on a test board: lighting up an LED for a few seconds when we pushed a button in the right pattern. But it never worked when we actually installed it. Guy's dad, an electrical engineer, suggested a few changed, including "pull-up resistors", which neither of us had heard of at the time and had no Google to help us, so the project fizzled.)I spent a day or two comparing Atmel, PIC, TI and a few others, and finally decided on Atmel. I liked them most of all because they're open: with a gcc-based toolchain and open-source C library the environment felt comfortable. Though I wasn't expecting to write assembly language, the instruction set for Atmel's microcontrollers seemed much easier than PIC's somewhat bizarre and tortured design. The Atmel has 32 registers -- more than my desktop machine has! The PIC is so weird that GCC can't even target it. The PIC's development board seemed a little better (cheaper, and USB rather than serial-port based), but ultimately I decided on Atmel. The microcontroller I picked was the Atmel Atmega8, an 8-bit microcontroller with about 20 digital I/O pins, as well as some analog-to-digital converters, which will come into play later in the story. Wednesday, April 1, 2009 -- jelson
When Jon first started talking about building a rocket ship treehouse for his kids, it sounded like a static display: other than the shape and the material, pretty much the same as any other treehouse. But then he started talking about features that would make it come alive: pilot-controlled thrusters! A paint-shaker that simulates the rumble of takeoff! I got excited. I told Jon I thought his plans were desperately lacking something. The quintisenntial artifact that screams "1950's-era fictional space program": lots of flashing lights and dials and buttons and beeps. One of the things I've been meaning to do for the past few years is improve my working knowledge of electronics. And, fresh off completion of my automatic closet light, I was ready for a bigger challenge. I offered my services as an avionics subcontractor, and Jon readily agreed. My original idea for the control panel, in April of 2009, was relatively simple: lots of seven segment displays, perhaps 30 of them total, arranged in 6 groups of 5-digit numbers of varying colors. I'd imagined them flashing and counting, a constantly changing sci-fi display of random numbers. As we'll see, I rather dramatically under-estimated the ultimate complexity – and fun – of the project. The avionics ended up being
|