Archive for May, 2008

Blinkenlichten RGB LED controller: protocol / firmware (1.2)

This is the protocol spec and PIC10 firmware download for Das Blinkenlichten (1.2). This version improves handling of the ‘Identify’ command by end devices. Backward compatibility to 1.1 is not affected.

I don’t have pretty datasheets, application notes, timing diagrams, or much example code / pseudocode, but I’m sick of sitting on this thing until I get around to those :-P So I figured I’d just stick it on the internet and see what happens. The rest might be filled in in my future spare time (or by some nice person in the comments)…

Das Blinkenlichten is an open-source RGB LED lighting system and protocol written for the PIC10F200 microcontroller. A complete node consists of this chip, an RGB LED, three current-limiting resistors and a small capacitor for power-supply smoothing. A single chain can have up to 255 unique nodes (or as many non-unique ones as the wires will carry power/data for, without burning up!). Everything is coordinated by a single master device, which can be any low-cost microcontroller or equivalent with a free I/O pin. The beginnings and goals, etc. of the design are described on this page.

Pretty Pictures
Pic: Blinkenlichten in melty, icicle-like resin
Pic: Swirled around by a girl dancing
Video: Very simple random-color-generator demo
Video: Cool video of blinkenlichten who react to music

Features / Commands in brief:

  • Cheap! At 34 cents each (qty:100), the PIC10 is probably one of the world’s cheapest and simplest microcontrollers. Complete parts cost can be less than $1US per node.
  • Fast 1-wire data bus – complete operation with only 3 wires (power, data, ground)
  • 3 colors (R,G,B) can each be set to one of 9 intensity levels – total 729 possible colors
  • Set Group Address command: control groups of LEDs at a time with a single command
  • Deferred Update command: Allows simultaneous color changes even with a large number of devices.
  • Identify command: Discover the addresses present on the bus.
  • Power Save command: Stop all clocks and enter low-power mode until the next command

Arduino/Wiring library and example
Library and example sketch showing common usages (move to /hardware/libraries in your Wiring folder, close and re-open Wiring. The example will then appear under Sketchbook -> Examples -> Library-Blinken). This library is released under the GPL.

Firmware and source code (PIC10 assembler)
Version 1.3 (“It’s Log!” edition) can be donwloaded in this zip file. A few lines at the beginning will have to be set according to your hardware configuration (see below). The “#define MYADDR …” line contains the address the chip should respond to – change this and rebuild for each chip you program. This version adds a logorithmic color table so that the color intensities you specify will appear linear (evenly-spaced steps) to the human eye. Adding this meant some idiotproofing had to be removed – sending an invalid (>8) intensity value will cause undesired operation. Starting with 1.3, this code is released under the GNU General Public License v3.

Version 1.2 (‘dumb’ linear color table) can be donwloaded in this zip file. A few lines at the beginning will have to be set according to your hardware configuration (see below). The “#define MYADDR …” line contains the address the chip should respond to – change this and rebuild for each chip you program.


Basic schematic for an individual node. The schematic shown uses a common-anode LED (common is connected to VCC); for a common-cathode, tie the LED common to Ground instead and change the appropriate #define at the beginning of the code. Different LED packages have different pinouts; test and make sure of them before wiring it up – or especially making boards. (The R/G/B connections to the LED can be easily remapped in software, but you have to get the LED’s common right the first time!)

Basic wiring diagram for a complete string with several nodes and a controller. There is a pulldown resistor between the data wire and ground (recommended value 100k ~ 1Meg). This is necessary for the ‘IDentify’ command to work, and it also helps prevent your string of lights from going haywire if the controller takes some time to start up and the voltage on the line is floating.

The maximum cable length, and maximum nodes reliably driven on it (or maximum speed), depends on how strong your controller drives the data line. As you add length and extra loads (inductance and capacitance) to this wire, the voltages on it will take longer to rise and fall, and be more difficult for the nodes to reliably consider a ‘1’ or ‘0’. I’ve run them with 6+m of cable without incident, but if you run into problems, reducing the data rate should help. If you don’t care about the IDentify feature, you can add a beefy buffer here to drive the data line harder. If driving long strings, you might also want to add decent-sized electrolytic capacitors between the power and ground wires at intervals along the string.

PCB and Parts List (Bill Of Materials)
This file contains a parts list for both DIP/breadboard and tiny surface-mount versions. Also included is an EAGLE schematic and Gerber files for a miniaturized, wearable board using surface-mount components. These data (schematics, BOM and Gerbers) are released into the public domain.

A picture of the finished SMT boards (panel) is shown below. With a jumbo 10mm RGB LED, the board is almost completely concealed behind the LED and only the sewable connections stick out.

Programming the chips
To write the firmware to these chips requires access to a PIC programmer. The official ones made by Microchip Inc. are quite expensive; fortunately there are many clones out there that work just as well, and some open-source designs you can build yourself. Just make sure that the programmer supports the PIC10 devices; some very simple/cheap designs (e.g. direct to PC serial port) may be designed only for “low voltage program” devices and won’t generate the +13V or so necessary to program this chip. The DIP variants can be programmed in or out-of-circuit; for the SMT variants, you will probably need to solder them to your board (with an appropriate pin header / etc for the programming lines), program the chip, and THEN add the LED (since it shares some of the programming pins and will interfere). For the ready-made SMT circuit board above, the following drawing indicates the pinout of the programming header on the edge of the board. For this, I soldered the wires from the programmer to the “wrong” side of a 5-pin 1.25mm connector (such as Molex 53047-05), then just press the other end into the PCB during program.

Command packet format: (forgive the horrible ASCII art)

     <start> <addr[7..0]><cmd[7..0]><stop>
_____- - - -. . . 16 data bits . . .______

The bus idles low.

Start condition: Bus goes HIGH and stays high for longer than the longest possible loop run (min. ~ 17uS), so that all devices are guaranteed to catch it.

Data bits consist of a low period (low half) followed by a high period (high half). A 1 is denoted by making the LOW half longer than the HIGH half, and a 0 by making the HIGH half longer. Ideally, all bits should total the same length, but since the low half sets the baud rate on a bit-per-bit basis, this is not required. However, any half should be a minimum 18 device clocks (18/1MHz=18uS) for most accurate timing, and should not exceed 255 device clocks (255uS).

Stop condition: Give some time for the cmd to be processed before sending a new one (bus idles low). If you’re in a hurry, this time depends on the specific cmd. Otherwise, you can just wait about 90uS (time for the longest 1-way cmd, activate_deferred, to complete) and not worry about it. (*See special timing notes for Identify cmd.) This is the preferred approach, but you could also just make the START condition longer.

Address BYTE format:

bit <76543210>

where AAAAAAAA is an 8-bit device address (or group address). Address 0 is the broadcast address. Since the ‘Group Address’ cmd only supports addresses up to 64 (0x40), I recommend a handful of low addresses (0x01 ~ 0x0F) be set asdie for group addresses if you plan to use this feature.

Cmd BYTE format:

bit <76543210>

E: Extended Command flag. If ‘1’, decode remaining bits as Extended Cmd as described under Extended Commands. Otherwise,
RGB: Which color(s) cmd applies to (set ‘1’ for each color this intensity applies to)
IIII: Set intensity (0 ~ 8)

Extended Commands

11xxxxxx : Set Group Addr to value xxxxxx
10XXyyyy : Poke "Virtual reg" XX with contents yyyy (see below), where XX is the address of a virtual 4-bit reg and yyyy is the value to poke.

Vreg 00: Flags [x identify activate_deferred power_save]
Vreg 01: Defer buf R
Vreg 02: Defer buf G
Vreg 03: Defer buf B

Detailed description of the virtual registers:

Vreg 01 ~ 03 allow a deferred update to be sent for the R, G and B channel respectively. The new intensity value(s) are stored in memory, but the old intensity values continue to be displayed until an activate_deferred command is executed, at which point the new intensities are displayed. This will be particularly useful for trickling new values over the bus, then sending a single activate_deferred to all devices (addr 0) to give the appearance of a simultaneous update.

