Final Project: Crypototube

SONY DSC

My group was inspired by Dan Brown’s “The Da Vinci Code” and the board-game “Mastermind” for our final project. We built a lock-box that can only be opened once you enter the correct sequence of on/off on the control panel. The photo above is from the ITP Winter Showcase 2013, where the project was showcases. I’ll be using media and images from our previous prototype, which looked like this:

Prototype image

Check out the video of our demo here.

Basically, if your code is right (as computed by an Arduino Mega), we send a signal to a linear actuator that connect the inside of the box to the lid. Relatively simple mechanism.

Here’s a closer look at the control panel:

IMG_1434

The yellow lights show which switches you’ve pressed (so which switches are on or off). We were initially hoping for switches that would stay down once you pushed them, giving both tactile and visual feedback, but we made a blunder and bought the wrong kind of switches online…yeah…

Each time you enter a code and present submit, the Cryptotube gives you a clue as to how close you are to the answer. The green lights tell you how many correct on/off switches your configuration has, while the red lights tell you how many positions on the switchboard have the correct on/off configuration. If you guess too many times, the board gives a few warning flashes and the code resets, so you can’t just brute-force your way through the code. Here are the instructions written on the Cryptotube:

Can you open the Cryptotube?
Or are you an utter noob?
A string of on and off you’ll need
And our hints you’ll have to heed.
Press “submit” to receive a clue,
Guess too much, the code will renew.

The number of on/off that match the key
Green will truly let you see.
The number of positions you guessed right
Red will offer the most insight.

Deduce quickly, tarry not,
Lest your treasure begin to rot.

Some of our classmates felt that with regards to the LED’s, green and red felt too much like YES and NO, so we changed that in the final project.

Two of us have experience in game design, and the team was pretty concerned about the “Game mechanic” of the project: how would people respond to the code-guessing? Was it too difficult? Too easy? Boring? We tested different versions of the mechanic (changing things such as number of switches, what type of feedback you get, number of guesses allowed etc.) before coming up with what we have now. You can check out some of our testing here.

Here’re some of our initial design sketches:bild (2) bild

We went through a number of different “versions” of the Cryptotube. For starters, none of us are very experienced with physical fabrication, so we brainstormed many different ways of putting together the tube before Tom Igoe and our TA suggested what we currently have. It was a good learning, experience though!

My own work focussed on the electronics, and some of the programming. The electronics was pretty exciting: I actually sat down and did a bunch of calculations to design a resistor array for our linear actuator (okay, the Math was equivalent to freshman-level Physics, but I was still excited about APPLYING it!). Here’s a look at the (very messy) electronics. And yes, that’s my handkerchief.

IMG_1431 IMG_1433

Major changes in the final version (based on feedback from our classmates and Professor):
a)we decided to use toggle switches that flick one way to turn on
b) Changed colours from red-green to yellow-green, to reduce the feel that green lights mean “correct” and red lights mean “wrong”
c) Changed from a linear actuator from a locking mechanism to a servo motor

Here’s a close-up of the project just before the show:SONY DSC

Susanne was in charge of making the code, with some input from me and Clio, and here it is:

//Code cracking system, how it works:
//the program randomizes a 4 sequence code
//the user guesses the code by switching the 5 toggle switches
//there has to be a way for the user to “tell the arduino” when to receive feedback. Suggestion would be to use a 5th switch
//the LED’s gives feedback back to user of how many are are positioned correct and how many are the correct “kind”

//switch that activates the battery (activates the setup up function, start by looking the box (or make sure it’s already looked))

//Electronics:
//5 toggle switches (that can stay in two states) to receive feedback from user
//1 switch that the user presses when he/she wants to receive feedback from the arduino
//10 LED’s to give feedback to the user
//1 servo motors that actions when 5 swtiches are correct
// Dont use the 52 digital port on the MEGA board. It seems not to work

#include <Servo.h>
Servo servoMotor;
int servoPin = 4;
int lockAngle = 90;
int openAngle = -lockAngle;
boolean trueCode[5]; //an int array to store the correct 4 digit code. Need to check syntax on how to set the size of an array!
boolean switchValues[5]; //an int array to store the guessed values
int AnalogRandomNumber[5]; //stores a random number between 0-1

boolean previouscheckPin = LOW;

//CHANGE THE PINS TO WHAT EVER PINS WE’RE USING!!
int checkPin = 40;

 

