Assignment Eight

Accelerometers, Interrupts, timing oh my.

Weakness: MPU-6050 GY-521 (a.k.a. “The Devil”)

I knew this was my weakness, and it still is. It’s broken me. After many frustrating hours moving this thing around, several tutorial (links below), and ultimately having it sit on the table and increment while no movement or rotation. I gave up. While I could get the tutorials to work, everything thing hooked up and the processing sketches to run, I still didn’t know what it was actually doing. Reading through the code only kind of helped, but when things started get dicey is how exactly they were using the raw data.

Gyroscopes and Accelerometers on a Chip

Arduino 5 Minute Tutorials: Lesson 7 – Accelerometers, Gyros, IMUs

Tutorial: How to use the GY-521 module (MPU-6050 breakout board) with the Arduino Uno

https://create.arduino.cc/projecthub/Aritro/getting-started-with-imu-6-dof-motion-sensor-96e066

http://www-robotics.cs.umass.edu/~grupen/503/Projects/ArduinoMPU6050-Tutorial.pdf

The list could go on. I’ve racked up an extensive search history of accelerometers & arduino as well as MPU6050 tutorials.


Interrupts

After picking myself back up, I decided to tackle another weakness. Interrupts. I’ve been avoiding them for some time, and am still working at fulling understanding their capabilities. The trouble I always run into is how to exit a light sequence. I also ran into some issues while using music. I decided to make a few simple interactions with button, sounds, and light to tackle my interrupt fears head on.

This project simple starts a song, pauses the song mid-way, lights a NeoPixel sequence (also the devil), and exits the sequence. A second button will stop the song or light sequence and restart the song from the beginning.

 

Arduino Code
/***************************************************
DFPlayer - A Mini MP3 Player For Arduino
<https://www.dfrobot.com/index.php?route=product/product&product_id=1121>

***************************************************
This example shows the basic function of library for DFPlayer.

Created 2016-12-07
By [Angelo qiao](Angelo.qiao@dfrobot.com)

GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution
****************************************************/

/***********Notice and Trouble shooting***************
1.Connection and Diagram can be found here
<https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
2.This code is tested on Arduino Uno, Leonardo, Mega boards.
****************************************************/

#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

//--------NEOPIXEL SETUP --------
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
static const int PIN = 5;
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
//------------------------------

static const int bPinOne = 2;
static const int bPinTwo = 3;
int bCountOne = 0;
int bCountTwo = 0;
bool bStateOne = false;
bool bStateTwo = false;

int currentState = 0;

void setup() {
mySoftwareSerial.begin(9600);
Serial.begin(115200);

Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while (true);
}
Serial.println(F("DFPlayer Mini online."));

myDFPlayer.volume(30); //Set volume value. From 0 to 30
myDFPlayer.play(1); //Play the first mp3

pinMode(bPinOne, INPUT_PULLUP);
pinMode(bPinTwo, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(bPinOne), bSwitchOne, CHANGE);
attachInterrupt(digitalPinToInterrupt(bPinTwo), bSwitchTwo, CHANGE);
pixels.begin();
pixels.show();

}

void loop(){

if(currentState == 3){
myDFPlayer.play(1);
}

if (currentState == 1){
myDFPlayer.pause();
rainbow(20);
} else if (currentState == 2){
pixelOff();
myDFPlayer.start();

}

if (myDFPlayer.available()) {
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
}

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

if (lastSampleTime + sampleInterval < now) {
lastSampleTime = now;
bCountOne++;
bStateOne = true;
Serial.print("button one: ");
Serial.println(bCountOne);

if (bCountOne % 2 == 1){
currentState = 1;
} else if (bCountOne % 2 == 0){
currentState = 2;
}

}

}

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

if (lastSampleTime + sampleInterval < now) {
lastSampleTime = now;
bCountTwo++;
bStateTwo = true;
Serial.print("button two: ");
Serial.println(bCountTwo);

if (bCountTwo % 2 == 1){
currentState = 3;
} else if (bCountTwo % 2 == 0){
currentState = 4;
}
}

}

void rainbow(uint8_t wait) {
uint16_t i, j;

for (j = 0; j < 256; j++) {
for (i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel((i + j) & 255));
}
pixels.show();
delay(wait);
}
}

