Making Things Interactive

May 14, 2008

spiderbot

Filed under: 1: Post Something Interesting,Gaku Sato — ponkotsu @ 9:01 am

dies ist mein spiderbot.  i worked on it all semester.  i think it came out real good and i just wanted to show everyone.

http://www.andrew.cmu.edu/user/gsato/spiderbot.jpg

Advertisements

Washroom Penitentiary [term paper]

Filed under: Final Project,Gaku Sato,Term Paper — ponkotsu @ 8:52 am

[final paper]

[final paper appendix]

May 12, 2008

Washroom Penitentiary [final]

Filed under: Final Project,Gaku Sato — ponkotsu @ 3:41 am

  this is a bathroom concept intended for consideration of possible implementation in the near future or at least further testing.  it is a sensor-driven room that advocates cleanliness by locking you in when you use it and telling you to wash your hands.  of course the lock can be manually disengaged (for legal reasons) and the sign can be ignored, but if you choose to do so, as you leave a sign and alarm will notify everyone around you that you have not washed your hands.  of course, if you do wash your hands (whether you used the bathroom or not), you will be thanked and rewarded with sounds of success as you leave.

  additionally, rinsing does not count as washing as they are two separate entities.  and you will be hounded similarly for not flushing the toilet if you use it and don’t flush.

prototype details and photo scenario:
  [Scenario.pdf]

state diagram, wiring schematic, and message list:
  [Schematic v2.pdf]

reviews:
  “great idea!”  -man at demo
  “we need this!”  -hospital worker
  “totally fascist!”  -g. levin
  “adorable!”  -l. albaugh

code:

#include

// PINS //
int soapLED_R = 10; // warning light
int soapLED_G = 9; // indicates soap being dispensed
int soapLED_B = 8; // standard light [GB=white]
int sinkLED = 11; // indicates running water [B]

int soapsensor = 0;
int sinksensor = 1;

int toiletswitch = 12; // indicates motion detected [in toilet!]
int flushbutton = 13;
int lockbutton = 7;
int doorswitch = 4;

int signservo = 3;
int locksolenoid = 2;
int speaker = 5;
int bell = 6;

Servo sign;

// STATES //
int State = 0;
const int Blank = 0;
const int Locked = 1;
const int Wash = 2;
const int LockWash = 3;
const int Flush = 4;
const int Toilet = 5;
const int DUnlock = 6;
const int DLeaving = 7;
const int DSoap = 8;
const int DRinse = 9;
const int Clean = 10;
const int CLeaving = 11;
const int TUnlock = 12;
const int TLeaving = 13;
const int TSoap = 14;
const int TWater = 15;

int LockState = 0;
const int Auto = 0;
const int Manual = 1;

// OUTPUT CONDITIONS //
int Reward = 0;
const int Off = 0;
const int On = 1;
int Buzzer = 0;
int Sign = 0;
const int Bl_Bl = 126; // in: blank out: blank
const int Wa_Bl = 110; // in: wash out: blank
const int Wa_Di = 89; // in: wash out: dirty
const int Ri_Bl = 71; // in: rinse out: blank
const int Fl_Bl = 55; // in: flush out: blank
const int Fl_Fl = 34; // in: flush out: flush
const int Th_Cl = 15; // in: thanks out: clean!
int Soap = 0;
const int White = 0; // standard light
const int Red = 1; // warning light
const int Green = 2; // indicates soap being dispensed
int Sink = 0;
int Lock = 0;

// ANALOG INPUT THRESHOLDS //
int soapmin = 50;
int soapmax = 100;
int sinkmin = 100;
int sinkmax = 300;

// OTHER //
int lockbuttonpress = 0;
int dooropentime = 0;
int dooropenmax = 5000;

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

pinMode(soapLED_R, OUTPUT); // digital
pinMode(soapLED_G, OUTPUT); // digital
pinMode(soapLED_B, OUTPUT); // digital
pinMode(sinkLED, OUTPUT); // digital
pinMode(soapsensor, INPUT); // analog
pinMode(sinksensor, INPUT); // analog
pinMode(toiletswitch, INPUT); // digital
pinMode(flushbutton, INPUT); // digital
pinMode(lockbutton, INPUT); // digital
pinMode(doorswitch, INPUT); // digital: LOW when closed, HIGH when open
pinMode(signservo, OUTPUT); // digital: PWM
pinMode(locksolenoid, OUTPUT); // digital
pinMode(speaker, OUTPUT); // digital
pinMode(bell, OUTPUT); // digital