int switchPin1 = 30;
int switchPin2 = 32;
int switchPin3 = 34;
int switchPin4 = 36;
int switchPin5 = 38;

/*int switchLED1 = 41;
int switchLED2 = 43;
int switchLED3 = 45;
int switchLED4 = 47;
int switchLED5 = 49;*/

//RED LED:s
int POSLED1pin = 11;
int POSLED2pin = 10;
int POSLED3pin = 9;
int POSLED4pin = 8;
int POSLED5pin = 7;

//GREEN LED:s
int COLLED1pin = 14;
int COLLED2pin = 15;
int COLLED3pin = 16;
int COLLED4pin = 17;
int COLLED5pin = 19;

int switchpins [5] = {
switchPin1,switchPin2,switchPin3,switchPin4,switchPin5};

int colorPins [5] = {
COLLED1pin,COLLED2pin,COLLED3pin,COLLED4pin,COLLED5pin };

int positionPins [5] = {
POSLED1pin,POSLED2pin,POSLED3pin,POSLED4pin,POSLED5pin };

/*int switchPinsLEDs[5] = {
switchLED1,switchLED2,switchLED3,switchLED4,switchLED5};*/
int correctPositions = 0;
int correctColors = 0;
void setup(){
Serial.begin(9600);

servoMotor.attach(servoPin);
pinMode(checkPin, INPUT);

pinMode(switchPin1, INPUT);
pinMode(switchPin2, INPUT);
pinMode(switchPin3, INPUT);
pinMode(switchPin4, INPUT);
pinMode(switchPin5, INPUT);

/*pinMode(switchLED1, OUTPUT);
pinMode(switchLED2, OUTPUT);
pinMode(switchLED3, OUTPUT);
pinMode(switchLED4, OUTPUT);
pinMode(switchLED5, OUTPUT);*/

pinMode(POSLED1pin, OUTPUT);
pinMode(POSLED2pin, OUTPUT);
pinMode(POSLED3pin, OUTPUT);
pinMode(POSLED4pin, OUTPUT);
pinMode(POSLED5pin, OUTPUT);
pinMode(COLLED1pin, OUTPUT);
pinMode(COLLED2pin, OUTPUT);
pinMode(COLLED3pin, OUTPUT);
pinMode(COLLED4pin, OUTPUT);
pinMode(COLLED5pin, OUTPUT);
//lock servo
servoMotor.write(lockAngle);

//Generates a random number by reading an analog pin and for
for (int i = 0; i < 5; i++){
AnalogRandomNumber[i] = analogRead(A0); // returns an int between 0 – 1023
if (AnalogRandomNumber[i] % 2 == 0){
trueCode[i] = true;
//Serial.println(AnalogRandomNumber[i]);
}
else{
trueCode[i] = false;
}
Serial.print(i);
Serial.print(” trueCode: “);
Serial.println(trueCode[i]);
}
switchValues != trueCode; //set switchValues = complement to trueCode to make sure they are not the same the first time it hits the while loop

int countNumberOfGuesses = 0;
//HERE STARTS THE MAIN WHILE LOOP
while (switchValuesVStrueCodeNotTheSame()){
digitalWrite(servoPin, LOW);
Serial.print(“countNumberOfGuesses: “);
Serial.println(countNumberOfGuesses);

//This if-statement re-randomizes the code after the user has guessed 20 guesses and indicates this by blinking the LED’s
if (countNumberOfGuesses == 500){
Serial.println(“randomize trueCode again: “);
for (int i = 0; i < 5; i++){
AnalogRandomNumber[i] = analogRead(A0); // returns an int between 0 – 1023
if (AnalogRandomNumber[i] % 2 == 0){
trueCode[i] = true;
Serial.print(“AnalogRandomNumber: =============================================”);
Serial.println(AnalogRandomNumber[i]);
}
else{
trueCode[i] = false;
Serial.print(“AnalogRandomNumber: “);
Serial.println(AnalogRandomNumber[i]);
}
Serial.print(i);
Serial.print(” trueCode: “);
Serial.println(trueCode[i]);

}
countNumberOfGuesses = 0;
blinkingLEDs(); //All LED:s will blink for 5 times to indicate that the trueCode has re-randomized
}

//THE PROGRAM RESTS HERE WHILE WAITING FOR THE USER TO PRESS THE CHECKSWITCH
while (digitalRead(checkPin) == LOW){
Serial.println(“stay here and do nothing until the user presses the checkSwitch”);
Serial.print(“checkpinValue: “);
Serial.println(digitalRead(checkPin));
delay(100); //this should not be needed now that I’m checking previouscheckPin vs checkPin and only then adding to the number of guesses
previouscheckPin = LOW;

}
delay(300);
if (digitalRead(checkPin) != previouscheckPin){
countNumberOfGuesses++;
previouscheckPin = HIGH;
}

//otherwise if checkPin == HIGH:
getCode();
correctPositions = checkPosition();
correctColors = checkColor();
lightPositionLEDs();
lightColorLEDs();

if (correctColors == 5 && correctPositions == 5){
Serial.print(“YOU GUESSED THE RIGHT CODE”);
//servo unlock
servoMotor.write(openAngle);
break;
}
}
}

