horaceh – Physical Computing https://courses.ideate.cmu.edu/16-223/f2014 Carnegie Mellon University, IDeATe Fri, 11 Aug 2017 21:41:33 +0000 en-US hourly 1 https://wordpress.org/?v=4.7.28 Final Project – UltraSonic https://courses.ideate.cmu.edu/16-223/f2014/final-project-ultrasonic/ Thu, 11 Dec 2014 05:03:24 +0000 http://courses.ideate.cmu.edu/physcomp/f14/16-223/?p=3411 Nkinde Ambalo, Horace Hou

Introduction

For our project, Ultrasonic, we created a device that tries to quantify a sense that we, humans, can’t sense. Using a microphone and a PureData patch we created a device that can sense ultrasonic sound waves in the range of 18kHz to 20kHz. Using this information we are able to tone the frequency of the sound waves to what humans are able to perceive. Also the strength of the signal changes the volume of the sound outputted. Using this information we also wanted to be able to map the what the variety and sources of ultrasonic waves that exist in a persons environment.

Technical Aspects

Our project consisted of a raspberry pi running pure data. The patch running on pure data watched for the plugged in microphone input level to go higher than the usual for background noise. When it did it played sound through the connected output device, sound which was pitched down 6 octaves from the input sound. This allowed anyone to hear sounds that could have been above their threshold of hearing, as the high frequency tone would be below 10,000 hz. The raspberry pi had to have an external usb sound card connected to it so that it could accept both a recording device as well as output to a speaker device. Other than power, no other cables were connected to the Raspberry Pi. In the plan for this device there was also the plans to add a gps device connected to the pins of the raspberry pi, or a bluetooth adapter connected to a smartphone pinging the location of the phone every time high frequency sound was detected.

Photos

20141210_232619

20141210_232534

20141210_232512

Video

]]>
Final Project Sketch – AdaptPack https://courses.ideate.cmu.edu/16-223/f2014/final-project-adaptpack/ Mon, 01 Dec 2014 16:27:31 +0000 http://courses.ideate.cmu.edu/physcomp/f14/16-223/?p=3108 Group Members: Horace Hou, Nkinde Ambalo

AdaptPack is a bag that adapts to your current social needs. Charging using the energy generated from you walking around, AdaptPack will allow you to warm/cool your drinks in the side pockets, play music through the speakers or headphones, as well as turn on fun colourful lights or just a simple reading light. All of this can be switched depending on your current needs. There is also a light that activates in the main pocket of the AdaptPack based on the current time of day and whether the zipper is open or not.

 

IMG_2060

]]>
Autonomous Robot Part 3 – TicTok https://courses.ideate.cmu.edu/16-223/f2014/anonymous-robot-part-3-tictok/ Tue, 18 Nov 2014 17:24:17 +0000 http://courses.ideate.cmu.edu/physcomp/f14/16-223/?p=2972 Group Member: Horace Hou, Zac Mau

Horace Hou, Zac Mau as Scribe, Designer, Integrator, Tutor,

 

Introduction

For this iteration we tried to incorporate ideas of one to many mapping into our project as way to make the interaction of the clock hands and the elastic to be more clear.

 

Technical Notes

The hardware of the project hasn’t changed much whereas the software changed a lot. Hardware wise we flipped the side of the clock hand the elastic was on so as to minimise it from getting tangled. Software wise we tried to incorporate an PureData sketch with an Arduino code.

Circuit Diagram

Clock schematic

Photos

tictok4

tictok2 copy tictok1 tictok3 copy

Arduino Code

