Monday, October 21, 2013

The Most Powerful Tool You'll Ever Use

The most powerful tool you'll ever use is storytelling. If you get that, skip the rest of this post.


Wikipedia defines storytelling as "the conveying of events in words, and images, often by improvisation or embellishment."

Storytelling is a phenomenon that transcends cultural divides. In fact, "humans [inherently] think in narrative structures and most often remember facts in story form." Have you ever noticed how often and how naturally we use analogies and anecdotes to explain complex concepts? Or how people binge-watch their favorite TV shows?

The problem with the Wikipedia article is that it only describes what storytelling is and not what it does. Stories are used for a variety of purposes. They entertain. They inform. They create bonds. They can be applied for the purposes of good or evil, but they always have purpose and are most effective when carefully crafted to achieve that purpose.

Stories are incredibly powerful. Every startup that's been funded received funding because of stories. Funding is the result of the story the entrepreneurs tell (the one used to influence others) and the story the investors construct for themselves (the one that forms the basis of their belief). An investor who's willing to commit a lot of money at a high risk of loss believes a series of events that hasn't yet happened is going to happen, resulting in a happy ending.

Stories have remarkable effects on the course of world-history. In 2008, Barack Obama was elected as president of the United States based on a powerful story that millions of Americans believed in; the idea that the American dream still exists and that no matter who we are, we can achieve it. Neither the story, nor the success of the campaign, were accidental.

When we interact with others, all the complexities of transmitting information between humans emerge. We constantly need to influence others. We need to convince them to join our team, we need to convince them to use (and pay for) our products/services, we need to convince them to partner with us.

The best way to convince them? Telling them a compelling story; one they want to (and can credibly) believe in.

Compelling stories are intentional and carefully crafted. Think of storytelling as an art that;s enhanced by science. Art, or instinct, places constraints on a world of infinite dimension, making it conceptually manageable. Art "solves" the blank canvas. Once we have an idea of what we want to paint, we can leverage science to optimize the layout, colors, etc. for maximum effect.

When we take control of our story and design it to deliver information in a convincing and compelling way, we win the hearts and minds of our audience. It's a big step toward achieving our grand vision.

Of course, this doesn't mean telling a compelling story is easy or that success is guaranteed. It takes a lot of work. However, considering it's power, the most incredible thing about storytelling is that it's a learned skill. It's a supernatural power that doesn't emerge from supernatural circumstances like radioactive spiders.

If you want to accomplish great things, start by learning to craft and tell great stories.

Saturday, October 19, 2013

How to Add a Dial to Your Arduino Project

This post is for hardware hackers interested in adding dials to their projects. It discusses what we learned about rotary encoders and provides info about how to add one to your Arduino project.

For the original timetravel.fm prototype, we used thumbwheel potentiometers (pots for short) as the dials for the radio. While these components worked well for the hackathon, they have a few limitations:
  • They have limited range
  • The mechanics of the component and Arduino limit precision
  • They are generally unattractive
Because the experience of using the device is extremely important to us, we place a lot of value on this element being (1) flexible, (2) pleasurable to use, and (2) attractive. While there are numerous types of pots, including ones that can rotate up to two full turns and allow a knob to be attached, a component called a rotary encoder performs better on each of the metrics that are important to us. Since I hadn't previously heard of a rotary encoder, I started out blindly searching Google using queries like "unlimited turn dial" (which I find humorous in retrospect). Eventually, I discovered the rotary encoder and pieced together what we'd need to experiment with them.