void loop(){
}

boolean switchValuesVStrueCodeNotTheSame(){
int localCounter = 0;
for (int i = 0; i < 5; i++){
if (switchValues[i] == trueCode[i]){
localCounter++;
}
else{
}
}
if (localCounter == 5){
return false;
}
else {
return true;
}
Serial.println(localCounter);
}

void getCode(){
for (int thisSwitch = 0;thisSwitch < 5; thisSwitch++){
switchValues[thisSwitch] = digitalRead(switchpins[thisSwitch]);
Serial.print(“switchValue”);
Serial.print(thisSwitch);
Serial.print(“: ” );
Serial.println(switchValues[thisSwitch]);

}
for(int thisSwitch = 0;thisSwitch < 5; thisSwitch++){
Serial.print(“trueCode”);
Serial.print(thisSwitch);
Serial.print(“: ” );
Serial.println(trueCode[thisSwitch]);
}
}
int checkPosition(){
//returns a number between 1-5 depending on how many LED’s should be lighting
int correctPositions;
for (int i = 0; i < 5; i++){
if (switchValues[i] == trueCode[i]){
correctPositions = correctPositions + 1;
}
}
return correctPositions;
}
int checkColor(){
//returns a number between 1-5 depending on how many LED’s should be lighting
int numberOfTrueIntrueCode = 0;
int numberOfTrueInswitchValues = 0;
for (int i = 0; i < 5; i++){
if (trueCode[i] == true){
numberOfTrueIntrueCode += 1;
Serial.print(” numberOfTrueIntrueCode: “);
Serial.println(numberOfTrueIntrueCode);
}
if (switchValues[i] == true){
numberOfTrueInswitchValues += 1;
Serial.print(” numberOfTrueInSwitchValues: “);
Serial.println(numberOfTrueInswitchValues);
}
}
if (numberOfTrueInswitchValues == numberOfTrueIntrueCode){
correctColors = 5;
}
else{
correctColors = 5 – abs(numberOfTrueIntrueCode – numberOfTrueInswitchValues);
Serial.print(“number of Green LED:s that should LIGHT “);
Serial.println(correctColors);

}
return correctColors;
}

//RED LED:s
void lightPositionLEDs(){
for(int i = 0; i < correctPositions; i++){
digitalWrite(positionPins[i], HIGH);
Serial.print(“POSLEDpin “);
Serial.print(i);
Serial.println(” light “);
}
for(int i = correctPositions; i<5; i++){
digitalWrite(positionPins[i],LOW);
Serial.print(“POSLEDpin “);
Serial.print(i);
Serial.println(” NoLight “);
}

}

//GREEN LED:s
void lightColorLEDs(){
for(int i = 0; i < correctColors; i ++){
digitalWrite(colorPins[i], HIGH);
}
for(int i = correctColors; i < 5; i ++){
digitalWrite(colorPins[i], LOW);
}
}

void blinkingLEDs(){
for (int i = 0; i <5; i++){
digitalWrite(positionPins[i], HIGH);
digitalWrite(colorPins[i], HIGH);
delay(300);

digitalWrite(positionPins[i], LOW);
digitalWrite(colorPins[i], LOW);
delay(300);
}

}

Advertisements

Midterm: Singing Gongs

IMG_1327

My team’s midterm project was an attempt to make an unusual musical instrument. You hit these gongs, and instead of the expected bass reverberations, you hear human song (currently my and my team-mate’s voices…). You can check out a video of the gongs in action here.

Basically, we cut up some wood to make our gongs and our mallet, added some padding to our mallet to muffle any sounds, and strapped some piezo’s to the gongs. Here’s what that looks like:IMG_1330