void pixelOff() {
for (int i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, (0, 0, 0));
}
pixels.show();
}

uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void printDetail(uint8_t type, int value) {
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
}

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

 

03/22 Assignment: Pepper’s cone.

The idea is to use the mirror illusion to create a 3D animation. This is a perspective mapping project that uses a unity plugin to create 3D objects by modifying the models. This is inspired by videos on Youtube about creating holograms through the phone. It uses a coin to calibrate the location and additionally uses environment mapping techniques to create the optical map. The map is then invested to create the model through the unity code. They propose that this system can be used to create 3D animations such as virtual agents.

References

Paper: http://roxanneluo.github.io/PeppersCone.html

Talk

 

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

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 Four

The pomodoro technique

Password: MakingThingsInteractive

This was a bit of a tricky project for me. I had several idea’s that seemed to bypass either the Arduino or p5.js completely. So, after my board kicked the bucket at 3 in the morning, I went back to the drawing board. Lately, I’ve been struggling with task management in terms of mustering up the courage to even begin. I was researching memory and multitasking for another class, when I stumbled upon something called The Pomodoro Technique. This is a technique that uses a timer to break down tasks into intervals of 25 minutes. The idea is to focus on something for 25 minutes straight, take a short break, then tackle another 25 minutes.

Using an RFID reader and tags, I sought to physicalize the interaction of changing tasks to intentionally bring awareness to the switch. These tags are labeled with my current class schedule, plus a personal passion project. You can scan in the task you want to focus on and a full screen time will take over the browser window. When 25 minutes have passed, the user will be notified by LED light. In addition, a small accomplishment dot is added to the task. You can collect up to three right now, however if you switch tasks in the middle of another, you will not get a dot.

Arduino Code:
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 newReader(SS_PIN, RST_PIN); // Create MFRC522 instance.
String id = "";

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

//--------INCOMING CASE STATE--------
int caseState;

//--------OUTGOING CASE STATE--------
static const int neutralState = 0;
static const int thesisState = 1;
static const int rmeState = 2;
static const int mtiState = 3;
static const int cdfState = 4;
static const int personalState = 5;
int sendState = neutralState;

//--------TIME--------
unsigned long lastSampleTime = 0;
unsigned long sampleInterval = 300000; // in ms 5 minutes

void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
newReader.PCD_Init(); // Init MFRC522 card
Serial.println("Scan PICC to see UID and type...");
pixels.begin();
}

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

if (Serial.available() > 0) {
caseState = Serial.read();
}

getID();

if (lastSampleTime + sampleInterval < now) {
lastSampleTime = now;
if (caseState == 6) {
pixelBlink();
} else {
pixelOff();
}
}
}

void pixelBlink() {
pixels.setPixelColor(0, pixels.Color(138, 70, 215));
pixels.show(); // This sends the updated pixel color to the hardware.
delay(500);
pixels.setPixelColor(0, pixels.Color(0, 0, 0));
pixels.show(); // This sends the updated pixel color to the hardware.
delay(500);
}

void pixelOff() {
pixels.setPixelColor(0, pixels.Color(0, 0, 0));
pixels.show(); // This sends the updated pixel color to the hardware.
}

