Course Description

Art B2050, Fall 2013, DIAP at CCNY
A survey of modern electromechanical construction. Lessons interweave hardware, firmware, software and networking. Specific focus on paper and cardboard prototyping.

Wednesday, December 11, 2013

Week 14, 12/11: Music Box 2

All the files for our music box can be found here: http://lauralippincott.com/musicbox

Here's the Sketchup file I have for us to start from. It has a cutout for each component, and interlocking box joints that require no glue or nails. We'll need to build a linkage to lift the lid, and a dancer to spin on the continuous rotation servo. Basel has composed a melody for us using the Pitches library.



#include "pitches.h"

// notes in the melody:
int melody[] = { NOTE_D3, NOTE_F3, NOTE_A3, NOTE_G3, 
NOTE_C3, 0, NOTE_C3, NOTE_D3, NOTE_F3, 
NOTE_A3, NOTE_D3, NOTE_F3, NOTE_A3, 
NOTE_G3, NOTE_C3, 0, NOTE_C3, NOTE_F3, 
NOTE_F3, NOTE_A3 };

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = { 34, 20, 20, 25, 45, 20, 20, 30, 
40, 30, 55, 23, 56, 40, 35, 23, 67, 5 };

void setup(){
}

void loop(){
  for (int thisNote = 0; thisNote < 18; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote]; // one second divided by note duration
    tone(8, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(8); // stop the melody
    delay(1000); // pause for a second
  }
}

Wednesday, December 4, 2013

Week 13, 12/4: Music Box

1. Piezo Sensor: Phyllis
We're still having trouble getting readings from the piezo sensor, but the idea is that an initial knock will activate the box. Deliverables: datasheet, circuit diagram, detectKnock() function that has a boolean knockDetected.

2. Standard Servo: William
William's job is to build the linkage that translates the motion of the servo to the door lifting up. Deliverables: datasheet, circuit diagram, openDoor() and closeDoor() functions, linkage.

3. Photoresistor: Shiang
When the door opens, light will hit the photoresistor and activate the RGB LED. The photoresistor has a boolean for lightDetected. When the box is closed, lightDetected is false. When the box is open, the brightness of the LED will be inversely proportional to the brightness of the room. Deliverables: datasheet, circuit diagram, detectLight() function, global boolean.

4. Continuous Rotation Servo: Michael
The motor will spin a dancer clockwise during the day and counterclockwise at night. When the global variable lightDetected is false, the motor won't move. Deliverables: datasheet, circuit diagram, spinDancer() function.

5. Gyroscope: Marianna
The values for the XYZ of the gyroscope will be mapped to the RGB of the LED. Deliverables: datasheet, circuit diagram, readGyro() function, gyroXYZ[] array.

6. Piezo Buzzer: Basel
Basel is composing a melody for the dancer. It should be responsive in some way to the motions of the dancer via gyroXYZ[]. Deliverables: datasheet, circuit diagram, playMelody() function, melody.

7. Ping Sensor: Robert
An always-on ping sensor will deactivate the box when the viewer walks away. Deliverables: datasheet, circuit diagram, readPing() function.

8. RGB LED: Clarinda
The RGB LED will be influenced by both the photoresistor and the gyroscope. The RGB values will be stored in an array, and mapped to the XYZ array of the gyroscope. Deliverables: datasheet, circuit diagram, changeColor() function, global ledRGB[] array.

The things we'll need to work on collectively are the master circuit diagram, the code architecture, and the box. I think we should 3D print the box. This is what I have so far in SketchUp; we can figure out how to add holes to mount all the components and Arduino in it. Inline image 1
I'm excited about this, hope you guys are too! We'll only end up with one, but with good design and documentation, everyone could easily make one of their own. 

Wednesday, November 20, 2013

Week 12, 11/20: Motor IO

It's your job to apply the code from the Light IO tutorial to a servo motor and potentiometer.

Code for a Standard Servo
#include <Servo.h> 
Servo SDservo;
int servoPin = 9;
int potPin = 0;
int potVal = 0;