Our Arduino code sensed vibrations from the gong, and sent it to a Processing sketch that used the minim library to play our pre-recorded singing. Here’s our code:

1) Arduino

//PUNCTUATION METHOD
void setup()
{
// start serial port at 9600 bps:
Serial.begin(9600);
}

void loop()
{
for (int thisSensor = 0; thisSensor < 3; thisSensor++) {
int sensorValue = analogRead(thisSensor);
if(sensorValue>500){
Serial.print(thisSensor);
Serial.print(“,”);
Serial.println(sensorValue, DEC);
}
}
}

 2) Processing

//before runnning this i have to upload the arduino program unto my board
//(make sure to close the serial monotor also before running this program, however do not remove the usb-cable)

import processing.serial.*;

Serial myPort; //our serial connection to the arduino

import ddf.minim.*;
AudioPlayer gong0;
AudioPlayer gong1;
AudioPlayer gong2;
Minim minim;
void setup () {
size(500, 500); // window size
fill(255, 0, 0);
minim = new Minim(this);
// load a file, give the AudioPlayer buffers that are 2048 samples long
gong0 = minim.loadFile(“LittleGong2.mp3”, 2048);
gong1 = minim.loadFile(“MiddleGong2.mp3”, 2048);
gong2 = minim.loadFile(“BigGong2.mp3″, 2048);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil(‘\n’);
}

void draw() {
}

void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil(‘\n’);
// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

int sensors[] = int(split(myString, ‘,’));

print(sensors[0] + ” ” + sensors[1] + “\t”); //sensors[1] = THE VALUE FROM THE PIEZO
println();
if (sensors[1]<600) {
if (sensors[0] == 0) {
gong0.setGain(1); //-48 (mute) to 6(loud)
gong0.play(0);
text(“Gong0 is playing. “, 100, 100);
}
if (sensors[0] == 1) {
gong1.setGain(1); //-48 (mute) to 6(loud)
gong1.play(0);
text(“Gong1 is playing. “, 200, 200);
}
if (sensors[0] == 2) {
gong2.setGain(1); //-48 (mute) to 6(loud)
gong2.play(0);
text(“Gong2 is playing. “, 300, 300);
}
}
else if (sensors[1]<800) {
if (sensors[0] == 0) {
gong0.setGain(4); //-48 (mute) to 6(loud)
gong0.play(0);
text(“Gong0 is playing. “, 100, 100);
}
if (sensors[0] == 1) {
gong1.setGain(4); //-48 (mute) to 6(loud)
gong1.play(0);
text(“Gong1 is playing. “, 200, 200);
}
if (sensors[0] == 2) {
gong2.setGain(4); //-48 (mute) to 6(loud)
gong2.play(0);
text(“Gong2 is playing. “, 300, 300);
}
}
else {
if (sensors[0] == 0) {
gong0.setGain(6); //-48 (mute) to 6(loud)
gong0.play(0);
text(“Gong0 is playing. “, 100, 100);
}
if (sensors[0] == 1) {
gong1.setGain(6); //-48 (mute) to 6(loud)
gong1.play(0);
text(“Gong1 is playing. “, 200, 200);
}
if (sensors[0] == 2) {
gong2.setGain(6); //-48 (mute) to 6(loud)
gong2.play(0);
text(“Gong2 is playing. “, 300, 300);
}
}
}
}

void stop()
{
// always close Minim audio classes when you are done with them
gong0.close();
gong1.close();
gong2.close();
minim.stop();

super.stop();
}

After a good bit of work, we found that calibrating our piezo’s was the hardest part: their calibration kept changing depending on where we were,  the number of people around etc. We did get the prototype to work, however!

Final Project Idea

After having seen some of the midterms made by other groups, my group decided on making a game-like device for our final project. As in, the device will be far more interactive, and not simply reactive like our singing gongs (video pending!). We threw around a bunch of ideas and decided to do something like the game Mastermind. We’re not going to simply duplicate the game, but we like the feel of making connections and linking different nodes to each other and though we haven’t figured out the fine mechanics of the game, I think we’re onto something really interesting!

Physical Interaction

Before ITP, I had had some experience with Interaction Design. I had both taken classes and worked at Tiltfactor Lab, a game lab that emphasizes games for social change. Focusing on Game Design, I worked a lot with what Donald Norman would call “Behavioral Design”: how do players interact with each other and with the game system? What can you do to motivate them to take certain actions, or to encourage a certain style of behaviour? What mechanics will provoke an “AHA!” moment?

