Norman’s Concepts and the iPod

Steve Job’s summary of what made the iPod successful find significant parallels in the first few of Norman’s concepts that we read about this week.

Constraints: According to Jobs, one of the most significant guiding concepts for the iPod design process was a rejection of the “gadget” mentality of the early 2000s. Steve felt that complex devices that offered an abundance of complex functionality were not usable by the average person, and steered the iPod in the opposite direction, limiting functionality and interfaces to the most minimal application possible. For example, all interaction with the device is done with a scroll wheel.

Discoverability: The same constraints that make the device simple to use also make it easy to learn. Since there are only a couple methods of interacting with the device, ie scroll wheel and a couple buttons, it is immediately clear that there are the controls for each function. Additionally, the firewire socket for the device both charges the device and loads music onto it. Users would be generally familiar with using a port for both of these actions, and since there is only one, it intuitively must serve both purposes.

Feedback: Although not discussed explicitly in this article, the first iPod is a masterpiece of feedback. Jobs famously delayed the release of the device for weeks near the end of production because the headphones didn’t snap into place when inserted in the headphone jack. This seemingly minute interaction actually offers a massively improved user experience; when the headphones are in, they click, and the user knows this and doesn’t worry about the headphones any further.

Future Visioning

Autobiography Exercise: This assignment was honestly pretty uncomfortable at first. At first I struggled with humility and downplayed my aspirations for ten years from now. After fighting through this, I realized that my plans for after college are fairly unclear; it’s a subject that frankly terrifies me. I do have goals, though. I want to work creatively for a living, live comfortably enough to support myself and family, maintain friendships and make new ones, and be generally happy. These goals are large, but feel attainable. Thinking about how to reach these goals is more inspiring than terrifying, and makes future visioning more comfortable.

Strategic Planning: This exercise formalized some of the steps I want to take to reach my goals. Steps included graduating cum laude, securing a job in the design industry in the next 2 years, and staying in Denver to stay connected to friends. Some of my steps were tentative or backups, such as living with my brother on the east coast to job search out there.

Portfolio and Capstone Goals

Portfolio Goals: At the end of this course, i.e. graduation, I want my portfolio to be an accurate representation of the work I’ve done in field I want to go into. My portfolio should be something that hiring managers can look at and see examples of my work in a diverse body of fields, with a focus in digital and typography design. All the examples of work on my page should be impressive, and speak for themselves. Additionally, a clear record of my design process for all projects should be presented.

Capstone Goals: I would like my capstone project to serve as the “jewel in the crown” of my portfolio. I would like my project to be centered in visual and typographic design, and serve as a primary example of my design skills in these areas. I am planning on this project being completely digital, and I don’t plan to work with anyone else on this project.

Jobs to Be Done

  1. Half an hour ago I was supposed to be on campus for work, and had a decision to make; to bike, or to drive? I make this choice many times a week, and it is interesting that both choices are selected equally often. My commute to work is short, so it often feels silly to drive. However, depending on the time of day, I may be feeling tired and unwilling to bike. I like the feeling of biking to work, as it starts my day with an energy boost, but biking takes about 5 minutes longer than driving. For such a seemingly simple decision, I spend a disproportionate time thinking about it.
  2. Besides biking and driving, I could walk or take the bus. I could also borrow my roommate’s skateboard, even though I don’t know how to ride it. This doesn’t seem like a terribly good option.
  3. Today I ended up biking to work. This made sense because I was going to work in the evening, when parking places are often scarce, and couldn’t immediately locate my keys when I needed to leave. I avoid buses like the plague because of aforementioned plague, and I really can’t ride a skateboard.
  4. After I choose to bike, I went outside, unlocked my bike from the fence, biked to campus, and locked my bike to the bike rack.
  5. A person with a similar problem might have ride a motorized unicycle to campus, as a friend sometimes does. This involves an electric self-balancing unicycle which reaches speeds up to 15mph.

“Jobs to Be Done” and User Personas

This article came as a breath of fresh air to me, as I have only ever been used personas before, and found them confusing and largely inaccurate. My issue with personas begins with the way they are generated: arbitrarily. Although consumer statistics and market reports may inform persona design to some extent, after a certain point all other details are generated entirely by the designer. In my opinion, this is often dangerous because it violated the purpose of the persona. Personas are intended to guide and inform design decisions, and point the designer towards a market focused solution. But when then designer is able to manufacture a character with little real bearing on the market, the persona backfires.

The theory of “Jobs to Be Done” makes much more sense to me. This theory bases design off of the idea that if a product does a job well, the consumer will repeatedly “hire” the product to do that job for them. This is an overly reductive description of the theory; there are many aspects to a job, such as emotional and social impact, and many aspects to why the customer would hire that certain product. However, at its core level, “Jobs to Be Done” theory is founded on an empirical truth about the consumer (the job they need done), while personas are often based on conjecture and manufactured details.

Monteiro: What is a Designer?

Dismissing the perception of a designer as a whimsical being floating above traditional work expectations resonated strongly with me. This is a perception I have encountered many times throughout my college experience. The work of a designer is fundamentally misunderstood as “easy”, a misconception that has done a massive disservice to designers overtime. This idea is so pervasive that some designers have internalized it as well (I’m looking at you, CU branding department), content to present mediocre work which perpetuates the myth of design as a soft option. Monteiro’s guidelines for designers serve as a framework for rebuking this destructive stereotype.

Object Final Project: Sound Box

Initial Concept

Inspired by the art of Zimoun, a fantastic installation artist who works primarily with sound, we wanted to create an interactive sound experience for our users. After briefly considering a room size installation, we decided to instead create a small box which users would move around, affecting the qualities of the sound. We planned to detect distance with ultrasonic sensors, and create sound with DC motors (again inspired by Zimoun), which would spin at variable rates and interact with materials to create sound. If a user was far from a sensor, the sound would be quiet, and become louder the closer they came to the sensor. A diagram of the planned user interaction can be seen below.

Initial Concept Exploration

As previously mentioned, we initially wanted to use DC motors to create our sound. This presented several challenges, since the amp draw from 4 different motors would be very high, making it difficult to run all 4 simultaneously. Because of this, we first decided to test 2 motors at a time, to iron out the small problems before we tackled the power issue.

In this video, the following code is used.

const int transistorPin = 9;    // connected to the base of the transistor
const int transistorPin2=10;
 
 void setup() {
   // set  the transistor pin as output:
   pinMode(transistorPin, OUTPUT);
   Serial.begin(9600);
 }
 
void loop() {
   // read the potentiometer:
   int sensorValue = analogRead(A0);
   // map the sensor value to a range from 0 - 255:
   int outputValue = map(sensorValue, 0, 1023, 0, 255);
   // use that to control the transistor:
   analogWrite(transistorPin, outputValue);
   analogWrite(transistorPin2, outputValue);
   Serial.println(outputValue);
 }

As you can see, although we did achieve speed variation of the DC motor, the motor is still spinning quite fast even at its slowest setting. Once we connected a piece of wire to the motor to test how it would sound, we realized that the motor really couldn’t go slow enough to make a sound that sounded pleasing. We realized we were going to have to back to the drawing board.

Revised Concept

After a brief collective panic attack, we brainstormed new ways to create our desired interaction. We decided to keep our ultrasonic sensors, but switch to solenoids for sound creation purposes. Additionally, we planned at this point to use the solenoids to interact with a kalimba, a sort of African instrument which creates sound with metal tines, usually plucked by thumbs.

Our new solenoid motors had the same issue as the last ones; we weren’t sure how to power them all at the same time, especially since we now planned on using as many as 15 solenoids. As before, we decided to test a few at a time to derive a proof of concept. In the video below, we test 3 solenoids firing in series and then in sequence.

Solenoids in sequence
Solenoids in series

Since these tests derived no real difference between the two methods, we decided to consult the data sheet. From this we discovered that each solenoid needed 1 amp to function. Since our arduino was only capable of supplying approximately 3 amps at a time, we decided that running the solenoids in sequence was the best solution to this problem.

Integrating the sensors

After solving our motor question, the next logical step was to connect the ultrasonic sensors. These sensors work by emitting an ultrasonic ping at a certain frequency and then sending a signal whenever that ping is heard bouncing back. This generates a unique set of issues with input. For one, the sensor data is not consistent, because the ping may bounce off of other acoustic surfaces. Also, the sensor may also not have heard the ping return until another ping has been fired, generating negative values. Some of these issues were solvable with software work arounds, and some were simply consequences of the medium.

To solve the inconsistent data issue, I created a function to clean the data using a series of if statements. These if statements throw out values less than zero and greater than 300. This implementation successfully made data predictable enough to be usable with the motors. This function is present in our final code.

To control the motors with the sensors, we set up an arbitrary upper distance limit for each sensor to start working. For example, one solenoid would only start working when distance was less than 30.

Note: Distance numbers from the sensor are by default unitless, unless otherwise mapped, which we chose not do.

First we connected just one sensor to two solenoids, and set them so it would control both of them.

This proved that our interaction would be possible using ultrasonic sensors paired to two solenoids each. In order to realize our full concept, all that was necessary now was to connect all the sensors and solenoids, and install them in an enclosure.

Installation and Fine Tuning

First we adapted our code to control three different sensors paired to 6 solenoids.

Luckily, this went off without a hitch. After securing our final sensor, we finalized the code to control 4 sensors. The final code can be seen below.

    //inputs
//sonic sensor 1
//trig is out echo is in
const int trigPin1 = 2;
const int echoPin1 = 3;

//sonic sensor 2
const int trigPin2 = 4;
const int echoPin2 = 5;

//sonic sensor 3
const int trigPin3 = 7;
const int echoPin3 = 6;

//sonic sensor 4
const int trigPin4 = 8;
const int echoPin4 = 9;

//solenoid pins
const int solenoidPin1 = 24;
const int solenoidPin2 = 28;
const int solenoidPin3 = 23;
const int solenoidPin4 = 27;
const int solenoidPin5 = 31;
const int solenoidPin6 = 32;
const int solenoidPin7 = 35;
const int solenoidPin8 = 36;

//the inputs we get from the sensors!
int distance1;
int distance2;
int distance3;
int distance4;

void setup() {
  //pinmoding the sonic sensor inputs
pinMode(trigPin1, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin1, INPUT); // Sets the echoPin as an Input

pinMode(trigPin2, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin2, INPUT); // Sets the echoPin as an Input

pinMode(trigPin3, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin3, INPUT); // Sets the echoPin as an Input

pinMode(trigPin4, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin4, INPUT); // Sets the echoPin as an Input

pinMode(solenoidPin1, OUTPUT);
pinMode(solenoidPin2, OUTPUT);
pinMode(solenoidPin3, OUTPUT);
pinMode(solenoidPin4, OUTPUT);
pinMode(solenoidPin5, OUTPUT);
pinMode(solenoidPin6, OUTPUT);
pinMode(solenoidPin7, OUTPUT);
pinMode(solenoidPin8, OUTPUT);

Serial.begin(9600); // Starts the serial communication
}

void solenoidControl(int sensorValue, int outPin, int rangeVal)
{
  if (sensorValue <= rangeVal)
  {
   digitalWrite(outPin, HIGH);
   delay(50); 
   digitalWrite(outPin, LOW); 
  }
}
int getDistance(int trigPin, int echoPin)
{
  int duration=0; 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  //Serial.print(duration);
  return(duration*0.034/2); 

}

int cleanDistance(int distance)
{
  if(distance > 150) distance = 150;
  else if(distance < 0) distance = 300;
  return(distance); 
}

void loop() {
  
distance1=getDistance(trigPin1, echoPin1);
delay(250);
distance2=getDistance(trigPin2, echoPin2);
delay(50);
distance3=getDistance(trigPin3, echoPin3);
delay(5); 
distance4=getDistance(trigPin4, echoPin4);
delay(5);

distance1=cleanDistance(distance1);
distance2=cleanDistance(distance2);
distance3=cleanDistance(distance3);
distance4=cleanDistance(distance4);
//Serial.print();
Serial.print(distance1); 
Serial.print("    ");
Serial.print(distance2); 
Serial.print("    ");
Serial.print(distance3); 
Serial.print("    ");
Serial.println(distance4);
//
solenoidControl(distance1, solenoidPin3, 10);
solenoidControl(distance1, solenoidPin4, 100);
solenoidControl(distance2, solenoidPin1, 100);
solenoidControl(distance2, solenoidPin2, 10);
solenoidControl(distance3, solenoidPin7, 100);
solenoidControl(distance3, solenoidPin8, 10);
solenoidControl(distance4, solenoidPin5, 100);
solenoidControl(distance4, solenoidPin6, 10);

//delay(50); 
}

After defining pins and inputs/outputs, first the program calls a function which pings the sensors, and returns a raw distance. This distance is then sent to the “cleanDistance” function, which removes extraneous values. Finally, the cleaned distance is sent to motor control functions which decide whether to fire the solenoid based on the range numbers. This process is repeated for all 4 sensors.

Our final circuit diagram can be seen below.

Essentially, the sensor pins take 1 input (output ping) and 1 input (returned distance). If the Arduino decides that a solenoid should fire, the digital output is sent first to a transistor, and then on to the solenoid itself.

At this point, we needed some way to mount the solenoids so that they could interact with our chosen surfaces. I designed a simple mounting bracket to be laser cut.

The solenoid brackets

Now that the sensors were mounted, we constructed the kalimba to test the solenoids. Unfortunately, the solenoids were not strong enough to push the keys down, so we revised our idea again. We ultimately decided that we only need 4 different sounds to make the interaction effective, so we chose to have the solenoids interact with jingle bells, a glass jar, a can lid, and the side of the enclosure itself.

After finalizing the electronics, we were ready to create an enclosure. We decided on a simple cube with ports for the sensors and a series of rectangles cut out to let out sound.

The sides of the enclosure

We designed this box to be cut from quarter inch thick birch using a laser cutter. Later on I added a piece of acrylic on the top to serve as an access panel.

After installing the electronics, we taped off the box for safe spraying, and sanded the sides down to prepare for a polyurethane coating. At this point, I sprayed several coats of polyurethane on the box.

