Friday, December 24, 2010

Arduino-Controlled Christmas Lights

It's not anything particularly impressive in the automatic Christmas light control category, but this is what I put up for the holidays.

It isn't much more than an Arduino and the TRIAC switch box out of my lamp control system.  The TRIACs are hung under the eves, with bell wire run into the garage where I have the Arduino board on an outlet timer.  It appears that the system is missing pull-down resistors on the TRIACs, since one of the channels leaks when the Arduino shuts down, glowing very dimly all day.  It never ended up being a problem, but since my TRIAC circuit is clearly wrong, I won't post it.

Source Code:

Thursday, December 23, 2010

Build Your Own Cloud Chamber

This last weekend, I had one of my friends down from Davis to experience the awesomeness that is the South Bay.  In addition to the typical Halted, Excess Solutions, and Weird Stuff, we also spent a day each going to the Exploratorium and the USS Hornet, which are both very good museums (Another we wanted to hit was the Computer History Museum, but they're closed for construction).  While at the Exploratorium, we saw an enormous cloud chamber, which is a device which allows you to see charged particles with the naked eye.  Theirs was quite big, being about the size of a desk, but I thought that even making a relatively small one would be pretty cool.  Marissa had to get back to Davis for work, but my best friend Jeff from middle school (Nine freakin years ago!) is back from Chicago for the month, and he's as big a nerd as I am, so we decided that today was a good day to try it.
The principle of operation of a cloud chamber is based on triggered condensation of saturated alcohol vapor.  In a closed container, you warm liquid alcohol on the top, then cool the bottom with dry ice.  As the alcohol falls to the bottom of the chamber and cools, it begins to condense, but it needs something to condense on, much like rain.  The typical trigger for this is dust, but once the air in the container becomes relatively clean, other irregularities start to trigger the condensation.  It turns out that alpha and beta particles, and muons, which hit the Earth all the time, slightly ionize the air as they pass through it, which is actually enough to trigger the alcohol to condense along the particle's path as it decelerates.  These alcohol trails are short-lived, but clearly visible with the naked eye (if not my video camera).

It actually worked!  This video was taken at the end when we finally got it working, which means I had spent the last three hours inhaling IPA and CO2 fumes, so pretty much ignore everything I say about which particles you're seeing; I'm wrong.  Just read the Wikipedia article for it.


Starting at the beginning, Jeff and I had no idea what we were doing.  I read a few vague articles on the principle of operation, but we had no real solid plans or expectation for it to work.
First step was collecting the materials.  Only critical parts are a container, some form of alcohol, dry ice, and some black paper.  For the container, my dad happened to have a 4L Erlenmeyer flask from his chemistry days at Berkeley, which was perfect for this project.  Different articles said different things about which alcohols you can or can't use, but we found a 16oz bottle of 99% Isopropyl alcohol at Safeway, and that worked for us.  We also bought 6lbs of dry ice at Safeway at $1.49/lb, which was pretty easy (just ask for a brick of ice at a register and show ID).
We decided to try and have a heated alcohol reservoir like they had in the Exploratorium instead of just soaked rags or paper, so we went to Halted and picked up some power resistors and a sample vial.  We didn't see much difference between this and just a hand-warmed rag, so I wouldn't recommend bothering with this unless you want to run it for a long time like for a science fair.
Soldering together a crude immersion heater.
The final heater in the sample vial of alcohol, hanging in the top of the flask by some light baling wire (family go-to tool, even two generations after moving from Montana).

Once the alcohol source was taken care of, the next step is to cool the bottom of the flask to cause it to condense again.  Our first attempt was by adding crushed dry ice into the flask, but this didn't work, causing a ton of turbulence by the subliming ice.
This is wrong; don't put the dry ice in the container.

This also didn't allow us to use the black paper on the bottom of the flask, so we tried again instead placing the dry ice in a pie pan around the flask.  This removed the turbulence problem, and we started seeing falling droplets in the flask.

This got us very close to a working cloud chamber.  The final trick was that it is CRITICAL that you have a standing pool of alcohol on the bottom of your container.  Without this pool, it's impossible to generate the saturated layer you need to see the alpha and beta trails.  After each time we opened the flask and adjusted something, it took about ten minutes for the flask to cool down again and form the temperature gradient from top to bottom needed.

So the tricks here are:
  • Keep the dry ice out of the container and finely powdered to better cool the container (unless you manage to get a flat piece, you lucky dog you)
  • You can use drug store IPA, and don't need anything more than your hand to warm it.
  • Lay a piece of black paper on the bottom of the flask to see the white droplets against
  • Have a pool of alcohol on the bottom to help form the saturated region
Overall, it was a very cool project, and at only $2 for the IPA and $10 for twice the dry ice we needed, it isn't that expensive of an experiment either.

Of course, once we had had enough electron spotting, we had to do something with the rest of the dry ice.

This may or may not have ended up with me managing to freeze a pie pan to the garage floor for several hours before the rest of the dry ice sublimed away...

Track Changing Public IP Addresses (with a Chumby)

I spent the winter break down in Sunnyvale with my parents for a month, which was somewhat unfortunate because their internet is very unstable, but only when it rains...  We're talking pretty much unusable for 6-12 hours after any form of precipitation.  Of course, isolating it to this correlation took a tremendous amount of work of itself, but to really finally get it fixed, we needed more data.  This was because AT&T takes 4-5 days after you call to get a technician out to look at your phone line, and the likelihood of us being able to call AT&T five days before a rainstorm is... marginal...

Once AT&T got here, if they didn't see anything wrong, they were going to hit us with $55 for wasting their time (ohhh the irony).  If we actually had some physical evidence to prove our theoretical correlation between rain and poor phone line quality, the likelihood of getting charged the $55 was reduced.

With the Chumby as my most recent hammer [1] [2], this certainly looked like a nail.  Write a short shell script on the Chumby, which is the closest thing to a computer which is always on, to periodically log our public IP address to a text file.  Then when it rains and the internet goes down, we get several hours of no public IP address, and a different one when the modem comes back online and gets a new DHCP lease from Earthlink.  To make monitoring the logs easier, my dad and I worked on a CGI script on the Chumby's web server to display the logs in an easy to read manner (I needed his help with AWK, which I have never done anything more than 'print $3' with before).

This was our result.  (The actual collected data can be viewed on the Chumby itself, which is finally back online after this internet connection problem and some DNS issues)

The logging script is not much more than an hourly cron job dumping the current time and the interesting line out of a wget http request to's geoip location service.

The resulting log file from this script ends up looking like this, which is a little challenging to scan quickly:

Sat Dec 11 12:00:01 PST 2010
<geoip ip="" iso_country="US">
Sat Dec 11 13:00:02 PST 2010
<geoip ip="" iso_country="US">
Sat Dec 11 14:00:02 PST 2010
<geoip ip="" iso_country="US">
Sat Dec 11 15:00:02 PST 2010
<geoip ip="" iso_country="US">
Sat Dec 11 16:00:01 PST 2010
<geoip ip="" iso_country="US">

The CGI script takes this log file, and formats each pair of lines to a single line which is much easier to read.  Additionally, it filters the results by eliminating all the lines that have the same ip address as the one before it by using uniq -f 7, which filters duplicate lines, ignoring the first six fields.

Note that the meat of this shell script, the awk command, doesn't have the program inline like is common for simple shell scripts, but instead references an external file, since the awk script ended up being several lines.  It also uses the argument -F\", which tell awk to use the double quote instead of white space to seperate fields (the backslash is to escape the double quote from the shell).  This splits the XML tag returned by geoip into five fields, so picking out the IP address is simply a matter of used regular expressions to determine if the IP address is returned before or after the country code (which is what you're supposed to actually be interested in).  The date lines will always start with an M, T, W, F, or S, so if a line starts with that, we want to go to a new line and print that and the % before finding the next IP address in the log.

