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:
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