The first thing to note about rotary encoders is that they come in numerous different styles. While browsing the options at my favorite supplier, Digi-Key, it took me a while to figure out what all the features meant (actually, I didn't fully understand until I received my first order of encoders). Looking at an example encoder, some noteworthy characteristics include:
  • Encoder Type: The method with which the encoder determines rotation. The example encoder is mechanical, which is a good choice for basic projects.
  • Output Type: How rotation is encoded in the output. The example encoder uses quadrature, which means the output is represented by out-of-phase waves.
  • Pulses per Revolution: The number of times the output changes per full revolution of the dial. The example encoder will cycle through the output phases 12 times per full turn of the dial.
  • Actuator Type: This contains the diameter of the encoder's dial and the style of shaft. This information will help determine which knobs will fit.
  • Detent: Whether the dial "clicks" or rotates smoothly as you turn it.
  • Built in Switch: Some rotary encoders have a built-in switch that is triggered by pressing down on the shaft.
  • Mounting Type: This indicates how you mount the component onto your device. The example includes "PCB Through Hole", which means it has legs that allow you to lock it into place on the PCB, and "Panel", which mean that it has threaded metal at the bottom of the shaft that allows it to be locked into place on a device using a nut (see the example component).
  • In addition to the above, I'd also recommend looking at the part's datasheet to see the length-wise parameters of the shaft to make sure it fits the dimensions you're looking for and that any knobs you intend to use will fit properly.
To try the encoder out, I wanted to plug it into a solderless breadboard. However, I found that the PCB mounting legs prevented it from fitting. To deal with this, I drilled two small holes in the breadboard and the encoder snapped into place:


With the encoder set up on the breadboard, I was ready to create an Arduino project. I started by writing the following for Arduino UNO R3:
// For Arduino UNO, only pins 2 & 3 work for interrupts
int _encoderDialPin1 = 2;
int _encoderDialPin2 = 3;

volatile int _changeInTicks = 0;

// Don't need to be volatile since only accessed from single interrupt handler
int _lastBit1 = 0;
int _lastBit2 = 0;

void setup() {
  Serial.begin (9600);

  pinMode(_encoderDialPin1, INPUT); 
  pinMode(_encoderDialPin2, INPUT);

  // Turn on pullup resistor
  digitalWrite(_encoderDialPin1, HIGH);
  digitalWrite(_encoderDialPin2, HIGH);
  
  attachInterrupt(0, handleEncoderChange, CHANGE); 
  attachInterrupt(1, handleEncoderChange, CHANGE);
}

void loop() {
  int changeInTicks = 0;
  noInterrupts();
    changeInTicks = _changeInTicks;
    _changeInTicks = 0;
  interrupts();
  
  if (changeInTicks != 0) {
    Serial.println(changeInTicks);
  }
  
  delay(250);
}

void handleEncoderChange() {
  int bit1 = digitalRead(_encoderDialPin1);
  int bit2 = digitalRead(_encoderDialPin2);

  int code = (_lastBit1 << 3) | (_lastBit2 << 2) | (bit1 << 1) | bit2;
  
  if (code == 0b0001 || code == 0b0111 || code == 0b1110 || code == 0b1000) {
    _changeInTicks++;
  } else if (code == 0b1011 || code == 0b1101 || code == 0b0100 || code == 0b0010) {
    _changeInTicks--;
  } else {
    // For this case, the direction of the turn is indeterminate
  }
  
  _lastBit1 = bit1;
  _lastBit2 = bit2;
}
This code warrants some explanation. Two things are key to understanding what's going on. The first is that we are using interrupts to signal that the dial on the encoder is turning. The second is how we interpret the output of the encoder.

To create interrupts, we are using Arduino's attachInterrupt function. Different versions of Arduino work differently with this function. For the UNO, which the above code was written for, only pins 2 and 3 can be used for interrupts. The first parameter to attachInterrupt says which of these are used, meaning a value of 0 maps to pin 2 and a value of 1 maps to pin 3. The second parameter is the function to execute on the interrupt. The third parameter is when to trigger the interrupt. Here, we are asking for an interrupt to be triggered whenever the value of one of the pins changes.

Because we can't be certain about when a context switch might occur, we turn off interrupts before accessing _changeInTicks in our main loop. Before calling an interrupt handler, Arduino disables interrupts, so we don't need to do this in the handler, handleEncoderChange. What this gives us is that when the signal to pin 2 or 3 changes, handleEncoderChange is called.

When handleEncoderChange is called, we determine the rotation of the dial on the rotary encoder. Because the encoder we're using uses quadrature as it's output encoding, the signals to the pin will repeatedly iterate through the following pattern as the dial rotates to the right. When rotated to the left, it will go in reverse.

step 1step 2step 3step 4repeat...
pin100110
pin201100
result0001111000

The logic in handleEncoderChange observes the sequence of values read from the encoder to determine whether the dial is being rotated forward or backward. For several sequences, like 0011, we can't tell which direction the encoder was turning, because it is possible to generate them by rotating the dial in either direction. In testing the example encoder, I occasionally observed such values, which is why we purposely ignore them in the code. At this point, it's worth noting that writing to the serial line (e.g. using Serial.print) in an interrupt handler doesn't always work properly. When I tried doing this, I found that Arduino's serial monitor would occasionally hang.

With this simple program ready to go, we can hook the encoder up to the Arduino.


Encoders are designed to allow a knob to be attached. As mentioned earlier, when looking for a knob, you'll want to make sure it fits the encoder. For this example, we'll use this knob. When selecting a knob, make sure the specs for "shaft size" and "height" match the corresponding values for the shaft of the encoder. To get the precise dimensions, look at the part's datasheet.


It's not obvious from most pictures of knobs, but they typically come with a screw on the side that tightens down to lock onto the shaft of the encoder.


Attaching the knob to the encoder, gives us a nice dial for our project.


One last thing to cover here is the push-button feature of the example encoder. The following code, which can be combined with the previous code, turns on an LED when the encoder shaft is pushed down.
int _encoderBtnPin = 4;
int _ledPin = 13;

// Don't need to be volatile since only accessed from single interrupt handler
int _lastBit1 = 0;
int _lastBit2 = 0;

void setup() {
  Serial.begin (9600);

  pinMode(_ledPin, OUTPUT);
  digitalWrite(_encoderBtnPin, HIGH);
  
  digitalWrite(_ledPin, LOW);
}

void loop() {
  int decompressed = digitalRead(_encoderBtnPin);
  if (decompressed) {
    digitalWrite(_ledPin, LOW);
  } else {
    digitalWrite(_ledPin, HIGH);
  }
  
  delay(250);
}
Now, we can connect the encoder button to the Arduino.


I've learned quite a bit of new things about encoders, knobs, and Arduino in figuring all this out. I hope sharing it helps accelerate your learning! Feel free to leave a comment if you have any questions.