As you can see, each line of an AWK program consists of two parts.  First, there is a regular expression condition, which tests for some specified pattern.  If that pattern happens to be matched by the current line being processed, the commands inside the { } are run on that line.

Take the first line, for example.  The pattern it looks for is /^[MTWFS]/.  The ^ means "starting at the beginning of the line", and the [...] means "one of these characters", so this pattern is looking for lines that start with any of M, T, W, F, or S.  If this condition is met, the command is run, which is printf("\n%s %% ", $0).  This means to print a new line (\n), print a string (%s), and print a % symbol (Have to escape it with a second one since % has special meaning for printf), and oh yeah, the string to print is $0, which in AWK is the entire line.  So this gets us the date and a % sign on a new line.  AWK then looks on the next line of the log file to find an IP address to place after the %.

This is done by the second and third lines, which are effectively the same except they handle the two cases where the XML comes back with either the country code or the IP address first.  For the sake of an example, we'll look at the first of the two:
/.*"US".*"[0-9.]*"/{printf ("%s",$4)}
The regex pattern is /.*"US".*"[0-9.]*"/.  The period (.) means any character, and the asterisk (*) means zero or more of the previous character, so ".*" means any number of any character, before the first ", which is the field delimiter for this specific program (via the -F/" argument).  Between the first and second ", there must be the string 'US', which obviously will break if this server leaves the country, but I don't plan on doing than, and changing it to match two of any letters would be relatively simple with ".." (match any character, twice).  After the second ", there's another .*, so any number of any characters, then the meat of the pattern, which is the IP address.  IPv4 addresses only consist of digits and periods, so we can say [0-9.]*, which means any number of (*) the digits 0-9 and periods ([0-9.]), which is what we're interested in. There's then another ", and that's the end of the pattern, if not the line.  The command to execute for lines matching this pattern is fairly simple, being only printf("%s", $4)

Taking the first two lines of the log, you can see how this converts the log into the result shown below.
Sat Dec 11 12:00:01 PST 2010
<geoip ip="" iso_country="US">

The first line starts with an S, matching the first AWK line, so it's printed on a new line with a % symbol after it.  The second line has an IP address in the second field, and US in the fourth, so it matches the third pattern, and AWK prints only the second field, giving the final result for the two lines:

Sat Dec 11 12:00:01 PST 2010 %

