Sketching08 talk: Good Hardware APIs et al

The Sketching in Hardware ’08 conference was held at RISD in Providence, Rhode Island this year. Both RISD and Providence were very welcoming and I think we had a lot of fun. Once again, Mike pulls off an awesome conference.

For my talk, since I didn’t have one big thing I’ve been working on this last year, I decided to shotgun blast a bunch of different topics out there, arranged roughly on the topics:
– Good Hardware APIs – about the evolution of BlinkM’s layout,
– USB not on Rails – an update to a previous Sketching talk of mine, and
– From 2D to 3D – experiments in 3D shapes from 2D lasercutter output

The PDF of my talk with notes:
sketching08-talk-todekurt.pdf (5.8MB PDF)

And some screencaps of a few of the slides:

Continue reading “Sketching08 talk: Good Hardware APIs et al”

BlinkM & Arduino 3D models

Here’s a really quick 3D model of BlinkM, if anyone needs it. It’s accurate to ~0.1mm.

blinkm.skp — BlinkM SketchUp model
rgb_led_piranha.skp — Piranha RGB LED SketchUp model

And here it is plugged into the awesomely done Arduino Diecimila model by Jon-Paul from the Google 3D Warehouse.

SketchUp is pretty great, but I found a problem with it if you’re trying to make accurate to-scale electronic parts: it won’t create surfaces with an area of <1mm. Took me a while to figure that out. The solution is to make a 10x or 100x size version and then do a scale by 0.1 or 0.01 when you’re done.

How To Do Big Strings in Arduino

Arduino makes it pretty easy to store & use character strings, but those strings compete with your variables, so you can’t do as much. Here’s how to put big strings into read-only program memory and use them.

Lots of sketches can have big strings in them. Maybe you’ve built a little command-line interface or you’re storing small web pages (for net-connected Arduinos). Normally you do something like this:

char hellostr[] =  "<html><head><title>hello world</title></head>"
                   "<body><p align=center><h1>hello world</h1></p>
                   "</body></html>";

// and then sometime later

Serial.println( hellostr );

The problem with this is that “hellostr” is stored in RAM along with your variables. The ATmega chip in Arduino only has 1kB of RAM. If your code is getting complex, and you’re using big strings, and lots of libraries, you may start having mysterious problems. Arduino can’t warn you if your sketch starts using too much RAM.

Instead, you can use PROGMEM, or PROGram MEMory, to store your strings. That is, the flash ROM memory that your code lives in. Using PROGMEM strings can be tricky, but here’s a little function called “printProgStr()” to make it almost as easy.

const char hellostr[] PROGMEM = "...";     // notice added 'const' and 'PROGMEM'

// given a PROGMEM string, use Serial.print() to send it out
void printProgStr(const prog_char str[])
{
  char c;
  if(!str) return;
  while((c = pgm_read_byte(str++)))
    Serial.print(c,BYTE);
}

// and then at some point

printProgStr( hellostr );

If you have another use for the string that isn’t “Serial.print()”, just create your own function and put whatever per-character handling function in there instead.

Spinning Knobs: Custom Rotary Encoders

For this project, I wanted a device that wasn’t an absolute mapping of position to color amount. I didn’t want a strict teaching device, but more of a fun color exploratory toy, able to be spun like mad by kids.

Rotary encoders are used to measure rotational amount and direction. You can find them in “infinite rotation” knobs, computer mice, robots, and lots of other things. They’re a good solution for user interface input devices when you want to make relative adjustments to a value, rather than absolute positioning (where a pot would work well). Wikipedia’s “rotary encoder” entry is a pretty good explanation of the various types of encoders. Wikipedia mentions absolute positioning encoders, a much rarer and more expensive type. Most all rotary encoders you’ll encounter are the relative positioning type. There are two main classes of relative rotary encoder implementations: mechanical and optical. Both make electrical signals when the encoder is rotated. Mechanical uses tiny electrical wipers to produce them. An optical encoder uses an optical interrupter, consisting of a light beam and light sensor.

I experimented with mechanical encoders but they had a lot of friction and their pulses-per-revolution were fairly low (12-24). I wanted a low-friction, high-resolution encoder. For low-friction this meant an optical encoder, and for high-resolution this meant a large encoder disk (since I was using fairly large optical interrupters).

To sense the slots in the disk, standard H21A1 optical interrupters are used. These optical interrupters are simply an IR LED (”emitter”) and an IR phototransistor (”detector”) in a single package, pointing at each other. Breaking or unbreaking the beam creates a signal you can measure. If you hook them up, you can see the IR LED using a digital camera:


You can see the “E” and “D” markings for “emitter” and “detector” above.

A single interrupter can measure speed of rotation by counting pulses. It can’t measure direction of rotation. But by using two interrupters and “quadrature encoding” (two output signals offset by 90º), you can measure both. The spacing between the slots, the spacing between the interrupters, and the aperture width of the LED emitter are interrelated in order to get proper quadrature output. Hopefully I’ll have a subsequent blog post describing this in more detail. :) To decode quadrature encoding, pick one of the two signals (call them “A” and “B”): when A goes HIGH, measure B. The value of B gives the direction of rotation. By counting the number of times A goes HIGH, you know how much rotation is happening. In the diagram below, follow the two signals as rotation happens either clockwise (to the right in the diagram) or counterclockwise (to the left)

