When first creating this jacket I wasn’t really invested in the material of the jacket, since I knew I just needed any jacket that could hold all the circuitry that it would have. I also recognized that the jacket I would need would have to be of a thinner material so that the LEDs could shine through, so I thought it would maybe be a good idea to put a bigger jacket over it, as to hide the wiring. In the end I ended up not having the bigger jacket over it, since I thought I did a good job of hiding the sewing I did on the jacket. I also knew the user would need a way to turn on the indicators in a way that would be easy for the user to do as well as safe for when they would be biking. For this reason I decided to add gloves to the jacket so that the user had access to buttons. I then decided that I would put the buttons on the gloves near the finger so that the user had very easy access to pressing the button and indicating in which direction they were going. I thought of maybe purchasing a real biking jacket with actual biking gloves, as to make the outfit feel more legitimate, but the overall cost steered me to instead find a cheap jacket. If I had a lot more time, and money, I would’ve loved to integrate the wires inside the actual jacket material, so they wouldn’t show.
While creating the jacket there were three main humps. These were, the actual design of jacket and how I would make it and how it would look, the communication between Arduino and Processing and how it would play into the jacket, as well as how the lights would look. These three were all huge parts of the production of the jacket and how it would turn out in the end. One of the biggest struggles for me at first was how I would be able top have LEDs on the back of the jacket showing animations. At first I thought having an LED matrix on the back of the jacket would be a good idea, but after looking at the schematics of it and how much time it would take to do it, I thought that it would be better to have four LED strips and control each individual LED strip to make the desired animations. This would make it a lot easier to make the jacket itself, as well as code for the animations. This decision was a big part of how I would proceed to do my project, since the matrix idea was more Processing based, while having four LED strips would be handled majority by Arduino. I would say that I ended up coming successful in these three humps, except for the fact that I didn’t have time to code for the ability for the user to change the colors of the jacket, which I thought would be a really nice addition.
Matrix Sketch Four LED Strips Sketch
IMG_4887
In user testing I was missing majority of my project, and though most students liked the idea of LEDs on a jacket and being able to control them for the practical purpose of riding a bike, many of the teachers wanted me to add more elements to the jacket, which is where one of my proudest success came from. Ironically the success wasn’t from the jacket but instead the interface of which one could interact on Processing with the jacket. I was really proud of the interface because of how it complemented the theme of the jacket, as well as do nice job of showing the interaction between the user and the jacket through the computer. The interface allowed me to play more with the theme that the jacket would follow, as well as how the user would be able to interact with the jacket, while still following the practical use of the jacket itself.
When I set out to make this project I wanted to make a jacket that could be worn by bikers, so that when they bike at night they are able to be seen by cars as well as by other bikers who, especially at night, don’t know in which direction one is turning. After witnessing many biking accidents here in China, as well as being in a couple myself, I noticed that most of them happen at night where visibility is low and riding itself is difficult because of the fact bikes have to share the road with pedestrians as well as electric scooters. I wanted an easy as well as cool way in which bikers could safely traverse the streets without feeling like they can’t be seen. I also wanted the driver to interact with the jacket itself, which is why I added buttons, as well as an interface where the user can change the animations to what they want. I have always defined interaction in levels instead of just having interaction, or not having. Obviously just pressing buttons on a jacket isn’t much of an interaction, but when thinking about the bigger picture of how one is able to choose what animations they want on their jacket as well how the usage of the jacket itself and how it lends to interacting with people on the streets while biking, it shows how just be able to control what your clothes do on your body you are able to interact with more than just two buttons on your gloves.
During my final presentation many of my peers enjoyed the project, but also offered many recommendations that I myself wanted to include in the project but I couldn’t because of time. This included a brake light, as well as feedback for the user when pressing the buttons, so that the user could have some indication that the lights were working in the right way, since the user cannot see the lights themselves. These were all recommendations that I thought were very helpful towards how I could improve the jacket. If I had more time with this project I would’ve loved to add more customization options, as well as take the recommendations I received into my project. I would have also loved to improve on the look of the jacket itself, so that it can look and feel like a regular bike jacket but have LEDs as well.
One thing that I definitely learned from this project is that combining technology with fashion, or just clothes in general, takes a lot of time, effort and patience. Not everything works the first time and one has many different factors when designing a meaningful way to use technology in ones clothes. The whole process is very tiresome but very rewarding when one is able to do it successfully, making the technology work meaningfully as well as look good. Clothing and technology, while two very different things, are a lot more similar than one thinks. While humans start using technology more and more in their daily lives, it should be natural that we start adapting it to fit our clothes, which is also necessary for every day use. The more and more comfortable we get with technology and how we can implement it into what we wear, the easier daily life can become, with having simple tasks be able to be done from our clothes instead of our phone or additional technology. My LED biking jacket shows something as simple as a jacket with lights can be used to help solve issues of safety on the road, as well as offer a different style to the bikers who use it. As technology gets better and more incorporated into what we wear, one will be able to interact easier with more from their daily lives, from the simple action of just wearing their clothes. These interactions we have with what we wear, not only can look really cool, but also have a big impact with how we interact with each other in the future.
Arduino Code:
#include <FastLED.h>
#define LED_PIN 7
#define LED_PIN_2 6
#define LED_PIN_3 5
#define LED_PIN_4 4
#define NUM_LEDS 18
#define NUM_OF_VALUES 3 /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
/* This is the array of values storing the data from Processing. */
int values[NUM_OF_VALUES];
int valueIndex = 0;
int tempValue = 0;
CRGB leds[NUM_LEDS];
CRGB leds_2[NUM_LEDS];
CRGB leds_3[NUM_LEDS];
CRGB leds_4[NUM_LEDS];
int leftButton = 8;
int rightButton = 9;
void setup() {
Serial.begin(9600);
values[0] = 1;
values[1] = 1;
values[2] = 1;
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.addLeds<WS2812, LED_PIN_2, GRB>(leds_2, NUM_LEDS);
FastLED.addLeds<WS2812, LED_PIN_3, GRB>(leds_3, NUM_LEDS);
FastLED.addLeds<WS2812, LED_PIN_4, GRB>(leds_4, NUM_LEDS);
//LEFT SIGNAL
pinMode(leftButton, INPUT_PULLUP);
//RIGHT SIGNAL
pinMode(rightButton, INPUT_PULLUP);
}
void loop() {
getSerialData();
if (digitalRead(leftButton) == LOW) {
//Play left animation
if (values[0] == 1) {
Left1();
Left1();
Left1();
}
if (values[0] == 2) {
Left2();
Left2();
Left2();
}
if (values[0] == 3) {
Left3();
Left3();
Left3();
}
}
else if (digitalRead(rightButton) == LOW) {
//Play right animation
if (values[2] == 1) {
Right1();
Right1();
Right1();
}
if (values[2] == 2) {
Right2();
Right2();
Right2();
}
if (values[2] == 3) {
Right3();
Right3();
Right3();
}
}
else {
if (values[1] == 1) {
Forward1();
}
if (values[1] == 2) {
Forward2();
}
if (values[1] == 3) {
Forward3();
}
}
}
void Direction1() {
for (int i = 18; i >= 0; i–) {
leds[i] = CRGB (255, 0, 0);
FastLED.show();
delay(40);
}
for (int i = 18; i >= 0; i–) {
leds[i] = CRGB (0, 0, 0);
FastLED.show();
delay(40);
}
}
void Direction2() {
for (int i = 0; i <= 18; i++) {
leds[i] = CRGB ( 255, 0, 0);
FastLED.show();
delay(40);
}
for (int i = 0; i <= 18; i++) {
leds[i] = CRGB ( 0, 0, 0);
FastLED.show();
delay(40);
}
}
void Blink() {
leds[0] = CRGB(255, 0, 0);
leds[1] = CRGB(255, 0, 0);
leds[2] = CRGB(255, 0, 0);
leds[3] = CRGB(255, 0, 0);
leds[4] = CRGB(255, 0, 0);
leds[5] = CRGB(255, 0, 0);
leds[6] = CRGB(255, 0, 0);
leds[7] = CRGB(255, 0, 0);
leds[8] = CRGB(255, 0, 0);
leds[9] = CRGB(255, 0, 0);
leds[10] = CRGB(255, 0, 0);
leds[11] = CRGB(255, 0, 0);
leds[12] = CRGB(255, 0, 0);
leds[13] = CRGB(255, 0, 0);
leds[14] = CRGB(255, 0, 0);
leds[15] = CRGB(255, 0, 0);
leds[16] = CRGB(255, 0, 0);
leds[17] = CRGB(255, 0, 0);
FastLED.show();
delay(500);
leds[0] = CRGB(0, 0, 0);
leds[1] = CRGB(0, 0, 0);
leds[2] = CRGB(0, 0, 0);
leds[3] = CRGB(0, 0, 0);
leds[4] = CRGB(0, 0, 0);
leds[5] = CRGB(0, 0, 0);
leds[6] = CRGB(0, 0, 0);
leds[7] = CRGB(0, 0, 0);
leds[8] = CRGB(0, 0, 0);
leds[9] = CRGB(0, 0, 0);
leds[10] = CRGB(0, 0, 0);
leds[11] = CRGB(0, 0, 0);
leds[12] = CRGB(0, 0, 0);
FastLED.show();
delay(500);
}
void getSerialData() {
while (Serial.available() > 0) {
char c = Serial.read();
//switch – case checks the value of the variable in the switch function
//in this case, the char c, then runs one of the cases that fit the value of the variable
//for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase
switch (c) {
//if the char c from Processing is a number between 0 and 9
case ‘0’…’9′:
//save the value of char c to tempValue
//but simultaneously rearrange the existing values saved in tempValue
//for the digits received through char c to remain coherent
//if this does not make sense and would like to know more, send an email to me!
tempValue = tempValue * 10 + c – ‘0’;
break;
//if the char c from Processing is a comma
//indicating that the following values of char c is for the next element in the values array
case ‘,’:
values[valueIndex] = tempValue;
//reset tempValue value
tempValue = 0;
//increment valuesIndex by 1
valueIndex++;
break;
//if the char c from Processing is character ‘n’
//which signals that it is the end of data
case ‘n’:
//save the tempValue
//this will b the last element in the values array
values[valueIndex] = tempValue;
//reset tempValue and valueIndex values
//to clear out the values array for the next round of readings from Processing
tempValue = 0;
valueIndex = 0;
Flash();
Flash();
Flash();
break;
//if the char c from Processing is character ‘e’
//it is signalling for the Arduino to send Processing the elements saved in the values array
//this case is triggered and processed by the echoSerialData function in the Processing sketch
case ‘e’: // to echo
for (int i = 0; i < NUM_OF_VALUES; i++) {
Serial.print(values[i]);
if (i < NUM_OF_VALUES – 1) {
Serial.print(‘,’);
}
else {
Serial.println();
}
}
break;
}
}
}
Processing Code:
import processing.serial.*;
int NUM_OF_VALUES = 3; /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
Serial myPort;
String myString;
// This is the array of values you might want to send to Arduino.
int values[] = {1,1,1};
char screen = ‘H’;
void setup() {
size(1440, 900);
printArray(Serial.list());
myPort = new Serial(this, Serial.list()[ 5 ], 9600);
// check the list of the ports,
// find the port “/dev/cu.usbmodem—-” or “/dev/tty.usbmodem—-”
// and replace PORT_INDEX above with the index of the port
myPort.clear();
// Throw out the first reading,
// in case we started reading in the middle of a string from the sender.
myString = myPort.readStringUntil( 10 ); // 10 = ‘\n’ Linefeed in ASCII
myString = null;
imgLeft = loadImage(“LeftReal.jpg”);
imgMenu = loadImage(“Menu.jpg”);
imgForward = loadImage(“Forward.jpg”);
imgRight = loadImage(“Right.jpg”);
}
void mousePressed() {
if (screen == ‘H’) {
mousePressHome();
} else if (screen==’L’) {
mousePressLeft();
} else if (screen==’F’) {
mousePressForward();
} else if (screen==’R’) {
mousePressRight();
}
//sendSerialData();
}
void sendSerialData() {
String data = “”;
for (int i=0; i<values.length; i++) {
data += values[i];
//if i is less than the index number of the last element in the values array
if (i < values.length-1) {
data += “,”; // add splitter character “,” between each values element
}
//if it is the last element in the values array
else {
data += “n”; // add the end of data character “n”
}
}
//write to Arduino
myPort.write(data);
}
void echoSerialData(int frequency) {
//write character ‘e’ at the given frequency
//to request Arduino to send back the values array
if (frameCount % frequency == 0) myPort.write(‘e’);
String incomingBytes = “”;
while (myPort.available() > 0) {
//add on all the characters received from the Arduino to the incomingBytes string
incomingBytes += char(myPort.read());
}
//print what Arduino sent back to Processing
print( incomingBytes );
}
void draw()//Title Screen
{
if (screen == ‘H’) {
drawHome();
} else if (screen == ‘L’) {
drawLeft();
} else if (screen == ‘F’) {
drawForward();
} else if (screen == ‘R’) {
drawRight();
}
// echoSerialData(20);
}
void keyPressed() {
printArray(values);
sendSerialData();
}