The final result of this exercise looks like this (which can also be seen live on the Chumby):

Sat Dec 11 12:00:01 PST 2010 %
Sun Dec 12 09:00:02 PST 2010 %
Sun Dec 12 10:00:01 PST 2010 % 
Sun Dec 12 12:00:02 PST 2010 %
Sun Dec 12 13:00:01 PST 2010 %
Sun Dec 12 17:00:02 PST 2010 %
Sun Dec 12 18:00:01 PST 2010 %
Mon Dec 13 06:00:02 PST 2010 %
Mon Dec 13 09:00:02 PST 2010 %
Tue Dec 14 09:00:02 PST 2010 %
Tue Dec 14 10:00:01 PST 2010 %
Tue Dec 14 14:00:02 PST 2010 %
Tue Dec 14 15:00:02 PST 2010 %

Luckily, we happened to get a very good AT&T tech, who didn't see anything wrong with the line tester (of course it wasn't raining that day), but climbed up the phone pole and said he didn't like how one of the wire crimps looked, so he switched us over to the spare phone line into our house and our internet has been stable ever since.

If you want to learn more about programming in AWK, the de facto book for which is The AWK Programming Language written by the three authors of the original program:

Sunday, December 19, 2010

Driving VFDs for Fun and Profit (And More Clocks)

Continuing my unstoppable obsession with clocks, I built another one this summer based around a vacuum fluorescent display I found at Excess Solutions (one of the many local bay area electronics salvage stores).  VFD's are pretty cool, because instead of having each segment be an LED in typical displays, a series of wires and meshes are used to shoot free electrons at a phosphor, which then creates the light you see from the display.
VFDs are unfortunately also very challenging, due to the fact that they require voltages in the range of 40-70V, well in excess of the 5V my trusty AVRs can handle.  While pondering how to handle this challenge, short of building 20 transistor-based voltage buffers, I stumbled upon the AdaFruit Ice Tube clock, which drives a VFD (along with a much more developed interface than any of my clocks...).  Lady Ada is kind enough to publish all of her kit schematics, so why try and figure out how to drive the display myself, when she's already found a functional solution?
(As you can see in this picture, the off segments aren't entirely off, since I'm only grounding them and not negatively biasing them.  The contrast is much better in person than in these photos)

This solved two of my problems.  It turned me onto the MAX6921 VFD buffer chip, which is the shift register and the voltage buffers combined in one chip, and it gave me the circuit I needed for the charge pump to step the 5V coming from my power supply to the 40V needed to light the VFD segments.  Thanks LadyAda!
The problem with the MAX6921 is that it only comes in surface mount packages.  AdaFruit uses the PLCC package, which is square and has pins on all four sides.  I wanted something a little more breadboard friendly, so I opted for the SOIC package, along with a breakout board from Electroboards.  This means I can now feed 40V and 5V logic signals into the MAX6921 buffer to drive the VLD.
The only challenge left is how to generate the 40V.  Again borrowing a page from AdaFruit, I used a power inductor and a transistor to pump the 5V power supply up to the needed 40V.  They used a MOSFET in their circuit, but I was putting this clock together during the silicon shortage last year, so the MOSFETs they used weren't available.  As a shot in the dark, I tried using a standard 2N2222, which happened to work out fine, as long as you didn't exceed the 100V rating on it, which is surprisingly precise.  This means the 5V is fed through the inductor, which on the other end is alternately grounded and shunted through a Schottky diode to a high voltage capacitor.  This is called a boost converter.  Feel free to hit Wikipedia for a better explanation.

The rest of the clock is a fairly typical DS1307 talking to an ATTiny2313, which then multiplexes the digits of the VFD at 300Hz.


Source code listing at the end of the post!

So how do VFDs work?
 Vacuum fluorescent displays work on a similar principle to vacuum tubes, not that I expect that analogy to help.  If you look closely at a VFD, which you likely see every day in appliances like your microwave or car stereo, you'll see a few tiny wires running from left to right, and thin grates, or grids, covering each digit.  A current flows through the wires, heating them, which makes it easier for them to eject electrons in vacuum.  These electrons are attracted to positive charge.
Using the grids on each digit, you can control whether electrons are guided to it or not, based on it's voltage relative to the cathode wires.  0V would make the grids not very attractive, where +40V would make the electrons much more attracted to the grids, because electrons are negatively charged.  The electrons are then attracted to the grids, but most of them miss the grid, and fly through the holes in the grid towards the segments.  Controlling the segments is much the same, each segment is either biased 0V for off, or ~40V for on.  The segments are coated with a phosphor, which when struck by flying electrons, lights up, usually a nice bright teal color, like in the picture at the top of this post.  To reduce the number of required pins on a display, all of each segment are wired together, so to independently control every segment, you would individually positively bias a control grid, and the segments for that digit you want lit, then bring the grid negative again and do the same for the next digit.  This means only one grid is every positively biased, and attracting electrons, at a time.

Source Code:

Friday, December 10, 2010

My Workspace

