Assignment 7: Musical Runs

For this assignment, I chose to make a script that allows a user to select a running pace (in steps per minute), which, in turn, selects a preloaded song whose bpm matches the steps per minute of the user. I then used a pedometer code to run a servo that would rotate at a certain speed based on the steps per minute of the user. In a more thoroughly developed version of this design, the servo would run a music box-esque display.

My original idea for this was to have the pedometer run all aspects of the project: it would determine the song choice and the display. I also wanted to use the spotify API to somehow allow a wider range of song choices that would match the pace goal perfectly. Unfortunately, I got too frustrated trying to find a way to use spotify, and my serial connection didn’t work, so I had to split my project into a computer half and an arduino half, and give up on the song range. What I ended up creating uses the computer to set a goal, and the arduino to give the user a visual platform to match the set goal. This way, a user sets their goal via the p5 platform, which sets the song beat, and then has to run at a pace that ensures that the servo rotation matches the song beat. It’s fun to play with. I also added a graphic display that allows the user to see the beat of the song as well as hear it.

Here are my codes:

ArduinoPedometerServo

Music box movement

And my fritzing sketch:

Class Notes, 22 March 2018

Nathan Shedroff’s definition of interaction tweaked by me.   (I’m not sure from where I cut-and-pasted this.)

  • Duration: Initiation, Immersion, Conclusion, and Continuation.  (I would include “memory” in this, that’s part of the duration of an event.)
  • Intensity: Reflex, Habit, Engagement
  • Breadth: Products, Services, Brands, Nomenclatures, Channels/Environment/Promotion, and Price
  • Interaction: Passive < > Active < > Interactive  (I would say “aggressive” goes after “interactive.)
  • Triggers: Human Senses, Concepts, and Symbols  (Swastikas in post WWII western countries vs. maps in Japan.)
  • Significance: Meaning, Status, Emotion, Price, and Function (How does an interaction compare to a static physical entity?)

Assignment7 – AR-Powered Walking Assistant

For this assignment, I worked with ARKit to turn our mobile phones into an effective physical-assistive device. Using ARKit’s plane recognition feature,  I created a virtual “stick” which the user can adjust its length and makes vibration when it is hitting the ground plane. From such haptic feedback, the user understands a correct navigation of the path. This is a more portable and customizable solution compared to the existing physical stick.

Assignment 6.5/7

Door Sensor System

This assignment was meant to tie in a motor to an I/C protocol. The initial set up consisted of: proximity/ambient sensor, servo motor, 16 servo driver, red LED, and an arduino. The proximity sensor is meant to tell the user when there is someone standing at the door. The user can then choose the yes button to turn the door and let them in, or the no button to flash a red light telling them to leave.

The GUI was a set of simple buttons. Yes in green, red in no, and a yellow door button that flashes onto the screen to alert the user that there is someone at the door. The yellow circle will not appear until the proximity sensor is triggered.

 

Code:

Assignment7

Assignment Six

setPixelColor

For this assignment, I wanted to further explore the serial protocol between p5.js and Arduino. Specifically, how to send more complex information from p5 (long strings) and read multiple values on the Arduino. I created a sketch that acts as a NeoPixel color picker where you can slide along and set the color, then click on the corresponding box to light that exact NeoPixel on the Arduino.

***This project will be updated shortly to include gyro sensor***

Arduino Code:
//--------NEOPIXEL SETUP --------
#include
#ifdef __AVR__
#include
#endif
static const int PIN = 3;
static const int NUMPIXELS = 7;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

static const int buttonPin = 4;
int buttonState = 1;

//-----STRING TEST-----
int pos1; // comma one
int pos2; // comma two
int pos3; // comma three
int r;
int g;
int b;

//-----INCOMING VALUES-----
String incomingString; // setting string from p5.js

//-----OUTGOING-------
String sendState;

//--------TIME--------
unsigned long lastSampleTime = 0;
unsigned long sampleInterval = 500; // in ms

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(buttonPin, INPUT);

  pixels.begin();
  pixels.show();
}

