|home||[ writing ]||bicycle repair||travel||software|
This page was last updated 18 october 2003.
On a party in San Francisco (where else) many years ago I have been shown a frisbee with some attached lights. Looked like a cool idea, but the concept obviously needed some enhancement.
Now I have this frisbee on my desk, made of rather stiff white plastic. I drilled 48 holes around the rim, and glued little red 1mm LEDs behind the holes. On top, there are two 74241 line drivers (they are powerful enough to drive an LED through their internal pullups), connected to a 1468705 microcontroller. They are very nice, 2 KB of on-chip eprom if I remember correctly, and 128 bytes RAM. Just about right for the job; 128 bytes of main memory may not seem very much, but the computational demands of a frisbee are relatively light and workstations cannot usually stay airborne long enough to replace frisbees despite their superior processing power.
The application notes for the 1468705 contain a programmer for the eprom. Erasing is no problem, it has a quartz window and every well-equipped household has a professional eprom eraser, right? Well, this one does.
The FOS (Frisbee Operating System) consists of some timing loops, the multiplexers for the LED array (the chip doesn't have 48 port bits, so I am driving the LEDs in a 6*8 array at high speed), and about 40 different preprogrammed patterns. It's amazing what you can do with 2 KB and tight coding: rotating dots, growing worms, flashing segments, all of the above in a single pattern. One of my favorites was an exclusive- OR pattern that slowly alternated between all-on and all-off. XOR is obviously an essential operation for a FOS, no microcontroller designer can omit it without risking losing the frisbee market.
This frisbee is guaranteed to draw a crowd at night in the park. It takes some practice because it's twice as heavy as a regular frisbee, you want to avoid being hit on the head by it, but it's great fun to throw in long arcs. You can see it strobing and pulsing on its flight path. Patterns that just briefly flash all LEDs produce a stroboscope effect. I also liked to just hang it on a wall at night and watch the light beams radiating out in all directions.
It's been a long time, and the NiCads are pretty much dead now. Several LEDs have broken when the frisbee collided with trees, and the glue has cracked in a many places. But I'll keep it even if it doesn't work, it's one of my more bizarre hacks.
I had this pile of over 1000 TTLs and 68k chips and decided to use them up for something fun and useless. So now I have a 68000-based board that controls things in my apartment, lights for the plants, door bell & buzzer, blinds, intercom, clocks, sensors and solenoids everywhere. It also talks to my SGI O2 and brings mail and (rsn) news to my bedside. There has been a lot of requests for details since I posted this to alt.hackers, so here are some technical details. I can't and won't provide detailed schematics here (they are very specific to my needs) but I will try to cover the basics, and communicate the fun I had (and have) building it.
Except for the big LCD screens, which require MHz pixel clocks, and the analog lines, everything is linked with a bus. The problem was that I can't have a central unit with hundreds of wires going everywhere. So I put substations where the data is collected, and connected the substations with a simple parallel bus. It has 14 lines:
D0-D7 data lines, used for addressing and data i/o SEL pulse to select a substation with D0-D7, or deselect R read a byte from the selected station W write a byte to the selected station PROBE confirms successful substation selection, SEL feedback GND,VCC powerEach station has up to 8 output registers and one input register. The neat thing about this is that a station consists of a single PAL16R4, of which I happened to have a rather large number, plus one latch for each output register and an octal driver for the input register. If there are more than 3 output registers, I also need a demultiplexer, a 74138 or 7442. That's all. The PAL handles substation selection, output register selection, and drives input and output enables.
What's more, the PAL does address comparison with its 8 inputs. All PALs are identically programmed and need no comparator and no DIP switches. The trick is that all PALs look for the same select address, 00001111. What makes them all respond to a different address is that D0-D7 are connected to PAL in0-in7 in different ways, so a D0-D7 bit pattern is seen differently by each PAL. Naturally, all valid addresses have four 0-bits and four 1-bits. There are 70 possible addresses, many more than I need.
The PAL also contains a state machine that interprets patterns with five 0-bits as output register selection commands, with the remaining three bits being the output register address. To write a byte to an output register, I go through four phases:
Step 2 is tricky because the register address is on different bits for every substation, but three 70-byte arrays in the central unit take care of that. Reading is easier, no step 2 and step 3 pulses R. Some of the output registers aren't really TTLs but numeric or alphanumeric LED and LCD displays, no problem. One station even acquired two static RAMs last weekend to scan a 6*5*7 dot alphanumeric LED matrix.
I am proud of this hack because of its absolute simplicity and the way it uses the PAL16R4 to the max. The central unit is a simple 68000 system with a big LCD frame buffer (all TTL plus memory), dynamic RAM, serial and parallel ports and an RTC. It also has a SCSI controller that I am not using right now. It's all handwired with thin Cu wire. No OS, just a simple loader and irq trampoline in NVRAM. I cross-compile with gcc on my O2 and use X fonts. I used xfig for the pictures on the LCDs.
Right now, I am considering to put the whole thing on the Internet. Then everybody on the planet can, say, download a temperature histogram for Berlin or trigger my alarm clock at unusual times. I can already telnet to it using a fixed TCP port. Although I have a leased line I am still considering the wisdom of giving too much access to random strangers on the Internet... Move over, Coke machines. Other planned extensions are infrared and speech I/O. "HAL, open the pod bay doors, please..." And I am still looking for a really horrible death scream to replace the door bell.
Here is a description of one of the more complex substations. It has four large 7-segment LED displays, one 8-digit alphanumeric LED display made by Siemens, and a button. I use this in my bedroom on the wall, it displays time, date, and temperature; the button suspends or disables the alarm (I figured I better force myself to get up to shut it off).
A very similar substation is in my kitchen; it has four buttons, each with a red and a green light, that I use for egg timers, to turn lights on and off, and various other things.
There is a compressed PostScript schematic (21 KB) on this server for the substation. When you read the schematic, you'll be surprised at my choice for the registers. I used 74192 counters because I happen to have a large number of these. A better choice would be 74374 or similar registers, and much cheaper too. BTW, a line with a cross: -----X----- means that there is a resistor in the line, like ----[####]----, not a pullup. Be careful with the Siemens display, and don't connect pin 23. Here is the PAL code for the PAL16R4:
TITEL CHIP PAL16R4 PAL16R4 CLK L0 L1 L2 L3 H0 H1 H2 H3 GND OE RIN WIN OUT0 OUT1 OUT2 SELOUT ROUT WOUT VCC EQUATIONS /SELOUT := /L0 * /L1 * /L2 * /L3 * H0 * H1 * H2 * H3 + /L0 * /L1 * /L2 * /L3 * /H0 * /SELOUT /OUT0 := /H0 * /H1 * /SELOUT + /OUT0 * SELOUT /OUT1 := /H0 * /H2 * /SELOUT + /OUT1 * SELOUT /OUT2 := /H0 * /H3 * /SELOUT + /OUT2 * SELOUT /ROUT = /SELOUT * /RIN /WOUT = /SELOUT * /WIN
The station has 6 registers that control the numeric and alphanumeric LEDs, an LED colon between digits 1/2 (left) and 3/4 (right) that flash with 1 Hz, and a minus sign before digit 1 (for negative temperatures, we use centigrade here). Digits 3/4 are mounted upside-down, which moves the dot to the top left corner of the digit; I use that for 'c .
i/o bit meaning ------- ------- --------------------------------------------- ctl 000 reset alpha display, data is ignored ctl 001 data writes go to alpha display out 0-6 data: store ascii character 40..7e 7 data: 1=underline 0-1 ctl: 0=dark, 1=25%, 2=50%, 3=100% brightness 2 ctl: 0=cont, 1=characters flash 3 ctl: 0=cont, 1=underlines flash 4 ctl: 0=ignore bits 2-3, 1=apply bits 2-3 5 ctl: 0=normal, 1=flash all characters 6 ctl: 0=normal, 1=lamp test 7 ctl: 0=normal, 1=clear all ctl 010 data writes go to numeric digits 1/2 (BCD) ctl 011 data writes go to numeric digits 3/4 (BCD) ctl 100 data writes go to alpha address register out 0-3 0=alpha ctl, 8-15=alpha data register ctl 101 data writes go to lamp register out 0 0=colon off, 1=colon on 1 0=minus off, 1=minus on 2 0=dot 3 on, 1=dot 3 off 3 0=dot 4 on, 1=dot 4 off
I used several different approaches for the various control panels:
I have cable tunnels all over my apartment. When I moved in, I didn't like the layout and had some walls removed and rewired most of the electrical lines and fuses, which means that there were lots of cables and holes in the wall anyway. Cable tunnels are very convenient.
Now I am really a software engineer, I build hardware just for fun. When I designed the software, I started thinking in terms of data sources and destinations, driven by a hierarchical multi-threaded rule-based system that can be configured dynamically. Then I stopped myself and decided to gleefully design a special-purpose system that is not at all portable. That doesn't mean it's not structured or poorly documented, I just decided that the code that controls my bedroom blinds exists to control my bedroom blinds and not some abstract virtual entity. This made it much more fun because portability issues greatly complicate matters (I have been there, I have two freeware projects running), but it also means there is little point in just publishing all my sources.
The software consists of three layers. The top layer is the user interface, one per substation that has a readout or button panel; the intermediate layer offers high-level commands such as "pulse that bit for 100 ms" or "wake me up after 5 minutes"; and the bottom layer talks to the hardware. The bottom layer includes
Here is the call interface for the bottom layer. s is a substation address (0..69), c is the register in that station (0..7), b is a bit number (0..7), v is a data bit value (0 or 1), and d is a data byte (0..255).
io_probe(s) FALSE if station is dead io_setbit(s,c,b,v) set a single bit 0..7 at a remote station io_pulsebit(s,c,b,v) set a single bit for a very short duration io_pollbyte(s,c) return what software did last to a byte io_pollbit(s,c,b) return what software did last to a bit io_setbyte(s,c,d) set a eight data bits at a remote station io_getbyte(s) read byte from remote station io_getbit(s,b) read a single bit 0..7 at a remote station
There is a source code file (12 KB) on this server that contains some of the more interesting routines, including the low-level hardware driver layer, and some high-level code. I never made any timing diagrams, but this is so extremely simple that it should become clear from the sources. As I said, the only mildly complex issue is addressing the registers 0..7 in a station because each PAL is connected to a uniquely permutated set of bus data lines. The code assumes a parallel 68230 PI/T interface controller chip. pad/pbd are port A/B data, padd/pbdd are port A/B data direction. The spl* routines disable interrupts (Set Priority Level).
(I never thought I could publish any of this. Well, more bandwidth is wasted with editor wars every day. The complete sources are 4500 lines.)
BTW, the title "intelligent homes" may seem slightly exaggerated, but these days a coffee machine is called "intelligent" if it can turn itself on in the morning so I'll just borrow that definition.
My design is based on my own microprocessor design - motherboard with CPU, dynamic RAM, storage, IO, frame buffer with video generator and all the necessary glue logic. It was a lot of fun, but I wouldn't recommend going to these lengths. In fact I am busy rebuilding everything from scratch for my new apartment in the center of Berlin, and this time I'll use a low-power PC running Linux, and standard external components.
Anyway, I am currently designing the whole thing. This web page has seen about 40,000 hits so far, so I'll put the complete design, with schematics, pictures, and source code, on the web when it's sufficiently evolved to be useful, on this page.
|home||[ writing ]||bicycle repair||travel||software|