Four-Three-Oh has been doing features of people's workspaces, so I figured I would jump on the band wagon and post some quick shots of mine.

 This first shot is my main electronics desk (yeah, cause I've got several desks squeezed into my apartment, like a boss).  The desk itself was custom made at a local machine shop in Sunnyvale.  There are two holes (you can see one to the left of the spool of solder on the main surface), which I can insert a crank handle into to raise and lower the desk from anywhere between very low and standing-desk-for-someone-short, which isn't quite me.

On the desk itself, from left to right, is the control panel for my apartment lights, some random Li-Ion batteries, a power strip and switch box, which I use for my cheapo Weller soldering iron, which is sitting in a Radio Shack third hands, an HP 3435 multimeter, my Chumby One, some chocolate chips (I freakin love chocolate!), and my final project for EEC180A Digital Systems.

The top level has a bunch of random class papers, lots of random pieces of wire and passives, an eight port gigabit switch, and my main WRT54GL (of six) [1] [2].

On the book shelf below the desk is all of the text books for my classes at UC Davis.

Not shown in this picture is the desk to the right of it, which has my main desktop computer on it (running Ubuntu 10.04), and 20 feet of textbooks not for class, but personal use (computer science, electronics, metallurgy, welding, civil engineering, battle tactics, science fiction, etc).  Also not shown is my walk-in closet, in which I only have three shirts, but a ton of boxes of cables and wires and e-waste, and 5 digikey boxes FULL of components for projects.  My closet just kind of becomes the dumping ground for stuff...

 This is my third desk, which has some of the bigger equipment on it.  On the left is a 7MHz Tectronics scope, which was new in mid-1970's, so the fact that it has digital memory is a big deal.  Next to that is a 1000x metallurgical reflective microscope, which I don't use for anything more serious than just looking at stuff (see below for some pictures from it).  Not much else of interest except for another computer (of the eleven I happen to own, most through people giving them to me), and spare monitors.  Right behind the scope is our Femtocell miniature cell phone tower, which gives us much better cell phone reception throughout the house through our internet connection.

I've never tried taking pictures through the microscope before, but these turned out pretty well, so I might try this again some time.  These are both pictures of a penny at 1000x magnification, which is more impressive than it is useful, due to the tight focal depth and almost instant motion sickness when you use it this high.  It has 5 optics, for 100, 200, 400, 600, and 1000x, and I usually just use the 200x one.

It was originally designed for looking at 3" wafers, which have gone out of style, so living in the Silicon Valley means I actually managed to snap this thing for free.
That is old Abe's head on the penny. On the back. In the Lincoln Memorial.  Yeah, the statue in the middle.  His shoulders are just below the frame.
This is just a random close-up of a flatter part of the penny, to show how you can see the crystalline nature of the copper no problem.  Playing with this while growing up really made the whole concept of metallic crystals in Properties of Materials less of a big deal...

I will definitely spend the rest of the month (yay no more school!) working on getting some good shots of stuff on this thing.  I haven't played with it in a while.

Monday, December 6, 2010

Soldering the GoodFET 31

I ordered all of the parts for two GoodFET 31 boards a few weeks ago, and the last of it finally came in today.  The GoodFET is an open source JTAG adapter, which has additional features, much like the bus pirate, allowing it to interface using several other protocols such as SPI or really any other protocol which you feel inspired to script for them.

The challenge of the GoodFET is that it isn't sold anywhere prebuilt, let alone sold as a kit, leaving the only option of ordering a board from the GoodFET team, and the rest of the parts from your standard parts supplier.  Since several of these parts are minimum quantity 10, and you only need two per board, I decided to order enough of everything else to build two complete boards.  The components and blank PCBs worked out to be about $25, which is a pretty good deal for two bus pirate like devices.
The finished boards.

Parts list:
I soldered the boards using the fairly standard solder paste and hot plate reflow technique.  Lacking a solder paste mask means that before reflowing the board, you need to spend a lot of time with a toothpick to make sure you have the amount of paste down correctly to save yourself rework later with solder wick braid and an iron.
Here is a slightly blurry picture of all of the components placed on the board with solder paste.  The exact amount of paste is an art more than a science when manually applied, so don't expect your first few attempts to turn out perfect.  I used a pair of tweezers and a few steel picks to place the parts.  You don't need to get the parts perfectly placed on the pads, but just close enough such that surface tension can do its job to pull them the rest of the way, which you can see in the video.

Reflow Video:

As you can tell, I was really excited in the video.  Unfortunately, the coffee I had while working on the first board started to kick in while I was working on the second board.  It is amazing how much caffeine can destroy your fine motor control.  I managed to drop the molten board, then flick several parts into oblivion on the second board.  The surface tension worked beautifully for this first board to pull in all the parts, but I didn't get the chips centered close enough on the second one, which then reflowed the 232 chip one pad off, which meant reflowing the board and edging it over into place.

As you can see in this (amazing) photo (thanks, prosumer camera!), the first board had a little too much solder paste on the IC pads.  This meant some manual rework with a soldering iron, flux, and copper braid to pull out the extra solder between pins.  A 30x jewelers loupe definitely helps find the less obvious bridges.

After rework, the solder bridges were all taken care of, the board checked for shorts and opens, and we're ready to plug it in to reprogram it.

I programmed these GoodFETs using my desktop running Ubuntu 10.04, and ran into some problems along the way.  The infodumps ran fine for both boards, but when it came time to program the MSP430s with the GoodFET firmware, the script kept dying.  90% of the time it gave a timeout error like the following, 7% of the time it gave a NACK error (bad password), and 3% of the time, it programmed fine.

kenneth@KWF2:~/prog/goodfet$ sudo goodfet.bsl --fromweb
MSP430 Bootstrap Loader Version: 1.39-goodfet-8
Use -h for help
Use --fromweb to upgrade a GoodFET.
Mass Erase...
MSP430 Bootstrap Loader Version: 1.39-goodfet-8
Use -h for help
Use --fromweb to upgrade a GoodFET.
Mass Erase...
Transmit default password ...
Invoking BSL...
Transmit default password ...
Current bootstrap loader version: 2.2 (Device ID: f227)
Grabbing f227 firmware.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 33993  100 33993    0     0  46812      0 --:--:-- --:--:-- --:--:-- 80743
Program ...
Traceback (most recent call last):
  File "/usr/local/bin/goodfet.bsl", line 1750, in 
  File "/usr/local/bin/goodfet.bsl", line 1688, in main
    for f in todo: f()                          #work through todo list
  File "/usr/local/bin/goodfet.bsl", line 1151, in actionFromweb
    self.programData(fw, self.ACTION_PROGRAM | self.ACTION_VERIFY)
  File "/usr/local/bin/goodfet.bsl", line 925, in programData
    self.programBlk(currentAddr,[pstart:pstart+length], action)
  File "/usr/local/bin/goodfet.bsl", line 910, in programBlk
    self.verifyBlk(addr, blkout, action & self.ACTION_VERIFY)
  File "/usr/local/bin/goodfet.bsl", line 873, in verifyBlk
    blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout))
  File "/usr/local/bin/goodfet.bsl", line 668, in bslTxRx
    rxFrame = self.comTxRx(cmd, dataOut, len(dataOut))  #Send frame
  File "/usr/local/bin/goodfet.bsl", line 445, in comTxRx
    rxFrame = self.comRxFrame(rxNum)
  File "/usr/local/bin/goodfet.bsl", line 362, in comRxFrame
    if len(rxFramedata) != rxLengthCRC: raise BSLException("Timeout")
