Luke Nguyen – Final Project – Can You See the Music?

Link to p5js code: https://editor.p5js.org/luke.s.ng/sketches/U8Xmnxnwu

Concept:

My final project is a Audio Workstation that can allow users to input music from Arduino using a special glove into p5 and visualize it. I was inspired by this Mimu glove created by MI.MU GLOVES LIMITED, which allows users to make music through movement using only a pair of glove with a lot of physical computing programmed into the device. My project is a simplified version of this, which only utilizes Arduino. I used p5.js to enhance the user’s experience visually, allowing them to see how their music is seen to the eyes.

User testing:

Some pictures / video of project interactions & comments + feedback:

What parts of your project did you feel the need to explain? How could you make these areas more clear to someone that is experiencing your project for the first time?

I got more than 10 people who came and interacted with my device, and a few of them were my classmates and friends from other classes.

Ume passed by, and I also invited her to test it. Afterward, she suggested that for future improvement, I could consider implementing this device in a way that it can trigger many musical instruments at the same time. She commented that this project of mine is already advanced enough, and her suggestion can be considered for a later, more advanced stage of learning interactive media.

Other than Ume, your friend also suggested that I can keep this device as a simple music maker but develop it into one that can incorporate more musical instruments.

Implementation/Description of interaction design:

Users can create music notes using Arduino and trigger them to appear inside p5. The Arduino board makes use of two major components: four buttons representing four fingers and one distance sensor. Each finger is assigned a different music instrument: index finger – piano, middle finger – drum, ring finger – guitar, pinky – synthesizer pulses.

The program currently supports the C major scale, consisting of 7 basic notes: C, D, E, F, G, A, B. Piano notes range from C4 to B5. Drum rhythm ranges from heavy kick to high crash. Guitar notes range from C3 to A3. And synthesizer pulses range from C6 to A6.

The user can control one instrument using two simultaneous actions: pressing the buttons attached to the tip of the glove they wear, users can trigger music notes inside p5.js. Simultaneously, by VERTICALLY controlling a distance sensor placed on the table, they can select/control the notes by changing the frequency of the buttons/their fingertips. Users can press other buttons at the same time to play with other musical instruments.

Additionally, they can press “R” and then play one instrument to record, then press “S” to stop, then press “L” to loop and save the first instrument. They can then input another instrument. The process can be repeated for other instruments. Users can keep doing that until they have generated something either funky, following a stream of consciousness, or a nice melody.

p5js will take the notes users input, put them through an amplitude analyzer and create a visualization on screen.

Arduino code: 

const int trigPin = 7;
const int echoPin = 8;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);

  // start the handshake
  while (Serial.available() <= 0) {
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    // digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    if (Serial.read() == '\n') {
      // detecting the pressure sensor
      int PressureSensor = analogRead(A0);
       delay(5);

      int PressureSensor2 = analogRead(A2);
      delay(5);

      int PressureSensor3 = analogRead(A4);
      delay(5);

      int PressureSensor4 = analogRead(A6);
      delay(5);


      long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // The same pin is used to read the signal from the PING))): a HIGH pulse
  // whose duration is the time (in microseconds) from the sending of the ping
  // to the reception of its echo off of an object.
  duration = pulseIn(echoPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);

  Serial.print(PressureSensor);
  Serial.print(',');
  Serial.print(inches);
  Serial.print(',');
  Serial.print(PressureSensor2);
  Serial.print(',');
  Serial.print(PressureSensor3);
  Serial.print(',');
  Serial.println(PressureSensor4);

  delay(100);
    }
    // digitalWrite(LED_BUILTIN, LOW);
  }

}

long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are 73.746
  // microseconds per inch (i.e. sound travels at 1130 feet per second).
  // This gives the distance travelled by the ping, outbound and return,
  // so we divide by 2 to get the distance of the obstacle.
  // See: https://www.parallax.com/package/ping-ultrasonic-distance-sensor-downloads/
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the object we
  // take half of the distance travelled.
  return microseconds / 29 / 2;
}

p5.js code:

The p5js code is too long to post here, so I’ll include aspects of code that I’m really proud of.