#include <Servo.h>
#include <Stepper.h>
#define MAX_SPEED 1000
const int stepsPerRevolution = 200;
int speed1 = 200;
int speed2 = 200;
int sensorNow;
int sensorLast;
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper stepper1(stepsPerRevolution, 6, 7);
Stepper stepper2(stepsPerRevolution, 8, 9);
static unsigned int hardware_polling_interval = 50; // 20 Hz samples to start
// The maximum message line length.
#define MAX_LINE_LENGTH 80
// The maximum number of tokens in a single message.
#define MAX_TOKENS 10
// Some version of the Arduino IDE don’t correctly define this symbol for an
// Arduino Uno.
/****************************************************************/
/**** Utility functions *****************************************/
/****************************************************************/
// Send a single debugging string to the console.
static void send_debug_message( const char *str )
{
  Serial.print(“dbg “);
  Serial.println( str );
}
/****************************************************************/
// Send a single debugging integer to the console.
static void send_debug_message( int i )
{
  Serial.print(“dbg “);
  Serial.println( i );
}
/****************************************************************/
// Send a single-argument message back to the host.
static void send_message( const char *command, long value )
{
  Serial.print( command );
  Serial.print( ” ” );
  Serial.println( value );
}
/****************************************************************/
// Send a two-argument message back to the host.
static void send_message( const char *command, long value1, long value2 )
{
  Serial.print( command );
  Serial.print( ” ” );
  Serial.print( value1 );
  Serial.print( ” ” );
  Serial.println( value2 );
}
/****************************************************************/
// Wrapper on strcmp for clarity of code.  Returns true if strings are
// identical.
static int string_equal( char *str1, char *str2)
{
  return !strcmp(str1, str2);
}
static void user_message_0( char *command )
{
  if (string_equal(command, “stop”)) {
    // do something to set the stop state here
    send_debug_message(“now stopped”);
  } else  if (string_equal(command, “start”)) {
    // do something to set the start state here
    send_debug_message(“starting”);
  }
  // …
}
// Process one-argument messages with a single value. E.g. “speed 33”.
static void user_message_1( char *command, int value )
{
  if (string_equal(command, “speed”)) {
    // do something to set the stop state using ‘value’
  }
  // …
}
// Process two-argument messages. E.g. “pantilt 0 33”.
static void user_message_2( char *command, int value1, int value2 )
{
  if (string_equal(command, “pantilt”)) {
    // do something using value1 and value2
  }
  // …
}
/****************************************************************/
// Process an input message.  Unrecognized commands are silently ignored.
static void parse_input_message(int argc, char *argv[])
{
  // Interpret the first token as a command symbol.
  char *command = argv[0];
  /* — process zero-argument commands ————————— */
  if (argc == 1) {
    send_message(“dbg”, 0, 1);
    // just pass it along
    user_message_0( command );
  }
  /* — process two-argument commands ————————— */
  else if (argc == 3) {
    send_message(“dbg”, 0, 2);
    int pin   = atoi(argv[1] );
    int value = atoi(argv[2] );
    if ( string_equal( command, “stepper” )) {
      if(pin == 0)  {
        stepper1.setSpeed(value);
        send_message(“dbg”, 0, value);
      }
      else if(pin == 1)  {
        stepper2.setSpeed(value);
        send_message(“dbg”, 1, value);
      }
      return;
    }
    else if ( string_equal( command, “dig” )) {
      pinMode( pin, OUTPUT );
      digitalWrite( pin, value );
      return;
    }
    // else just pass it along
    else user_message_2( command, pin, value );
  }
}
/****************************************************************/
// Polling function to process messages arriving over the serial port.  Each
// iteration through this polling function processes at most one character.  It
// records the input message line into a buffer while simultaneously dividing it
// into ‘tokens’ delimited by whitespace.  Each token is a string of
// non-whitespace characters, and might represent either a symbol or an integer.
// Once a message is complete, parse_input_message() is called.
static void serial_input_poll(void)
{
  static char input_buffer[ MAX_LINE_LENGTH ];   // buffer for input characters
  static char *argv[MAX_TOKENS];                 // buffer for pointers to tokens
  static int chars_in_buffer = 0;  // counter for characters in buffer
  static int chars_in_token = 0;   // counter for characters in current partially-received token (the ‘open’ token)
  static int argc = 0;             // counter for tokens in argv
  static int error = 0;            // flag for any error condition in the current message
  // Check if at least one byte is available on the serial input.
  if (Serial.available()) {
    int input = Serial.read();
    // If the input is a whitespace character, end any currently open token.
    if ( isspace(input) ) {
      if ( !error && chars_in_token > 0) {
if (chars_in_buffer == MAX_LINE_LENGTH) error = 1;
else {
  input_buffer[chars_in_buffer++] = 0;  // end the current token
  argc++;                               // increase the argument count
  chars_in_token = 0;                   // reset the token state
}
      }
      // If the whitespace input is an end-of-line character, then pass the message buffer along for interpretation.
      if (input == ‘\r’ || input == ‘\n’) {
// if the message included too many tokens or too many characters, report an error
if (error) send_debug_message(“excessive input error”);
// else process any complete message
else if (argc > 0) parse_input_message( argc, argv );
// reset the full input state
error = chars_in_token = chars_in_buffer = argc = 0;
      }
    }
    // Else the input is a character to store in the buffer at the end of the current token.
    else {
      // if beginning a new token
      if (chars_in_token == 0) {
// if the token array is full, set an error state
if (argc == MAX_TOKENS) error = 1;
// otherwise save a pointer to the start of the token
else argv[ argc ] = &input_buffer[chars_in_buffer];
      }
      // the save the input and update the counters
      if (!error) {
if (chars_in_buffer == MAX_LINE_LENGTH) error = 1;
else {
  input_buffer[chars_in_buffer++] = input;
  chars_in_token++;
}
      }
    }
  }
}
static void hardware_input_poll(void)
{
  static unsigned long last_time = 0;
  unsigned long now = millis();
  if ((now – last_time) > hardware_polling_interval) {
    last_time = now;
    // send A0 analog state
    send_message( “ana”, 0, analogRead(0) );
    // send PIN8 digital state
    send_message( “dig”, 7, digitalRead(7) );
    send_message( “dig”, 9, digitalRead(9) );
    // send a time reading
    long clock = micros();
    send_message( “clk”, clock );
  }
}
void setup()
{
  Serial.begin(9600);// nothing to do inside the setup
  // initialize the Serial port
  // send a message as a diagnostic
  send_debug_message(“wakeup”);
  // set up the hobby servo control output
  //servo_output.attach( servo_output_pin );
  //servo_output.attach( servo_output_pin_2 );
  // additional hardware configuration can go here
}
void loop()
{
  serial_input_poll();
  hardware_input_poll();
}

]]>
Autonomous Robot Part 2 – TicTok https://courses.ideate.cmu.edu/16-223/f2014/autonomous-robot-part-2-chasing-clocks/ Tue, 04 Nov 2014 20:52:56 +0000 http://courses.ideate.cmu.edu/physcomp/f14/16-223/?p=2669 Group Member: Horace Hou, Zac Mau