State = Blank;
LockState = Auto;
Reward = Off;
Buzzer = Off;
Sign = Bl_Bl;
Soap = White;
Sink = White;
Lock = Off;

lockbuttonpress = 0;
dooropentime = 0;

sign.attach(signservo);
sign.setMaximumPulse(2400);
sign.setMinimumPulse(544);
sign.write(Bl_Bl);
}

void loop()
{
// SWITCH STATES //
switch(State)
{
case Blank:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
{ lockbuttonpress=1; State=Locked; }
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(analogRead(soapsensor)dooropenmax)
{ dooropentime=0; State=Blank; }
if(analogRead(soapsensor)dooropenmax)
{ dooropentime=0; State=Blank; }
break;
case TUnlock:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
{ lockbuttonpress=1; State=Toilet; LockState=Manual; }
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(digitalRead(doorswitch)==HIGH) {dooropentime=0; State=TLeaving;}
if(analogRead(soapsensor)

May 1, 2008

course_review.txt

Filed under: Final Writing Assignment,Gaku Sato — ponkotsu @ 11:04 am

  First I’d like to state that overall I think this class was a raging success.  I learned more than I can put into words so my attempts to describe it may be futile but I will continue as it is the assignment.

  I came in knowing I wanted to make things but had no idea what those things would be.  After being given the first assignment I still didn’t know what that would be.  The fact that we could choose basically whatever we wanted to do at first seemed a bit unguided, but it got me thinking about what I would want to make and not just how I would make the thing I was told to make.  So given that I could apply my interests and not just my skills however limited they may be.  And with interest followed motivation, insight, and ultimately determination to actually reach the goal I had set for myself, of punching Godzilla in the face.  The results of this were projects I was personally vested in and not just for a grade or a page in my appalling portfolio.

  This kind of open-endedness and lack of rigid structure allowed, and at times enforced, me to learn through experience.  It was daunting at times because the scope of the projects was so unlimited, but that was good too, although more in retrospect than at the time.  It was a real challenge to be creative and resourceful, to be able to use anything at our disposal to make our ideas.  Not restricted to kits or anything, to me it was “here’s the world; put something in it using anything from it.”

  And before implementation and prototyping, concept generation was the other sub-boss in this wonderful dungeon.  For every single project I fought that beast and died many times.   If I were given a more specific direction in terms of the design or functionality of the project, I assume this may not have been the case as much or as often, but I don’t think I would have really gained anything from that.  Because I kept running into brick walls I feel like I got better not at running into brick walls but at seeing the path to avoid them, which I think is critical in an iterative design process.  I propose that I got better at it since I’m most happy with my final project.

  In terms of the class structure and material itself, I think it was great: the chosen hardware, the tutorials in the beginning, the pacing and scale of the projects, the slope of increasing complexity, the use of state diagrams, all the reference material, etc.  With the emphasis on implementation, it was at times frustrating to not really know how to make things interactive, but I think now it’s good that I took the time scratching my head to be able to come up with that stuff on my own, unlike programming or wiring that I can just look up.  Whining about that’s like asking my soccer coach not to yell at me because it makes me feel bad, not that I play soccer but if I did I think the coach would yell at me.  Anyways the point is education isn’t easy.  Stuff isn’t easy to learn.

  So I learned a lot doing what I wanted.  And if that isn’t a reason to be in school, what is?  The awesome meal plan?  Being broke or the lack of sleep?  No.  No and no.  For me it’s classes like this.

April 18, 2008

Washroom Penitentiary

Filed under: Final Project,Gaku Sato — ponkotsu @ 3:24 am

Here is my final state diagram, wiring schematic, and code (though I might change some threshold values).  The code is excessively long and definitely not optimized; it was just the easiest way to understand what was going on so I can more easily debug.  It should be relatively self-explanatory therefore.  The state diagram from which the code was derived is similarly not optimal for the same reason.

And I figured out that the reason the bell & buzzer weren’t going off during the demo was because I turned on the batteries improperly, as in apparently I need to turn on the Arduino last, otherwise it will enter some strange inescapable state-change path.  I don’t have it all figured out but it’s hopefully enough such that the effectiveness of Murphy’s Law won’t be consistent.

HELP REQUEST!
I’m having no luck photographing it and I honestly have no idea how to videoscenario it so if anyone has any suggestions or can offer help it would be greatly appreciated!

[State Diagram & Wiring Schematic]

[Code]

#include

// PINS //
int soapLED_R = 10; // warning light
int soapLED_G = 9;  // indicates soap being dispensed
int soapLED_B = 8;  // standard light [GB=white]
int sinkLED = 11;   // indicates running water [B]

int soapsensor = 0;
int sinksensor = 1;

int toiletswitch = 12; // indicates motion detected [into toilet!]
int flushbutton = 13;
int lockbutton = 7;
int doorswitch = 4;

int signservo = 3;
int locksolenoid = 2;
int speaker = 5;
int bell = 6;

Servo sign;

// STATES //
int State = 0;
const int Blank = 0;
const int Locked = 1;
const int Wash = 2;
const int LockWash = 3;
const int Flush = 4;
const int Toilet = 5;
const int DUnlock = 6;
const int DLeaving = 7;
const int DSoap = 8;
const int DRinse = 9;
const int Clean = 10;
const int CLeaving = 11;
const int TUnlock = 12;
const int TLeaving = 13;
const int TSoap = 14;
const int TWater = 15;

int LockState = 0;
const int Auto = 0;
const int Manual = 1;

// OUTPUT CONDITIONS //
int Reward = 0;
const int Off = 0;
const int On = 1;
int Buzzer = 0;
int Sign = 0;
const int Bl_Bl = 125; // in: blank   out: blank
const int Wa_Bl = 107; // in: wash    out: blank
const int Wa_Di = 87;  // in: wash    out: dirty
const int Ri_Bl = 68;  // in: rinse   out: blank
const int Fl_Bl = 51;  // in: flush   out: blank
const int Fl_Fl = 31;  // in: flush   out: flush
const int Th_Cl = 13;  // in: thanks  out: clean!
int Soap = 0;
const int White = 0;  // standard light
const int Red = 1;    // warning light
const int Green = 2;  // indicates soap being dispensed
int Sink = 0;
int Lock = 0;

// ANALOG INPUT THRESHOLDS //
int soapmin = 30;
int soapmax = 100;
int sinkmin = 100;
int sinkmax = 300;

// OTHER //
int lockbuttonpress = 0;
int dooropentime = 0;
int sinkontime = 0;

void setup()
{
  Serial.begin(9600);
 
  pinMode(soapLED_R, OUTPUT); // digital
  pinMode(soapLED_G, OUTPUT); // digital
  pinMode(soapLED_B, OUTPUT); // digital
  pinMode(sinkLED, OUTPUT);   // digital
  pinMode(soapsensor, INPUT); // analog
  pinMode(sinksensor, INPUT); // analog
  pinMode(toiletswitch, INPUT);  // digital
  pinMode(flushbutton, INPUT);   // digital
  pinMode(lockbutton, INPUT);    // digital
  pinMode(doorswitch, INPUT);    // digital: LOW when closed, HIGH when open
  pinMode(signservo, OUTPUT);    // digital PWM
  pinMode(locksolenoid, OUTPUT); // digital
  pinMode(speaker, OUTPUT);      // digital
  pinMode(bell, OUTPUT);         // digital
 
  State = Blank;
  LockState = Auto;
  Reward = Off;
  Buzzer = Off;
  Sign = Bl_Bl;
  Soap = White;
  Sink = White;
  Lock = Off;
 
  lockbuttonpress = 0;
  dooropentime = 0;
  sinkontime = 0;
 
  sign.attach(signservo);
  sign.setMaximumPulse(2400);
  sign.setMinimumPulse(544);
  sign.write(Bl_Bl);
}

void loop()
{
  // SWITCH STATES //
  switch(State)
  {
    case Blank:
      if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
      { lockbuttonpress=1; State=Locked; }
      if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
      if(analogRead(soapsensor)1000) {sinkontime=0; State=Clean;} }
      if(analogRead(sinksensor)>sinkmax) {sinkontime=0;}
      if(digitalRead(flushbutton)==HIGH) {State=Flush;}
      if(digitalRead(toiletswitch)==HIGH) {State=Toilet;}
      break;
    case Flush:
      if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH)
      { lockbuttonpress=1; State=DUnlock;}
      if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
      if(digitalRead(doorswitch)==HIGH)
      { dooropentime=millis(); State=DLeaving; }
      if(analogRead(soapsensor)1000) {dooropentime=0; State=Blank;}
      if(analogRead(soapsensor)1000) {sinkontime=0; State=Clean;} }
      if(analogRead(sinksensor)>sinkmax) {sinkontime=0;}
      if(digitalRead(flushbutton)==HIGH) {State=Flush;}
      if(digitalRead(toiletswitch)==HIGH) {State=Toilet;}
      break;
    case DRinse:
      if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH)
      { lockbuttonpress=1; State=DUnlock;}
      if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
      if(digitalRead(doorswitch)==HIGH)
      { dooropentime=millis(); State=DLeaving; }
      if(analogRead(soapsensor)1000)
      { dooropentime=0; State=Blank;}
      break;
    case TUnlock:
      if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
      { lockbuttonpress=1; State=Toilet; LockState=Manual; }
      if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
      if(digitalRead(doorswitch)==HIGH) {dooropentime=millis(); State=TLeaving;}
      if(analogRead(soapsensor)1000) {dooropentime=0; State=Blank;}
      if(analogRead(soapsensor)

April 10, 2008

URBI Studio

Filed under: 1: Post Something Interesting,Gaku Sato — ponkotsu @ 1:51 pm

http://www.gostai.com/studio.html

This is fantastic.  It’s hard to explain.  It’s basically a prototyping framework.  Check it out.

– You can graphically create a state diagram and it’ll convert the logic to code automatically.  Each state/node has code in it to execute and you can obviously set the conditions for state change and such.  All this is dynamic (realtime & pause/resumable) and you can set nodes within nodes.  This executes in exactly the same way it would had you coded all this manually, as I’ve been having to do.
– You can sequence motion graphically as well as record motion for repeat.  Again, code is automatic.  So if you want the camera to pan left<—>right at various speeds, it would be insanely simple.
– You can create a control panel with specified widgets to control things.  This is also dynamic.  You can use a slider gui to manually control a servo or something.
– It also has its own parallel-execution language but it can interface with other programs as in it can be used in conjunction with some other coding structure.

It’s really hard to explain in words.  I met with a guy from URBI that demoed (sp?) it for us using an Aibo and it really made everything from control/actuation to debugging to editing incredibly simple, visible, and IMMEDIATE.

Other logic/control gui programs may already be out there that I totally don’t know about, but this one looked excellent.  If no one else, I really recommend Mark and Jet check it out!

March 27, 2008

light-aiming turret [related work]

Filed under: Final Project,Gaku Sato — ponkotsu @ 2:36 am

TECHNOLOGY

Light-Tracking Wheel
<http://www.youtube.com/watch?v=Y5qi711PRbI>
<http://www.physicsforums.com/showthread.php?p=1659156>
The basic control scheme for this device is the same as that intended for the turret control.  It rotates the wheel in the direction of the photosensor with the higher reading.  The movement is unfortunately very twitchy, and aside from the obvious reasons, it may be due to the large light source.

Sunlight-Tracking System
<http://www.wipo.int/pctdb/en/wo.jsp?wo=2006131028>
This system tracks sunlight in a similar fashion (by analyzing the difference between two separately located sensors).  It addresses the issue of having an incredibly large light source (the sun) is by filtering the light through a “microhole”.

Fuzzy Logic Light Tracker
<http://books.google.com/books?id=m8eVNWGnt5YC&pg=PA130&lpg=PA130&dq=light-tracker&source=web&ots=ItpZCLviYR&sig=L3CG8S0FvgupBvb0mkkeYz5FcXg&hl=en#PPA131,M1>
This is a device that accurately aims at light albeit in a narrow range with an ingenious light-blocking vane between the input sensors to exaggerate the light difference.

Optical Guidance System
<http://www.patentstorm.us/patents/6629028.html>
still decyphering…

Laserpointer-Tracking Program
<http://www.wipo.org/pctdb/en/wo.jsp?wo=2006085580>
still decyphering…
ENTERTAINMENT

Airsoft RC Tank
<http://www.hobbytron.com/AirsoftRCType90BattleTank.html>
320° turret (20° height) mounted on RC airsoft tank with 25m firing range and accurate 1/24-scale design!!

USB Missile Launcher
<http://www.thinkgeek.com/geektoys/warfare/8bc4/>
This is a stationary 180° turret (45° height) controlled by a computer via USB.

wash your hands v2

Filed under: 8: State Machine,Gaku Sato — ponkotsu @ 12:38 am

This is my bathroom rig.  It annoyingly advocates sanitation by locking the door when it senses a flush until it determines that the occupant has washed his/her hands.

wyh-circuit.jpg

The black button on the right is the flush button.  Once that is pressed, the “wash your hands” LED blinks and the door locks via a solenoid deadbolt (behind protodoor).  The occupant’s intent to leave is signified by the doorknob switch (optimally a proximity sensor so no touching is necessary).  Initially it would re-remind the occupant to “wash your hands.”  If the water, which is represented by the potentiometer faucet, is turned more than a specified min threshold, the system registers that the occupant has rinsed his/her hands, but not washed them.  Pushing the which soap button tells the system that soap has been dispensed, but unless the water is running after that, it determines that the occupant is trying to trick the system!  Once the occupant has properly washed, the door unlocks and the “Thanks” LED blinks.

wash your hands!

wyh-statediagram-v2.jpg

int flushpin = 12;
int soappin = 11;
int waterpin = 5;
int lockpin = 8;
int doorpin = 2;
int thankspin = 7;
int washpin = 6;
int rinsepin = 4;
int fakepin = 3;
int state = 0; // 0=off, 1=on, 2=rinse, 3=soap

void setup()
{
Serial.begin(9600);
pinMode(flushpin, INPUT);
pinMode(soappin, INPUT);
pinMode(waterpin, INPUT);
pinMode(lockpin, OUTPUT);
pinMode(doorpin, INPUT);
pinMode(thankspin, OUTPUT);
pinMode(washpin, OUTPUT);
pinMode(rinsepin, OUTPUT);
pinMode(fakepin, OUTPUT);
digitalWrite(lockpin, LOW);
digitalWrite(thankspin, LOW);
digitalWrite(washpin, LOW);
digitalWrite(rinsepin, LOW);
digitalWrite(fakepin, LOW);
}

void loop()
{
if(digitalRead(flushpin)==HIGH) {blink(washpin); state=1;}
if(state>0) {digitalWrite(lockpin, HIGH);}
if(state==1 && digitalRead(doorpin)==HIGH) {blink(washpin);}
if(state==1 && analogRead(waterpin)<800) {state=2;} if(state==1 && digitalRead(soappin)==HIGH) {state=3;} if(state==2 && digitalRead(doorpin)==HIGH) {blink(rinsepin); state=1;} if(state==2 && digitalRead(soappin)==HIGH) {state=3;} if(state==3 && digitalRead(doorpin)==HIGH) {blink(fakepin); state=1;} if(state==3 && analogRead(waterpin)<800) { digitalWrite(lockpin, LOW); blink(thankspin); state=0; } } void blink(int pin) { digitalWrite(pin, HIGH); delay(100); digitalWrite(pin, LOW); delay(100); digitalWrite(pin, HIGH); delay(100); digitalWrite(pin, LOW); delay(100); digitalWrite(pin, HIGH); delay(100); digitalWrite(pin, LOW); } [/sourcecode]

March 25, 2008

vehicle-mounted light-aiming turret

Filed under: Final Project,Gaku Sato — ponkotsu @ 8:07 am

For the final project, I propose a light-chasing application similar to my midterm project (lightchaser).  This time, it will be an auto turret that aims at light.  A 360deg servo will be the base platform onto which the firing mechanism will be mounted.  There will be 4 light sensors affixed at 90degs facing outward.
turret2.pdf

My primary objective is to be able to shoot down various stationary targets from a fixed position (as drawn).  Once that is working accurately and fast enough, my secondary objective is to be able to shoot down moving targets.  Ultimately I will mount the turret on an RC car and shoot down target cars (also RC).If things go magically well, I want to make two of these turret cars which could play Tag by alternating being the light source.  It would alternate when the target car sensed that it had been hit, which I’m not sure how to do, nor do I know how to send that “hit” signal to the chaser car.  So for this I think I would need some type of wireless signal.  I don’t think this would be possible by the end of the semester, so I also had the idea of mounting the turret onto the lightchaser (will be changed to IR lightchaser), and that may be better not only for feasibility, but for entertainment purposes, since it is intended to be a toy.

From working on the lightchaser I know that photoresistor inputs are tricky (especially in calibration when comparing multiple sensor inputs) so I may use pairs of sensors.  Also, a small solenoid is an inadequate firing mechanism, so I will opt for a larger one or a different assembly altogether.

March 20, 2008

Wash Your Hands

Filed under: 8: State Machine,Gaku Sato — ponkotsu @ 2:15 am

Indeed, wash your hands.  I secretly hate when people don’t wash their hands, so this is a system that would automatically engage a door lock if you try to leave the bathroom without washing your hands.  The state diagram is as follows:

 wash-your-hands.jpg

Next Page »

Blog at WordPress.com.