Vreg 00 is a virtual register among virtual registers: Rather than writing a value to it, you write to it setting an individual bit to perform the requested action. Once the action is performed, the bit can be considered automatically cleared.

  • Unused (bit 3): “No-Op” – Dummy command, doesn’t do anything.
  • Identify (bit 2): On receipt of this cmd by a given device address, this device shall pull the data line HIGH (internal weak pull-up) for a period of about 512 device clocks (or whatever, plenty long enough for master device to see it). Normal operation is then resumed. (Note that this may disrupt other devices on the bus, who interpret the pullup signal as a new START command. If this is bothersome an Identify command may be followed immediately by a dummy command if a device responds. The device’s response will be seamlessly eaten by the dummy cmd’s START, so it just looks like an extra-long start bit to all devices.)
  • Activate_deferred (bit 1): Replaces the currently displayed intensities with the contents of the Defer (R,G,B) regs if they contain a valid update.
  • Power_save (bit 0): This command will effectively stop the CPU and any pulse modulation activities and enter a low-power SLEEP mode. The device will remain in SLEEP mode until the next bus activity occurs, at which point it will re-awaken. Technically it will be waking up occasionally due to WDT, but these activity periods will be brief.

Quick Examples

Set device id 02 Red to max (8):

Set device id 02 to bright white (Red, Green, and Blue to max):

Set device id 02 to arbitrary color (Red 8, Green 2, Blue 3):

Set device id 07 off (Red, Green, and Blue to 0):

Clear all group addresses to 0 (default):

Assign device id 0x9F to group (address) 05:

Set all devices to power save:

Advanced Examples

Identify all the devices on the bus (pseudocode):

for (id = 1 to 255)
    Send1Wire(id, b'10000100'); // Extended cmd: Identify
    Delay(100); //delay 100 uS, to give device time to respond
    DATA_WIRE = 'INPUT'; // However you switch this pin to an input on your preferred platform
    gotResponse = DATA_WIRE; // read the data line to check if anyone is responding (pulling the data line high)
    DATA_WIRE = 'OUTPUT'; // Switch it back to an output (retaining same value as was read)
    if (gotResponse == 1) // Was there a response?
       print("Found device " , id); // do something with this information, e.g. store active IDs to a table
       Send1Wire(0, b'10001000'); // send dummy command if there was a response.
                                        // Or you can just wait a few hundred msec for the other devices to reset

Specific firmware points of interest

The intensity of the LED colors is controlled using pulse width modulation (PWM). The basic operation is that the intensity value for each color (0 ~ 8) is converted to that many ‘1’s and stored in a register, and this register’s contents are continually rotated in circles. Each time, the last bit is used to determine the on/off state of the LED. So with 8 bits in a register, it can be on 0/8 of the time (off) or 1/8 of the time or … 8/8 of the time (full brightness).

To provide the fastest possible update rate, it’s necessary to squeeze as much performance out of these cheap tiny PICs as possible. The PIC10 supports only a handful of instructions, no interrupts, and only a rudimentary 8-bit timer. For the PIC10F200, the entire program is limited by memory to 255 instructions. Therefore we can’t afford to be too sloppy.

The code uses look-up tables in place of any loops/math wherever possible. The chip does not support table-indexing operations in ROM (Flash), so this is done using computed GOTO: In many microprocessors including this one, the Program Counter register (which acts as the processor’s bookmark in the code’s execution) can be modified by the program directly. Thus, by writing a new value to the Program Counter you can force the processor to lose its place, resuming program execution from the address you just wrote. By performing math operations directly on the program counter, this method can be used to index a lookup table nearby. In the example below, the intensity value is added to the program counter to make it an index into a table stored just after it. The ‘retlw’ instruction returns from the function with a specific value saved in a register. This code snippet converts the (0 ~ 8) value to a value containing that many ‘1’s, using only a few clock cycles.

