Assignment Five

Simple Shapes

For this, I wanted to investigate different Arduino inputs and how that might control elements of my objects in p5. I used two pots and two tact switches. The pots control size and spacing, while the switches can add and subtract a rectangle element. Right now there are two circles, however I’d like to work and see more ways to add an object.

Arduino Code:
//--------NEOPIXEL SETUP --------
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
static const int PIN = 40;
static const int NUMPIXELS = 1;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);


//--------POT & TACT LEFT--------
static const int potLeft = A0;
int potValLeft;
int mapValLeft;

static const int switchLeft = 2;
int switchStateLeft = 0;
int lastStateL = LOW;

//--------POT & TACT RIGHT--------
static const int potRight = A1;
int potValRight;
int mapValRight;

static const int switchRight = 3;
int switchStateRight = 0;
int lastStateR = LOW;


int count = 2;

const bool isInterrupt = true;

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

//------------------------------------------------------------------------------------

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

pinMode(switchLeft, INPUT);
 pinMode(potLeft, INPUT);
 pinMode(potRight, INPUT);
 pinMode(switchRight, INPUT);

pixels.begin();
}

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

potValLeft = analogRead(potLeft);
 potValRight = analogRead(potRight);

switchStateLeft = digitalRead(switchLeft);
 switchStateRight = digitalRead(switchRight);

if (lastSampleTime + sampleInterval < now) {
 lastSampleTime = now;

mapValLeft = map(potValLeft, 0, 1023, 20, 350); // sends offset
 mapValRight = map(potValRight, 0, 1023, 20, 300); // sends size

if (switchStateLeft && switchStateLeft != lastStateL) {
 if (count <= 12 && count > 2) {
 count -= 1;
 } else {
 count = 2;
 }
 } else if (switchStateRight && switchStateRight != lastStateR) {
 if (count < 12) {
 count += 1;
 } else {
 count = 12;
 }
 }
 lastStateL = switchStateLeft;
 lastStateR = switchStateRight;

Serial.print("N,");
 Serial.print(count);
 Serial.print(",O,");
 Serial.print(mapValLeft);
 Serial.print(",S,");
 Serial.print(mapValRight);
 Serial.print("\r\n");
 
 }
}

/* //-----DEBUGGING-----
 Serial.print("count: ");
 Serial.println(count);

Serial.print("Left Pot Send: ");
 Serial.println(mapValLeft);

Serial.print("Right Pot Send: ");
 Serial.println(mapValRight);
*/
p5.js Code:
/*
//-----ATTRIBUTION-----
  Based on "Sea Shell" by Michael Pinn
  https://www.openprocessing.org/sketch/402526
*/

var serial;
var portName = '/dev/cu.usbmodem1411';

var xLen = 1200;
var yLen = 700;

var bubbles;
var bubbles2;

var latestData;
var aNum = 0; // number of squares from arduino
var aOff = 0; // offset number from arduino
var aSize = 0; // size number from arduino

function setup() {
 serial = new p5.SerialPort();
 // now set a number of callback functions for SerialPort
 serial.on('list', printList);
 serial.on('connected', serverConnected);
 serial.on('open', portOpen);
 serial.on('error', serialError);
 serial.on('close', portClose);
// serial.on('data', serialEvent);
 serial.on('data', gotData);

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

// set up our drawing environment
 createCanvas(xLen, yLen);
 background(240);
 ellipseMode(CENTER);
 rectMode(CENTER);

bubbles = new Bubble(240,0); // sets the location
 bubbles2 = new Bubble(240,5); // sets the location

}

function draw() {
 background(240);
 bubbles.show(40,100, 8, aOff); // sets up the size, offset, rotational controller (mouse position here
 bubbles2.show(aSize/2, aOff, aNum, mouseX); // sets up the size, offset, rotational controller (mouse position here)
}


class Bubble {
 constructor (l, w){
 this.l = l;
 this.w = w;
 }

show(s, o, n, m){
 this.s = s;
 this.offset = o;
 this.n = n;
 this.m = m;

push();
 translate(width/2, height/2);
 for (var i = 0; i < 360; i += 360/this.n) {
 this.x = sin(radians(i)) * this.offset;
 this.y = cos(radians(i)) * this.offset;
 push();
 translate(this.x, this.y);
 rotate(radians(+i + this.m));
 stroke(this.l);
 strokeWeight(this.w);
 fill(sin(radians(i / 2)) * 255, 50, 100);
 rect(0,0,this.s,this.s,2);
 pop();
 }
 pop();
 }
}


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

function printList(portList) {
 for (var i = 0; i < portList.length; i++) {
 print(i + " " + portList[i]);
 }
}

function serverConnected() {
 print('serverConnected');
}

function portOpen() {
 print('portOpen');
}

function gotData() {
 var stringRead = serial.readLine(); // read the incoming string
 trim(stringRead); // remove any trailing whitespace
 if (!stringRead) return; // if the string is empty, do no more
 // console.log(stringRead); // println the string
 latestData = stringRead; // save it for the draw method

var aString = latestData.split(",");
 if (aString.length>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');
}

Arduino, p5.js, Fritzing files

Sketchbook Color Sliders

This sketch uses conductive silver ink to create capacitive sliders on paper. Three sliders can control Hue, Saturation, and Value to help a designer tactfully choose colors. The interface features a “tap in/tap out” button, so the user lifting their finger on the slider doesnt affect the color reading.

 

This interface is a sketch at bringing digital decisions, like RGB color,
into the physical world through tangible interaction.

The project features teensy 3.2’s touchRead() function for capacitive input.


As an attempt to reduce interference noise in the sensor system, a swatch of conductive fabric was added to the opposite side of the page; it was grounded to the the teensy. Sensor signal smoothing still needs works.

 

 

Assignment 5

Car Driver

Description: 

For this assignment, I made a car animation. The user can click anywhere on the black background to place a car. The cars start at speed = 0 and add 10 each time the button is pressed.

Basic GUI: 

Breadboard: 

Video demo: 

Code: 

assignment5

 

**Code/idea is a combination of alterations from class 10 notes and http://coursescript.com/notes/interactivecomputing/objects/index.html  **

Assignment5 – Interactive Map

I worked with Mappa.js to visualize a dataset on Google Maps. I found Mappa.js useful for quickly getting interactive online maps running. I tweaked one of the example code so that the objects get updated by the user’s mouse click.

I used NASA’s open data portal and took the meteorite dataset as input. Each row is the history of meteorite landings with latitude/longitude information. Every time the user clicks, it reads the new row and visualizes on Google Maps where it landed. It calls Google Maps API to map latitude/longitude to a city and creates an object for each city. If data with the previously appeared city is observed, it increments the size of the circle. Since there are cases where the city is not included in the API response, I used try/catch to ignore unidentifiable data.

Code-Assign5

Assignment4 – Visual Support for Drummers

Motivation:

When I think of human assistance, a topic that comes to my mind relates to music or rhythm since I’m poor at singing and playing instruments. In this project, I explored an approach to extract sound information from an instrument and to provide real-time visual feedback to the player so that he is always making an ideal sound.

Process:

Using the knock sensing interface from Assignment2, I built an assistive interface for drummers. A piezo sensor attached to a drum captures the strength of hit which is sent to P5JS to visualize whether or not the strength is within an appropriate range. The red line indicates the ideal strength and the gray bar is the actual hit value. The red bar continuously changes as the music progress.

Proof-of-Concept Demo:

Code – Assign4