The spraying process

After the box dried, we only had to calibrate the sensors to be ready for critique.

The installed electronics and acoustic surfaces
The final interaction

In the video above, you can see us interacting with the box at critique. In this video, the box is too close to the wall, so one set of solenoids is always firing.

Summary

Overall, we achieved our goal of creating an interactive sound box using proximity sensors. Given more time, we would have liked to refine the produced sounds more, either by using p5 to play digital sounds, or by choosing better acoustic surfaces to interact with.

Object Lab #5: Motors

The first circuit for this lab is a simple DC circuit using a switch and an H-bridge to reverse the direction of the motor.

DC motor diagram

First, the arduino reads input from pin 2, which determines whether the switch is open or closed. Using a series of if statements, based on this input the arduino sends output to the motor driver for the corresponding motor direction.

The second portion of this lab involves control of a stepper motor. The circuit for this motor is fairly similar to the DC control circuit, since I elected not to use the 12V power supply. Essentially an H bridge serves as a driver for the stepper based on output from the arduino.

Stepper Circuit Diagram

The code for this circuit is very simple. After setup, the stepper is revolved 513 steps (the total number of steps in this motor’s range). This action is repeated following a brief delay.

Form Final Project: CNC Lamp

Part 1: Ideation and Rendering

When doing ideation for this project, I was trapped between two motivations: my drive to make an interesting final project, and the urge to not go completely broke while doing so. These conflicting ideals fought for dominance over my fevered brain while I tossed and turned, night after night. Finally, in a moment of clarity, the solution presented itself to me; I would design and manufacture Christmas presents for my parents, thus getting two birds stoned at the same once.

I really enjoyed the way that light interacted with apertures in my unrolled object, so I have decided to make a pair of lamps for this project. They will be desk sized, with a wide base and a more narrow top. Inspired by the slicing method, a polar arrangement of vertical slices will diffuse the light emitted by a filament light bulb in the center of the lamp.

One possible lamp

My primary goals for this project are to become more comfortable with Grasshopper and CNC machining. Because of this, I have decided to model the sliced pieces of the lamp with Grasshopper. To add a personal element to each lamp, I am considered using data relating to each of my parents to determine aspects of the sliced piece. For example, birthdates might change width of a certain polyline point.

As of now, I am aiming to mill the cap and base from oak, and use laser cut birch for the sliced portion. I will house a lightbulb and accompanying electronics inside the lamp.

The lamps will be sized so that they can sit comfortably on a desk or small table, and diffuse light evenly on that surface.

Part 2: Execution

I decided against using oak for my base and cap because of cost. Instead I bought 7 ply pinewood plywood. These pieces came in 3/4 inch thickness, so I bought two and glued them together. This required redesigning the base and cap to the new thickness. The redesigns can be seen below.

The redesigned pieces

As you can see, I added a channel for the chord in the middle of the base. This required splitting the base into two sections to be machined separately.

The ribs

I bought 1/4 inch birch to use to cut the ribs. After experimenting with spacing in the model, I decided to distribute the ribs along the points of a 30 sided polygon, to diffuse the light without exposing the bulb (too much).

To house the pieces of the bulb, I designed a laser cut baseplate for all of the ribs to fit into, both at the top and at the base. The vectors for these can be seen below, along with the ribs.

The laser cut vectors

Tracking down an effective and functional CNC router proved to be the hardest part of this project. First I was scheduled to cut at the CLC, but was cancelled on last minute. Later, after my first cut, the BTU lab CNC broke. Finally, with Camila’s help, I gained access to the art department’s CNC, to which the others paled in comparison (thanks again!).

CNC milling the top of the base in the BTU
Milling the rest of the parts in the VAC

After I had all my parts present, all that was necessary now was to assemble everything. Easier said than done!

First, I wired the bulb housing to the plug, through the top of the base. This required some trial an error, but I eventually got everything working.

Following this, I realized that I definitely should have glued the bottom of the base and finished the wood on before wiring, but live and learn. I glued the base portion on, the cord in, and then sanded everything down. I also sanded the cap piece. After this, I covered the interior elements of the base plate in plastic to protect them from the polyurethane finish.

The spraying process
The drying process

Finally, I only needed to insert the ribs. Again, easier said than done.

The ribs and baseplate

Turns out that getting the ribs to stay in the baseplate was easy, but getting them to fit into the top plate was very difficult. After numerous attempts, and an overuse of masking tape, I decided to make a new part for the top. For this piece, I essentially just bisected the inside and outside of the top plate, so that one keeper controlled the inside of the ribs, and another controlled the outside. This piece can be seen assembled below:

The two top keeps in action

After that all I need to do was add the cap, but I decided against glueing it so that the lightbulb can be replaced easily in the future.

The Final Product