; Want to return a value containing the number of '1's specified in the intensity
; value. But want to spread them out for faster switching and less perceivable flicker.
    movf INDF, w ; cmd value
    andlw B'00001111' ; mask off bogus bits
    addwf PCL, f ; skip that many instructions
    retlw B'00000000' ; 0x00
    retlw B'00000001' ; 0x01
    retlw B'00010001' ; 0x02
    retlw B'01001001' ; 0x03
    retlw B'01010101' ; 0x04
    retlw B'01010111' ; 0x05
    retlw B'01110111' ; 0x06
    retlw B'01111111' ; 0x07
    retlw B'11111111' ; 0x08 ; last valid value

This same method is used to allow the PWM loops to keep running while receiving data. Each time a bit is received, the PWM loop “jump table” is called. The count of the number of bits received is used as the index into the jump table; instead of a list of data values, each table entry contains a jump (GOTO) to the address of either the red, green or blue updater.

Determining between ‘1’ and ‘0’ bits on the data wire also takes just a few instructions. For each bit, the line is held low for some amount of time by the controller, then held high. Whether the low or high half was longer determines whether it was a 1 or 0. The way to measure this can be thought of as a stopwatch that counts up during the first half, then down during the second half. If the count goes negative, the second half was longer and we record a ‘0’, else we record a ‘1’. The ‘stopwatch’ here is the chip’s 8-bit counter/timer register. But it can’t count down, it can only count up! So a little cheating: when finished timing the first half, we complement (invert) the contents of the timer register. Now it’s still counting up, but if the original count was 7, now it’s (256-7) or 249. If the 2nd half is longer, the timer will reach its maximum value (255) and roll over to zero again like an old car odometer (and ending at a low number again, the Most Significant Bit will be a 0). Otherwise it will be a high number, and the Most Significant Bit will be a 1. So, at the end of one up/down cycle on the data line, the timer’s MSB will automatically contain the correct bit as it was sent on the data wire.

You might also have noticed that the PIC10 only has 3 pins that can function as outputs; according to the datasheet the 4th (which I’ve used for the data wire) is input only. The 3 output pins are already being used to drive the 3 LED colors. So how does a node send data back to the controller in response to an IDentify command? There is a register setting that enables weak pullup resistors (~10k-20k) on all the pins. On the output pins this does nothing, but on the input (data) pin this applies voltage to the wire, overpowering the even weaker pulldown resistor (~100k) added to the controller side. (The controller stops driving the I/O pin briefly to await this response.) So by toggling the pullup resistor on and off, we can send data the ‘wrong’ direction :-)

Version History and Compatibility:

  • v0.x (2005) Nora Nightlight edition. Quick n dirty hack with hardcoded timer to distinguish 1/0 data bits. Set Group Address is the only valid extended command. Didn’t get around to touching it again for a long time.
  • v1.0 (2007) Beloved edition, demoed at VNV Nation concert April 07. Changed from fixed-frequency to variable baudrate data encoding/decoding; re-ordered some bits in the command packet format to make more sense.
  • v1.1 (2008) Proper edition; first public release. Implemented remaining Extended commands: power save mode, deferred update stuff, and device identification.
  • v1.2 (2008) More-Proper edition. Improved handling of IDentify cmd; now can avoid flashes during identify as non-responding devices on the bus reset. Compatibility with v1.1 devices is not affected.
  • v1.3 (2009) It’s Log! edition. This version implements a logorithmic color scale in order to better match the human visual response (intensity steps now appear evenly-spaced). Compatibility with v1.1 and v1.2 devices is not affected, unless you are sending invalid (>8) intensity values, which you shouldn’t be!

v1.1, v1.2, v1.3 are backward / forward compatible and can be used on the same bus. V1.0 supports only the basic command set (Set Colors and Set Group Address). Versions prior to 1.0 are not compatible at all…luckily, they basically don’t exist in the wild.

Encryption: Not just against the bad guys anymore! (or, how Comcast contributes to global warming)

In Part 1, we explored evidence supporting the conclusion that Comcast’s well-known policy of blocking / interfering with p2p file transfers (notably BitTorrent protocol) extends to several other legitimate moderate- to high-bandwidth activities, including collaboration via Lotus Notes, remote desktop applications, FTP, and even sending emails with large attachments. A working temporary solution (again, while counting down the days until FIOS comes to your area) is to just encrypt the hell out of everything, every HTTP request, every email sent, every file uploaded, your freaking grocery list, to force Comcast’s braindead filter to leave it alone.