Horace Hou, Zac Mau as Scribe, Designer, Integrator, Tutor,

Introduction

TicTok is a set of clocks which have their hands linked together by a conductive elastic. One of the clocks behave like a regular clock whereas the other clock actively tries to stop the other from rotating regularly.

Video

 

Circuit Diagram

Clock schematic

Technical Notes

For our project we used a flexible conductive elastic, whose resistance changes when it is pulled. Using an Arduino we measured the current of the elastic to determine when the clock hands where farthest away from each other. Using this information we adjusted the speed of the each individual stepper motor. The stepper motors are powered by a 6V power supply and the elastic is powered by the 3.3V input on the Arduino. The stepper motors are connected to stepper drivers which is in turn connected to the Arduino.

The stepper motor has a pedestal which allows the motor to be at the centre of the clock face. The stepper motor is screwed into the pedestal. The elastic is tied onto the ends of the clock hands. Wiring is passed underneath the clock hands where an exposed wire rotates over some conductive foil which acts as a slip ring.

 

Photos

Initial Design Drawing

diagram

 

First PrototypeIMG_6446

Second Prototype

IMG_6464 IMG_6472

Stepper Motor HolderIMG_6455

IMG_6489

 

Arduino Code

#include <Stepper.h>
#define MAX_SPEED 1000
const int stepsPerRevolution = 200;
int speed1 = 200;
int speed2 = 200;
int sensorNow;
int sensorLast;
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper stepper1(stepsPerRevolution, 6, 7);
Stepper stepper2(stepsPerRevolution, 8, 9);
void setup() {
  Serial.begin(9600);// nothing to do inside the setup
}
void loop() {
    sensorLast = sensorNow/2;
  sensorNow = analogRead(A0);
  if (sensorNow < sensorLast) {
   stepper1.setSpeed(sensorNow);
   stepper2.setSpeed(sensorLast);
  }
  if (speed1 >= 0 )
      {stepper1.setSpeed( speed1 += 400);}
      else {stepper1.setSpeed( speed1 -= 400);}
  if (speed2 >= 0 )
      {stepper2.setSpeed( speed2 += 400);}
      else {stepper2.setSpeed( speed2 -= 400);}
   Serial.print(“Sensor Now: “);
   Serial.print(sensorNow);
   Serial.print(” | Stepper 1: “);
   Serial.print(speed1);
   Serial.print(” | Stepper 2: “);
   Serial.println(speed2);
    // step 1/100 of a revolution:
    stepper1.step(20);
    stepper2.step(-10);
}

 

]]>
1B – Arduino Project – Algorithm of the Cave https://courses.ideate.cmu.edu/16-223/f2014/1b-arduino-project-algorithm-of-the-cave/ Mon, 22 Sep 2014 05:37:47 +0000 http://courses.ideate.cmu.edu/physcomp/f14/16-223/?p=2008 Group Members: Alice Borie, Luke Hottinger, Horace Hou, Vivian Qiu, Rebecca Wolfinger