void setup(){ 
  SDservo.attach(servoPin);


void loop(){ 
  controlServo();
  delay(15);


void controlServo(){
  potVal = analogRead(potpin);
  int mappedVal = map(potVal, 0, 1023, 0, 179);
  SDservo.write(mappedVal);
}

Code for a Continuous Rotation Servo
#include <Servo.h>

Servo CRservo;
const int halt = 90;

void setup(){
  CRservo.attach(7);
}

void loop(){
  CRservo.write(halt+20);
  delay(500);
  CRservo.write(halt-20);
  delay(500);
  CRservo.write(halt);
  delay(2000);
}

Code for Four Standard Servos
#include <Servo.h> 

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

int pos = 0;

void setup(){ 
  Serial.begin(9600);
  servo1.attach(3);
  servo2.attach(4);
  servo3.attach(5);
  servo4.attach(6);

void loop() { 
  sweep(servo1, 1, 80, 120, 30);
  sweep(servo2, 1, 80, 160, 15);
  sweep(servo3, 1, 100, 160, 15); 
  sweep(servo4, 1, 60, 140, 15);

void sweep(Servo s, int inc, int smin, int smax, int del){
  for(int pos=smin; pos < smax; pos += inc){
    s.write(pos);
    delay(del);
  }
}

Thursday, November 14, 2013

Week 11, 11/13: Light IO



Code Version 1

int LEDpin = 9;
int PRpin = A0;
int PRval, LEDval;

void setup(){
  pinMode(LEDpin, OUTPUT);
  pinMode(PRpin, INPUT);
  Serial.begin(9600);
}

void loop(){
  readPR();
  writeLED();
}

void readPR(){
  PRval = analogRead(PRpin);
  Serial.print("PRval = ");
  Serial.print(PRval);
}

void writeLED(){
  LEDval = map(PRval, 0, 450, 0, 255);
  analogWrite(LEDpin, LEDval);
  Serial.print(", LEDval = ");
  Serial.println(LEDval); 
}

Code Version 2

int LEDpin = 9;
int PRpin = A0;
int PRval, LEDval, num;

void setup(){
  pinMode(LEDpin, OUTPUT);
  pinMode(PRpin, INPUT);
  Serial.begin(9600);
}

void loop(){
  readPR();
  Serial.print("PRval = ");
  Serial.print(PRval);
  if(PRval < 10) num = 1;
  else if(PRval > 300) num = 3;
  else num = 2;
  switch(num){
    case 1: // PR is in shadow
      Serial.println("shadow");
      digitalWrite(LEDpin, LOW);
      break;
    case 2: // PR is in ambient light
      Serial.println("ambient");
      writeLED();
      break;
    case 3: // PR is in bright light
      Serial.println("bright");
      digitalWrite(LEDpin, LOW);
      break;
  }
  delay(20);
}

void readPR(){
  PRval = analogRead(PRpin);
}

void writeLED(){
  LEDval = map(PRval, 0, 450, 255, 0);
  analogWrite(LEDpin, LEDval);
}

Wednesday, November 6, 2013

Week 10, 11/6: Debugging

So far we've seen all the ways a physical computing project can be difficult. Here's a troubleshooting checklist to help you figure out what's going wrong.

1. Is the code correct?
Code is the most complex and most edited part of a project, so it's the most likely source of a bug. This is why it's so important to keep your code clean and well-organized. Give each component its own function, keep variables local, and give the functions and variables obvious names. Use Serial.print() and Serial.println() liberally (then comment them out when you're done).

2. Did it work before you changed something?
If yes, isolate the change. Comment things out until you've located the problem. Save working versions of the code with clear version numbers (and don't save non-working versions). It may be that the newest change revealed an older bug, but that's less likely. If the code has never worked, and you're sure the code is right, check the wiring.

3. Is the wiring correct?
Visually inspect all soldered and solderless connections. Use the multimeter on the continuity setting to ensure conduction is happening where it's needed, and not happening elsewhere. Use the multimeter on the DC voltage setting to make sure the right amount of power is getting to each component. Isolate each component to make sure they're not interfering with each other.

Wednesday, October 30, 2013

Week 9, 10/30: Sensors

Sensors come in many shapes and sizes. Understanding what types of sensors are around at what price points will help you shape your projects. The thing most of you were interested in sensing was the presence and proximity of people, so here are two sensors for that purpose. A piezo sensor detects vibration— a very crude version of a microphone. A ping sensor emits and detects an ultrasonic pulse; the time it takes the pulse to return to the sensor tells you how far away the closest object is. 

Sensors typically have two or three terminals. Every sensors needs power, ground, and at least one signal wire. With two-terminal sensors, like photoresistors and piezos, a voltage divider is required. The ground terminal connects to ground; the positive terminal connects to the signal input pin and also to a resistor; the resistor connects to the source voltage.



Piezo Code
int ledPin = 13;
int knockSensor = 0; 
byte val = 0;
int statePin = LOW;
int THRESHOLD = 100;

void setup(){
  pinMode(ledPin, OUTPUT); 
  Serial.begin(9600);
}

void loop(){
  val = analogRead(knockSensor); 
  if (val >= THRESHOLD) {
    statePin = !statePin;
    digitalWrite(ledPin, statePin);
    Serial.println("Knock!");
  }
  delay(100);
}

Ping Code
const int pingPin = 10;

void setup() {
  Serial.begin(9600);
}

void loop(){
  Serial.println(ping());
  delay(100);
}

int ping(){
  long duration, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  return cm;
}

long microsecondsToCentimeters(long microseconds){
  return microseconds / 29 / 2;
}


Wednesday, October 16, 2013

Week 8, 10/23: Processing

Today we'll look at the art history of mechanical systems. Here's a link to the image gallery, here's a link to the reading, here's a link to the circuit symbol index. We'll also talk about how the four programming paradigms— imperative, functional, object-oriented, logic— and how they're all encapsulated in the familiar line, Serial.println("hello world");

The goal of today's workshop is to get Arduino communicating with Processing. It's easier to go from Processing to Arduino than the reverse, so we'll start there. The one trick to getting this working is to select the correct Serial port in Processing. When you first launch the Processing code, it will list the Serial ports in the debugging window. One will match the board ID# you selected in the Arduino/Tools menu. Whatever number in the list matches your board ID# will be substituted for 0 in the line port = new Serial(this, Serial.list()[0], 9600);


Arduino Code
const int ledPin = 13; 
int incomingByte;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if(Serial.available() > 0){
    incomingByte = Serial.read();
    if(incomingByte == 'H'){
      digitalWrite(ledPin, HIGH);
    } 
    if(incomingByte == 'L'){
      digitalWrite(ledPin, LOW);
    }
  }
}

Processing Code
import processing.serial.*; 
float boxX;
float boxY;
int boxSize = 20;
boolean mouseOverBox = false;
Serial port; 

void setup(){
  size(200, 200);
  boxX = width/2.0;
  boxY = height/2.0;
  rectMode(RADIUS); 
  println(Serial.list());  // find your Arduino in log list
  port = new Serial(this, Serial.list()[0], 9600);
}

void draw(){ 
  background(0);
  if (mouseX > boxX-boxSize && mouseX < boxX+boxSize && 
    mouseY > boxY-boxSize && mouseY < boxY+boxSize) {
    mouseOverBox = true;  
    stroke(255); 
    fill(153);
    port.write('H');
  } 
  else {
    stroke(153);
    fill(153);
    port.write('L');      
    mouseOverBox = false;
  }

  rect(boxX, boxY, boxSize, boxSize);
}

Week 7, 10/16: Arduino



Arduino is a development platform consisting of a microcontroller and a programming environment. There have been several versions of Arduino; the model we're using is called the Uno. It has 13 Digital I/O pins and 6 Analog I/O pins. This is a typical Arduino workflow:
  1. Select desired components
  2. Google "[name of component] + Arduino" to find examples of wiring and code
  3. Wire and code one component at a time
  4. Splice the code together
The Arduino microcontroller can be purchased here, and the Arduino environment can be downloaded here. Sparkfun is a great resource for parts. I recommend getting LEDs, servo motors, and ping))) sensors. The Arduino has an LED built into pin 13— here's code to make it blink.

int led = 13;

void setup(){                
  pinMode(led, OUTPUT);     
}

void loop(){
  digitalWrite(led, HIGH);  
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}

If it's not working on the first try, it's probably one of three things. The wrong board or serial port might be selected in the Tools menu of Arduino, or your computer might be missing a driver. Google "[name of your operating system] + Arduino driver" to find a solution. At the bottom of the Arduino window is a black debugging panel; sometimes copy/pasting a specific error message into Google can help as well.

Wednesday, October 9, 2013

Week 6, 10/9: Weather Machine



Introduction
A weather machine tells you something invisible about the world through mechanical means. A thermometer can be made of a metal that expands or contracts with heat, a hygrometer can use horse hair, a barometer can use water. A weather meter might also detect noise, light, pollution, motion, wind— any measurable metric.

The tricky part of a weather machine is plotting the data. A grapher requires a drawing implement that can make a uniform line on paper without hesitation. Computer graphics require a bit of math knowledge. Your machine should have both an instantaneous analog indicator, and a digital time plot.

Common Weather Machines
Wind Vane, Weather Balloon, Hygrothermograph, Smartphone, NOAA DART

Common Sensors
Sound, Light, Temperature, Pressure, Altitude, CO, VOCs, Direction, Geiger, Humdity, IR, Gas, Tilt, Methane, Current, pH

