MLB.TV still stupidly refusing to offer me a product that I want to buy…

Two years ago, I complained that MLB.TV’s black out rules basically robbed them of a chance to get $120 of my hard earned cash in exchange for a product which they supply to others in the U.S., but which they refuse to sell me. Fast forward to today, and nothing has changed: I still can’t buy live access to all Oakland Athletics games for any amount of money, even though if I lived in somewhere else, I could buy their product. Isn’t it time (beyond time) for these silly exclusivity agreements to fade away?

I’m not the only one whose been complaining about this for years.

It seems startlingly anti-consumer for these blackout agreements to continue. The artificial scarcity created by these policies do nothing to enhance the fan experience. I’ve seldom seen an industry work so hard to avoid selling a product that they have and could sell to consumers.

Ridiculous.

Why I am not going to play Skyrim any more…

Okay, a diversion from my regular topics.

And that’s what computer games are for me: a diversion. I play them because I like to be diverted from my work and from even my normal bits of hackery and play. I tend to play games with a strong story component, like the Zelda games on Nintendo, and more recently Mass Effect/Mass Effect 2 on the Xbox. Because I have a job and a regular life, I really only play about one of these games a year, usually in the span of my Christmas break. This year, my wife got me Elder Scrolls V: Skyrim. And after playing it for more hours than I care to admit, I’ve come to this conclusion.

I hate it, and I’m not going to play it anymore.

It’s not a question of graphics. It’s got some great graphics, with a huge rich world presents an everchanging landscape.

Some people have dinged it for having an unimaginative plot line. I disagree: I think the breadth of the game is pretty incredible, and there is lots of stuff that you can do and follow that I found engaging.

Given my particular requirements, I am actually tempted to complain that the game is too big. It’s got so much to do, it simply demands too much in the way of time to really be completely enjoyable. It’s like seeing a good movie, but having to leave in the middle because you are getting bedsores from just sitting there for so long. But that’s not my real problem with the game.

The real problem is bugs. Bugs. BUGS!

To my way of thinking, there is one sin in game development. It’s not being boring, or repetitive, or derivative. It’s releasing software that contains bugs that affect game play. Bugs like getting wedged in a wall, and being unable to extricate yourself (yep, happened to me in Skyrim). But minor bugs like this are usually not too bad: you simply reload from the last save point and try again. For simple bugs like this, it means that you’ve lost a few minutes of playing (since your last save point). That’s annoying, but I could understand a certain number of them.

But Skyrim goes beyond these simple venial sins, and elevates them to mortal sins. It has bugs which basically prevent the completion of quests, and which you usually discover only well after you somehow encountered the bug. My current save situation has no less than five active bugs of this nature:

  • I can’t complete the Waking Nightmare quest, since Erandur apparently entered the Nightcaller Temple ahead of me, and is inexplicably not there.
  • I can’t get any companions to join me, because the game apparently thinks I have a follower. Yes, I’ve tried waiting for him to catch up. No dice. Scanned back to find where it glitched. Apparently somewhere about five hours of gameplay ago, although I have no idea why/where.
  • I can’t complete College of Winterhold. Reasons unknown.
  • I can’t find anyone to identify Unusual Gems. Reasons unknown.
  • Can’t intimidate Xander. Walk right up to him, he says I shouldn’t be there. Apparently it’s buggy for lots of people.

Bethesda game director Todd Brown thinks we have a right to be pissed off. Well Todd, I am pissed off. It is a pity that you haven’t taken the opportunity to actually offer any remedy to those players who have been robbed of enjoying your games because of these bugs. At least on the PC version of the game, you can activate a console and find some secret command that can ameliorate the problems (sure, it completely breaks the game experience to have to go out and twiddle hex digits, but at least it keeps you from completely wasting your time).

Have some pride, and fix your damn game, Bethesda.

50th anniversary of Glenn’s orbit aboard Friendship 7

50 years ago today, American astronaut John Glenn completed three orbits of the earth aboard Friendship 7. Glenn would later become Senator, and would return to space aboard the Space Shuttle Discovery as part of the STS-95 crew, becoming the oldest person to fly into space. These three orbits started fifty years of an American presence in space. Salutations to Senator Glenn, and to NASA.

Examining the output of a simple remote-keyless-entry transmitter…