function startPlayingGame() {

// remember to calibrate the note accordingly
background(0);

console.log(note_piano);
if (note_piano > 200){
        if (freq_piano >= 1 && freq_piano <= 2){
          c4_piano.play(); c4_piano.setVolume(0.1);    
    }
        else if (freq_piano >= 3 && freq_piano <= 4){
            d4_piano.play(); d4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 5 && freq_piano <= 6){
            e4_piano.play(); e4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 7 && freq_piano <= 8){
            f4_piano.play(); f4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 9 && freq_piano <= 10){
            g4_piano.play(); g4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 11 && freq_piano <= 12){
            a4_piano.play(); a4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 13 && freq_piano <= 14){
            b4_piano.play(); b4_piano.setVolume(0.1);
    }
        else if (freq_piano >= 15 && freq_piano <= 16){
            c5_piano.play(); c5_piano.setVolume(0.1);
    }
        else if (freq_piano >= 17 && freq_piano <= 18){
            d5_piano.play(); d5_piano.setVolume(0.1);
    }
        else if (freq_piano >= 19 && freq_piano <= 20){
            e5_piano.play(); e5_piano.setVolume(0.1);
    }
        else if (freq_piano >= 21 && freq_piano <= 22){
            f5_piano.play(); f5_piano.setVolume(0.1);
    }
        else if (freq_piano >= 23 && freq_piano <= 24){
            g5_piano.play(); g5_piano.setVolume(0.1);
    }
        else if (freq_piano >= 25 && freq_piano <= 26){
            a5_piano.play(); a5_piano.setVolume(0.1);
    }
    else if (freq_piano >= 27 && freq_piano <= 28){
            b5_piano.play(); b5_piano.setVolume(0.1);
    }
  }


  if (drum > 200){
    if (freq_piano >= 1 && freq_piano <= 3){
      heavykick.play(); heavykick.setVolume(0.1);
    }
        else if (freq_piano >= 4 && freq_piano <= 6){
            lightkick.play(); 
            lightkick.setVolume(0.1);}

            else if (freq_piano >= 7 && freq_piano <= 9){
              snaresidekick.play(); 
              snaresidekick.setVolume(0.1);}

              else if (freq_piano >= 10 && freq_piano <= 12){
                lowtom.play(); 
                lowtom.setVolume(0.1);}

                else if (freq_piano >= 13 && freq_piano <= 15){
                  snarecenter.play(); 
                  snarecenter.setVolume(0.1);}

                  else if (freq_piano >= 16 && freq_piano <= 18){
                    hihatopen.play(); 
                    hihatopen.setVolume(0.1);}

                    else if (freq_piano >= 19 && freq_piano <= 21){
                      hitom.play(); 
                      hitom.setVolume(0.1);}

                      else if (freq_piano >= 22 && freq_piano <= 24){
                        crash.play(); 
                        crash.setVolume(0.1);}
    
  }

  if (guitar > 200){
    if (freq_piano >= 1 && freq_piano <= 3){
      c3_guitar.play();
      c3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 4 && freq_piano <= 6){
      d3_guitar.play();
      d3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 7 && freq_piano <= 9){
      e3_guitar.play();
      e3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 10 && freq_piano <= 12){
      f3_guitar.play();
      f3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 13 && freq_piano <= 15){
      g3_guitar.play();
      g3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 16 && freq_piano <= 18){
      a3_guitar.play();
      a3_guitar.setVolume(0.1);
    }

    else if (freq_piano >= 19 && freq_piano <= 21){
      b3_guitar.play();
      b3_guitar.setVolume(0.1);
    }
  }



  if (synth > 200){
    if (freq_piano >= 1 && freq_piano <= 3){
      c6_synth.play();
      c6_synth.setVolume(0.1);
    }

    else if (freq_piano >= 4 && freq_piano <= 6){
      d6_synth.play();
      d6_synth.setVolume(0.1);
    }
    else if (freq_piano >= 7 && freq_piano <= 9){
      e6_synth.play();
      e6_synth.setVolume(0.1);
    }

    else if (freq_piano >= 10 && freq_piano <= 12){
      f6_synth.play();
      f6_synth.setVolume(0.1);
    }

    else if (freq_piano >= 13 && freq_piano <= 15){
      g6_synth.play();
      g6_synth.setVolume(0.1);
    }

    else if (freq_piano >= 16 && freq_piano <= 18){
      a6_synth.play();
      a6_synth.setVolume(0.1);
    }

    else if (freq_piano >= 19 && freq_piano <= 21){
      b6_synth.play();
      b6_synth.setVolume(0.1);
    }
  }
// Visualization for the drum 
  push()
    angleMode(DEGREES);
    colorMode(HSB);
    spectrum2 = fft2.analyze();

    // background(0);

    noStroke();
    translate(windowWidth / 2, windowHeight / 2);
    //beginShape();
    for (let i = 0; i < spectrum2.length; i++) {
      let angle = map(i, 0, spectrum2.length, 0, 360);
      let amp = spectrum2[i];
      
    //change the shape of the visualizer
      let r2 = map(amp, 0, 512, 50, 500);
      
    //create the circle
      let x2 = (r2 + 50) * cos(angle);
      let y2 = (r2 + 50) * sin(angle);
      
    //color the bar
      stroke(i, 100, 100);
      line(0, 0, x2, y2);
      }
  pop()

    angleMode(RADIANS)


// Visualization for the piano
  push()
  fill(0, 0, 0, 5);
  stroke(0, 255, 255);
  angleMode(RADIANS)

    for (let i = 0; i < n; i++) {
      theta.push(random(0, 2 * PI));
      dir.push(1);
      r.push(random(30, 380));
      rdir.push(1);
      c.push(createVector(windowWidth/2, windowHeight/2));
    }

    rect(0, 0, windowWidth, windowHeight);
    let spectrum = fft.analyze();

    // Calculate average amplitude to detect beats
    let level = amplitude.getLevel();

    // Adjust animation based on music intensity or beats
    for (let i = 0; i < n; i++) {
      theta[i] = theta[i] + (PI / 100) * dir[i];
      rdir[i] = checkr(rdir[i], r[i]);
      r[i] = r[i] + rdir[i];
      x = c[i].x + r[i] * cos(theta[i]);
      y = c[i].y + r[i] * sin(theta[i]);
      point(x, y);

      // modify animation based on beat detection
      let bass = fft.getEnergy("bass");
      let treble = fft.getEnergy("treble");

      // adjust wave parameters based on music energy
      r[i] = map(bass, 0, 255, 30, 380);
      dir[i] = map(treble, 0, 255, -1, 1);
  }
  pop()

// waveform visualization
  push()
    angleMode(DEGREES);
    stroke('rgb(255,182,222)');
    noFill();
    translate(windowWidth / 2, windowHeight / 2);

    let wave = fft_waveform.waveform();

    for (let k = -1; k <= 1; k += 2) {
      beginShape();
      for (let i = 0; i <= 180; i+= 0.7) {
        let j = floor(map(i, 0, windowWidth, 0, wave.length - 1));

        let r3 = map(wave[j], -1, 1, 100, 250);

        let x3 = r3 * sin(i) * k;
        let y3 = r3 * cos(i);
        vertex(x3, y3);
      }
      endShape();
    }
  pop()

// waveform of the particles
  push()
    translate(windowWidth/2, windowHeight/2);
    
    let spectrum4 = fft_particles.analyze(); // Analyze frequency spectrum
    
    // console.log(spectrum);

    let currentHasFrequency = spectrum4.some(freq => freq > 0);
    
    // If frequency detected and no particle created for this frequency yet
    if (currentHasFrequency && !particleCreated && spectrum4[0]) {
      let p = new Particle();
      particles.push(p);
      particleCreated = true; // Set flag to true to prevent continuous particle creation for this frequency
    }

    // Update and display particles
    for (let i = particles.length - 1; i >= 0; i--) {
      particles[i].show();
      particles[i].update();
    }
    
    // Reset flag after particle creation
    if (particleCreated && particles.length > 0) {
      particleCreated = false;
    }
  pop()
// function to initiate commands.
function keyPressed() {
  if (key == " ") {
    setUpSerial();
  }

  if (key == 'r') {
    startRecording();
  } else if (key == 's') {
    stopRecording();
  } else if (key == 'p') {
    playRecording();
  } else if (key == 'l') {
    loopRecording();
  }
}


// functions to initiate music-making options
function startRecording() {
  recorder.record(soundFile);
  console.log('Recording started...');
  recordingStarted = true;
}

function stopRecording() {
  recorder.stop();
  console.log('Recording stopped.');
}

function playRecording() {
  soundFile.play();
  console.log('Playback started...');
}

function loopRecording(){
  soundFile.loop();
    isLooping = true;
}

 

Communication between Arduino and p5.js:

From p5js side:

function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    print(fromArduino);
    // if the right length, then proceed
    if (fromArduino.length == 5) {
      // only store values here
      // do everything with those values in the main draw loop

      // We take the string we get from Arduino and explicitly
      // convert it to a number by using int()
      // e.g. "103" becomes 103
      
      if (isLooping == false){
        note_piano = int(fromArduino[0]);
        drum = int(fromArduino[2]);
        guitar = int(fromArduino[3]);
        synth = int(fromArduino[4]);
      }

      // get frequency for all types of sound
      freq_piano = int(fromArduino[1]);

      if (!recordingStarted && freq_piano != 0) {
        startRecording(); // Start recording
      }
    }
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake) - MUST have these lines for Arduino to send to p5
    //////////////////////////////////
    let sendToArduino = fromArduino + "\n";
    writeSerial(sendToArduino);
  }