__main__.BSLException: Timeout

The few times I did manage to flash the firmware, the self-test went down in flames:

kenneth@KWF2:~/prog/goodfet$ goodfet.monitor test
Performing monitor self-test.
Warning: waiting for serial read timed out (most likely).
Echo test failed.
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
ERROR Fetched 0154, 0302
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
ERROR, P1OUT not cleared.
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Echo test failed.
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
ERROR Fetched 0100, 0302
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
ERROR, P1OUT not cleared.
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Echo test failed.
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).
Warning: waiting for serial read timed out (most likely).

This wasn't good.  I double checked the boards, but since the infodumps worked, it looks like we're looking at an intermittent software problem, which is THE WORST KIND OF PROBLEM.
Long story short, some poking around yielded that another program, upowerd, was fighting with python over control of the serial port, which was screwing the bit-banging required to program it.

kenneth@KWF2:~/prog/goodfet$ sudo lsof | grep USB
[sudo] password for kenneth: 
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /home/kenneth/.gvfs
      Output information may be incomplete.
upowerd   1501          root   11u      CHR      188,0      0t0      18775 /dev/ttyUSB0
python    2389          root    3r      CHR      188,0      0t0      18775 /dev/ttyUSB0

Everyone thank Ubuntu once more for doing more than we asked or wanted it to do, screwing the advanced users yet again.

One "sudo killall upowerd" later, the boards programmed and self-tested fine.  Killing upowerd to use my GoodFET is pretty annoying though, so some more digging was in order.  Between trawling upowerd bug reports, and running /usr/lib/upower/upowerd -v, I finally figured out what the problem was.

Turns out, the problem is that there was some random device made by Watts Up, Inc., which happened to use the FTDI 232 chip (USB ID 0403:6001).  Udev then uses this very generic USB ID (try running lsusb) to identify this specific device, and screws everyone with cheap USB-to-RS232 adapters.  The fix is relatively simple, if obscure.  Delete, or comment out, the udev rule for this device, which is typically stored in /lib/udev/rules.d/95-upower-wup.rules.  Reboot or restart of upowerd later, the GoodFET works fine in Ubuntu.

<evil glare at Ubuntu />

Obviously, it's unlikely I'll ever be using two of these at once, so if anyone wants to give me their best offer, I might be able to be talked into parting with one of these babies, or even make you some more, for $40 (Parts, labor, US shipping).

Edit 2011-02-18: Alex has bought my second board, but I will certainly be willing to purchase, assemble, and ship additional boards for anyone.  You'll just suffer the additional lead-time of me not having the primary components in stock.

Sunday, December 5, 2010

Final Project for Digital Systems Course

It's finals week, which is why I've been so quiet, but next week is the start of Winter break, so I'll finally have some free time again.

