Saturday, March 26, 2016

Midterm Project

The information related to the in-class presentation was/will be given in class itself. The in-class presentation is available at https://docs.google.com/presentation/d/1f2q-bnjgmTGTGDaIORXxPnVoGM0FWm_QAYhCOtABfzI/ for reference purposes (you will need to sign in with your NYU credentials).

The product is called "eLSAR" which stands for "thE Light Sensitive AlaRm." It is a light sensitive alarm. The interaction we are mediating is between human and light, and waking up. The device senses the amount of ambient light and wakes up the human depending on the device's configuration. Input is the ambient light in the room, the on-off switch on the device, and the configuration knob on the device. Output is either no sound, or sound.

I worked with Giorgio Pizzorni on this project.

Plan for where the pieces should go (outside the casing)

Plain Arduino in casing
Potentiometer (10k ohm) soldered with wires
Speaker (8 ohm 0.25W) soldered with wires
Photoresistor soldered with wires
Switch soldered with wires
Completed upper casing with parts put in their places
Complete circuitry
Completed product (back left open to cause less headaches)
Testing the potentiometer

Testing the speaker

Testing the photoresistor

Testing the switch

Demo of the product:

Giorgio was, in fact, not very happy


Timeline of our project:
Wednesday (March 23): Finalized product idea
Thursday: Went to Leslie eLab for 3D printer/laser cutter training; our idea for 3D printing the casing was shot down (too large, would take too long), idea instead to laser cut wood/other material
Friday: Came up with list of components/materials to buy. Attempted to book laser cutter, system did not let us book over the weekend, earliest was Monday 10 AM, laser cutter idea scrapped.
Saturday: Purchased components/materials. Built casing (foam board rather than wood) and circuitry.
Sunday: Tested product. Wrote documentation.

Regarding our process and the various phases:
Concept/parts/planning: decided to build an alarm clock, thought of various parts to buy with Amos's help, and purchased them at Tinkersphere.
User observation/implement concept revisions/technical development iteration until complete: our various iterations are documented above where we test out each individual component and our final product. No obvious bugs/glitches/errors were found on first revision, so we stuck with it. One functionality we decided to change was rather than having a snooze/setup switch, instead have an on/off switch.
Demonstration of functioning project: documented above.

Presentation related information:
Located in the presentation above (link at top of post).

Sunday, March 20, 2016

Interactive Toy









Where's Waldo? created by Chaitanya Garg and Giorgio Pizzorni



Find all 5 of the characters, press the paper where they are, a tone will play for each one found and a victory tone will play when all 5 are found (and the game resets).

We tried to 3D print a box to hold our circuitry, however the resources at the Leslie eLab were closed to us over break. Instead, we ended up soldering wires and the force sensitive resistor.

Intended user: basically anyone. A child can play it and so can an adult (it's not the easiest game if you don't cheat!).
Limitations and capabilities: assumes no limitations and capabilities of a human being
How design of toy takes above into account: requires sight and ability to press; an infant can play this game, but their strategy would probably just be random guessing
Affordances the toy offers: Press the game board for input, keep the entire game on a table, listen to sounds for output

Here is the code we used:
/**
 * Interactive toy: Where's Waldo?
 * Created by Chaitanya Garg and Giorgio Pizzorni
 */

#include "pitches.h"
#define THRESHOLD 100
#define TONE_TIME 500

const int fsr[5] = { A0, A1, A2, A3, A4 };
const int tones[5] = { NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5 };
const int speaker = 11;
bool activated[5] = { false, false, false, false, false };

void reset()
{
  for (int i = 0; i < 5; i++)
  {
    activated[i] = false;
  }
}

void setup()
{
  Serial.begin(9600);
  
  // initialize input/output pins
  pinMode(speaker, OUTPUT);
  for (int i = 0; i < 5; i++)
  {
    pinMode(fsr[i], INPUT);
  }
}

void play(int note, int duration)
{
  tone(speaker, note, duration);
}

void loop()
{
  int readings[5] = { 0, 0, 0, 0, 0 };
  bool pressed[5] = { false, false, false, false, false };
  for (int i = 0; i < 5; i++)
  {
    readings[i] = analogRead(fsr[i]);
    if (readings[i] > THRESHOLD)
    {
      pressed[i] = true;
      activated[i] = true;
    }
  }
  
  // if two are pressed at once, picks the "first" one based on array index
  int pressed_fsr = index_of(pressed, 5, true);
  if (pressed_fsr == -1)
  {
    // implies that no fsr was pressed
    return;
  }
  
  // play tone corresponding to which fsr was pressed
  play(tones[pressed_fsr], TONE_TIME);
  
  // now check if all 5 are pressed
  if (all_pressed())
  {
    victory();
  }
}