void loop() {
  unsigned long now = millis();

  if (Serial.available() &gt; 0) {
    // "A,100,20,5" ADD COMMENTS
    incomingString = Serial.readStringUntil('\n'); // takes the incoming string sent from p5 and puts into incomingString

   
    pos1 = incomingString.indexOf(",");
    pos2 = incomingString.indexOf(",", pos1 + 1);
    pos3 = incomingString.indexOf(",", pos2 + 1);
    String letter = incomingString.substring(0, pos1);
    String red = incomingString.substring(pos2, pos1 + 1);
    r = red.toInt();
    String green = incomingString.substring(pos3, pos2 + 1);
    g = green.toInt();
    String blue = incomingString.substring(pos3 + 1);
    b = blue.toInt();
   
    if (letter == "A") { // LED POSITION 1
      pON(0, g, r, b); // 1
    } else if (letter == "B") { // LED POSITION 2
      pON(1, g, r, b); // 2
    } else if (letter == "C") { // LED POSITION 3
      pON(2, g, r, b); // 3
    } else if (letter == "D") { // LED POSITION 4
      pON(3, g, r, b); // 4
    } else if (letter == "E") { // LED POSITION 5
      pON(4, g, r, b); // 5
    } else if (letter == "F") { // LED POSITION 6
      pON(5, g, r, b); // 6
    } else if (letter == "G") { // LED POSITION 7
      pON(6, g, r, b); // 7
    }
  }
}


void pOFF(int n) {
  pixels.setPixelColor(n, pixels.Color(0, 0, 0));
  pixels.show();
  delay(2000);
  // pixelOff = true;
}

void pON(int n, int g, int r, int b) {
  pixels.setPixelColor(n, pixels.Color(g, r, b));
  pixels.show();
  // pixelOn = true;
}
p5 Code:
// color picker based on jasmine c. lee's sketch https://gist.github.com/jasmineclee/86236bc2bd16cb279b52

//-----SERIAL VARIABLES-----
var serial;
var portName = '/dev/cu.usbmodem1411';

//-----WINDOW DIMENSIONS-----
var windW = 600;
var windH = 400;

//-----Color Picker-----
var x; // where the spectrum starts (X)
var y; // where the spectrum starts (Y)
var end; // where the spectrum ends (X)
var totalWidth; // width of the spectrum
var totalHeight; // height of the spectrum
var incStart; // setting where the incrementing values will start, using X, but this will NOT change

//-----Color Values-----
var rd;
var gr;
var bl;

//-----Picker Variables-----
var colChange;
var colRecWidth = 1;

// array of colors in spectrum
var colorAtTime;
var array;
var arrayR;
var arrayG;
var arrayB;

// the colors at the specific time (what you're hovering over)
var rNow;
var gNow;
var bNow;
var colNow;

// the colors you've selected
var rChoice;
var gChoice;
var bChoice;

// setting up LED boxes
var squares = [];
var counter = 1;

var latestData;

function setup() {
  //-----Serial Setup-----
  serial = new p5.SerialPort();
  serial.on('list', printList);
  serial.on('connected', serverConnected);
  serial.on('open', portOpen);
  serial.on('data', gotData);
  serial.on('error', serialError);
  serial.on('close', portClose);

  serial.list();
  serial.open(portName);
  //----------------------

  createCanvas(windW, windH);
  smooth();
  background(245);

  x = 100; // where the spectrum starts on X
  y = 250; // where the spectrum starts on Y
  end = windW - x; // where the spectrum ends (y)
  totalWidth = windW - x*2;
  totalHeight = 75;

  incStart = x;

  rd = 255;
  gr = 0;
  bl = 0;

  rChoice = 0;
  gChoice = 0;
  bChoice = 0;

  array = [rd + ", " + gr + ", " + bl];
  arrayR = [rd];
  arrayG = [gr];
  arrayB = [bl];

  // initial text at the top (where your color's RGB will be)
  push();
  textSize(20);
  textAlign(CENTER);
  noStroke();
  text("NeoPixel Color Picker", windW / 2, 50);
  pop();

  for (var i = 0; i  y &amp;&amp; mouseY = incStart &amp;&amp; mouseX &lt;= incStart + totalWidth) {
        push();
        fill(245);
        noStroke();
        rect(0, y - 30, windW, 32);
        stroke(0);
        strokeWeight(1.5);
        line(mouseX, y - 20, mouseX, y + 1);
        fill(rNow, gNow, bNow);
        ellipse(mouseX, y - 20, 15, 15);
        noFill();
        rect(incStart, y + 2, totalWidth, totalHeight - 2);
        pop();
      }
    }
}