From Arduino side:

Serial.print(PressureSensor);
  Serial.print(',');
  Serial.print(inches);
  Serial.print(',');
  Serial.print(PressureSensor2);
  Serial.print(',');
  Serial.print(PressureSensor3);
  Serial.print(',');
  Serial.println(PressureSensor4);

Schematics:

Some issues and aspects of the project I’m particularly proud of:

I was particularly proud of creating the visualizer. I took some time to learn how to use the p5.FFT function inside p5js. Initially, I watched this Sound Visualization: Frequency Analysis with FFT – p5 tutorial from Daniel Shiffman: https://www.youtube.com/watch?v=2O3nm0Nvbi4. But the tutorial is about syncing the visualizer with a played sound. I had a lot of trouble making the visualizer sync to every time the music note is triggered. I also had some issues combining the visualizers onto one plane and arranging their positions. I had to be really careful with controlling the variables.

I also wanted the users to have the option to record what they play, and figuring out how to record took me a lot of time. I kept failing at this part as I initially approached the code from the perspective of adding each note and each sound byte to an array and playing it back later.

BUT the aspect that I was struggling with the most was about using a pressure sensor. Its variable range varied way too much. The threshold for triggering the music notes when I pressed kept changing from time to time. The music generated inside p5 was not good at all. I was so fixated on this idea as I thought it was the only possible option. Until I discovered the button. It provided a much more stable parameter range of extremely high values and extremely low values for controlling the threshold as a digital device. The buttons I found are really soft to the touch, and they can be attached to the tip of the glove.

Another issue I ran into was about establishing a connection between Arduino and p5js:

I kept running into this error:

and

Pressure sensor doesn’t run when adding while (Serial.available() <= 0) {} and while (Serial.available()) {}

Future improvement:

I approached the project hoping to have only one visualizer for each instrument, but it seems that the object p5.FFT is a universal object that can’t take the frequency of any individual musical instrument. Therefore, I have to think of ways to make that happen for the future.

Also, I hope to be able to incorporate the accelerometer or gyrometer to monitor the motion of wrists and use that to trigger drum pattern/rhythm.

Observations from IM Showcase interactions for future improvements:

Everyone intuitively followed the screen instructions, but almost everyone seems to not know how to proceed at the connecting p5js with Arduino part.

There are two aspects where users are mostly confused about: how to use the distance sensor and how to connect p5js to Arduino. In terms of the distance sensor, it doesn’t come to them intuitively that they can hover their left hand up and down above the distance sensor to trigger different frequencies, hence different musical notes. For a few users, I had to explain to them how they should operate the project, and for them, I had to provide very detailed instructions. I’ve implemented the text “Press Space Bar to connect to the glove,” but it seems that only those who know how to set up serial communication understand it; those who don’t seem not. So for an area of improvement, I’m thinking of having it run as soon as the user presses the “ROCK ON” button to start the visualizer.

Luke Nguyen – Week 12 Reading Reflection

I agree with the point that there is a contention between designing for disability and fashion. After all, designing for disability is all about functionality and fashion/aesthetics should be considered a complementary part. However, I do think that sometimes fashion/aesthetics does have to be taken into account. Our lives are highly driven by shame and embarrassment, mostly because of internalized unpleasant experience regarding how we are seen by other people, so sometimes technology designed for disability has to serve a good luck to boost the wearers’ confidence. I don’t completely agree that we should incorporate the “spectacle design” into disability product as the author argues, because this contention I think depends on the type of product and its potential users.