Through courses at ITP, especially Physical Computing and Visual Language, I’ve been thinking a little more about the physical design of things, which includes what Norman calls “Visceral Design”, and features that directly address the senses.  I’ve scratched the surface of this type of design in my past life as a bioengineer (see my adventures with poop), but not in any great detail.As an example, my team’s midterm project is a set of singing gongs. We really want to enforce a serene, calming aesthetic and we’ve had to think about how qualities of the gongs that will reinforce this (such as the weight of the materials used, the type of mallet etc.). I’ve been reading Norman’s “Emotional Design”, where he talks about how the aesthetic qualities of a product can go a long way in making it a more usable product, and Timothy Samara’s “Design Elements: A Graphic Style Manual”, which is a great book with concrete suggestions about visual design.

So yeah, that’s one of the major things I’ve been learning about physical interaction!

Musical Instrument

Susanne Forcheimer and I finally managed to complete our musical instrument!

We wanted to make a device that you could scream into, which would then take your scream, add some nifty processes and output music. At first, we tried screaming into a piezo, with little effect. We tried using mics, which worked better, but then couldn’t find enough mics while we worked on it outside of class. We finally went back to using a piezo, and the device has now become a tap-to-music-converter!

How it works:

1) Press the “record” button (you’ll see a red light) and tap on the piezo a few times, in whatever rhythm you like.

2) Press the play button and see your rhythm converted to music!

The device took quite a bit of work, and we came away with a number of questions to pose during class or Office Hours…

musikinstrument2

 

musicinstrument3

 

Here’s the arduino code:

#include "pitches.h"

//

int piezo, piezo2;
int speaker = 7;
int recordpin = 2;
int playpin = 4;
int record = 0;
int play = 0;
int memory[90] = {
};
int i = 0; //counter for memory values 
int j = 0; //counter for playing 

int arr[]= { 
  NOTE_B0,  NOTE_C1,
  NOTE_CS1,
  NOTE_D1,
  NOTE_DS1,
  NOTE_E1,
  NOTE_F1,
  NOTE_FS1,
  NOTE_G1,
  NOTE_GS1,
  NOTE_A1,
  NOTE_AS1,
  NOTE_B1,
  NOTE_C2,
  NOTE_CS2,
  NOTE_D2,
  NOTE_DS2,
  NOTE_E2,
  NOTE_F2,
  NOTE_FS2,
  NOTE_G2,
  NOTE_GS2,
  NOTE_A2,
  NOTE_AS2,
  NOTE_B2,
  NOTE_C3,
  NOTE_CS3,
  NOTE_D3,
  NOTE_DS3,
  NOTE_E3,
  NOTE_F3,
  NOTE_FS3,
  NOTE_G3,
  NOTE_GS3,
  NOTE_A3,
  NOTE_AS3,
  NOTE_B3,
  NOTE_C4,
  NOTE_CS4,
  NOTE_D4,
  NOTE_DS4,
  NOTE_E4,
  NOTE_F4,
  NOTE_FS4,
  NOTE_G4,
  NOTE_GS4,
  NOTE_A4,
  NOTE_AS4,
  NOTE_B4,
  NOTE_C5,
  NOTE_CS5,
  NOTE_D5,
  NOTE_DS5,
  NOTE_E5,
  NOTE_F5,
  NOTE_FS5,
  NOTE_G5,
  NOTE_GS5,
  NOTE_A5,
  NOTE_AS5,
  NOTE_B5,
  NOTE_C6,
  NOTE_CS6,
  NOTE_D6,
  NOTE_DS6,
  NOTE_E6,
  NOTE_F6,
  NOTE_FS6,
  NOTE_G6,
  NOTE_GS6,
  NOTE_A6,
  NOTE_AS6,
  NOTE_B6,
  NOTE_C7,
  NOTE_CS7,
  NOTE_D7,
  NOTE_DS7,
  NOTE_E7,
  NOTE_F7,
  NOTE_FS7,
  NOTE_G7,
  NOTE_GS7,
  NOTE_A7,
  NOTE_AS7,
  NOTE_B7,
  NOTE_C8,
  NOTE_CS8,
  NOTE_D8,
  NOTE_DS8}
;