void victory()
{
  // play all 5 tones in order
  
  for (int i = 0; i < 5; i++)
  {
    play(tones[i], TONE_TIME);
    delay(TONE_TIME);
  }
  
  reset();
}

int index_of(bool *arr, int size, bool val)
{
  for (int i = 0; i < size; i++)
  {
    if (arr[i] == val)
    {
      return i;
    }
  }
  return -1;
}

bool all_pressed()
{
  for (int i = 0; i < 5; i++)
  {
    if (activated[i] == false)
    {
      return false;
    }
  }
  return true;
}

Wednesday, March 16, 2016

Processing Labs

Oscillating circle


1. Java
2. Technically speaking, the only distinction is scope (where they live and die). Global variable has a scope of the file (or more depending on your linker), and a local variable has a scope of whatever block you're in.
3. void which means no return type
4. When the ellipse reaches the top or bottom of the screen, reverse its direction of movement

Potentiometer controlled ellipse


(no questions)

Etch-a-Sketch



(no questions)
Here is my code:

Processing:
import processing.serial.*;

Serial arduino;
int x;
int y;
int x_prev;
int y_prev;

void setup()
{
  x = 0;
  y = 0;
  x_prev = 0;
  y_prev = 0;
  
  size(320, 240);
  background(0,255,255);
    
  String port = Serial.list()[0];
  arduino = new Serial(this, port, 9600);
}

void draw()
{
  fill(0, 0, 0);
  if (!(x_prev == 0 && y_prev == 0))
  {
    line(x_prev, y_prev, x, y);
  }
  x_prev = x;
  y_prev = y;
}

void serialEvent(Serial port)
{
  try
  {
    String input = port.readStringUntil('*');
    if (input != null)
    {
      int[] vals = int(splitTokens(input, ",*"));
      x = vals[0];
      y = vals[1];
      println("x: " + x + ", y: " + y);
    }
  }
  catch (Exception e)
  {
    
  }
}

Arduino:

const int pot_left = A0;
const int pot_right = A1;

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

void loop()
{
  int pot_left_val = analogRead(pot_left);
  int pot_right_val = analogRead(pot_right);
  int left = map(pot_left_val, 0, 1023, 127, 0);
  int right = map(pot_right_val, 0, 1023, 127, 0);
  // pack the two values together into one
  Serial.write(44);
  Serial.print(left, DEC);
  Serial.write(44); // comma
  Serial.print(right, DEC);
  Serial.write(42); // asterisk
}

Friday, March 4, 2016

Servo Labs

Servo controlled via pulse width modulation

1. The delay is because we can't create an analog signal out of the Arduino, only simulate one. And in order for pulse width modulation to work, you need some time in order to simulate the analog signal.
2. The range of the servo motor is from 0 to 180. Then a 45 rotation is 1/4th of the maximum pulse, or 25%.
3. Here is a quote from the tone manual page (located https://www.arduino.cc/en/Reference/Tone): "Use of the tone() function will interfere with PWM output on pins 3 and 11 (on boards other than the Mega)." This means that the PWM required for both tone and servo movement will interfere with each other.

Servo controlled by potentiometer

(no questions)

Servo controlled by push button switch

(no questions)

Here is the code I wrote for this to work (I will leave pin setup and circuit setup as an exercise for the reader):
#include <Servo.h>

const int servo_pin = 5;
const int pause = 45;
const int switch_pin = 3;
int angle = 0;
int direction = 1;
Servo servo;

void setup()
{
  servo.attach(servo_pin);
  pinMode(switch_pin, INPUT);
}

void turn_servo()
{
  if (angle == 0)
  {
    direction = 1;
  }
  if (angle == 180)
  {
    direction = -1;
  }
  angle += 10 * direction;
  servo.write(angle);
}

void loop()
{
  int switch_val = digitalRead(switch_pin);
  if (switch_val == HIGH)
  {
    turn_servo();
    delay(100);
  }
  else
  {
    delay(100);
  }
}