Building the Knobs

The knobs are constructed out of PVC drainage caps, laser cut acrylic for hubs & diffusers, rollerblade bearings to give a smooth spin, 5/16″ bolts to act as axles, hot glue to put it all together, and a plywood base. The black, slightly rubbery texture was from the spray-on form of PlastiDip.

My good friend Ben Franco helped prototype many iterations of the physical design of the knobs, until we came upon the final result. He was the one who recognized that the diameter of 5/16″ nuts was just perfect enough to grasp the inner ring of a rollerblade bearing. So a 5/16″ bolt through the center of the bearing becomes the axle and the outer ring of the bearing can be attached to a stationary base, giving a smoothly spinning knob.

Rotary encoder Arduino code

When reading rotary encoders, it’s useful to think of the two signals coming out of it as a “clock” and a “data” signal. It doesn’t matter which one you treat as which, as it’s the interrelationship between the two that matters. Usually you’d use interrupts to handle reading encoders because it makes it very simple: on interrupt of the “clock” signal, read the “data” signal, and its value gives you the rotation direction. On Arduino we’ve only got one interrupt and three knobs, so polling is easier. I started with the a really good Arduino playground rotary encoder polling example and then went from there.

The relevant parts of the BlinkMCylon code for dealing with rotary encoders is below. It’s almost encapsulated enough to be a library. The “knobs” data structure contains a list of “knob” data structures, which in turn is just a holder for which pins the knob is connected to, what the last value was of that knob’s clock pin, and its current rotation value.

The “knobs_init()” function sets up the pins correctly, and by calling “knobs_poll()” as fast as possible, you can read many knobs fairly accurately.

typedef struct _knob {
    uint8_t clkpin; uint8_t datpin; uint8_t clklast; uint8_t val;
} knob;
knob knobs[num_knobs] = {
    { 2,3, 0, 0},    // first knob on pins 2 & 3
    { 4,5, 0, 0},    // second knob on pins 4 & 5
    { 6,7, 0, 0},    // third knob on pins 6 & 7
};

static void knobs_init(void)
{
    for( int i=0; i<num_knobs ; i++ ) {
        pinMode( knobs[i].clkpin, INPUT );
        pinMode( knobs[i].datpin, INPUT );
        // turn on internal pullup resistors so we don't need external ones
	digitalWrite( knobs[i].clkpin, HIGH);
        digitalWrite( knobs[i].datpin, HIGH);
    }
}

// this function must be called as quickly and as regularly as possible
static void knobs_poll(void)
{
    byte c,d;  // holder for readings
    for( byte i=0; i<num_knobs; i++ ) {
	knob k = knobs[i];           // get a knob
	c = digitalRead( k.clkpin ); // read its pins
	d = digitalRead( k.datpin );
	if( c != k.clklast  ) {      // look for clk line transition
            d = c^d;                   // xor gives us direction
	    if( d ) k.val++;           // non-zero means clockwise rotation
	    else k.val--;              // zero means counter-clockwise rotation
	    k.clklast = c;             // save the clk pin's state
            knobs[i] = k;              // save our changes
	}
    }
}

Resources & Links

Other info:

Get on the BlinkM Bus with a BlinkM Cylon

BlinkMs are a lot of fun by themselves, but they’re also little network devices, each having its own address on an I2C network. Here’s where I think BlinkM can really shine since it makes controlling multiple RGB LEDs pretty easy. For Maker Faire, I wanted to show off this facet by having a single Arduino control a dozen or so BlinkMs on a single I2C bus. The result is shown in the little video below.

Read on for how this was put together.

Continue reading “Get on the BlinkM Bus with a BlinkM Cylon”

ThingM & BlinkM at Maker Faire!

ThingM (Mike and me and some friends) will be at Maker Faire Bay Area 2008 this weekend. Come by and visit us!

Our bench will be about “Experiments with Smart LEDs”. Basically we’re showing off BlinkM, the projects that led up to BlinkM, like my experiments with Smart LEDs, some future products we’re working on, and some fun projects using these gizmos.

Here’s some photos of some of the projects as they were being built:



And lots of the projects will be using various types of Arduino, if you’re into that sort of thing.

FunGizmo’s colorful tiny breadboards

I just received some colorful tiny mini-breadboards from FunGizmos.com. They are pretty great. Now quickie ideas prototyped with Arduino can be even smaller than the “1¢ Arduino under-shield”.

They appear to be the same quality as the other breadboards I have, just different color plastic. I can already tell the colors will help me differentiate projects, which all tend to look alike from 10 feet away. Normally when you buy these from Digikey or similar places, these little ones cost $7 a piece. FunGizmos has them for $5.40. And that’s cheap enough to get a few. Note that all these tiny breadboards don’t have the side power busses like the larger breadboards do. That’s the price you pay for tininess.