Yesterday I was looking (sadly unsuccessfully) for some BPW32 photodiodes that I know I have somewhere, when I ran across some of 434 Mhz transmitter modules from Sparkfun (now a retired part) that I had never used. These little $4 transmitters are commonly used for remote-keyless access or similar applications. They have just four pins: power, ground, a data pin, and an antenna, so they are easy to interface. I thought that they might be useful as backup low power beacon transmitter aboard a high altitude balloon payload, but I had never unpacked them, never tried them out. It dawned on me that I might also be able to use them with my code which I had previously written to send Hellschrieber telemetry. But to start out, I just made a simple program that sent the string “BEACON” at 1 second intervals and fed it to the data pin.

But how to receive it? I fired up my FT-817 and tuned it roughly to 433.920 Mhz (the nominal frequency) and even without an antenna, I could clearly hear the buzzy signal with a 1 second period. In fact, I could still hear it over 50Khz away from the nominal frequency. The signal was very, very wide. That got me curious so I dug out my Funcube Dongle Pro, hooked up a simple wire whip antenna, and tuned it in.

Here’s a picture of 96Khz surrounding 433.920:

Bleh. Really wide, really ugly, and really unpleasant sounding in the earphone. The horizontal lines coincide with the transmissions, the long harmonic laden regions in between are the “dead times”.

I suppose that if you were only using these intermittently in a key fob kind of situation, I could justify using something like this, but for the kind of application I was envisioning, they just seem gratuitously poor. Still, it was fun getting my Funcube Dongle out of the box and playing with it again.

Addendum: they also don’t work as a Hellschrieber transmitter. I hooked up my “Hellduino” code, but the resulting spray of noise didn’t provide any useful decodes. I think that the transmitter has an upper limit on how long pulses can be, and is also sending AM modulated signals, rather that keyed CW.

A simple beacon keyer for the ATtiny13

Roger, G3XBM built a simple beacon for light communication using a K1EL beacon keyer chip and a handful of other components. I didn’t have any of those chips around, but I did have some Atmel ATtiny13s lying around. I hacked this simple program together to send Morse code in two different ways: on pin PB1 (pin six) there is a simple on/off keying signal. On pin PB0 (pin five) there is the same signal, modulated with an 800 hz signal. Roger used a similar output to send a modulated version of his call. I hardcoded this program to transmit slow Morse with three second dits (QRSS3). I loaded this onto an ATtiny13 tonight, and hooked a small white led the PWM output pin through a current limiting resistor. Using a primitive receiver I built before, a solar cell hooked into a Radio Shack powered speaker, I tested it out, and it seemed to work rather well: the 800hz tone was clear and audible. I’ll be playing with this some more, but for now, here’s the code:

/*
 * beaker.c 
 *
 * A simple beacon beeper for the ATtiny13
 */

// #define F_CPU        1200000UL
#define F_CPU   9600000UL

#include <inttypes.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <util/delay.h>

#define FREQ    (800)
#define DIT_MS  (3000)

#define OUTPUT  PB0             /* 800 Hz PWM signal, OC0A */
#define KEY     PB1             /* Just a keying output */
#define SWITCH  PB4             /* a switch between 12 WPM and QRSS3 */

void
dit()
{
    /* on */
    TCCR0A |= _BV(COM0A0) ;     /* enable OC0A */
    PORTB |= _BV(KEY) ;
    _delay_ms(DIT_MS) ;

    /* off */
    TCCR0A &= ~_BV(COM0A0) ;    /* disable... */
    PORTB &= ~_BV(KEY) ;
    _delay_ms(DIT_MS) ;
}

void
dah()
{
    /* on */
    TCCR0A |= _BV(COM0A0) ;
    PORTB |= _BV(KEY) ;
    _delay_ms(3*DIT_MS) ;

    /* off */
    TCCR0A &= ~_BV(COM0A0) ;
    PORTB &= ~_BV(KEY) ;
    _delay_ms(DIT_MS) ;
}

void
space()
{
    _delay_ms(2*DIT_MS) ;
}

void
ioinit()
{
    DDRB = _BV(KEY) | _BV(OUTPUT) | _BV(SWITCH) ;
    PORTB &= ~_BV(OUTPUT) ;

    TCCR0A = _BV(COM0A0) | _BV(WGM01) ;
    TCCR0B = _BV(CS01) | _BV(CS00) ;
    OCR0A = 93 ;
}

int
main(void) 
{
    ioinit() ;

    for (;;) {
        dah() ; dit() ; dah() ; space() ;
        dah() ; dit() ; dit() ; dit() ; dit() ; space() ;
        dit() ; dit() ; dit() ; dit() ; space() ;
        dah() ; dit() ; dit() ; dah() ; space() ;
        space() ; space() ;
    }

    return 0 ;
}

Spray-on Antennas? I say “Spray-on Bunkum”

Thanks to John, who pointed out that this post was mangled. Fixed now.

I wasn’t going to mention this one, but Dave, Chris and Jeff over at The Amp Hour brought it up on their most recent podcast, but other than Jeff’s somewhat enthusiastic declaration that he thought it was BS, I don’t think they pulled it apart enough.

The topic is a recent video poasted under the auspices of Google’s new Solve for X program. Try watching it:



If you try googling for “spray on antennas”, you’ll find dozens and dozens of links to this video, or what amounts to a copied press release regarding this video. If you dig a little deeper, you’ll find lots of people complaining about how poor the presentation was. What is somewhat harder to find is any kind of a critical evaluation of the information (what little there is) on this antenna scheme. I’ll try to confine my comments to the latter.

It’s begins with a pitch, and not a modest one. We are told to imagine that we can send signals twice as far using no more power. Or the same distance with half the power. Or that we can get rid of cell towers. Or communicate from the depths of the ocean to outer space. And the key is some kind of nanotechnology. that Chamtech has developed for “spray on antennas”.

Following this pitch is a story: a story how “a business partner” who asked him develop a hidden antenna for Special Operations. He was then asked by “the government” to try his antenna technology, which was then tested by “a government team”, who found that this spray on antenna was “an order of magnitude better” than their best antenna.

I’m sorry, but that’s just bunk. Good antennas are efficient. A given antenna has a particular radiation resistance. For instance, a typical dipole antenna such as the antennas that many radio amateurs use might have a radiation resistance of around 70 ohms or so. But, of course, there are other bits of resistance in the antenna too. There is the ohmic resistance of the antenna, so-called “ground losses”, and “coil losses”. The antenna efficiency is just the ratio between the radiation resistance and the total resistance of the antenna.

But here’s the thing: at VHF+ frequencies, it’s just not that hard to make antennas with efficiencies that are 90% or higher. And that means that there is no “head room” to make an antenna which is “an order of magnitude more efficient”. It’s just basic math. You can’t get more energy out of an antenna than you put in, and existing antenna designs are already enormously efficient at radiating what you put in.

Beyond that, the geometry of antennas is important. You can’t generate an efficient one by just stringing a random conductor (or spraying one) higglety piggly all over the place. The length of the various elements change the feedpoint impedance and that must be matched carefully to the transmitter output impedance in order to be efficient. The idea that these nanocapacitors can “hold” electrons and then release them at their “happy place” is enough to make milk shoot out of my nose.

The “test” on the iPhone was comical: inside an Faraday cage (originally he said anechoic chamber, which I thought was an odd mistake for an RF engineer to make) he claimed that their technology improved the output power of the iPhone by “20 dBm”. I’m sorry, but I cry BS on this as well: dBm is the power ratio referenced to a 1mw signal. It doesn’t make any sense to say that there is a 20dBm improvement. An improvement of 20dB is a hundred fold increase in output power. Just where is this power supposed to be coming from? A typical cell phone has an output power of around 27dBm, or around 500mw. A 20dB improvement would raise that to 47dBm, which is about 50 watts. Bunkum.

Honestly Google, I know you have some pretty smart guys who know about RF: why did you let this guy use your forum to sell this complete nonsense? It doesn’t bode well for Solve For X if it can’t distinguish between “radical solutions” and “snake oil”.

More on ATtiny programming…

Last night’s hacking adventure was inspired by a couple of recent posts from Roger, G3XBM having to do with light based communication. The first was his simple beacon design: it’s just a keyer chip, a MOSFET, a voltage regulator, and some (beefy) current limiting resistors. Roger used this beacon to do some non-line-of-sight communications via “cloudbounce”.