Design a Circuit
Figure out what kind of data you’re interested in gathering, and find the appropriate sensor(s). Figure out what type of indicator is best-suited to your sensor, and what it requires. For each component, find the part number and datasheet, and use those to determine the proper Arduino wiring.

Build a Housing
Decide on all the sensors and indicators before settling on a housing. The most important question to consider is whether or not the machine will sit outside. Other considerations are portability, precision, clarity, reliability.

Code a Plotter
Use paper and colored pencils to test out different visualization schemes. Download the Processing environment. Try some basic, then more complex examples that are relevant to your project. Familiarize yourself with the relationship between firmware, software, and serial communication. Write Processing code that responds to your Arduino circuit.


Wednesday, October 2, 2013

Week 5, 10/2: SketchUp + MakerBot

Sketchup is a free piece of 3D modeling software. After planning a project out on paper, 3D rendering is an excellent next step. It forces you to understand in very certain terms what materials will be needed in what dimensions, and how all the parts will relate and attach to each other. If you have access to a 3D printer, you can also use Sketchup to build custom parts.

Here are the steps for building a panel based on the mandala from Week 1.

Click and drag the Rectangle Tool, then adjust size in the Dimensions Box.

Wednesday, September 25, 2013

Week 4, 9/25: Woodworking

Wood is a lovely and useful material. It comes in a spectrum of hardness and color. It can be worked by machine or hand. It looks beautiful painted or left bare. It lasts long and ages well, it can float or burn, it can be curvy or straight.


Wood and paper both come from the trunks of trees. Trees are plants, and live through a chemical process called photosynthesis. Their cells have a pigment called chlorophyll, which absorbs red and blue light very effectively, and converts the light energy into chemical energy.


Pine is the most common tree for woodworking, though I’m partial to Poplar for boxes. Pine is soft, cheap and attractive. For straight cuts across the grain, the right tool is a hand saw, circular saw or chop saw. A miter box can align 45° cuts for a seamless joint, which look particularly nice with a continuous grain.


There are a number of ways to join the sides of a box. With a miter cut, wood glue maintains the aesthetic. For 90° cuts: nails are the quickest, screws are better if the box needs to disassemble. The more advanced option is a dovetail or box joint with no connectors.





Build a Wooden Circuit Box


  1. Go to a nearby hardware store and check out their wood stock. Unless you go to a specialty store, it will be pine. Compare the different sizes and compositions, find something you like. Borrow a ruler, measure the thickness of the board; don’t buy anything yet.


  1. On paper, draw your box as a rectangular prism. Use your hands with a ruler as a guide, and figure out what general size box you want. Make sure it can accommodate a microcontroller under the lid. Note Width, Height, and Depth on your drawing.


  1. In 3D modeling software, render your box precisely. Account for the thickness of the wood you’ve selected.


  1. Consider how to join the sides of your box. Do you want to mitre? Nails, glue, or neither? Remodel your box accordingly.


  1. Explode the box model into six pieces and flag the lengths of the unique edges of each.


  1. Make a printout for yourself and/or the hardware store. Add ⅛” to every saw line. Figure out exactly how much wood you need.


  1. Select an appropriate saw, given your box design and woodworking experience.


  1. Cut your wood, get it cut at the hardware store for a small fee (straight edges only), or find a laser cutter (thin wood only).


  1. Sand every face of every piece in a circular pattern with first the coarse side, then the fine side of a sanding sponge.

  1. Find two metal hinges and a clasp. Attach the lid, keeping it well-aligned.

Wednesday, September 18, 2013

Week 3, 9/18: Soldering

Soldering is the act of joining two metals together by melting a filler metal between them. The filler metal, called solder, has a low melting temperature. There are many kinds, but we use a lead-free rosin-core solder in class. This variant is non-toxic and self-cleaning. It's important to have a nice soldering iron as well— Weller is a reliable brand.