void getID() {
// Getting ready for Reading PICCs
if ( ! newReader.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
return 0;
}
if ( ! newReader.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return 0;
}

// Serial.print("Card UID:");

for (byte i = 0; i < newReader.uid.size; i++) {
// Create a RFID Hexdecimal String
id += String(newReader.uid.uidByte[i], HEX);
// Serial.print(newReader.uid.uidByte[i] < 0x10 ? " 0" : " ");

}
// Convert to Uppercase
id.toUpperCase();

// If it is this card, do something
if (id == "B0A167A") {
sendState = thesisState;
// Serial.println("Card One: Thesis");
// Serial.print("State: ");
// Serial.println(sendState);
}
if (id == "B0DECE7A") {
sendState = rmeState;
// Serial.println("Card Two: Responsive Mobile Environments");
// Serial.print("State: ");
// Serial.println(sendState);
}
if (id == "702E89C") {
sendState = mtiState;
// Serial.println("Card Three: Making Things Interactive");
// Serial.print("State: ");
// Serial.println(sendState);
}
if (id == "3078E49B") {
sendState = cdfState;
// Serial.println("Card Four: Communication Design Fundamentals");
// Serial.print("State: ");
// Serial.println(sendState);
}
if (id == "50611A9C") {
sendState = personalState;
// Serial.println("Card Five: Personal Projects");
// Serial.print("State: ");
// Serial.println(sendState);
}
Serial.write (sendState);

// Reset Id
id = "";
// Serial.println();
newReader.PICC_HaltA();
newReader.PCD_StopCrypto1();
}
p5.js Code:
//---Serial---
var serial;
var portName = '/dev/cu.usbmodem1411';
//---Incoming Case State---
var caseState;
//---Outgoing Case State---
var accomplishState;

//---Color---
var c;
var thesisColor;
var rmeColor;
var mtiColor;
var cdfColor;
var personalColor;

//---Canvas---
var xLen = 1000;
var yLen = 700;

//---Squares & Grid---
let squares = [];
let bubbles0 = [];
let bubbles1 = [];
let bubbles2 = [];
let bubbles3 = [];
let bubbles4 = [];

//---Time---
var time = 1500;
var timer0 = time;
var timer1 = time;
var timer2 = time;
var timer3 = time;
var timer4 = time;

//---Counter---
var count0 = 0;
var count1 = 0;
var count2 = 0;
var count3 = 0;
var count4 = 0;

//---Converts Time to minutes and seconds---
function convertTime(s){
var minutes = floor(s / 60);
var seconds = s % 60;
return nf(minutes,2) + "m " + nf(seconds,2) + "s"; // formats to look like "00m 00s"
}

function setup() {
createCanvas(xLen, yLen);
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('data', serialEvent);
serial.on('error', serialError);
serial.on('close', portClose);

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

// setting task squares as well as accomplished "dots" through objects
for (let i=0; i<5; i++){
for(let j =0; j<3; j++){
let x = 0 + 200 * i;
let y = 550;
let w = 200;
let h = 150;
let gridX = 50;
let gridY = 625;
let offset = 50;
let gridR = 10;

squares[i] = new Square(x,y,w,h);

bubbles0[j] = new Bubble(gridX + offset*j, gridY, gridR);
bubbles1[j] = new Bubble(200 + gridX + offset*j, gridY, gridR);
bubbles2[j] = new Bubble(400 + gridX + offset*j, gridY, gridR);
bubbles3[j] = new Bubble(600 + gridX + offset*j, gridY, gridR);
bubbles4[j] = new Bubble(800 + gridX + offset*j, gridY, gridR);

}
}
}

function draw() {
// put drawing code here
// background(255);

checkIncoming(); // checks the incoming state and runs the proper timer
statusBar(); // keeps the tabs with what tasks, right now classes
bubbleKeeper(); // keeps the circles that tick when time has been accomplished

}

function bubbleKeeper(){

for(let i=0; i < bubbles0.length; i++){ // accomplish bubbles for thesis
noStroke();
// bubbles[i].show(0);
if (count0 == 1){
bubbles0[0].show(0);
}
if (count0 == 2){
bubbles0[0].show(0);
bubbles0[1].show(0);
}
if (count0 == 3){
bubbles0[0].show(0);
bubbles0[1].show(0);
bubbles0[2].show(0);
}
}

for(let i=0; i < bubbles1.length; i++){ // accomplish bubbles for RME
noStroke();
// bubbles[i].show(0);
if (count1 == 1){
bubbles1[0].show(0);
}
if (count1 == 2){
bubbles1[0].show(0);
bubbles1[1].show(0);
}
if (count1 == 3){
bubbles1[0].show(0);
bubbles1[1].show(0);
bubbles1[2].show(0);
}
}

for(let i=0; i < bubbles2.length; i++){ // accomplish bubbles for MTI
noStroke();
// bubbles[i].show(0);
if (count2 == 1){
bubbles2[0].show(0);
}
if (count2 == 2){
bubbles2[0].show(0);
bubbles2[1].show(0);
}
if (count2 == 3){
bubbles2[0].show(0);
bubbles2[1].show(0);
bubbles2[2].show(0);
}
}

for(let i=0; i < bubbles3.length; i++){ // accomplish bubbles for CDF
noStroke();
// bubbles[i].show(0);
if (count3 == 1){
bubbles3[0].show(0);
}
if (count3 == 2){
bubbles3[0].show(0);
bubbles3[1].show(0);
}
if (count3 == 3){
bubbles3[0].show(0);
bubbles3[1].show(0);
bubbles3[2].show(0);
}
}

for(let i=0; i < bubbles4.length; i++){ // accomplish bubbles for Passion Projects
noStroke();
// bubbles[i].show(0);
if (count4 == 1){
bubbles4[0].show(0);
}
if (count4 == 2){
bubbles4[0].show(0);
bubbles4[1].show(0);
}
if (count4 == 3){
bubbles4[0].show(0);
bubbles4[1].show(0);
bubbles4[2].show(0);
}
}

}