In terms of weather the design should be universal or not, I think that universality should be a more a desirable achievement than a compulsory mission. If the goal can be achieved, then it’s laudable. Universality doesn’t have to be too complicated to cover a wide range of disabilities. The iPhone, and its peer iPod, is a very epitomic example. Such design with compact features successfully serve mostly everybody. Before the birth of the iPhone, nobody really thought almost every aspect of their lives could be condensed into one device until such a device was created. Nevertheless, if we treat universality as a mission then the amount of the design work necessary might not be worth it.

The level of accessibility and the quality of life is increasing. People have access to more and more well-designed devices that serve their needs; once they have used up all the features that satisfy their needs, there is no point for them to use those that don’t. In other words, users might not use, or even bring themselves to use, every feature available in their gadgets these days. Still, despite this, manufacturers have been competing with one another to provide a centralized experience to their users with their multimodal products, so we are moving towards such future either way. And they succeed in encouraging consumerism with successful and strategic marketing. People rush to buy devices that are promoted to serve in multi-facets but only utilize a few facets.

Luke Nguyen – Final Project Idea – DJ Turntable/Audio Workstation

Updated Sunday April 28:

My final project idea is a DJ Turntable/Audio Workstation that can allow users to input music from Arduino using a special glove into p5 and visualize it. The idea for the project comes from this Mimu glove.

Users can send music notes from Arduino to p5 using different sensors such as pressure sensors, distance sensors, and either an accelerometer or a gyrometer.

Using the pressure sensors attached to the tip of the glove that they wear, users can transfer 7 basic music notes from C to B into p5 by tapping their fingers or tapping on the table?. Simultaneously combining it with a distance sensors placed on the table, they can change the frequency/pitch of the music notes, ranging from B0 to D#8 that Arduino can interpret (if they input the music notes using their fingers then the distance sensor should be placed in a way that can red their hands’ position. Keeping doing that until they have generated something either funky, something following a stream of consciousness, or a nice melody.

In terms of generating rhythm, the users can input rhythm from Arduino to p5 by using the same method, or should I use the accelerometer/gyrometer to sense motion to input the rhythm?

As of now, I’m thinking of having users control all the melody and the rhythm by just utilizing the pressure sensor and the distance sensor as a simple way, or incorporating an accelerometer/gyrometer to measure their wrists’ motion and input their drum as a more advanced way.

These music notes will be recorded, once the p5 don’t detect the users generate the music notes for more than 5/8/10 secs?, it will save the melody and keep looping it. This melody will be visualized. This will apply to the rhythm as well.

Users can input at most 5 melodies/rhythms and have them visualized.

Added Thursday, April 25:

My final project idea is a DJ Turntable that can allow users to control music using Arduino and p5.

Initially my idea is about controlling music with the potentiometer on Arduino but the song mixing will be inside p5 (mixing the melody of one song with the melody of another song).

Users can send music notes from potentiometer inside Arduino to p5, then mix the notes inside p5, and then send it back to Arduino to play.

Professor’s comments:
– Utilize Touch sensor from Arduino, remix songs in p5,

– Make turntable funky on Arduino board with different settings using buttons, sensors, control everything on the Arduino but mix the songs in p5,

– When someone DJ for 5 secs, the LEDs blink up and down like in a club,
– Use flex sensor to change frequency, use pressure sensor to […],

  • Don’t depend on Arduino to play sound

The DJ Turntable will be incorporated with Music Visualizer:
– Send music from Arduino into p5 to visualize in visualizers (maybe galaxy theme like the ones shown in the hallway from decoding nature class?)

– P5 send visualizers back to Arduino to light up the LEDS to light up accordingly to the colors inside the visualizer.

Visualizer in p5 examples:
– Sine and cosine
– How users choose songs
– Maybe frequency change wave, amplitude change colors….

Luke & Gunjan – Assignment 12

Exercise 1:

Circuit:

Code:

P5Js:

//Exercise 1 P5js Code

let ellipseX; // Variable to store ellipse's x-coordinate

function setup() {
  createCanvas(600, 400); // Create a canvas of 800x400 pixels
  ellipseX = width / 2; // Set initial x-coordinate of ellipse to middle of the screen
  noStroke(); // No stroke for the ellipse
}

function draw() {
  
  background(220); // Refresh background on each frame
  fill(0, 0, 255); // Set fill color to red
  ellipse(ellipseX, height / 2, 50, 50); // Draw ellipse at current x-coordinate and middle of the screen
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);}
}


function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }   
}

// this callback function
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the message
   
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      // only store values here
      // do everything with those values in the main draw loop
//values from light sensor roughly ranged between 0 and 500,000 so map them between 0 and width of the screen
//use the mapped value as x-coordinate of the ellipse
      ellipseX = map(data,0,500000, 0,width);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
   let sendToArduino = fromArduino + "\n";
   writeSerial(sendToArduino);
  }
}

Arduino codes:

//Exercise 1 Arduino Code 

void setup() {
  Serial.begin(9600); // Start serial communication at 9600 bps

  pinMode(LED_BUILTIN, OUTPUT);
// start the handshake
  while (Serial.available() <= 0) {
    //digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    //digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}
void loop() {

  // wait for data from p5 before doing something
    while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

  // Read sensor value
  int sensorValue = analogRead(A0);
   Serial.print(sensorValue);
  // Map sensor value to screen width 
  int screenValue = map(sensorValue, 0, 1023, 0, 600);

  // Send mapped value to p5.js
  Serial.println(screenValue);

  delay(50); //    for stability
}
digitalWrite(LED_BUILTIN, LOW);
}

In future implementations, we may want the ball to move in a smoother fashion. We can consider adding codes that can smooth out the path of the ball’s movement. But using the photosensor to control the ball, we reinforce the knowledge about coding in Arduino and sending data from Arduino to p5.

Exercise 2:
Circuit:

P5js code:

let rVal = 0;
let alpha = 255;
let left = 0; // True (1) if mouse is being clicked on left side of screen
let right = 0; // True (1) if mouse is being clicked on right side of screen
let slider;

function setup() {
  createCanvas(640, 480);
  textSize(18);
  slider = createSlider(0,255,0);
  slider.position(50,50);
}

function draw() {
  // one value from Arduino controls the background's red color
  background('white');

  // if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  // } else {
  //   text("Connected", 20, 30);
  //   // Print the current values
    // text('rVal = ' + str(rVal), 20, 50);
  //   text('alpha = ' + str(alpha), 20, 70);
  // }


  // click on one side of the screen, one LED will light up
  // click on the other side, the other LED will light up
  // if (mouseIsPressed) {
  //   if (mouseX <= width / 2) {
  //     left = 1;
  //   } else {
  //     right = 1;
  //   }
  // } else {
  //   left = right = 0;
  // }
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

// This function will be called by the web-serial library
// with each new *line* of data. The serial library reads
// the data until the newline and then gives it to us through
// this callback function
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = slider.value() + "\n";
    console.log(slider.value());
    writeSerial(sendToArduino);
    
    }

}

Arduino code:

int rightLedPin = 5;
int brightness = 0;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);

  // Outputs on these pins
  // pinMode(leftLedPin, OUTPUT);
  pinMode(rightLedPin, OUTPUT);

  // Blink them so we can check the wiring
  // digitalWrite(leftLedPin, HIGH);
  digitalWrite(rightLedPin, HIGH);
  delay(200);
  // digitalWrite(leftLedPin, LOW);
  digitalWrite(rightLedPin, LOW);



  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    // int left = Serial.parseInt();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      // digitalWrite(leftLedPin, left);
      analogWrite(rightLedPin, right);
      
      
      // int sensor = analogRead(A0);
      // delay(5);
      // int sensor2 = analogRead(A1);
      // delay(5);
      // Serial.print(sensor);
      // Serial.print(',');
      Serial.println();
    }
  }
  digitalWrite(LED_BUILTIN, LOW);

}

In terms of the future improvement for this one, we may want to control multiple LEDs with only one slider, or add more sliders to control many LEDs. But it helped us think about writing the code on transferring data to Arduino.

Exercise 3:
Circuit:Code:

p5js code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let rVal ;

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);
}

function draw() {
  background(255);
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  fill("blue");
  ellipse(position.x,position.y,mass,mass);
  if (position.y > height-mass/2) {
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
    }
  if (position.y == height - mass/2) {
      right = 1;
  } else {
      right = 0;
  }
  if (rVal > 522) {
    wind.x = 1;
} else if (rVal < 502) {
    wind.x = -1;
} else {
    wind.x = 0;
}

  
  // if (!serialActive) {
  //   text("Press Space Bar to select Serial Port", 20, 30);
  // } else {
  //   text("Connected", 20, 30);
  //   // Print the current values
  //   text('rVal = ' + str(rVal), 20, 50);
  //   text('alpha = ' + str(alpha), 20, 70);
  // }
}

function applyForce(force){
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

// if (position.y == height - mass/2) {
    
//     //   left = 1;
//     // } else {
//       right = 1;
//     // }
//   } else {
//     // left = right = 0;
//   right = 0;
//   }

function keyPressed(){
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  // if (keyCode==LEFT_ARROW){
  //   wind.x=-1;
  // }
  // if (keyCode==RIGHT_ARROW){
  //   wind.x=1;
  // }
  if (keyCode==ENTER){
    // mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}

function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the me ssage
    rVal=data;
    print(rVal);

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = right + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino code:

// Week 11.2 Example of bidirectional serial communication

// Inputs:
// - A0 - sensor connected as voltage divider (e.g. potentiometer or light sensor)
// - A1 - sensor connected as voltage divider 
//
// Outputs:
// - 2 - LED
// - 5 - LED

// int leftLedPin = 2;
int rightLedPin = 5;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);

  // Outputs on these pins
  // pinMode(leftLedPin, OUTPUT);
  pinMode(rightLedPin, OUTPUT);

  // Blink them so we can check the wiring
  // digitalWrite(leftLedPin, HIGH);
  digitalWrite(rightLedPin, HIGH);
  delay(200);
  // digitalWrite(leftLedPin, LOW);
  digitalWrite(rightLedPin, LOW);



  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    // int left = Serial.parseInt();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      // digitalWrite(leftLedPin, left);
      digitalWrite(rightLedPin, right);
      // int sensor = analogRead(A0);
      // delay(5);
      int sensor2 = analogRead(A1);
      delay(5);
      // Serial.print(sensor);
      // Serial.print(',');
      Serial.println(sensor2);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

Challenges and implementations: we had no problem making the LED blink every time the ball touches the ground. But we did face some challenges in controlling the wind with the potentiometer initially. The ball kept moving to the left and we couldn’t figure out how to control it no matter what. In the end, we figure out that the issue lies in mapping and in coding the snippets of codes we want to send from p5 into Arduino. For improvements, we want to increase the speed of the ball being controlled by the potentiometer. At the moment, it is moving rather slowly.

Luke and Yaakulya – Week 11 Assignment – Turntable

Week 11 – Turntable

Concept & Inspiration:

Approaching this assignment, we wanted to create a turntable that can let user become a DJ controlling two songs. This DJ takes the party people from West to East, blending music from a Western country across the globe to an Eastern country. We have the supposedly the most popular song on the planet at the moment (no, it’s not Baby Shark), the pop song with the most views on YouTube, the song that caused a whirlwind, Despacito by Luis Fonsi and Daddy Yankee from Puerto Rico. We also have the all-time iconic Mario Theme Song hailed from Japan composed by Koji Kondo for the video game company Nintendo. The DJ user can control these two songs by using the switch button as the digital sensor and the potentiometer as an analog sensor. As for the songs, we picked the most memorable and recognizable parts: the chorus for Despacito and the gameplay theme for Mario Theme Song.

Circuit:

Circuit connections from above Schematics diagram.

1) Potentiometer Connections: The potentiometer is crucial for song selection and control. It has three pins: two for power and one for the signal. The outer pins are connected to the 5V and GND (ground) terminals on the Arduino to provide it with power. The middle pin, which is the wiper, is connected to the analog input A0 on the Arduino. As the user turns the knob of the potentiometer, the resistance changes, and the Arduino reads this as an analog value, allowing the user to blend between the two songs.

2) Button Connections: A push button is used to start or stop the song playback. One side of the button is connected to the digital pin 2 on the Arduino. The other side is connected to the GND terminal on the breadboard. A pull-up resistor is not necessary as the Arduino’s internal pull-up resistor is used in the code to avoid floating values when the button is not pressed.

3) Speaker Connections: The speaker, which outputs the sound, has two wires. The positive wire is connected to digital pin 8 on the Arduino. This pin is set up in the code to deliver a pulse-width modulation (PWM) signal that creates the audio tones for the songs. The negative wire from the speaker is connected directly to the GND terminal on the breadboard to complete the circuit.

4) Power Connections: The breadboard’s power rail is used to distribute the 5V and GND connections to the potentiometer and the button. Wires run from the 5V and GND pins on the Arduino to the power rail on the breadboard.

With this setup, the user interacts with the button and potentiometer to control the playback of “Despacito” and the “Mario Theme Song”. The code on the Arduino processes the input signals and triggers the speaker to play the appropriate song based on the state of the button and the value from the potentiometer.

What does the Analog and Digital Sensor do in this circuit? – Schematics:

The code and circuit are structured to respond to the interactions with the potentiometer and the push button:

1) Button Press: Initiates the playback of “Despacito” or stops the current song.

2) Potentiometer Rotation: Facilitates the blending from “Despacito” to the “Mario Theme Song.” and vice versa.

The user must press the button to start playing “Despacito.” They can then rotate the potentiometer to initiate the “Mario Theme Song” by pressing the button again. This interaction can be repeated to switch between the two songs.

Code (with comments):

The button acts as a trigger to play the music and the potentiometer act as a dial to alternate between the 2 songs. The first song is Despacito. The user have to press the button for it to play. Then they can turn the potentiometer to the other side and press the button again to play the second song, Mario Theme Song. They can repeat playing these two songs however much they want.