Roles: Alice Borie as Scribe, Luke Hottinger – Integrator, Horace Hou as Designer , Vivian Qiu as Designer, Rebecca Wolfinger as Tutor

 

Introduction

Change, something that we all experience multiple times in our lives whether it be transitioning from high school to college or moving to another city. These changes bring unnecessary stresses to our lives, however, given time we are able to adapt and calm ourselves down. The relationship of change and stress is something we tried to highlight in our project.

We related our idea to the allegory of the cave where the people chained up in a cave are used to experiencing the world through shadows, when one prisoner is freed, he experiences a shocking change where his whole belief of the world is suddenly destroyed. However, given time he slowly gets used to his new surroundings and thus returns to his previous calmness.

In our project we aim to show a system that responds stressfully when there is a change to the system. Over time the system gets used to the new environment and returns to the initial resting state. In our project the wooden box represents the cave in the allegory of the cave and the mini acrylic boxes represent the prisoners. One of the acrylic boxes has the sensor and arduino embedded in the box to represent the freed prisoner.

Video

 

Technical Notes

Our project uses a light sensor to detect a change in the surroundings. Once the sensor detects a change in the systems, the LED’s stress out and flicker between colours. For this project we used the RGB LED’s to allow for a greater control of the colours output and allow changes in the colour. There is also a motor that is turned on when the system is stressed. The arduino compares the average light readings over time and thus allows the system to get used to the new environment and calm down. In its resting state the box slowly fades between turquoise and green. A hole was drilled in the box in order for the light sensor to more accurately measure the amount of light in the environment. The light sensor was also blocked from the LED’s in order to prevent the light sensor from measuring the light being emitted by the LED’s.

 

Photos

 

IMG_5008Prisoner in calm state.

IMG_5015Prisoner in stressed state.

fritzcaveCircuit Diagram

IMG_1370

Actual Circuit

]]>