void setup(){
  Serial.begin(9600);
  pinMode(speaker,OUTPUT);
  pinMode(recordpin, INPUT);
  pinMode(playpin, INPUT);

}

void loop(){
  record = digitalRead(recordpin);
  play = digitalRead(playpin);
  //  
  if(record == HIGH){
    //Serial.println("hello");
    piezo = analogRead(A0);
    piezo2 = constrain(map(piezo, 200,700,0,89),0,89);
    if (i<90){
      memory[i] = piezo2;
      i++;
    }
    //Serial.println(piezo2);
    Serial.println(i);
    Serial.println(memory[i]);
  }
  if(play == HIGH){
    //Serial.println("bye");
    tone(speaker,arr[memory[j]]);
    j++;
    delay(500);
    //tone(speaker,arr[piezo2],3000);
  }
  else{
    noTone(speaker);
  }

}

/*************************************************
* Public Constants
*************************************************/

/*************************************************
* Public Constants
*************************************************/

 #define NOTE_B0  31
 #define NOTE_C1  33
 #define NOTE_CS1 35
 #define NOTE_D1  37
 #define NOTE_DS1 39
 #define NOTE_E1  41
 #define NOTE_F1  44
 #define NOTE_FS1 46
 #define NOTE_G1  49
 #define NOTE_GS1 52
 #define NOTE_A1  55
 #define NOTE_AS1 58
 #define NOTE_B1  62
 #define NOTE_C2  65
 #define NOTE_CS2 69
 #define NOTE_D2  73
 #define NOTE_DS2 78
 #define NOTE_E2  82
 #define NOTE_F2  87
 #define NOTE_FS2 93
 #define NOTE_G2  98
 #define NOTE_GS2 104
 #define NOTE_A2  110
 #define NOTE_AS2 117
 #define NOTE_B2  123
 #define NOTE_C3  131
 #define NOTE_CS3 139
 #define NOTE_D3  147
 #define NOTE_DS3 156
 #define NOTE_E3  165
 #define NOTE_F3  175
 #define NOTE_FS3 185
 #define NOTE_G3  196
 #define NOTE_GS3 208
 #define NOTE_A3  220
 #define NOTE_AS3 233
 #define NOTE_B3  247
 #define NOTE_C4  262
 #define NOTE_CS4 277
 #define NOTE_D4  294
 #define NOTE_DS4 311
 #define NOTE_E4  330
 #define NOTE_F4  349
 #define NOTE_FS4 370
 #define NOTE_G4  392
 #define NOTE_GS4 415
 #define NOTE_A4  440
 #define NOTE_AS4 466
 #define NOTE_B4  494
 #define NOTE_C5  523
 #define NOTE_CS5 554
 #define NOTE_D5  587
 #define NOTE_DS5 622
 #define NOTE_E5  659
 #define NOTE_F5  698
 #define NOTE_FS5 740
 #define NOTE_G5  784
 #define NOTE_GS5 831
 #define NOTE_A5  880
 #define NOTE_AS5 932
 #define NOTE_B5  988
 #define NOTE_C6  1047
 #define NOTE_CS6 1109
 #define NOTE_D6  1175
 #define NOTE_DS6 1245
 #define NOTE_E6  1319
 #define NOTE_F6  1397
 #define NOTE_FS6 1480
 #define NOTE_G6  1568
 #define NOTE_GS6 1661
 #define NOTE_A6  1760
 #define NOTE_AS6 1865
 #define NOTE_B6  1976
 #define NOTE_C7  2093
 #define NOTE_CS7 2217
 #define NOTE_D7  2349
 #define NOTE_DS7 2489
 #define NOTE_E7  2637
 #define NOTE_F7  2794
 #define NOTE_FS7 2960
 #define NOTE_G7  3136
 #define NOTE_GS7 3322
 #define NOTE_A7  3520
 #define NOTE_AS7 3729
 #define NOTE_B7  3951
 #define NOTE_C8  4186
 #define NOTE_CS8 4435
 #define NOTE_D8  4699
 #define NOTE_DS8 4978

Design Analysis

This week we were tasked with analysing the design of a device used by humans. Specifically,  we were supposed to examine a public device. I creepily stared at people at ATM’s and subway-ticket-vendors, both of which failed to inspire me. Then I noticed something right at home when my roommate and I tried to do some emergency cleaning after the sighting of a cockroach (it has since been dealt with, thank goodness).