// function for whole color picker spectrum; increments represent the six segments of color changing
function colorPicker(increment1, increment2, increment3, increment4, increment5, increment6) {
  colChange = 4; // 3.825;

  while (x = increment1 &amp;&amp; x = increment2 &amp;&amp; x = increment3 &amp;&amp; x = increment4 &amp;&amp; x = increment5 &amp;&amp; x  200 &amp;&amp; mouseX = 100 &amp;&amp; mouseY  y &amp;&amp; mouseY = incStart &amp;&amp; mouseX &lt; incStart + totalWidth) {

      value = mouseX - 100 // this is to get determine where in the array you are (because at mouseX = 100, you&#039;re at the 0 index of the array)

      rNow = arrayR[value]; // sets the red value of what you&#039;re hovering over, from the array
      gNow = arrayG[value]; // sets the green value of what you&#039;re hovering over, from the array
      bNow = arrayB[value]; // sets the blue value of what you&#039;re hovering over, from the array

      if (rNow  255) { // this is to deal with any math that made the value greater than 255
        rNow = 255;
      }
      if (gNow  255) {
        gNow = 255;
      }
      if (bNow  255) {
        bNow = 255;
      }

      colNow = array[value];
      stroke(255);
      //fill(0); // this is here just in case I want to add a darker color option/slider later
      // rect(200, height - 200, 100, 25);
      fill(rNow, gNow, bNow);

    }
  }
  // else{
  //   fill(255);
  // }
  // rect(width / 2 - 50, 350, 100, 25); // this creates the rectangle at the bottom (but now, it's filled in w/ the color you're hovering over OR you have selected)

}

function mousePressed() {

  // this is to say: if you press on any part of the spectrum, you will make display the selected color at the rectangle AND fill in the rectangle at the bottom
  if (mouseX &gt;= incStart &amp;&amp; mouseX  y &amp;&amp; mouseY &lt; y + totalHeight) {
      push();
      fill(245);
      noStroke();
      rect(0, windH - 70, windW, 100);
      pop();

      textSize(18);
      noStroke();
      fill(0);
      text(&quot;R: &quot; + round(rNow), incStart, windH - 50);
      text(&quot;G: &quot; + round(gNow), incStart, windH - 33);
      text(&quot;B: &quot; + round(bNow), incStart, windH - 16);

      // push();
      // fill(0);
      // rect(width / 2 - 50, 350, 100, 25);
      // fill(rNow, gNow, bNow);
      // rect(width / 2 - 50, 350, 100, 25);
      // pop();

      // setting the color so that it can be used on the drawing pad
      rChoice = round(rNow);
      gChoice = round(gNow);
      bChoice = round(bNow);
    }
  }

  for (var i = 0; i &lt; squares.length; i++) {
    squares[i].clicked(mouseX, mouseY,rChoice,gChoice,bChoice);

  }
}

//-----SERIAL FUNCTIONS-----

function printList(portList) {
  // for (var i = 0; i 5)
        // {
        //   aNum = aString[1];
        //   aOff = aString[3];
        //   aSize = aString[5];
        // }
  // console.log("aNum: " + aNum + "aOff: " + aOff + "aSize: " + aSize);
}

function serialError(err) {
  // print('serialError ' + err);
}