One of my technical electives this quarter was EEC180A, Digital Systems, which is one of the hardest EEC classes at UC Davis.  I didn't end up learning much in it, but the final lab, which took three weeks, ended up pretty impressive.

The game consists of flipping one switch to roll a dice to pick a number between one and six.  If you roll a six, you have to add it to your score, otherwise you have the choice to add it or pass.  The goal is to reach 15 points without going over in as few rolls as possible.  It's entirely implemented using TTL gates, though I cheated and used several gates out of my stock in addition to the ones allowed in the class (eg using a 74174 hex D flip flop instead of several 7474 gates).  I also used a 555 for the clock source, where we were only expected to use the lab's function generators.  Since I did most of the work in one night at home, I didn't have a function generator to work with.

No detailed schematic or anything for this one, just thought I'd share why things have been quiet as of late.

Monday, November 29, 2010

Chumby Status CGI Script

After writing about my Chumby based web server this weekend, it managed to work its way onto Hacker News, which meant that my internet connection and alarm clock got to be on the sharp end of a good old fashioned slash-dotting, and considering, held up admirably well.
The statistics for the blog post itself are almost as good, but, these statistics are for a web server which I set up and which I have full control over, so I'm afraid I spent a lot of time this weekend watching `watch -n 10 tail /mnt/storage/logs/lighttpd.access.log` seeing the new hits literally roll in, some times reaching into the tens per minute.

By the end of the weekend, having to ssh into my router, then ssh into my Chumby (obviously not publicly open, due to lack of root password), then run the watch tail command got a little tired.  I decided that it was time to learn some shell tools like awk and write my first useful CGI script to allow me to monitor the Chumby's health remotely from a web browser.

A CGI script is a program available at a URL.  When a web visitor accesses this URL in their browser, it causes the CGI script or program to run, and then the resulting web page the user sees is the output of the CGI script.  As for exactly what language the script is written in is only limited by what languages the server can handle, so one could invent an entirely new programming language, and then simply start their scripts with #!/bin/interpreter or compile the code down to an executable binary, and stick it in their web server's cgi-bin folder.

Since I'm mainly handling large text files and formatted output already available through such programs as df, free, and ifconfig, it seemed most reasonable to write this status script in shell.

The simplest shell cgi script would simply use echo to print first a MIME content-type header, and then as much of that content type as one feels fit to pipe through echo, be it text/html, or text/plain, or anything else for that matter.

I decided to use text/html as my content type, with plenty of pre tags sprinkled throughout, to preserve the mono-space type of the shell output, while allowing me to use html tags to set the page title, include analytics javascript, and eventually include graphs.

The last fancy thing about my script you can notice below is the fact that it uses a cache file for all of the status output.  This is because, when I was writing it, the daily access log was nearing 40,000 lines long, so even relatively simple commands such as wc -l < lighttpd.access.log (Count the number of lines in the log file) started taking several seconds to complete.  When a single page load takes several seconds, the likelihood of a second person visiting the site while it's still working on the previous one increases, which then takes ever longer, and pretty soon my Chumby is sitting in a pool of molten lead-free solder crying.

This caching is done by using `stat` to find the age of the current cache file as a number of seconds since epoch, then subtract that from the current time.  The larger this number, the staler the cache.  By the time I finished, traffic had died down, so I decided to set the cache timeout as low as 20 seconds, which means it rarely serves the same stats twice, but does prevent someone with a hot CTRL-R finger from DoSing my alarm clock.  It also means the script can fire off the cached status for the current request, then worry about regenerating the entire output for the next visitor, meaning the results page loads much faster than it should otherwise. (There is a risk of a race condition where many people hit it when the cache is expired but before any of them finish the CGI script to update it, but the timing would be challenging, and would be a very transient CPU spike)

The problem with this caching system is that if no one visits the status page in a long time, it doesn't get run in a long time, and the cached page served to the first visitor could be horribly (several hours, or even days) old.  To prevent this, in addition to all of the visitors, I have cron run the cgi script once an hour into /dev/null to quietly update the cache for the next web visitor.

I also included the Chumby octopus from /etc/motd, which gets displayed every time you ssh into the Chumby, on the page, because it was cute.

A lot of credit has to be given to my Dad, who has been writing shell scripts much fancier than this since before I was born, who nudged me in the right direction for a lot of the scripting I needed to get done this weekend.

Wednesday, November 24, 2010

Chumby Webserver Without the Flash Drive

This summer, I bought a Chumby as my birthday present for myself.  For those who don't know, the Chumby is an internet-connected alarm clock, meaning my desk-side clock can do such fun things as scroll by my most recent email, play Pandora, and display the weather forecast.  I opted for the Chumby One, saving me a little money compared to the Classic and it better matches my style, I feel.
Click here to visit my Chumby!

Most importantly, the Chumby runs Linux.  Much like the games I've been playing with my WRT54G[L] routers, this means I can make the Chumby do so much more than it's originally presented to do.

The one that particularly interested me, for no good reason, was getting a web server setup on the Chumby.  To think that I was server a website from my alarm clock is just the kind of ridiculous idea I revel in.