#include "pitches.h"
#define BUZZER_PIN 9
#define POTENTIOMETER_PIN A0
#define BUTTON_PIN 7
// Melody for the first song
int melody1[] = {
  NOTE_D4, NOTE_CS4, NOTE_B3, NOTE_FS3, NOTE_FS3, NOTE_FS3, NOTE_FS3, NOTE_FS3,
  NOTE_FS3, NOTE_B3, NOTE_B3, NOTE_B3, NOTE_A3, NOTE_B3, NOTE_G3, NOTE_G3, NOTE_G3, NOTE_G3, NOTE_G3,
  NOTE_G3, NOTE_B3, NOTE_B3, NOTE_B3, NOTE_B3, NOTE_CS4, NOTE_D4, NOTE_A3, NOTE_A3, NOTE_A3, NOTE_A3, NOTE_A3,
  NOTE_A3, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_E4, NOTE_CS4
};
// Note durations for the first song
int noteDurations1[] = {
  4,4,8,8,16,16,16,16,
  16,16,16,8,16,8,16/3,16,16,16,16,
  16,16,16,16,8,16,8,16/3,16,16,16,16,
  16,16,16,16,8,16,8,16/3
};
// Melody for the second song
int melody2[] = {
  NOTE_E4, NOTE_E4, NOTE_E4, NOTE_C4, NOTE_E4, NOTE_G4, NOTE_G3, NOTE_C4, NOTE_G3, NOTE_E3, NOTE_A3, NOTE_B3, NOTE_AS3, NOTE_A3,NOTE_G3,NOTE_E4,NOTE_G4,NOTE_A4,NOTE_F4,NOTE_G4,NOTE_E4,NOTE_C4,NOTE_D4,NOTE_B3,NOTE_C4
};
// Note durations for the second song
int noteDurations2[] = {
  16,8,8,16,8,4,4,16/3,16/3,16/3,8,8,16,8,32/3,32/3,32/3,8,16,8,8,16,16,16/3,8
};
// Flag to indicate if a song is currently playing
bool songPlaying = false;
// Variable to store the previous state of the button
bool lastButtonState = false;
// Setup function to initialize the pins
void setup() {
  // Set the buzzer pin as output
  pinMode(BUZZER_PIN, OUTPUT);
  // Set the button pin as input with internal pull-up resistor enabled
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
// Loop function to continuously check for button presses and play melodies
void loop() {
  // Read the current state of the button
  bool buttonState = digitalRead(BUTTON_PIN);
  // Check if the button is pressed and it was not pressed in the previous loop iteration
  if (buttonState == LOW && lastButtonState == HIGH) {
    // Toggle the song playing state
    songPlaying = !songPlaying;
    // Start or stop playing the selected song
    if (songPlaying) {
      // If the potentiometer value is less than 512, play the first melody; otherwise, play the second melody
      if (analogRead(POTENTIOMETER_PIN) < 512) {
        playMelody(melody1, noteDurations1, sizeof(melody1) / sizeof(int));
      } else {
        playMelody(melody2, noteDurations2, sizeof(melody2) / sizeof(int));
      }
    } else {
      // If the song was playing, stop playing it
      noTone(BUZZER_PIN);
    }
  }
  // Update the last button state for the next iteration
  lastButtonState = buttonState;
}
// Function to play a melody
void playMelody(int melody[], int noteDurations[], int size) {
  // Iterate over each note in the melody
  for (int thisNote = 0; thisNote < size; thisNote++) {
    // Calculate the duration of the current note
    int noteDuration = 1000 / noteDurations[thisNote];
    // Play the current note on the buzzer pin
    tone(BUZZER_PIN, melody[thisNote], noteDuration);
    // Wait for the duration of the note
    delay(noteDuration * 2);
    // Stop playing the note
    noTone(BUZZER_PIN);
    // Add a short pause between notes
    delay(noteDuration * 0.1);
  }
}

Challenges and reflections:

Initially, we had a few issues with coding for the potentiometer to change from one song to another using the potentiometer. We also had a few issues with triggering the song to play when the button is pressed. We managed to do it after trial and error.

For future improvements, we would like to configure an intricate system of LEDs into the board and program them to blink following the notes of the song being played, simulating a “mini club” when the room lights are turned off. We also want to have one song easing into the other while turning the potentiometer’s knob instead of them playing separately.

Luke Nguyen – Week 11 Reading

I understand that the author has a somewhat critical view towards that Pictures Under Glass paradigm because it decreases the flexibility of the humans’ hands. However, I do not how to feel towards his plea that humans should work their brains and put them into research to advance themselves. I think we seem to have reached a stagnant point in human timeline where things can only be extrapolated from their descendants. Everything innovative has been done before, and now researchers are working on how to enhance their performance and utility. Until some innovations highly unimaginable, a teletransportation device might be a stretch but I’ll assume a device along the same line, are conceived, we just have to rely on what we have created and achieved.

Reading the rant article gets me to notice how much those who responded to the author’s rant really take most advanced inventions for granted. To them, these inventions, such as the iPad as one of the main targets of the debate, seem to be so high-tech that it is now serving them in their life, not helping them to progress in terms of working and perceiving the world, much less incentivizing them to contribute to developing such inventions further. I do agree that iPad seem more like a toy to children these days than an invention that encourages their curiosity and thinking. I also do agree some adults become man-children in succumbing to the urge of merely using it for not very useful purposes. To attract buyers’ attention, manufacturers need to make products that are advanced enough but still have simple instructions for easy wield. Some people fuss when a product has a steep learning curve.

Luke Nguyen – Week 10 Reading

I was particularly fascinated by the Gloves section in the Physical Computing’s Greatest Hits reading. It is interesting to learn how engineers created the gloves that could respond to the movements of fingers to make rhythm; I wondered how they created and programmed the force-sensing resistors so that when attached to the fingertips, these sensors would know what kinds of triggers to create according to how strong the forces are. A few years ago, I was amazed at how Ariana Grande could control music with her gloves during her Honeymoon Tour in 2015. Here are a few videos of the way she did it: video 1, video 2. After doing some research, I discovered that she was using the Mi.Mu Gloves developed by MI.MU GLOVES LIMITED (UK) which enables music through movement as the company advertised. During her tour, Ariana used the motions and forces of her gloved hand gestures to add effects to her live performances, for example: holding up one finger to add harmony, opening her palm to add major-sounding harmonies, etc. I didn’t know back then that this technology is called physical computing; it was physical computing that enabled her to do this. In retrospect, it is amazing how physical computing has opened up countless opportunities for musicians to create and control their music both in studio and live environment. This glove technology is a mega hit to them.

I resonate with the author’s point in the second article “Making Interactive Art: Set the Stage, Then Shut Up and Listen”. I think artists’ intentions while making the interactive artworks are important but the audience’s experience is equally important as well. Most of the time when I see an interactive artwork, it is interactive in itself but not to the spectators, which I find to be rather frustrating. One time when I was visiting the Museum of Natural Science, there was a very awesome exhibition about nature that I remembered till this day. The exhibition was showcased in a sphere. When visitors stepped inside, they would directly interact with the elements of nature through their feet. One would step on the elements, for example, water, leaves, wind, bubbles, butterflies, etc. to see how they would become interactive. I got no instructions on how to interpret the artwork but I learned how to interact with it purely through interacting with it. I felt alive; I felt that was such a unique experience; the artwork made me want to play with it again and again. In contrast, most of the interactive artworks I had seen before this one were presumably “interactive” but I wasn’t given any opportunity to interact with them. I did not know how to feel viscerally towards what I was observing, which I think made the objects hardly memorable without photography after moving on from them.

Luke Nguyen – Week 10 Assignment – Thanos Snap


Concept & Inspiration:

I thought of Thanos in Marvel Comics while I listened to a song by Beyoncé where he is referenced. Analog versus sensor seems to be a duality that reminds me of the notion of half and half that Thanos is fervent believer of. He believes that if he wipes out half of the population of the universe, he could restore its balance (half-populated and half-empty); fully populated would tip the scale. This assignment is set in that universe. I want the population of the universe to be represented by the number of LEDs; I used 4 LEDs in this case. I would play 2 roles as I operate the circuit: the creator of life and Thanos. To bring “life” to the LEDs, I would use the photocell as the analog sensor. To destroy “life” inside the LEDs, I would use the button as the digital sensor.

Circuit:

Code:

When I touch the photocell (the analog sensor), I would bring “life” to the LEDs by making them turn on. When I press the button (the digital sensor), I would wipe out half of the universe (half of the number of lives) by turning off two pre-determined LEDs. This way, I only have to code in a way so that that is possible.

int led1 = 4;
int led2 = 7;
int led3 = 8;
int led4 = 12;
int brightness = 0;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(A3, INPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A2);
  int buttonState = digitalRead(A3);

  sensorValue = constrain(sensorValue, 500, 900);
  brightness = map(sensorValue, 500, 860, 255, 0);


  if (brightness > 0){
    analogWrite(led1, brightness);
    analogWrite(led2, brightness);
    analogWrite(led3, brightness);
    analogWrite(led4, brightness);

    if (buttonState == HIGH ){
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
    }

  }

  Serial.println(sensorValue);
  delay(30);  // delay in between reads for stability

}

