Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

12 Lauf der Dinge

8. Dezember 2011

YouTube Preview Image Als Ausgangsmaterial diente der Film "Der Lauf der Dinge" von Fischli und Weiss von 1987 und davon inspirierte (und nachgemachte) Installationen und Werke. Ursprünglich wollten wir uns mit Wasser und Wind beschäftigen; als Input wird eine Windmaschine angeworfen, welche dann ein Segelboot in Gang setzt. Von dieser Idee gingen wir weiter über Origamiobjekte, welche mit Drähten verändert werden können. Leider sind die Drähte zu spät eingetroffen und konnten so nicht berücksichtigt werden. So haben wir unser Konzept in Richtung Papier und Zugkraft weiterentwickelt, was unserer Ursprungsidee doch wieder nahe kommt. Nach vielen Testversuchen mit verschiedenen Papierfliegern fanden wir den idealen Flieger, nämlich das Modell "Nick's Paper Airplane" - selten so einen guten Papierflieger gesehen. Der Input der vorangehenden Gruppe stösst den Servo an, welcher das Gewicht unseres Fliegers trägt. Sobald das Gewicht mit Schwung gelöst ist, wird der Flieger mit Zugkraft hochgezogen und fliegt auf sein Ziel zu: eine schräggestellte "Landerampe", auf welche ein Piezosensor angeschlossen ist. Dieses Piezo gibt den Impuls dann entsprechend an die folgende Gruppe weiter. Bei Start und Ziel werden zudem noch schöne Lichtinstallatiönchen ausgelöst.

Technisches

Die Funktion der Startrampe ist folgendermassen aufgebaut: Im schwarzen Trichter, welcher die Pinpong Kugel auffängt ist ein Lichtsensor verbaut, welcher ab einem gewissen Wert die Startrampe in Gang setzt. Nach der LED Animation, welcher über 2 seriell geschaltete Shift-Register gesteurt wird, setzt sich der Servo in Bewegung und läst so die Schlaufe los. Durch das Gewicht wird die Schlaufe nach vorne geszogen uns reist so den Papierflieger mit. Stösst der Papierflieger auf die Landebahn, wird der Impuls von einem Piezo-keramischen Sensor aufgefangen und mittels zwei Drähten an das Arduino der nächsten Grupper weitergeleitet.

Code Startrampe:

// Includes
#include <Servo.h>

// Pins
#define SERVO 5
#define LIGHT 0
#define REG_LATCH 8
#define REG_CLOCK 12
#define REG_DATA 11

// Constants
#define DEBOUNCE 1000
#define ANIMATION_PACKS 40
#define ANIMATION_DELAY_START 200
#define REWIND_DELAY 2000
#define LIGHT_TRESHHOLD 30

// Objects
Servo servo;

// Variables
boolean hasReleasedOnce = false;
unsigned long lastReadFromLight = 0;
boolean doRelease = false;
boolean doRewind = false;
boolean doAnimate = false;
unsigned long releaseTime = 0;
int animationDelay = 0;
int animationPacks = 0;
boolean animateRow = true;
unsigned long lastAnimationChange = 0;
int animationStep = 0;

// Rows
int row1a = B00001101;
int row1b = B00000000;
int row2a = B00100010;
int row2b = B00000010;
int row3a = B11000000;
int row3b = B00000001;
int row4a = B00010000;
int row4b = B00000000;

// Cols
int col1a = B01010001;
int col1b = B00000010;
int col2a = B00111000;
int col2b = B00000001;
int col3a = B10010110;
int col3b = B00000000;

// Off
int allOn = B11111111;
int allOff = B00000000;

// Setup Routine
void setup()
{
  // Setup Serial
  Serial.begin(9600);
  Serial.println("SETUP");
  
  // Attach Servo
  servo.attach(SERVO);
  
  // Rewind Servo
  servo.write(0);
  Serial.println("REWIND SERVO TO 0");
  
  // Prepare Shift Register
  pinMode(REG_LATCH,OUTPUT);
  pinMode(REG_CLOCK,OUTPUT);
  pinMode(REG_DATA,OUTPUT);
  
  // Clear Shift Register
  off();
}

void loop()
{
  // Check Button
  if(millis() - lastReadFromLight > DEBOUNCE && analogRead(LIGHT) < LIGHT_TRESHHOLD && !doAnimate && !hasReleasedOnce)
  {
    Serial.println("HAS BUTTON -> START ANIMATION");
    doAnimate = true;
    lastReadFromLight = millis();
    animationDelay = ANIMATION_DELAY_START;
    animationStep = 0;
    animationPacks = 0;
  }
  
  // Check for Animation
  if(doAnimate)
  {
    // In Animation?
    if(animationPacks < ANIMATION_PACKS)
    {
      // New Change?
      if(millis() - lastAnimationChange > animationDelay)
      {
        // Set
        lastAnimationChange = millis();
        
        // Debug
        Serial.println("CHANGE ANIMATION");
        
        // Is Animating Row?
        if(animateRow)
        {
          switch(animationStep)
          {
            case 1: row1(); break;
            case 2: row2(); break;
            case 3: row3(); break;
            case 4: row4(); break;
          }
          
          if(animationStep == 4) {
            Serial.println("SPEEDUP ANIMATION");
            animationStep = 0;
            animationDelay -= 5;
            animationPacks++;
            animateRow = false;
          }
          else
          {
            animationStep++;
          }
        }
        else
        {
          switch(animationStep)
          {
            case 1: col1(); break;
            case 2: col3(); break;
            case 3: col2(); break;
          }
          
          if(animationStep == 3) {
            Serial.println("SPEEDUP ANIMATION");
            animationStep = 0;
            animationDelay -= 5;
            animationPacks++;
            animateRow = true;
          }
          else
          {
            animationStep++;
          }
        }
      }
    }
    else
    {
      Serial.println("FINISH ANIMATION");
      on();
      doAnimate = false;
      doRelease = true;
      releaseTime = millis();
    }
  }
  
  // Check for Release
  if(doRelease)
  {
    // Release Servo
    Serial.println("RELEASE SERVO");
    servo.write(180);
    doRelease = false;
    doRewind = true;
  }
  
  // Check for Rewind
  if(millis() - releaseTime > REWIND_DELAY && doRewind)
  {
    // Rewind Servo
    Serial.println("REWIND SERVO");
    servo.write(0);
    doRewind = false;
    off();
    hasReleasedOnce = true;
  }
}

void row1()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row1b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row1a);
  digitalWrite(REG_LATCH,1);
}

void row2()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row2b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row2a);
  digitalWrite(REG_LATCH,1);
}

void row3()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row3b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row3a);
  digitalWrite(REG_LATCH,1);
}

void row4()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row4b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,row4a);
  digitalWrite(REG_LATCH,1);
}

void off()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,allOff);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,allOff);
  digitalWrite(REG_LATCH,1);
}

void on()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,allOn);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,allOn);
  digitalWrite(REG_LATCH,1);
}

void col1()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col1b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col1a);
  digitalWrite(REG_LATCH,1);
}

void col2()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col2b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col2a);
  digitalWrite(REG_LATCH,1);
}

void col3()
{
  digitalWrite(REG_LATCH,0);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col3b);
  shiftOut(REG_DATA,REG_CLOCK,MSBFIRST,col3a);
  digitalWrite(REG_LATCH,1);
}

Landebahn Code:

// Pins
#define PIEZO 0
#define SOUND 6
#define OUT 2
#define LED1 8
#define LED2 10

// Constants
#define TRESHHOLD 25
#define BLINK_SPEED 500

// Variables
unsigned long lastLEDChange = 0;
boolean isActive = false;
boolean isOn = false;

// Setup Routine
void setup()
{
  // Set Pin Modes
  pinMode(SOUND,OUTPUT);
  pinMode(OUT,OUTPUT);
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  
  // Default
  digitalWrite(OUT,LOW);
}

// Loop Routine
void loop()
{
  // Read
  int in = analogRead(0); 
  
  // Check
  if(in > TRESHHOLD)
  {
    // Set Active
    isActive = true;
  }
  
  // Check for Activeness
  if(isActive)
  { 
    // Write Out
    digitalWrite(OUT,HIGH);
    
    // Set LED's
    digitalWrite(LED1,HIGH);
    digitalWrite(LED2,HIGH);
    
    // Play Sound
    tone(SOUND,110);
    delay(100);
    tone(SOUND,220);
    delay(100);
    tone(SOUND,440);
    delay(100);
    tone(SOUND,880);
    delay(100);
    noTone(SOUND);
    delay(2000);
    
    // Write Out
    digitalWrite(OUT,LOW);
    
    // Turn Off
    isActive = false;
  }
  else
  {
    if(millis() - lastLEDChange > BLINK_SPEED)
    {
      if(isOn)
      {
        digitalWrite(LED1,HIGH);
        digitalWrite(LED2,LOW);
        isOn = false;
      }
      else
      {
        digitalWrite(LED1,LOW);
        digitalWrite(LED2,HIGH);
        isOn = true;
      }
      
      lastLEDChange = millis();
    }
  }
}