The (outstanding) Chumby wiki already has excellent documentation as to how to setup lighttpd as the web server on the Chumby, but has the one short-fall of all being contained on a flash drive which has to stay plugged into the back of the Chumby for the web server to work.  What I really wanted was for all of the storage to be internal to the Chumby, so that I can still pick it up and interact with it like I normally do.

Fortunately, the microSD card inside the Chumby used to store the firmware has additional storage capacity, which is formatted and mounted as /mnt/storage/.  Unfortunately, I timed buying my Chumby when they were building them with 1GB SD cards, which leaves about 500MB for /mnt/storage/, to be shared between this web server, and all of my mp3s that I store on it to play when my internet / wifi isn't cooperating enough to listen to Pandora.  This isn't nearly enough for my taste, but I happen to have had an 8GB microSD card laying around with no use, and found instructions to upgrade the SD card inside the Chumby, which I did.

Now that I have 7GB of FLASH storage to play with, it has become only a software issue, which is easy, right?

Not so much.  The directory prefix of the /lighty/lib folder is a compile-time option, which means the binary posted on the wiki didn't work for me (There may be a config option for it, but I didn't find it).  This left compiling the entire lighttpd package from source, which turned out to not be that bad, once you get the dev environment setup, which I've become pretty good at in Linux (AVR, MSP430, WRT54G[L]).

I simply compiled the lighttpd server from source using the configure option:
instead of the
option documented in the wiki.  Once the compile was complete, I scp'd the finished binary to the Chumby to finish the install.

This suffers from the one shortfall of how to start it.  The USB-based web server used the debugchumby script in the root of the flash drive, but with no flash drive, I have no debugchumby script there to use.  Again, the Chumby wiki has an entire page devoted to documenting the different injection points for scripts to be run.  Moving the sample debugchumby script to /psp/rfs1/userhook1 got my web server to start when I rebooted the Chumby.

Prebuilt tarball of lighty to be extracted in /mnt/storage/
If you're not big into the whole wasting an hour of your life trying to get an ARM compiler working, here is my working binaries and scripts.  The easiest way to get the tarball onto the Chumby would be to load it onto a flash drive, then SSH into the Chumby and move it around from there.

At this point, I have an entirely working web server, which also logs every request to the microSD card for later analysis, if I'm interested.  As it stands, I have little more intest than just how many requests a day are handled, so to prevent the log files from growing out of control, I wrote a small log rotation script to be run by cron at the end of every day, which counts the number of lines in the lighty.access.log file, appends that and the current date to another log file, and moves the access log file to lighty.access.log.yesterday, to give me some sort of chance of reviewing what requests are being made (a lot of bots looking for wiki and wordpress admin pages).  This script can be stored anywhere, and only needs to be added to the cron table by manually adding the following to /psp/crontab/root:
59 23 * * * /mnt/storage/lighty/

Note that the crontab shipping with the Chumby doesn't default to the correct folder, so to edit the cron table requires crontab -c /psp/crontabs/ -e.

I am working on adding on to this script to have it cause a growl notification on my desktop with the day's statistics, as well as email me the raw logs, but I'm working remotely from my parent's house for the weekend, so I can't test that until next week.  Feel free to do what you like with it, and let me know in the comments.

You can visit my bedside web site here:

Friday, November 19, 2010

Switching with a Vacuum Tube

WARNING: This is a bad idea. Prototyping with 170VDC is horrible.  Never work on a live circuit, and always have protective fuses.  I blew several fuses while working on this.

This summer, I managed to get my hands on several miniature vacuum tubes at a good price, and have been rolling around the idea of playing with them.  One of my friends and I were hanging out last night with little better to do, so I decided to see if I could wire one up to use it to switch on and off an LED.
It worked!  I applied 170V to the plate of the pentode, and 3V to the heater, and applying 170V to the middle grid allowed me to turn on and off the LED with 1-3mA.  I tried connecting the other grids positively as well, but this caused a significant amount of current to flow through the tube and blew the LED.


For the record, I do not know what I'm doing here.  I managed to destroy two tubes, an LED, and two 2A fuses.  On the bright side, I never shocked myself, which is the important part.
Close-up of the connections on the tube.  Note that everything is either isolated from ground, or fused such that a short on these connections does no real damage.  The tubes were all 6x6 types, with the final one being a 6CF6.  The others had metal shrouds around them, but once I killed one of them (arced grid to cathode), I broke it open for your enjoyment.
Vacuum tube broken open with the shroud removed.  The solid plates along the outside are the plates, which catch the electrons.  Inside of that is three coils of wire to control the electron flow, and finally the heated cathode in the center, which ejects the electrons.
Finding information on the tubes was challenging online, but luckily I bought an older (1981) edition of the ARRL Handbook on eBay, since the older editions tend to be more interesting from a builder's perspective.  The older editions also have significantly more information about vacuum tubes in them.  Where the modern book only has 3 columns of tube listings and half a page of bases, the older edition had 14 pages of vacuum tube listings.

Finding the pinout of a vacuum tube is a two step process.  On the side of the tube is a part number; for example, the tube I randomly picked out of the box and used was a 6CF6.  Once you know what tube you have, you look up the base type for it:
 This goes on for four pages...
As you can see, the 6CF6 has a 7CM base.

