WIP [ITP Blog]

Tangible Interaction - Week 1

January 30, 2019

The first assignment for Tangible Interaction Workshop was to make the controls for a desk or bedside clock — specifically focusing more on the inputs, their design, and expected behavior and less on the clock display. Considering clocks I’ve used in the past and the inputs I’ve encountered before, I was inspired by the tangible designs of older flip clocks.

flip clock example

The rotating knob intuitively rotates the flip clock’s number values when engaged. The sideways profile allows for a comfortable, ergonomic grip given that our hands naturally rest at against our side. I was also inspired by a tangible interaction I encountered at SFMOMA that I liked because having the primary, rotating knob on the side just felt more comfortable.

sfmoma knob

So I attempted to emulate this design using a rotary knob from Tom, the Encoder microcontroller library, and Arduino code that would switch between editing modes on the rotary knob button click.

first sketch

Rotary + Encoder

After I had an initial sketch, schematic, and code logic flow, I built a simple rotary knob circuit that used the Encoder library and wrote the values to serial (heavily based on the Encoder code example). I used my Arduino MKR 1010’s digital pins 4 and 5 because they’re one of the pins that support external interrupts which leads to better rotary encoder performance.

first sketch

I then spent time working on code functions that would convert the rotary values into delta values that either increase or decrease an hour/minute unit by 1 and are smart enough to reset to 0 when it passes the time range limit (0-23 for hours, 0-59 for minutes). This required some hand math and modulus functions.

doing pseudo algebra

// CODE EXCERPT

void loop() {
  ...

  if (newRoPosition != currentRoPosition) {
    currentRoPosition = newRoPosition;
    long adjustedRoPosition = currentRoPosition / 4;

    if (currentMode() == HOUR_EDIT_MODE) {
      setNewHour(adjustedRoPosition);
    } else if (currentMode() == MIN_EDIT_MODE) {
      setNewMin(adjustedRoPosition);
    }
  }

  ...
}

void setNewHour(long adjustedRoPosition) {
  newHour = adjustedTimeValue(adjustedRoPosition, currentHour, 24);
}

void setNewMin(long adjustedRoPosition) {
  newMin = adjustedTimeValue(adjustedRoPosition, currentMin, 60);
}

int adjustedTimeValue(long adjustedRoPosition, int currentTimeValue, int modUnit) {
  int delta = adjustedRoPosition % modUnit;
  int newTimeValue;
  if (delta < 0) {
    if (currentTimeValue + delta < 0) {
      newTimeValue = modUnit + currentTimeValue + delta;
    } else {
      newTimeValue = currentTimeValue + delta;
    }
  } else {
    if (currentTimeValue + delta < 24) {
      newTimeValue = currentTimeValue + delta;
    } else {
      newTimeValue = (currentTimeValue + delta) % modUnit;
    }
  }
  return newTimeValue;
}

I also added the Debounce library to handle the rotary knob button click event that toggles between the different edit modes.

Screen Time

To provide better visual feedback for the user, I then experimented with using an LCD screen instead of the serial monitor. The LCD I used was a 0.96” OLED LCD screen that is compatiable with AdaFruit’s SSD1306 driver. I reformatted my Arduino with the LCD example code to make sure the screen was functional.

LCD test

When I updated my rotary clock code to print to the LCD instead of the serial monitor, the encoder’s performance degraded. Rotating the knob resolved in less accurate value changes as demoed in this video. I wasn’t able to pinpoint the cause of this degradation — I even tried using a second Arduino as a separate power source for the display. My guess is the encoder interrupts wasn’t working well with the LCD’s i2c communication.

external arduino power

I’d like to return to using the LCD display in the future, but for this project I decided to move on and consider the additional feature of this rotary clock. I originally experimented with adding an alarm clock mode in which the rotary knob could set an alarm time.

toggle switch

But then my classmate Matt gave me the idea of creating a nightlight that only turns on during certain hours of the day. To make this feature, I included the RTC library and added an LED to the circuit. Adding the RTC library allowed the microcontroller to keep track of time and I refactored the code to write the new hour and minute values to the rtc object.

LED light

Here is a breadboard image and schematic of the final circuit:

fritz circuit

schematic

Fabricating

I then started to consider the clock’s fabrication and extensions to the physical interface on the breadboard. And one of the first upgrades I wanted to do was use a bigger and beefier knob on the rotary input for ergonomic comfort and greater visual cue that it’s meant to be turned. There was a round wooden piece in the junk shelf that with a bit of filing could fit the rotary knob cap.

filing

cap in wood

testing on cardboard

To keep the enclosure simple, I opted to upcycle a cardboard box from the ITP shop. I tested if the rotary knob and its wires could stick well to the inside of the box while still in a breadboard, but found it to be unstable. So I soldered the input to a PCB, used the included panel mount nut to secure it to the box’s side and finished the enclosure with a hole for the LED.

soldering

underside

finished enclosure

finished enclosure with hand

enclosure top

Future Thoughts

Some thoughts I had if I continue to iterate on this idea:

  • Continue investigating the LCD component and see if the problem is caused by my code, the LCD library, or a mixture of both
  • Use a sturdier enclosure material than cardboard — Ada pointed out during class feedback that pressing the rotary knob’s button required a second stabilizing hand on the other side of the enclosure
  • Add a clicking noise when rotating the knob in edit mode for more experiential cue that user action is changing digital values

Adrian Bautista

A perpetual work in progress blog documentating my NYU ITP projects. Words are my own.