It’s inspiring, so I’ve been thinking about trying some similar experiments. As it would happen, I have some reasonably high power LEDs floating around, and rigging up the transmitter really wouldn’t be too hard. I don’t have any of the K1EL chips that he used, but I do have a few of the Atmel ATtiny13s floating around, so I figured I’d go ahead and write up a simple beacon program to send my call via QRSS3 and (if a switch is tossed) 12wpm Morse. After my ATtiny powered Halloween Pumpkin and my ATtiny13 powered Christmas hat, I figured it would be a snap. I fetched an Arduino, programmed it with the AVRISP sketch, and then went to wire up the Arduino to program the code (did I mention I wrote some code?) to an ATtiny13 which I stuck on a breadboard.

And that’s when I realized that I didn’t take very good notes about how I did it last time, and refinding the necessary connections and commands was both difficult and some sources didn’t even have the information correct.

So I’ll remember, here’s the list of connections you need:

  • ATtiny pin 4 goes to ground.
  • ATtiny pin 8 goes to 5V.
  • ATtiny pin 1 goes to Arduino pin 10.
  • ATtiny pin 5 goes to Arduino pin 11.
  • ATtiny pin 6 goes to Arduino pin 12.
  • ATtiny pin 7 goes to Arduino pin 13.
  • Many sources say that for Unos, you must put a 10uF cap between the RESET and GROUND on the Arduino. I had one, so I did it. I’ve used older Arduinos (such as the NG) which have different reset circuits (you must manually reset them to program them) and for those it isn’t necessary. Your mileage may vary.

Lastly, you need the right avrdude command. It took me an embarrassingly long time to come up with the right command, mostly because it appears that I needed to manually set the baud rate to 19200 (what the AVRisp sketch expects). Archived for posterity:


avrdude -v -c avrisp -p t13 -P /dev/tty.usbserial-A800eKtX -b 19200 -U flash:w:beaker.hex

I discovered a couple of things: while the previous versions of the ATtiny I used seemed to have fuses set so that the internal oscillator (nominally 9.6Mhz) would be divided by 8, this one did not. I sorted this out by defining F_CPU appropriately, but it was late and I didn’t get my PWM code (which generates the 800hz sidetone) working properly. Tonight, I’ll dust it off and hook it to the scope and see what’s going on.

When this is done, it should be fairly simple to get the rest of the prototype transmitter together. Roger used a 4″ or so lens as the collimating optic for his transmitter. As it happens, I have a dusty 6″ Newtonian telescope that I purchased for a pittance, whose mirror really isn’t up to the kind of standards I appreciate. I think I can mount a high power LED into a 35mm film can and insert that into the telescope eyepiece, and it should make an excellent collimator (I may need an auxillary lens if the cone from my LED is too broad, I think the telescope is around f/5 or so). Perhaps by this weekend, I’ll have the transmitter setup, and I can start working on the (much harder) receiver.

Hope this article saves someone some time. I know I’ll be referring back to it in the future.

Web-based control of an RGB LED via the Nanode, an Arduino compatible microcontroller

Okay, I finally got some time to record a video about a simple little webserver project I hacked together earlier this week. My wife Carmen got me a Nanode kit from Wicked Device around Christmas. These are Arduino compatible development boards which include a Microchip ENC28J60 Ethernet device to enable web connectivity. One slight drawback is that they are not compatible with the Ethernet shields which are based upon the Wiznet 5100 chipsets, so you’ll need different drivers and different code. I’ve been experimenting with the Jeelabs EtherCard drivers, which seem to work well and are well supported, although they are limited in their TCP implementation (it limits TCP responses to just a single TCP/IP packet). Nevertheless, I implemented a simple webserver to control the I/O pins of the Nanode, based upon the ideas (but not the code) of Jason Gullickson’s RESTduino. I then did a short demo of how you could use it to control a strip of RGB LEDs from a simple jQuery based interface. Watch:



Here’s the sketch. Feel free to swipe it and any ideas for any web enabled projects you need (nothing here is worth copyrighting or licensing at all, consider it public domain).

#include <EtherCard.h>
#include <NanodeUNIO.h>