Voila, our bottle of  spray-disinfectant:Bottle full view

First off, the bottle is NOT an interactive device. Yes, you can argue that it responds to our input (it sprays out liquid when we pull the trigger), but Chris Crawford would, I’m sure, have something snarky to say about that. So much of what Crawford says is irrelevant to the bottle.

I’m more interested in how our humble spray-bottle relates to Donald Norman’s ideas of good design.

1) For starters, as household disinfectants go, it’s a pretty attractive bottle, and Norman talks about the importance of attractiveness in well-designed things. “Negative affect can make it harder to do even easy tasks: positive affect can make it easier to do difficult tasks,” he says.  The bottle’s never going to earn an exhibit in the Met, by any means, but it’s not ugly. It has an sleek lines and a nice white colour. “I’m all about cleanliness,” it tries to say.  It also has some nice, ergonomic grips that tell you where to hold it, and a trigger, which is just fun to use. Personally, though, I feel that attractiveness is not as important a feature in this particular case, because we’re unlikely to need to perform very many complex tasks with this device. It’s just point and shoot. To me, the aesthetics here are more marketing-related. But it’s attractive, and that earns it a plus on the design scale.

2) The very first time we sprayed it, however, we encountered a problem. For starters, no-where does it indicate that you’ll have to do any special actions to activate it for the first time. It’s neither written nor obvious from the design. Experience with household cleaners was our only guide. When I did try and activate it though, I was at a loss. I didn’t know what to press or turn. I spent a minute and a half playing with the thing followed by another minute of prodding by my roommate before we figured out that you needed to turn the red part of the nose. Here’s a closer view:

Bottle top

The design does not lend itself to helping us understand this. The first thing I tried was pull the trigger repeatedly, with no effect. The bottle is designed to bring attention to the trigger, and triggers are culturally known to be pulled, so that’s not a surprising first instinct. Then, I tried turning the round, toothed, red component. This section immediately stands out as something that should be turned (it “affords” turning, in Norman’s words). And why not? It’s a) round, which implies rotation,  b) grooved, which implies grip, and c) red, which makes it stand out from the rest of the bottle and screams, “Use me!” . Indeed,  this portion is for turning, but it unscrews the whole top of the bottle, not what I wanted.

The nose, while red, does not afford turning. It’s also the tip of the device, where the cleaning solution is ejected, a location that does not intuitively invite probing fingers. A good design solution would be to use the same “turning signals” that the previous component used: roundness and ribs. One could argue that the square-shape was purposefully designed for optimal aerosol aerodynamics, but this seems unlikely given that the actual aperture in the tip  through which the liquid escapes is a tiny round hole.  So I see no reason for the square shape. In fact the tip is marked with the words “ON” and “OF, but the writing is tiny, red, and carved into the tip, and hence, invisible. Here’s a more extreme close-up, where you can somewhat make-out the writing:Bottle closeup

So this device, while fails to follow one of Norman’s “rules”: the simple but not obvious thought of “making things visible”.

In its defence, once the bottle has been used for the first time, it’s simple and intuitive to use (the cockroach scared us and inspired a stricter cleaning regimen…).

Thoughts on Physical Interaction

Keeping Chris Crawford’s opinions in ind, I think I’d define “physical interaction” as the manipulation of something physically which then processes that interaction in some way and then gives a meaningful response, to which we can then make further responses. I’m not QUITE so clear, however, with the boundaries of this definition…

Imagine moulding a lump of clay. The human hands, as Bret Victor puts it, “two utterly amazing things”, and we can use them both to shape and to get information from the clay. You “communicate” with the clay by manipulating your hands, the clay “processes” these signals by being moving and holding together, and then responds with a shape. You can both see and physically feel the effects of your effort. Would Crawford call this an “interactive process”? I would suspect not…

But as Victor puts it, imagine if we integrated this sort of manipulation into how we use technology. What if the interface to a 3D-modelling program included, along with a screen and stylus, a touch-sensitive lump of clay peppered with tiny sensors? This would be an example of “good” physical interaction: easing the entire range of sensing and actuating capabilities of our hands (or any other organ we might use to interact with something!).

Of course, you don’t NEED something to be “interactive” to be effective. For example, many people don’t like video-games with too linear a plot. While I agree that the power of games lie in the decision-response cycle players have with the system, many wonderful but pretty linear games exist. Reacting and participating in a narrative, if it’s engaging and well-told, has its merits!