function statusBar(){
textSize(20);
textAlign(CENTER);
textStyle(BOLD);
var textY = 575;

//---Using these to change the color of the timer background based on the class
thesisColor = color(236,195,211);
rmeColor = color(247,161,171);
mtiColor = color(250,116,86);
cdfColor = color(252,195,135);
personalColor = color(242,240,181);

//---Setting up the squares based on color
for(let i =0; i<squares.length; i++){
noStroke();
squares[0].show(thesisColor);
squares[1].show(rmeColor);
squares[2].show(mtiColor);
squares[3].show(cdfColor);
squares[4].show(personalColor);
}

fill(0);
noStroke();
text("THESIS", 100, textY);
text("RME", 300, textY);
text("MTI", 500, textY);
text("CDF", 700, textY);
text("PASSION", 900, textY);

}

function checkIncoming(){
textSize(200);
textAlign(CENTER);

if (caseState == 1){ // THESIS
if (frameCount % 60 == 0 && timer0 > 0) { // if the frameCount is divisible by 60, then a second has passed. it will stop at 0
timer0 --;
}
if (timer0 == 0){ // if time reaches zero, task accomplished
timer0 = time; // timer resets to 25minutes (1500 seconds)
count0++; // counter adds one
accomplishState = 6; // sends notification to arudino to light up light
} else{
accomplishState = 5;
}
if (count0 > 3){
count0=0; // resets after three rounds
}

background(color(236,195,211));
fill(0);
noStroke();
text(convertTime(timer0), width/2, height*.5);

}

if (caseState == 2){ //RME
if (frameCount % 60 == 0 && timer1 > 0) { // if the frameCount is divisible by 60, then a second has passed. it will stop at 0
timer1 --;
}
if (timer1 == 0){
timer1 = time;
count1++;
accomplishState = 6;
} else{
accomplishState = 5;
}
if (count1 > 3){
count1=0;
}

background(color(247,161,171));
fill(0);
noStroke();
text(convertTime(timer1), width/2, height*.5);

}

if (caseState == 3){ // MTI
if (frameCount % 60 == 0 && timer2 > 0) { // if the frameCount is divisible by 60, then a second has passed. it will stop at 0
timer2 --;
}
if (timer2 == 0){
timer2 = time;
count2++;
accomplishState = 6;
} else{
accomplishState = 5;
}
if (count2 > 3){
count2=0;
}

background(color(250,116,86));
fill(0);
noStroke();
text(convertTime(timer2), width/2, height*.5);

}

if (caseState == 4){ // CDF
if (frameCount % 60 == 0 && timer3 > 0) { // if the frameCount is divisible by 60, then a second has passed. it will stop at 0
timer3 --;
}
if (timer3 == 0){
timer3 = time;
count3++;
accomplishState = 6;
} else{
accomplishState = 5;
}
if (count3 > 3){
count3=0;
}

background(color(252,195,135));
fill(0);
noStroke();
text(convertTime(timer3), width/2, height*.5);
}

if (caseState == 5){ // PERSONAL
if (frameCount % 60 == 0 && timer4 > 0) { // if the frameCount is divisible by 60, then a second has passed. it will stop at 0
timer4 --;
}
if (timer4 == 0){
timer4 = time;
count4++;
accomplishState = 6;
} else{
accomplishState = 5;
}
if (count4 > 3){
count4=0;
}
background(color(242,240,181));
fill(0);
noStroke();
text(convertTime(timer4), width/2, height*.5);
}

serial.write(accomplishState);

}