//
// remote by Mark VandeWettering
//
// a reimplementation of the "RESTduino" idea, first published at:
//     http://jasongullickson.posterous.com/restduino-arduino-hacking-for-the-rest-of-us
//
// I decided to rewrite this application because:
//   1. originally, it was written for the Wiznet based Ethernet Shield, but I have 
//      mostly Nanodes, based upon the ENC28J60
//   2. It was ported to the Ethershield library by Andrew Lindsay, but Andy has decided
//      that he's decided not to continue development of that library, deferring to the 
//      EtherCard library being developed by JeeLabs
//   3. I thought there was a lot of cool additions that could be made!  Okay, I haven't
//      implemented any at the moment, but I will!
//

#define DEBUG 		1
#define BUFFER_SIZE 	(900)

byte Ethernet::buffer[BUFFER_SIZE] ;
BufferFiller bfill;

char okHeader[] PROGMEM = 
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n" ;
    
char responseHeader[] PROGMEM = 
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Access-Control-Allow-Origin: *\r\n"
    "\r\n" ;

void
homepage(BufferFiller& buf)
{
  buf.emit_p(PSTR(
	"$F"
	"<html>"
	"<head>"
	"<title>webserver remote</title>"
	"<style type=\"text/css\">"
	"body 	{ width: 640px ; }"
	"</style>"
	"</head>"
	"<body>"
	"<h1>webserver remote</h1>"
	"<p>"
	"This webserver is running on a <a href=\"http://nanode.eu\">Nanode</a>, an "
	"Arduino-compatible microcontroller with web connectivity. It uses the <a"
	"href=\"https://github.com/jcw/ethercard\">EtherCard library</a> written by "
	"<a href=\"http://jeelabs.net/projects/cafe/wiki/EtherCard\">JeeLabs</a>.  "
        "Inspired by Jason Gullickson's <a href=\"http://www.youtube.com/watch?v=X-s2se-34-g\">RESTduino</a>."
	"</p>"
	"<hr/>"
	"<p style=\"text-align: right;\">Written by Mark VandeWettering</p>"
	"</body>"
	"</html>"
    ), okHeader) ;
}

#define CODE_ERROR          (-1)
#define CODE_WRITE          (0)
#define CODE_READ           (1)
#define CODE_ANALOG_WRITE   (2)
#define CODE_INDEX          (3)

int
cmdparse(const char *cmd, int &pin, int &val)
{
    const char *cp = cmd+4 ;

    if (*cp++ == '/') {
	if (*cp == ' ') {
	    return CODE_INDEX ;
	} else if (isdigit(*cp)) {
	    pin = atoi(cp) ;
	    while (isdigit(*cp)) cp++ ;
	    if (*cp == ' ') {
		return CODE_READ ;
	    } else if (*cp == '/') {
		cp++ ;
		if (isdigit(*cp)) {
		    val = atoi(cp) ;
		    while (isdigit(*cp)) cp++ ;
		    if (*cp == ' ') 
			return CODE_ANALOG_WRITE ;
		    else
			return CODE_ERROR ;
		} else if (strncmp(cp, "HIGH", 4) == 0) {
		    cp += 4 ;
		    if (*cp == ' ') {
			val = 1 ;
			return CODE_WRITE ;
		    } else 
			return CODE_ERROR ;
		} else if (strncmp(cp, "LOW", 3) == 0) {
		    cp += 3 ;
		    if (*cp == ' ') {
			val = 0 ;
			return CODE_WRITE ;
		    } else 
			return CODE_ERROR ;
		}
	    } else
		return CODE_ERROR ;
	} else {
	    return CODE_ERROR ;
	}
    } else {
	return CODE_ERROR ;
    }
}


void
setup()
{
    byte mac[6] ;

    Serial.begin(9600) ;
    Serial.println("\nbrainwagon remote webserver\n") ;

    NanodeUNIO unio(NANODE_MAC_DEVICE) ;
    unio.read(mac, NANODE_MAC_ADDRESS, 6) ;

    if (ether.begin(sizeof Ethernet::buffer, mac) == 0) {
	Serial.println("Failed to access Ethernet controller.") ;
	for (;;) ;
    }

    if (ether.dhcpSetup()) {
	ether.printIp("IP:  ", ether.myip) ;
	ether.printIp("GW:  ", ether.gwip) ;
	ether.printIp("DNS: ", ether.dnsip) ;
    } else {
	Serial.println("DHCP failed.\n") ;
	for (;;) ;
    }
}