Challenges and reflections:

My biggest challenge has to do with the coding. I couldn’t figure out how to write the code for both the third and fourth LED, both of which are controlled by the analog sensor and the digital sensor at the same time, in a way that would make them turn on when I touched the photocell and turn off when I pressed the button.

A first few attempts resulted in these 2 LEDs not turning on at all, them only turning on when I was not touching the photocell, them turning on when I touched the photocell but not turning off when I pressed the button.

The commented-out parts are these first few attempts:

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A2);
  int buttonState = digitalRead(A3);

  sensorValue = constrain(sensorValue, 500, 900);
  brightness = map(sensorValue, 500, 860, 255, 0);

  // analogWrite(led1, brightness);
  // analogWrite(led2, brightness);
  // analogWrite(led3, brightness);
  // analogWrite(led4, brightness);



  // if (buttonState == LOW && sensorValue > 600 ){
  //   digitalWrite(led3, HIGH);
  //   digitalWrite(led4, HIGH);
  // }
  // else{
  //   digitalWrite(led3, LOW);
  //   digitalWrite(led4, LOW);
  // }


  if (brightness > 0){
    analogWrite(led1, brightness);
    analogWrite(led2, brightness);
    analogWrite(led3, brightness);
    analogWrite(led4, brightness);

    if (buttonState == HIGH ){
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
    }

  }
  // else{
  //   if (buttonState == LOW ){
  //     digitalWrite(led3, HIGH);
  //     digitalWrite(led4, HIGH);
  //   }
  //   else{
  //     digitalWrite(led3, LOW);
  //     digitalWrite(led4, LOW);
  //   }
  // }

  Serial.println(sensorValue);
  delay(30);  // delay in between reads for stability

}

 

Luke Nguyen – Week 9 Assignment – Lantern

 

 

Concept & Inspiration:

It’s during Ramadan and I wanted to capture the spirit and create something inspired by the month. I was working in the majlis room available in the Baraha area in C2 and I found this lamp stashed in the room corner. When I picked it up and opened the door, I noticed there was no light inside. It gave me the idea of putting a light in there with this assignment.

Circuit:

 

Demo:

Since the requirement of the assignment is creating an unusual switch that uses no hand, I thought of the idea that when the door is closed, the light will turn on. The body of the lamp besides the glass is made of metal material so it should transmit electricity almost everywhere on the surface. Taking advantage of this, I rigged the circuit inside the lamp and arranged of the placement of 2 jumper wires so that when the lamp’s door is closed, the circuit is closed and the LED will turn on thanks to the current running through it.

I created the entire circuit outside of the lamp, estimated the number of jumper wires I would need, then rigged/taped the circuit inside later though.

Challenges and reflections:

Initially, I planned to attach the 2 jumper wires in a way that when the door is closed, they would close the circuit. But that was not possible all the time because of the tape. So I took advantage of the material which the surface of the lamp is made of instead. The point is as long as their is a current running through the LED. Other than that, taping the entire circuit inside the lamp took a little bit of time because the space was too small for my hands, but I managed to do it.

Luke Nguyen – Week 8 Reading

I find it fascinating that there is this duality pertaining to how affect impacts the way humans function. Norman demonstrates that negative affect tends to have an effect on the mind that is contradictory to that of positive effect, for example, negative effect aids the focus process whereas the positive effect relaxes it; negative affect makes it harder to do easy tasks whereas positive affect makes it easier to do difficult tasks; negative affect makes simple tasks difficult whereas positive affect makes difficult tasks easier (4, 5). When it comes to a product, this duality has an even more noticeably contradictory impact on the engineers and the users. Positive affect can make the engineers design a product in a more comprehensive way, that is, to fill it with functions ranging from simple to advanced; this, however, can render some negative affects from the users especially when they cannot figure out how to operate the advanced parts of the product. Negative affect can sometimes make the engineers feel less incentivized to improve their product and only try to finish it, which can make the product become easier for users to operate. This may prime users’ minds and make them become more tolerable to trying advanced functions within the product when the engineers decide to improve it, as Norman argues, “although poor design is never excusable, when people are in a relaxed situation, the pleasant, pleasurable aspects of the design will make them more tolerant of difficulties and problems in the interface” (6).

Another point that Norman makes to which I find worth mentioning is the harmony between beauty and usability. Obviously, the product is useless when it is beautiful but not functional; similarly, the product is also hard to use design and appeal-wise if it is highly functional but not beautiful. However, I do not fully agree with him there has to be a balance between beauty and usability. This should be dependent on the purpose of the product itself and how it is going to be used. If users choose the product because of its functions, then there is no point that the product’s level of beauty should match its functionality; the product then only needs to be decent looking enough. Vice versa, if the beauty of the product is the main selling point, then that should be the manufacturer’s main focus in design and production.

As for the story about Margaret Hamilton and how her codes help the astronauts successfully land their mission, I really admire her determination to finish up the product that she helped start. It is about her integrity and not to give in when she has more to offer. When designing and creating a product, it is important to be as thorough as possible in terms of codes and functions. It is fine if the users decide not to use it, as in the case for most computers and laptops and their users these days. However, when the users want to maximize their laptops and computers, they will really need to use what is on the table, hard.