class Square{ // object class for bottom squares
constructor(x,y,w,h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}

show(c){
fill(c);
rect(this.x, this.y, this.w, this.h);
}
}

class Bubble { // onject class for dots
constructor(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}

show(c) {
// stroke(90);
// strokeWeight(1);
fill(c);
ellipse(this.x, this.y, this.r * 2);
}
}

//-----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 serialEvent() {

var incoming = serial.read();
caseState = incoming;

}

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

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

 

Assignment Four Files: Fritzing, p5.js, Arduino

Walking in the Dark

Background: For people who have migrane, it is terribly painful to turn on the light in the room (any light is unbearable at times) or have sound playing, talking would be painful. Even though this doesn’t mean they can’t open their eyes to see things. However, the light and sound sesitivity make it really difficult for them to walk around in the house for certain necesaties.

Therefore, my project is to help people when they have to walk in the dark, and lights cannot be used as an indicator. Instead of lights, I used buzzer as indicator. If the person is too close to the wall on the left, the buzzer on the left (stick on the person’s hand) will vibrate. Same goes to the buzzer on the right. However, if they have a pet at home, the pir sensor attached to their chest will be active and the buzzer will both buzz at a certain meter.

[Insert picture here]

 

Here is the code part of it:


/* Jean Zhang


*/


const int leftDistPin = A1;
const int rightDistPin = A2;
const int pirPin = 8;

const int buzzLeft = 6;
const int buzzRight = 10;

const int critDist = 950; // somewhat arbitrary number

int leftDist = 0;
int rightDist = 0;

int buzzState = 0;
int buzzStatePrev = 0;


bool isPet = false;


void petPresent() {
 if (digitalRead(pirPin == HIGH)) {
 isPet = !isPet;
 }
 Serial.println(isPet);
}


void determineState() {

if (leftDist > critDist) {
 if (rightDist > critDist) {
 buzzState = 1;
 }
 else {
 buzzState = 2;
 }
 }
 else {
 if (rightDist > critDist) {
 buzzState = 3;
 }
 else {
 buzzState = 4;
 }
 }


 if (isPet == true) {
 buzzState = 5;
 }
}

void setup() {
 // put your setup code here, to run once:

Serial.begin(9600);

pinMode(leftDistPin, INPUT);
 pinMode(rightDistPin, INPUT);
 pinMode(pirPin, INPUT);

pinMode(buzzLeft, OUTPUT);
 pinMode(buzzRight, OUTPUT);


 //attach Interrupt
 if (isPet == HIGH) {
 attachInterrupt( digitalPinToInterrupt (pirPin), petPresent, HIGH);
 }
}


void loop() {
 // put your main code here, to run repeatedly:

//read distance and compare to critDist
 leftDist = analogRead(leftDistPin);
 rightDist = analogRead(rightDistPin);

buzzStatePrev = buzzState;
 determineState();

Serial.print("left");
 Serial.print(leftDist);
 Serial.print(" right");
 Serial.println(rightDist);
 Serial.print("buzzState");
 Serial.println(buzzState);

if (buzzStatePrev != buzzState) {
 switch (buzzState) {
 case 1: break;
 case 2:
 digitalWrite(buzzRight, HIGH);
 break;
 case 3:
 digitalWrite(buzzLeft, HIGH);
 break;
 case 4:
 digitalWrite(buzzRight, HIGH);
 digitalWrite(buzzLeft, HIGH);
 break;
 case 5:
 digitalWrite(buzzRight, HIGH);
 digitalWrite(buzzLeft, HIGH);
 delay (500); //@TODO: write a function that does not use delay
 digitalWrite(buzzRight, LOW);
 digitalWrite(buzzLeft, LOW);
 delay (500); // Yeah, try not to use delay
 break;


 }
 }


}