void
loop()
{
  word len = ether.packetReceive() ;
  word pos = ether.packetLoop(len) ;
  int pin, val ;
  
  if (pos) {
    bfill = ether.tcpOffset() ;
    char *data = (char *) Ethernet::buffer + pos ;
    Serial.println(data) ;
    switch (cmdparse(data, pin, val)) {
    case CODE_READ:
        pinMode(pin, INPUT) ;
        bfill.emit_p(PSTR(
          "$F"
          "{\"$D\" : \"$S\"}"),
          responseHeader,
          pin, val ? "HIGH" : "LOW") ;
        break ;
    case CODE_WRITE:
        pinMode(pin, OUTPUT) ;
        digitalWrite(pin, val ? HIGH : LOW) ;
        bfill.emit_p(PSTR(
            "$F"), responseHeader) ;
        break ;
    case CODE_ANALOG_WRITE:
        pinMode(pin, OUTPUT) ;
        analogWrite(pin, val) ;
        bfill.emit_p(PSTR(
            "$F"), responseHeader) ;
        break ;
    case CODE_INDEX:
        homepage(bfill) ;
        break ;
    case CODE_ERROR:
    default:
        bfill.emit_p(PSTR(
            "HTTP/1.0 404 Not Found\r\n"
            "Content-Type: text/html\r\n"
            "\r\n"
            "<html><body><h1>404 Not Found</h1></body></html>")) ;
        break ;
    }
    ether.httpServerReply(bfill.position()) ;
  }
}

Boring statistics re: brainwagon

Okay, today is February 6, which means that my revolvermap that you can see over in the left margin has been up one entire year. Right now, it’s showing 148,950 visits since it’s inception. I suspect a couple of thousand of those are actually me, but I’m pretty happy that so many people stumble their way to my blog in that time. Over that same time period, Google Analytics reports 126,340 visits, 96,891 unique visitors, and 387,172 page views. The traffic to my blog has been pretty constant: around 300 views per day, with five or six blips caused by links from hackaday or Reddit. About one in four visitors are returning: the rest are new visitors. That seems pretty cool to me: reaching nearly 100K people with something I wrote seems oddly empowering.

But here’s the reality check. My most popular post: Viewing a V4L webcam with mplayer: a little throw away post I did back in 2007, giving the options that allowed me to show video from a V4L webcam using mplayer. It accounts for a little under 2.5% of all the hits to my blog. Two postings on the Fuji Real 3D W1 camera sum to actually a greater percentage (right around 3%). My Downside of Arduino is about 1.41% of all hits, mostly courtesy of a brief mention and flurry of activity from Reddit. My Hellduino project and my Arduino n’ Gameduino Satellite Tracker came in virtually tied at 1.16% and 1.15%, respectively.

What am I to make of all this? Well, I’m not quitting my day job anytime soon. 🙂

Addendum: Tomorrow will be February 7, 2012. This marks the completion of twenty years of work at Pixar Animation Studios. To all those who I’ve worked with over the span of the last two decades, thanks for helping provide one of the most stimulating work environments I could imagine, and for letting me play a small role in the history of animated films.

maniacbug is an Arduino wizard…

Ken Boak was nice enough to gift me with a pair of Nanodes when he was out visiting last month. Much to my embarrassment, I haven’t had much time to play with them, so tonight I tried to do a bit more research to figure out how I could use them in some more advanced projects. Previously I had found the Ethercard library which was developed by Jeelabs. It works okay for many things, but has a web server implementation which is too limited for many uses: all web pages must fit in a single TCP/IP packet. I was digging around trying to find a TCP/IP implementation that could handle larger ones. I knew about Adam Dunkel’s uIP stack for microcontrollers which has been ported to many microcontrollers, but the first link I found to an implementation on the Nanode didn’t seem to have any example web server code. But then I ran across this posting on maniacbug’s blog describing a complete webserver using uIP. He’s got his own github repository which seems to have a lot more complete examples fleshed out. I downloaded and tested the code, and it appears to work pretty well. I’ll be digging into it over the next few days, and perhaps making my own webserver application to run on the nanode.

He’s also got a huge number of other rather sophisticated postings on stuff he’s done with the Arduino. Check them all out, I know I will be too.

maniacbug | AVR Microcontroller Projects