Assignment Seven

Patch UI

I wanted to create a simple wearable patch that could act as an integrated user interface. This first step was about understanding out this type of interface may work to send notifications. Using conductive fabric and capacitive touch, a user can simply touch the patch and send a light or vibration notification to someone. As I mentioned, this is just the first step, I plan to work further on this project to incorporate gestures such as swiping, investigate the form more by researching existing patch styles and alternative materials such as conductive ink that can be screen printed.

The patch itself is paired with a web program that can set the geometric pattern to hold different values. This way the user is able to program and reprogram the patch to suit their needs. This portion of the project needs a great deal of work, particularly in sending the data to the Arduino. This will be updated.

Password: MakingThingsInteractive

Arduino Code:
/***************************************************
This is a library for the CAP1188 I2C/SPI 8-chan Capacitive Sensor

Designed specifically to work with the CAP1188 sensor from Adafruit
----> https://www.adafruit.com/products/1602

These sensors use I2C/SPI to communicate, 2+ pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
//--------CAP1188 SETUP --------
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_CAP1188.h>
#define CAP1188_SENSITIVITY 0x1F // Setting the sensitivity....lower the number the more sensitive!!
static const int CAP1188_RESET = 12; // Reset Pin is used for I2C or SPI
Adafruit_CAP1188 cap = Adafruit_CAP1188();
//------------------------------

//--------NEOPIXEL SETUP --------
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
static const int PIN = 4;
static const int NUMPIXELS = 2;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//------------------------------

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

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

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

//-----VIBE PINS-----
static const int vibePinOne = 6;
static const int vibePinTwo = 9;

int vibeOne;
int vibeTwo;

int wait = 10;
int touchedNUM;

int lightCount = 0;
int personOneCount = 0;
int personTwoCount = 0;
int vibeCount = 0;

bool personOne = false;
bool personTwo = false;
bool light = false;
bool vibe = false;

void setup() {
Serial.begin(9600);
Serial.println("CAP1188 test!");
if (!cap.begin()) { // Initialize the sensor, if using i2c you can pass in the i2c address // if (!cap.begin(0x28)) {
Serial.println("CAP1188 not found");
while (1);
}
Serial.println("CAP1188 found!");
cap.writeRegister(CAP1188_SENSITIVITY, 0x6F); // 2x sensitivity THIS SEEMS TO WORK THE BEST FOR 3.5" plate sensors

pinMode(vibePinOne, OUTPUT);
pinMode(vibePinTwo, OUTPUT);
pixels.begin();
pixels.show();
}

void loop() {
unsigned long now = millis();
uint8_t touched = cap.touched();

if (touched == 0) {
// No touch detected
return;
}

if (lastSampleTime + sampleInterval < now) {

lastSampleTime = now;

for (uint8_t i = 0; i < 8; i++) {
if (touched & (1 << i)) {
int currentTouch = i + 1;

if (currentTouch == 1) { // RIGHT Light
touchedNUM = 1;
lightCount++;
light = true;
vibe = false;
} else if (currentTouch == 2) { // TOP Person One
touchedNUM = 2;
personOneCount++;
personOne = true;
personTwo = false;
light = false;
vibe = false;
// Serial.print("PersonOne: "); Serial.println(personOne);
// Serial.print("PersonTwo: "); Serial.println(personTwo);
} else if (currentTouch == 3) { // BOTTOM Person Two
touchedNUM = 3;
personTwoCount++;
personOne = false;
personTwo = true;
light = false;
vibe = false;
// Serial.print("PersonOne: "); Serial.println(personOne);
// Serial.print("PersonTwo: "); Serial.println(personTwo);
} else if (currentTouch == 4) { // LEFT Vibe
touchedNUM = 4;
vibeCount++;
light = false;
vibe = true;
}

if (personOne == true){
Serial.println("Active: PERSON ONE");
} else if (personTwo == true) {
Serial.println("Active: PERSON TWO");
}

}
}
}
personOneFun();
personTwoFun();
}

void personOneFun() {
if (personOne == true && personTwo == false && light == true) {
lightBLINK(0);
//lightON(0); // person ONE light on
lightOFF(1); // person two light off
vibeOFF(0); // vibes off
vibeOFF(1);
} else if (personOne == true && personTwo == false && vibe == true) {
lightOFF(0); // lights off
lightOFF(1);
vibeON(0); // person ONE vibe on
vibeOFF(1); // person two vibe off
} else {
lightOFF(0); // lights off
lightOFF(1);
vibeOFF(0); // vibes off
vibeOFF(1);
}
// Serial.print("Light Count: "); Serial.println(lightCount);
// Serial.print("Vibe Count: "); Serial.println(vibeCount);
}

void personTwoFun() {
if (personOne == false && personTwo == true && light == true) {
lightBLINK(1);
// lightON(1); // person TWO light on
lightOFF(0); // person one light off
vibeOFF(0); // vibes off
vibeOFF(1);
} else if (personOne == false && personTwo == true && vibe == true) {
lightOFF(0); // lights off
lightOFF(1);
vibeON(1); // person TWO vibe on
vibeOFF(0); // person one vibe off
} else {
lightOFF(0); // lights off
lightOFF(1);
vibeOFF(0); // vibes off
vibeOFF(1);
}
// Serial.print("Light Count: "); Serial.println(lightCount);
// Serial.print("Vibe Count: "); Serial.println(vibeCount);
}

void vibeON(int m) {
if (m == 0) {
digitalWrite(vibePinOne, HIGH);
delay(500);
digitalWrite(vibePinOne, LOW);
delay(250);
} else if (m == 1) {
digitalWrite(vibePinTwo, HIGH);
delay(500);
digitalWrite(vibePinTwo, LOW);
delay(250);
}

}

void vibeOFF(int m) {
if (m == 0) {
digitalWrite(vibePinOne, LOW);
} else if (m == 1) {
digitalWrite(vibePinTwo, LOW);
}
}

void lightON (int m) {
pixels.setPixelColor(m, pixels.Color(255, 255, 255));
pixels.show();
}

void lightOFF (int m) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}

void lightBLINK (int m) {
pixels.setPixelColor(m, pixels.Color(255, 255, 255));
pixels.show();
delay(750);
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
delay(500);
pixels.setPixelColor(m, pixels.Color(255, 255, 255));
pixels.show();
delay(750);
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
delay(500);
}
p5js Code:
//-----SERIAL VARIABLES-----
var serial;
var portName = '/dev/cu.usbmodem1411';

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

//-----Color Values-----
var colorLeft = 255;
var colorTop = 255;
var colorRight = 255;
var colorBottom = 255;

var personOneColor = 255;
var personTwoColor = 255;
var lightColor = 255;
var vibeColor = 255;

//-----button counts-----
var countLeft = 0;
var countTop = 0;
var countRight = 0;
var countBottom = 0;

var personOneClick = 0;
var personTwoClick = 0;
var lightClick = 0;
var vibeClick = 0;

//-----button selected-----
var buttonLeft = false;
var buttonTop = false;
var buttonRight = false;
var buttonBottom = false;

var personOne = false;
var personTwo = false;
var light = false;
var vibe = false;

//-----Icons & Images -----
var personOneImg , personTwoImg, lightImg, vibeImg;
var personOneImgW , personTwoImgW, lightImgW, vibeImgW;

var squares = [];
//------------------------

var latestData

var serialPortThree;

function preload() {
// preload() runs once
personOneImg = loadImage('assets/person.png');
personTwoImg = loadImage('assets/person.png');
lightImg = loadImage('assets/light.png');
vibeImg = loadImage('assets/vibe.png');
personOneImgW = loadImage('assets/person-w.png');
personTwoImgW = loadImage('assets/person-w.png');
lightImgW = loadImage('assets/light-w.png');
vibeImgW = loadImage('assets/vibe-w.png');
}

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);

console.log("Port Name: " + portName);
//----------------------

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

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

// for (var i = 0; i 220 && mouseX 195 && mouseY 330 && mouseX 151 && mouseY 544 && mouseX 195 && mouseY 330 && mouseX 239 && mouseY 140 && mouseX 400 && mouseY 315 && mouseX 400 && mouseY 480 && mouseX 400 && mouseY 645 && mouseX 400 && mouseY < 500) {
vibeClick++;
if (vibeClick % 2 == 1 ){ //&& personTwo == false && personOne == false && light == false
vibeColor = 100;
vibe = true;
} else if (vibeClick % 2 == 0){
vibeColor = 255;
vibe = false;
personOneClick = 0;
personTwoClick = 0;
lightClick = 0;
}
console.log("Vibe clicked: " + vibeClick);
}
}

//-----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');
}

Arduino + p5js + Fritzing files

 

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:

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