Once you know the base type, you then look that up in another table to get the final pinout.
 This goes on for seven pages!  I guess them all having the same pinout would've been too easy...
And here is shown the 7CM base.  Looking from the bottom of the tube, clockwise from the gap is Grid 1, Cathode, Heater, Heater, Plate, Grid 2, and Grid 3.  I left grid 1 and grid 3 unconnected, treating this tube like a really poor triode.  I won't begin to try and explain the difference between the three grids and their uses, since this has been covered quite well online by people who actually know what they're talking about.

I'll say it again: Don't do this.  I did this last night because I was bored, and that's really a bad excuse.  It was fun to see an LED lit by electrons flying through the air (I also lit a Neon tube with it later), but the risk of electrocution from 170V is very high.  I've been collecting tubes and older electronics books recently (Some of the books are quite quaint, having not yet started using such units as picofarads and Hertz, opting instead for the micromicroFarad and the cycle.), so I very well might end up doing something with this in the future, but for now I'll suggest we all stick to 5V and don't die.

Monday, November 15, 2010

Lamp Controller - Phase 1

WARNING: This project uses high (120VAC) voltage, and thus should not be duplicated without a strong understanding of what one is doing, and a handle on one's compulsive need to touch things.  Not only am I in no way liable for what you do with this information, I would be VERY SAD if I found out someone had killed themselves inspired by my project blog.

ALSO NOTE: Since all of the 120VAC equipment I build plugs into the wall and is not hard wired, I in NO WAY violate the NEC, as this is all "temporary" wiring.  This means I do NOT want to read any comments about how this will void my fire insurance or how unsafe this project is, without a specific critique as to how to improve it (A choice place for improvement would be in the TRIAC triggering circuit, for which I could not find a concise application note as to how to use the TRIACs, which is why the schematic is deliberately vague there.  I've seen a lot of crazy stuff, including BJTs, capacitors, and several resistors, with no explanation as to their purpose.  I very carefully watched my circuits for the first few days and severely derate it.)

This is an on-going project involving the lighting situation in my room.  I live in an apartment which doesn't have any overhead lighting in the bedrooms, which means I have to light my room with several lamps scattered throughout the room.  This would be fine, except that the outlet controlled by the light switch is in quite possibly the least useful place based on my room's arrangement.  This means all of my lamps are individually controlled, and the light switch controls none of them.  One of them didn't even have a switch on it, so I had to hack one together from spare parts.

This post covers only the initial, crude version of this project.  At this point it does nothing other than turn the lights on and off at command.  Future enhancements will be documented as they happen.


Currently, there is individual buttons for each of the three lamps, and a circuit to monitor the switched outlet across the room.  Pressing any of the buttons will toggle the respective lamp.  A positive edge on the light switch will turn a select two of the lamps on, regardless of the current state of the lamps.  A negative edge on the light switch will turn off all lamps.  This makes the light switch useful again, as it allows it to turn on a useful set of lights on entrance to the room, and turn off all lights on exit.  If the light switch is in the wrong position (up when a positive edge is needed), all you have to do is switch it down, and back again.
The controller consists of two main parts: The AVR-based controller breadboarded by my bed, and the TRIAC junction box under my desk.

  • The AVR watches for button presses from five push buttons (only three are function as of yet, toggling individual lights), and changing edges on the input from the switched outlet.  The switched outlet powers a 5V power supply, which then feeds a 3.3V linear regulator, since this entire project runs on 3.3V.  An AC wall wart would allow for detecting the light switch being turned off earlier, since the DC power supply has filtering capacitors (thus the 100 ohm pull-down resistor), but I didn't have one handy, and would require the increased complexity of watching for changing edges and then deciding when the switch is turned off based on a lack of edges.
  • The TRIAC junction box has four independent channels to switch low current (<10A) 120VAC, using pairs of optoisolated TRIACs and power TRIACs in TO-220 packages.  TRAICs can be used to dim lights, but my optoisolators have zero-cross detectors in them, so there is no way to phase the output of the TRIACs (Informative GIF from Wikipedia).
Outside view of the junction box:
 Three of the four channels are in use.
 Screw terminals for connecting the low voltage control lines.  The box was designed to reliably run on either 3V or 5V without requiring external current-limiting resistors.

TRIAC control board:
 Each optoisolator 8-DIP contains two channels (thus why the part number ends in -2)
Standard duplex 15A outlets from ACE.  Note that I cut out the bus bar between the top and bottom outlets to separate their hot conductors, allowing me to control them individually.

Source code:

Saturday, November 6, 2010

Maximum Resistor Voltage Chart

I'm constantly trying to find a happy medium between current limiting resistors too large, causing too small of a current, and too small, exceeding their power ratings.

I finally got tired enough of iterating through one of these problems today that I fired up Octave and made this handy Resistor - Voltage chart for 1/4W resistors.
(Click to Enlarge)

Making the chart was fairly simple:

r = logspace(0, 7, 10000); 
emax = sqrt((0.25).*r);
title("Maximum Voltage Chart (1/4W)")
xlabel("Resistor Value")
ylabel("Maximum Voltage")

This is why I love Octave.