To solder, anchor one or both of the targets. Tin each target by holding the solder and the iron to the target for two seconds. Then hold the targets together, and apply the solder and iron at the junction. To desolder, apply fresh solder to the joint and use a sucker or wick if necessary.


Wednesday, September 11, 2013

Week 2, 9/11: Electricity

ἢλεκτρον μαγνήτης

There are four forces that govern everything in the universe: gravity, electromagnetism, and the strong and weak nuclear forces. We'll focus on electromagnetism, which is the law of opposites attracting. The force gets its name from the Greeks, who noticed the peculiar behavior of both amber and iron. Amber— translucent, golden stones of fossilized tree resin— has a more negative charge than the human hand. The friction of rubbing two opposite-charge materials together produces static electricity: valence electrons will jump from amber to finger, building up until released as a spark. Static electricity can cause super-charged surfaces to attract and repel each other (like balloons towards walls, or hairs away from each other). Iron molecules align into poles, which produces the magnetic behavior of iron attracting and repelling itself. The Greek words above, "elektron magnetes", come from the names and stories of amber (Phaeton and Helios), and the Magnetes tribe.


This a diagram of a copper atom. Copper is the 29th element in the periodic table, meaning it has 29 protons and electrons. Electrons orbit the nucleus of an atom in something more akin to a cloud, but we talk about them as shells of varying energy levels. The electron capacity for each shell equals twice the Principal Quantum Number squared. The Principal Quantum Number is both the energy level and the ordinal number of the shell. The innermost shell has a capacity of 2 electrons (2*1^2), the second has 8 (2*2^2), and so on. Because 29 is a number that leaves a lone electron in the outer shell, copper is a very conductive element. That outer, valence electron is easily passed in an electric circuit, which is why most wires are made of copper.

The metrics for each circuit are determined by the chemical composition and sequencing of components. Order doesn't matter for every component in every circuit, but these three metrics— voltage, current, and resistance— must be balanced with every component in consideration. It takes the energy of one volt to move a current of one amp through a resistance of one ohm. Because the units are related to each other in this way, the energy of a circuit can be expressed through an equation known as Ohm's Law: V = I*R, where V is voltage, I is current, and R is resistance.

When we talk about directionality in a circuit, there are a few confusing subtleties. If you're already confused, please skip this paragraph and just remember that current flows from the positive to the negative in a circuit. It's much more common to talk about the flow of current than the flow of electrons, and they're actually moving in opposite directions. Every component has two or more electrodes— the wire terminals that allow you to solder things together. With components that only allow the flow of electricity in one direction, the electrode that collects current is called the anode, and the electrode that emits current is called the cathode. Here's the confusing part: in a battery, the anode is the negative terminal where electrons flow out and current flows in; in an LED, the anode is the positive terminal where electrons flow out and current flows in. The difference comes from the former being a generator and the latter being an emitter.

Wednesday, August 28, 2013

Week 1, 8/28: Mandalas

मण्डल

Mandala is the phonetic pronunciation of the Sanskrit word for circle. We'll begin here because it provides a unifying conceptual foundation for a number of themes. As a circle, it lends form to an electric circuit. As an image, it can be translated from a bitmap to vector to 3D model. As an art form it encourages patience, precision with materials, respect for tradition, and an understanding of color.

The painting below is a mandala thangka painting from Bhaktapur, Nepal. The mandala begins with a theme color, outside the outer ring. You begin looking at the image here, slowly spiraling inwards. There’s a halo, the theme color’s complement, a mantra and a wheel, the sea, a garden with four gates, then a temple with a lotus at the top. The gates are each assigned a color and a cardinal direction: Yellow North, Blue East, Black South, Red West. You select one gate for each trip through the painting. By the time you reach the lotus at the center, your mind should be clear.


When painting a mandala, the brush never touches the canvas— only the paint does. The paint is applied in the resting part of the breath cycle (between inhales and exhales), to encourage stillness. The paint is not built in layers; if you hold a mandala up to a window, the image shines clearly. The whole painting is done with a single brush, crafted for a perfect tip. It takes years of training to even begin a painting like this. But we can borrow from its technique and concept.

The objective of this project is to build a box that will house a microcontroller circuit. The body of the box is made of wood, with a 3D printed panel for the lid. Since the Bhaktapur mandala is a bird's-eye-view of a temple, it's a good form to extend into 3D. We'll build a circuit into the mandala's circle, with an LED as the lotus.