PCOMP – Week 4: Analog Output

This week’s project is a continuation and the final piece of my “First Year @ITP Trilogy”. The name of the project is called ITP Life, and it’s a box that depicts the norm of many first year students in their first month at ITP.

It works like this:

 

Ideation

I got the project idea from my observation of a rotating servo. Unlike a motor which is capable of circling round and round in one direction, a servo can usually rotate only 180 degrees (some can do 360 max). So it comes with two directions.

It gives me a feeling of the progression and regression of a movement, and a symbolization of something that can go up and down. Relating to my first month’s experience at ITP, it reminds me of the work we have to do every week – as classes go by, the amount of work gradually piles up, and we keep working on them one by one until finally someday before the next class, they’re all cleared. Then the cycle begins again throughout the semester.

To express this “catch me if you can” feeling, I think it’ll be good to line up two servos vertically and in parallel, one stands for the homework, and the other stands for myself:

  • In order to enable two servos to rotate vertically, I need to build a base that can hold them both in the air;
  • Both servos will rotate in the same direction;
  • The homework servo will have a head start, and my servo will be the one chasing the homework;
  • The homework servo will gradually rotates at a constant speed, and my servo will rotate a certain degree as long as I send it a message to the micro-controller (meaning that I’ve finished my homework for a particular class).
  • To make the rotation of both servos visible, I’ll need something larger to delineate the servos’ movement. In this case, I’ll make two pieces of circular cardboard, and align their centers to those of the servos.
  • LEDs and paper with drawings can be attached to the cardboard circles to indicate which one is which.
  • When I finally catch up with the homework (the rotation of my servo equals to that of the homework servo), I’ll be happy. So, a joyful piece of music should be played for celebration (I put the Mario Level Complete music in it). Also the LED color would change.

 

Circuit Design

The circuit itself is pretty simple:

  • Two servos are connected to the Arduino board in parallel;
  • One red LED and one 220 ohm resistor are in series, and they’re parallel to the servos;
  • Same thing for a blue LED + resistor combo, and a RGB LED + resistor combo;
  • A buzzer connected parallel to the servos.

 

Building Process

The assembly of different parts were straight forward, as seen from the images below.

Here are a few things I found worth noting after the building:

  • The stability of connectivity between different components seemed to be susceptible to the rotation of servos. This had led to the unstable lighting of LEDs particularly. Without soldering, I could only attach extra tapes to glue them together.
  • With only a limited number of pins available at the Arduino board, the usage of pins should be carefully planned at the beginning. We should pay attention to components that would eat up a lot of pins (e.g. a RGB LED requires three Analog pins).
  • Also, the physical layout of pins should be mapped with the physical layout of components, so that the wires connecting the board and the components would not be a mess. In this case, I connected the two servos to the analog pins at both ends (pin 3 and pin 11), and reserved the analog pins in the middle for the RGB LED.

And that’s it! 😀

 

Code

/* ITP Life
by Yuguang Zhang @NYU ITP, Oct 3, 2018
*/

#include <Servo.h>
#include “pitches.h”

Servo servoITP; // the ITP homework servo
Servo servoMe; // my servo

int posITP = 70; // variable to store the initial servo position
int posMe = 0; // variable to store the initial servo position

int currentPosITP = 70; // current servo position
int currentPosMe = 0; //  current servo position

//Pins Setup
int ledITP = 2;
int buzzerPin = 8;
int ledCatchRed = 5;
int ledCatchGreen = 10;
int ledCatchBlue = 6;
int ledMe = 13;

// notes in the melody:
int melody[] = {
NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_C6, NOTE_E6, NOTE_G7, NOTE_E7,
NOTE_GS4, NOTE_C5, NOTE_DS5, NOTE_GS5, NOTE_C6, NOTE_DS6, NOTE_GS7, NOTE_DS7,
NOTE_AS4, NOTE_D5, NOTE_F5, NOTE_AS5, NOTE_D6, NOTE_F6, NOTE_AS7, NOTE_AS7, NOTE_AS7, NOTE_AS7, NOTE_C8
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
8, 8, 8, 8, 8, 8, 9/3, 9/3,
8, 8, 8, 8, 8, 8, 9/3, 9/3,
8, 8, 8, 8, 8, 8, 9/3, 8, 8, 8, 4/3
};

void setup() {
pinMode(ledITP, OUTPUT); //ITP LED
pinMode(ledCatchRed, OUTPUT); //catchup Red LED pin
pinMode(ledCatchGreen, OUTPUT); //catchup Green LED pin
pinMode(ledCatchBlue, OUTPUT); //catchup Blue LED pin
pinMode(ledMe, OUTPUT); //my LED

Serial.begin(9600);

servoITP.attach(3);
servoMe.attach(11);
servoITP.write(posITP);
servoMe.write(posMe);
}

void loop() {

for (int i = posITP; i <= 150; i += 1) {

if (currentPosMe < currentPosITP) {

digitalWrite(ledITP, HIGH);
digitalWrite(ledMe, HIGH);

digitalWrite(ledCatchRed, LOW);
digitalWrite(ledCatchBlue, LOW);

servoITP.write(i);
delay(200);
currentPosITP = i;

if (Serial.available() > 0 && posMe <=160 ) {
String message = Serial.readStringUntil(‘\n’);
Serial.print(“received:”);
Serial.println(message);

if (message == “do homework”) {
for (int j = posMe; j <= posMe + 20; j +=1){
servoMe.write(j);
delay(15);
}
posMe += 20;
currentPosMe = posMe;
}
}

} else {
digitalWrite(ledITP, LOW);
digitalWrite(ledMe, LOW);

digitalWrite(ledCatchRed, HIGH);
digitalWrite(ledCatchBlue, HIGH);

// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 27; thisNote++) {
int noteDuration = 1000 / noteDurations[thisNote];
tone(8, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}

posMe = 0;
servoMe.write(posMe);
currentPosITP = 70;
currentPosMe = 0;
}
}

posMe = 0;
servoMe.write(posMe);
currentPosITP = 70;
currentPosMe = 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *