9. Wearables¶
What the week looked like¶
As worried as I was about learing electronics in general, this week seemed very well paced. Especially since our mentor Rico wanted all 3 of us; Koshi, Shefali and Me; to work together and divide & conquer the assignment. Knowing that we could divide the research and only have to work on separate parts, trusting that we could depend on each other to catchup on the research side of explorartions we didn't pursue ourself, was quite liberating.
This week we happened to have a hoilday on a weekday and me & Shefali decided to work together, escpecially since our access to electronic materials was limited.
Takeaways from Global Session¶
The sessions with Liza Stark are always extremely inspiring and insightful. We were shown a spectrum of wearbles intergrating electronics, especially microcontrollers.
Especially thankful to her for sharing her entire presenation and a vocabulary list of terminologies used in the lecture. That has been extremely helpful as a one stop guide to check and understand basics.
Checklist for the week¶
Personal thoughts and Ideas¶
Based on what Liza showed and what Rico showed us in the Local session, i decided to not look at this sesion as something to finalaise what i would want to do in my final project, but just as a chance to explore what all is possible through a hands-on approach to attempting these visual, audio and movement actuators.
Since electronics is not my forte, the materials available at our electronic lab became the main guiding principle of what devices i could experiment with. I made a list of ALL the materials mentioned on the website and marched into our lab to dig for them. Managed to pickup Servo Motors, LEDs and Neopixel Strip (which eventually didn't work since it was defective).
Apart from the materials in the lab, few things i am curious to explore later are Fibre optics and Thermoreactive Pigments. I plan to get my hands on them eventually and attempt some basic explorations with these as well, if posssible.
Research & Inspiration¶
I was blown away by the examples that Liza showed us in class of integration of electronics within the fabric. So far, i have ONLY looked deeper into the examples that she shared.
Since this is such a new way of thinking for me, i wanted to attempt making the wearable first to understand what is cuttin edge here, to then be inspired by!
Softwares & Tools¶
SOFTWARES¶
- Arduino
- TinkerCAD
TOOLS¶
- Arduino UNO
- Micro Servo Motor (9gm) SG90
- LEDs (20 minimum)
- Jumper Wires (male to male)
- Jumper Wires (female to female)
- Jumper WIres (male to female)
- Resistors (100 ohm)
- 3v Battery cell (to test LED)
Work Flow¶
Shortlisting possible explorations¶
At our Lab, i could only find Servo Motors, LEDs and NeoPixel strips, that fit the criteria for this week's assignment. I also had magnetic beads and was planning on trying to use them for making FlipDots.
After our Local session, i went forward with researching and laying out the possible materials needed to create these circuits, as well as shortlisting relevant YouTube links for tutorials. During this i researched about Servo Motor connections, Flip Dots, Charlieplexing LEDs and NeoPixel Strips.
Based on my research about the circuits, i reaalised that we didn't have materials on-hand to experiment with FlipDots, so had to chuck that option. And during our hours of experimenting with NeoPixels and attempting atleast 5 different tutorials, we figured that our NeoPixel strip was defective, and ended up leaving that out as well.
Finally i was left with Servo Motors and LEDs, and had a lot of fun playing around with the code for the motor and integrating LEDs onto an extra Poncho Module from my Open Source Circular Fashion assignment!
Experimenting with Servo Motor¶
Installing Servo Library on Audrino¶
The Audrino software has an extremely straightforward userflow to install a Library.
- Go to Sketch > Include Library > Manage Libraries.
- A Library Manager screen opens up.
- Select 'Audurino UNO' in the 'Select Board' option.
- Next, search for 'Servo' in the Search bar, and a list of options show up.
- Select the 'Servo by Arduino' library and press Install
To begin work, we need to now access the library, inorder to integrate it into the code.
- Once installed, go to File > Examples > Servo > Sweep.
- A new sketch is created with an existig template of Sweep code for Servo Motor.
Circuit Making¶
For making the circuit, i refered to this video which was extremely straightforward in explaining how to connect the motor to the audurino.
Attached images below show the circuit diagram (made on TinkerCAD) and the actual circuit we made.
Playing with the Code¶
In order to get the Servo Motor running, i referred to this video that also explained how to edit the code to play with the delay and position settings of the motor.
Basic Code: Manual delay¶
Here is the first code attempted using Manual entry of delay values. This helped get an idea of what ranges and speed of rotation would look like on the Servo Motor.
#include <Servo.h>
Servo myservo; // Create servo object to control a servo
void setup() {
Serial.begin(9600);
myservo.attach(9); // Attach the servo on pin 9 to the servo object
}
void loop() {
int val; // Creating a variable val
while (Serial.available() > 0) {
val = Serial.parseInt();
if (val != 0) {
Serial.println(val);
myservo.write(val);
}
delay(5);
}
}
Basic Code with delay value of 15¶
Below is the Basic Code as available on Audurino using the Servo Library, with an inherent delay value of 15.
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
// twelve Servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the Servo object
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach the position
}
}
Reducing the Delay value to 5¶
Here the delay value is reduced to 5 from the previous value of 15.
Considering 15 as a benchmark, with a delay value of 5 here, the motion observed is faster and snappy.
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
// twelve Servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the Servo object
}
void loop() {
for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
}
Inreasing the Delay value to 30¶
Here the delay is increased to 30, from the original value of 15.
Considering 15 as a benchmark, and comparing also to the previous delay value of 5, with a delay value of 30 here, the motion observed is extremely slow and tortise like.
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
// twelve Servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the Servo object
}
void loop() {
for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 15 ms for the servo to reach the position
}
for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 15 ms for the servo to reach the position
}
}
Loop and change Delay values between 30 and 5¶
Here the attempt was to increse the delay to 30 between the First motion & Second motion , as well as reduce the delay to 5 between the Second & First motion.
The observed here was that the first movement was snappy and the next movement was slow. And since this movement was looped, it went fast and then slow in the consequent movement till the loop completed.
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
// twelve Servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the Servo object
}
void loop() {
for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 15 ms for the servo to reach the position
}
for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
}
Here the attempt was to reduce the delay to 5 between the First & Second motion, as well as increase the delay to 30 between the Second & First motion.
The observed here was that the first movement was slow and the next movement was snappy. And since this movement was looped, it went slow and then fast in the consequent movement till the loop completed.
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
// twelve Servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the Servo object
}
void loop() {
for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 15 ms for the servo to reach the position
}
}
Video compilation of the different movements achieved¶
Charlieplexing with LEDs¶
We were introduced to the idea of attempting to do this by our mentor Rico. This was also attempted by our mentor Mina, whose documentation i referred to to understand the scope of the experiment.
Setting up Library¶
Since Charlieplexing doesn't need anything apart from LEDs, there is no additional library installation required.
Circuit Making¶
To attempt this, i refered to this video exactly and was successful in Charlieplexing 6 LEDs on the first attempt itself!
Below is the Circuit design (made on TinkerCAD) and the pictures of the real circut building.
Playing with the Code¶
The video also came with a reference to the code used. Since we were working with 6 LEDs and there were soo many wired connections, it took a while to understand and edit the code towards the desired outcome.
#define delay50 100
int myled[] = {8,9,10,11,12,13};
int num_of_leds;
void setup() {
num_of_leds = sizeof(myled) / sizeof(int);
for (int i = 0; i < num_of_leds; i++) {
pinMode(myled[i], OUTPUT);
}
}
void loop() {
delay(1000);
ledonn();
delay(2000);
ledoff();
delay(2000);
for (int i = 0; i < 5; i++) {pattern1();}
for (int i = 0; i < 5; i++) {pattern2();}
for (int i = 0; i < 5; i++) {pattern3();}
for (int i = 0; i < 5; i++) {pattern4();}
for (int i = 0; i < 25; i++){pattern5();}
for (int i = 0; i < 5; i++) {pattern6();}
for (int i = 0; i < 15; i++){pattern7();}
for (int i = 0; i < 15; i++){pattern8();}
for (int i = 0; i < 5; i++) {pattern9();}
for (int i = 0; i < 5; i++) {pattern10();}
for (int i = 0; i < 50; i++){pattern11();}
for (int i = 0; i < 50; i++){pattern12();}
ledoff();
delay(5000);
}
//TURN ON ALL LEDs
void ledonn() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
}
}
//TURN OFF ALL LEDs
void ledoff() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], LOW);
}
}
//LEFT TO RIGHT
void pattern1() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
}
}
//RIGHT TO LEFT
void pattern2() {
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
digitalWrite(myled[i - 1], LOW);
}
}
//LEFT TO RIGHT FILL
void pattern3() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
}
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], LOW);
delay(delay50);
}
}
//RIGHT TO LEFT FILL
void pattern4() {
ledonn();
delay(delay50);
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], LOW);
delay(delay50);
}
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
}
ledoff();
}
//ALTERNATE LEDs
void pattern5() {
for (int i = 0; i < num_of_leds; i = i + 2) {
digitalWrite(myled[i], HIGH);
digitalWrite(myled[i + 1], LOW);
}
delay(delay50);
for (int i = 0; i < num_of_leds; i = i + 2) {
digitalWrite(myled[i], LOW);
digitalWrite(myled[i + 1], HIGH);
}
delay(delay50);
}
//OSCILLATING LEDs
void pattern6() { //osc
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
}
delay(delay50);
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
digitalWrite(myled[i - 1], LOW);
}
}
//INSIDE
void pattern7() {
for (int i = 0; i < num_of_leds / 2; i++) {
digitalWrite(myled[i], HIGH);
digitalWrite(myled[num_of_leds - 1 - i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
digitalWrite(myled[num_of_leds - 1 - i], LOW);
}
}
//OUTSIDE
void pattern8()
{
for (int i = (num_of_leds / 2) - 1; i >= 0 ; i--)
{
digitalWrite(myled[i], HIGH);
digitalWrite(myled[num_of_leds - 1 - i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
digitalWrite(myled[num_of_leds - 1 - i], LOW);
}
}
//LEFT TO RIGHT 3 LEDs
void pattern9() {
for (int i = 0; i < num_of_leds + 3; i++) {
if (i <= num_of_leds) {
digitalWrite(myled[i], HIGH);
}
if (i > 2) {
digitalWrite(myled[i - 3], LOW);
}
delay(delay50);
}
}
//OSCILLATING 3 LEDs
void pattern10() {
for (int i = 2; i < num_of_leds; i++) {
if (i == 2) {
digitalWrite(myled[0], HIGH);
digitalWrite(myled[1], HIGH);
}
digitalWrite(myled[i], HIGH);
digitalWrite(myled[i - 3], LOW);
delay(delay50);
}
for (int i = num_of_leds - 4; i > -1; i--) {
digitalWrite(myled[i], HIGH);
digitalWrite(myled[i + 3], LOW);
delay(delay50);
}
}
//RANDOM EFFECT 1
void pattern11() {
int randomnum = random(0, num_of_leds + 1);
digitalWrite(myled[randomnum], HIGH);
delay(delay50);
digitalWrite(myled[randomnum], LOW);
delay(delay50);
}
//RANDOM EFFECT 2
void pattern12() {
int randomonn = random(0, num_of_leds + 1);
int randomoff = random(0, num_of_leds + 1);
digitalWrite(myled[randomonn], HIGH);
digitalWrite(myled[randomoff], LOW);
delay(delay50);
}
Video compilation of the LEDs litup¶
Neopixels¶
I found an entire roll of Neoplixels strip, and attempted to make it work. However despite trying about five tutotials and spending more than 90 minutes trying to make it work, i eventually realised that the Neopixel Strip was defective.
Installing NeoPixel Library on Audrino¶
To use the Neopixel strip, we need to install the Library by Adafruit.
- Go to Sketch > Include Library > Manage Libraries.
- A Library Manager screen opens up.
- Select 'Audurino UNO' in the 'Select Board' option.
- Next, search for 'Neopixel' in the Search bar, and a list of options show up.
- Select the 'Adafruit Neopixel by Adafruit' library and press Install
Circuit Making¶
We setup the circuit below and tried various codes using Youtube, Google and even ChatGPT but, we had to let go of this exploration at this point.
Hard Soft Connection¶
For this i wanted to integrate LEDs onto my Felt Poncho module from the Open Source Circular Fashion week. So i took forward my learnings from Charlieplexing LEDs and integrated 6 LEDs into the Felt Module.
Circuit Making¶
Below is the Circuit diagram (made on TinkerCAD) and the real breadboard connections.
Here are how the 6 LEDs were integrated into the Felt Module and the wire connections made.
Code Editing¶
I used the Charlieplexing code for 6 LEDs and edited it so that the LEDs in my design would light up one-after-the-other and then flash once together and so on.
#define delay50 100
int myled[] = {8,9,10,11,12,13};
int num_of_leds;
void setup() {
num_of_leds = sizeof(myled) / sizeof(int);
for (int i = 0; i < num_of_leds; i++) {
pinMode(myled[i], OUTPUT);
}
}
void loop() {
delay(1000);
ledonn();
delay(2000);
ledoff();
delay(2000);
for (int i = 0; i < 5; i++) {pattern1();}
for (int i = 0; i < 5; i++) {pattern2();}
for (int i = 0; i < 5; i++) {pattern3();}
for (int i = 0; i < 5; i++) {pattern4();}
for (int i = 0; i < 25; i++){pattern5();}
for (int i = 0; i < 5; i++) {pattern6();}
ledoff();
delay(5000);
}
//TURN ON ALL LEDs
void ledonn() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
}
}
//TURN OFF ALL LEDs
void ledoff() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], LOW);
}
}
//LEFT TO RIGHT
void pattern1() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
}
}
//RIGHT TO LEFT
void pattern2() {
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
digitalWrite(myled[i - 1], LOW);
}
}
//LEFT TO RIGHT FILL
void pattern3() {
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
}
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], LOW);
delay(delay50);
}
}
//RIGHT TO LEFT FILL
void pattern4() {
ledonn();
delay(delay50);
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], LOW);
delay(delay50);
}
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
}
ledoff();
}
//ALTERNATE LEDs
void pattern5() {
for (int i = 0; i < num_of_leds; i = i + 2) {
digitalWrite(myled[i], HIGH);
digitalWrite(myled[i + 1], LOW);
}
delay(delay50);
for (int i = 0; i < num_of_leds; i = i + 2) {
digitalWrite(myled[i], LOW);
digitalWrite(myled[i + 1], HIGH);
}
delay(delay50);
}
//OSCILLATING LEDs
void pattern6() { //osc
for (int i = 0; i < num_of_leds; i++) {
digitalWrite(myled[i], HIGH);
delay(delay50);
digitalWrite(myled[i], LOW);
}
delay(delay50);
for (int i = num_of_leds; i > 0; i--) {
digitalWrite(myled[i - 1], HIGH);
delay(delay50);
digitalWrite(myled[i - 1], LOW);
}
}
Final Piece Assembled and Litup¶
I put the Wearable as a neckpiece and it worked pretty well i would say; apart from all the wires hanging!!
Learnings¶
-
Have a LOT of patience and trust in the process.
-
Always check all connections multiple times, and then check once more. Before discarding a circuit completely, try changing out one element at a time.
-
Always ALWAYS test an LED before connecting it to a circuit. This will save a LOT of heartache and tears.
Simple way to test an LED is working or not, is to place the legs of the annode and cathode legs on the respective ends of a 3V cell battery
-
When using a breadboard, always push the pins of the electronics into the cutouts perpendicularly, and with more force than you expect. If the connections aren't properly in their place to begin with, figuring out those later on is extremely difficult, since from afar, everything looks perfect.
-
Always assume that the first Tutorial or attempt at Coding, will not work. Everything needs a bit of tweaking and logical edits.
People to thank for this week¶
Shefali: working together with her made this scary subject, less so as we hand-held each other through the ups and downs of wires not working; and we powered through it all