Now, this misbehavior is bad enough while I’m trying to pirate Linux distros, but when I have to disguise my goddamn EMAIL to get it through? Something is very wrong with this picture.

Now, what does that have to do with global warming, the global war on BitTerrorism (net neutrality), and the price of broadband in China? Simple: Until Net Neutrality is enforced by law, the Comcasts of the world (any similarly shitheaded companies) will increasingly turn to methods such as this (nuking “bad customers”) as a profitable band-aid fix for the problem of rampantly overselling their capacity. As is already happening, users and software will respond by increasingly turning to unnecessary encryption in an effort to keep malicious third parties (in this case the user’s own, paid ISP) from tampering with the stream. If it continues, web sites will switch to using SSL (https:// links) by default to ensure their “eyeballs” can reliably reach the site, and soon, encryption of every last little unimportant snippet of data will be de rigeur to limit packet discrimination.

SSL encryption is a mathematically cumbersome, CPU-hungry process. While an average home PC slurping down Internet packets at a rate limited by the connection speed will not be overly taxed by this, the server that has to perform this encryption for thousands of visitors at a time is working up a sweat. A CPU that’s doing heavy math is consuming more power and generating more heat than one that isn’t. Multiply this by the number of Internet users and encrypted-by-default sites, and you see that you are needlessly wasting a huge amount of power to triple-DES Grandma’s grocery lists, and throwing wads and wads of unnecessary heat into the air.

Encryption also counts on generating a stream that looks like random noise. If you can suss out a pattern in an encrypted stream, chances are you can crack it. Consequently, cryptographic engines take great pains to ensure that the streams they generate do not contain repeating patterns. Compression, meanwhile, depends on identifying repeating, redundant data and optimizing it out. Consequently, encrypted streams are ideally uncompressible, which means all the current “mid-pipe”, bandwidth-saving tricks such as transparently compressing traffic between routers, also go out the window. Bandwidth consumption skyrockets and pipes saturate like never before. (Nevermind that under the current scheme, Comcast is already doing this to itself to some degree – see previous post for how my 1-hour FTP upload becomes an all-day FTP upload, continuously restarting the interrupted transfers from the beginning and saturating my upstream for the whole damn day.)

Fixing Gmail, FTP, VNC, p2p, and other legitimate traffic not working in a Comcast Town (part 1: solutions)

As fate (or rather, failure to research local broadband monopolies and factor them into my home-buying decisions) would have it, I am a Comcast cable internet customer, in a Comcast town. As you might now, Comcast has for some time been quietly blocking…er, the polite term is “throttling”, certain types of bandwidth-intensive traffic. While that traditionally has meant BitTorrent (to cite the most well-publicized example), several researchers have presented evidence showing Comcast interfering with other types of traffic, such as Gnutella and even Lotus Notes. Comcast of course openly denies any “blocking” of “applications”* using lawyeresque weasel-words, in effect tacitly admitting to interference that falls just short of outright blocking. (The admission is typically couched in terms such as “traffic management to ensure the best service for everybody”, which is marketing speak for “we ridiculously oversold our capacity, and are blaming Bad Customers** for our mistake. Phooey on them, wanting to actually use the bandwidth they paid for and such.”.) From a technical standpoint, Comcast’s blocking throttling is done using a Sandvine box to sniff the user’s packet stream for possible P2P connections, then inject fake packets into the stream (known as a man-in-the-middle attack). Comcast sends fake RST (reset) packets to both the sender and receiver, spoofed to appear as though the other side sent them. This results in both sides dropping the connection, typically appearing as a “Connection reset by peer” error if the program actually displays errors. BitTorrent clients typically don’t, but other affected programs might.

I have personally found evidence that suggests Comcast’s ham-handed blocking attempts have been interfering with even other types of legitimate traffic, including FTP, VNC and GMail. Yes, Gmail.

Intermittently, certain activities in Gmail (mainly, attempting to send an email with file attachments, although the Chat feature is intermittently affected as well) at home would fail in various nondescript ways – for example, just sit there and do nothing, or pop up a bizarre, title-less lowercase “please try again” Javascript popup that even Google’s tech support couldn’t identify. Of course, trying it from my work connection (same browser version, approximately same time, by the power vested in me by VNC) would always work fine. This would persist for several days at a time, then go away for a while, then come back…

Solution: During one particularly extended period of brokenness, I tried changing the standard “http://” URL to “https://” to force an encrypted connection, and reloaded the page. Lo and behold, everything now worked flawlessly! The only difference “https://” makes is it uses a different portnumber and the traffic stream is encrypted. On Gmail’s side, the same requests are answered by the same scripts, then sent back to me and read by the same browser. The only difference is that Comcast can’t snoop the streams, misdetect one as a bandwidth-hungry file transfer and inject crap into the conversation.

Occasionally, I have a need to pull data from my home machine to my work machine, or run a program on my home machine that I can’t or don’t want to re-install at work, so I run a VNC server at home. One day, I could not connect to it from work, although nothing had changed (including IP address) and the server was definitely running (I could connect to it from other machines at home). Likewise, the VNC client at work could connect to other machines, just not on Comcast. Our IT guy at work also reported difficulty with his Comcast connection. Upgrading to the latest version of TightVNC, which uses a newer protocol, on both sides solved it. (So it seems that either my client and server both experienced bit rot, or a certain ISP decided not to like the protocol.)

Trying to upload large files to my Web site has been failing with repeated “Connection reset by peer” errors after only a few megs have been transferred. I can let my FTP client run overnight, trying to post 30-meg videos with arbitrarily many retries, and by the morning not a single file has successfully transferred. Hmm, I said. Connection RESETs, that appear to be coming from the peer, why does this sound familiar…? Now to test a theory. As I let the FTP continue to run and fail, I research and find that my Web host supports Secure FTP, which boasts end-to-end encryption. So with only a couple-minute delay to download and install a SFTP client, I replace this simple, time-honored protocol with a CPU-hungry encrypted version, and guess what? The screenshots may speak for themselves.

Unencrypted file transfer over Comcast: no successes. Encrypted transfers over Comcast: no failures!

So it seems, if you’re stuck with Comcast, any type of transfer that doesn’t fit their preferred usage profile (that is, a granny paying $45/mo to send a couple short emails every week) is a potential target for packet discrimination during times of peak demand***. It also seems that the solution so far involves encrypting or obfuscating as much of your traffic as possible. The stream then appears as random noise, and no man-in-the-middle crap can be injected without invalidating the signature. Comcast in my area doesn’t seem to be blanket-blocking encrypted traffic (yet!), so this can be an interim solution while counting down the days until FIOS (or any competition what-so-bloody-ever) is available in your Comcast Town.

(Finally, for actual p2p transfers, this link provides instructions for enabling encryption in BT, as well as some other workarounds.)

* they don’t block applications, they block packets from those applications. The applications themselves are installed on your own PC, which they can’t do anything about without deploying a rootkit.

**there is actually a commercial to this effect running as part of the cable/satellite TV wars, but I couldn’t find a link to it. A bunch of fatcat executives are sitting around a downward-spiralling profits graph, one exclaiming, “I’ve figured out the problem! It’s the CUSTOMERS. They keep calling, and complaining, and wanting better service.” The solution was to fire all the customers and find replacement customers who were more willing to accept crappy service.

***it’s possible that these issues manifest only for users who occasionally run one of the targeted applications, such as BitTorrent (which my housemate often does). Since it is unlikely that even CrapCast would intentionally target e.g. GMail, it may be that their braindead filter just nukes TCP streams from your modem indiscriminately if recetn BitTorrent activity has been detected. Further study will be performed when I can set up a clean test at a friend’s house with Wireshark running on both sides, as the Lotus Notes guy did.

Vibe update

So, Jane and I built the electronics for 30 of them, then I took them home and plugged one in for a test drive. It connected to the USB port, beautifully, then I go to turn up the juice. As soon as there is power going to the motor and it’s getting ready to turn, the USB connection is lost and resets/re-enumerates (Windows makes an unhappy dink-dunk…dunk-dink noise). Try another board, and the same thing happens. The first one built worked just fine (on Jane’s PS2), exact same design and components. What’s going on?

Long story short, scoping on the USB 3V regulator pin reveals a steady 3V when nothing’s happening, but an unstable mess when power is being switched to the motor. Small, almost negligible power dips on Vcc are translating to huge, yawning valleys of undervoltage on the regulator output. This on-chip regulator sucks. Beefing up the storage cap on Vusb does nothing, but another 10uF or so across the power rails seems to solve the problem. The USB specs recommend a power supply bypass cap of no more than 10uF, which is already present in the design, so increasing it further is not my first choice for a solution. Then I had a moment of smartness… I was using the front USB ports on my computer, since they were easily accessible, then I remembered those long, puny little ribbon cables that connect the front ports to the motherboard.

A quick look with the side cover off confirmed that pulling half an amp through one of those puny wires was asking for trouble. Combine that with the new longer, skinnier USB cables, and said trouble answers. Plugging into the rear ports made things much more reliable, as did adding a bit more capacitance across the power rails (reliable rear AND front port operation). But now I have to wonder, just how crappy does USB port wiring in the field come? The last thing I need is a pile of angry returns when people start plugging these things into their eMachines Celerytron craputers, with USB ports wired up using wet cat whiskers and good intentions by China’s most optimistic child labor, and wondering why their vibe doesn’t work…

So, final solution is to add the extra capacitance across Vcc, along with a big dire warning about crappy front ports. Yesterday I also made an enclosure-milling template, basically an aluminum bracket with cutouts in the appropriate spots. Sliding an enclosure into the left or right side exposes only the plastic that needs to be removed for the USB port or vibe connector, respectively. (Yeah, I’m supposed to have made a CNC milling machine for this by now, but haven’t gotten around to finishing it yet…) Now with all this hacking around for suboptimal ports, I need to throw together a long-term automated test script too.

On nomenclature (Soylent Green is… is..)

Ok, so, apparently in certain circles of defense parlance, you do not blow up people. Well, you do, but the correct euphemism is “soft targets” (as opposed to “hard targets”, such as tanks, buildings, etc.). Referring to soft targets as people is rather frowned upon. I managed to inadvertently silence a getting-out-of-hand meeting yesterday as follows:

(various talking, sniggering and head-shaking about ‘targets’ nomenclature)
me: So this thing has about 4 seconds to decide if it’s being shot at buildings or people…
AL: Soft targets!
me: OK, so seriously, in the event of Soft Targets (arf! arf!), 4 seconds to reconfigure?
DE: How about bad people?
me: How about, brown people?


Apparently, certain coworkers have far not enough respect for Carlin. (That and, certain coworkers probably now think certain other coworkers have far not enough respect for other cultures and/or not being a racist fuck, even after attempting to explain the Carlin sketch…)

Ok, I’ma just continue sitting on my hands and rocking. (“I am not designing a weapons system… I am not a racist fuck… I am not designing a weapons system…”)

* * *

On a lighter note, from the People who Have Entirely Too Much Fun at their Jobs department…

Toilet colors. The person at toilet companies whose job it is to name the different colors their product comes in* has the Funnest. Job. Evar. One particular model comes in your choice of Thunder Gray, Innocent Blush, or Biscuit.

Hehe…Innocent Blush… “who, me?” Yeah, I’ve had performances like that. Usually a few hours after eating Anna’s.

* * *

Some days ago my girlfriend was staying over, and I was in earshot when she called up her lab to ask someone to turn off an experiment in her hood that was inadvertently left running. My eyes widened and I said, “Whoa, you can do that? You just MeatVNC’d into your lab.” She had no idea what I was talking about and I had to explain. (Meanwhile however, one or more nearby computer geeks were cracking up.)

* not to mention file trademark applications if they Google it and get 2 or less digits of hits. Imagine how that must look on a re`sume`. “I’m also the mark holder for Baby Green(R), Cornfetti(R) and Pilsner Swirl(R)!”