function portClose() {
  // print('portClose');
}
p5 Object Code:
function Square(){
  this.w = 65;
  this.h = 25;
  this.col = 200;

  this.display = function(x,y,i){
    this.x = x;
    this.y = y;
    this.index = i;
    noStroke();
    fill(this.col);
    rect(this.x, this.y, this.w, this.h,1.5);
  }

  this.clicked = function(px,py, r, g, b){
    var sendLED;
    var red;
    var green;
    var blue;

    if (px &gt; this.x &amp;&amp; px  this.y &amp;&amp; py &lt; this.y + this.h){
    this.col = color(r, g, b);
      red = r.toString();
      green = g.toString();
      blue = b.toString();

      if (this.index == 0) {
        serial.write( &quot;A,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 1) {
        serial.write( &quot;B,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 2) {
        serial.write( &quot;C,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 3) {
        serial.write( &quot;D,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 4) {
        serial.write( &quot;E,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 5) {
        serial.write( &quot;F,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      } else if (this.index == 6) {
        serial.write( &quot;G,&quot; + red + &quot;,&quot; + green + &quot;,&quot; + blue);

      }
    }
  }
}

Assignment 6: Mouse motion based on wire protocol

Move an object based on accelerometer movement. I used an ADXL362 and the wire protocol to move an object on the screen. The accelerometer sends the raw XYZ values and a state of a button, the P5Js scripts map the raw acceleration values to areas on the screen.

Todo: Need to update the p5js script and improve documentation and add photos.

A6_v0

 

Assignment6 – spatial sensor viz experiment

This is a preliminary experiment for my project which aims to visualize sensor network data of a room/building in three dimensions. For this first test, I took temperature data through I2C and visualized particles on Unity that changes the alpha of color depending on the sensor readings. The demo is a bit unintuitive since only a single sensor is being used,  but the intention is to take temperature data from each part of a room, manually map the reading location on Unity, and visualize for the entire room.

Assign6-Code

Assignment 6

For this assignment, I decided to do another iteration of my assignment 4 light project using Neopixel.

I used the same basic GUI with three settings: Sleep, Bathroom, and Movie. The sleep mode is a green light, the bathroom mode is a red light, and the movie mode is a blue light.

I only got one neopixel to work so far because of some arduino issues / my original neopixel was broken.

 

Future work:

I want to create the full lighting system idea with neopixels. I also hope to integrate it into an interactive standing desk and make it bluetooth controlled. I also want to work on different light diffusion techniques to create a brighter light display.

Assignment6

 

Assignment 6: Cornflower Field

For this assignment, I wanted to create a sort of minefield using p5 that you could navigate (as a blue dot with a trail) using a gyroscope. I turned the minefield into a calming blue field of dots that don’t explode when you run over them, mostly because I was having enough difficulty creating the player and chose to ignore adding too much detail to the scene.

My main issues with this assignment arose with my serial, naturally. I tried to make a complex connection, but after spending ages attempting to make it work, I decided that maybe I needed to try making a more basic interaction and work upwards from there. I was still hopeful that my serial control issues were just due to my own oversights. So instead of trying to create a mouse using a gyro, I chose to start with getting data from a photo sensor, which I had used before, and using those numbers to drive the distance that the dot travels every time the player hits the space bar. So essentially, the game would be to be able to manipulate light and shadow on the sensor accurately to ensure that the player doesn’t run into a friendly blue flower (or mine) in their travels from one side of the screen to the other. The player would also be using their arrow keys (up and down) to determine the direction of the player.

Obviously, my problem actually didn’t lie in the complexity of my code, and my use of the photo sensor didn’t work out. Instead, I made/collaged from different random walker codes I found to create a code that would move the player at random speed intervals in quick succession. The game would be to use the up/down/side keys to navigate the board vertically. This took me a very long time to successfully create, and the result is a little disappointing, but kind of weirdly fun to play with.

Be warned, the player moves very fast, even at its slowest.

Here’s the code:

Cornflower_minefield