Das Gegenteil des Perpetuum Mobile?
Claude Elwood Shannon baute 1950 die „ultimate machine“, ein Kästchen mit einem Schalter, den eine mechanische Hand wieder auf „aus“ stellte, nachdem man ihn eingeschaltet hatte.

Google: Useless Box (57.900.000) - Ultimate Machine (50.700.000 ) - Leave me alone Box (47.700.000) - Useless Machine(34.300.000) - Leave me alone machine (27.000.000)

 

Schaltplan

 

Bauteile

Bauteile Menge Preis [€] Lieferant Summe [€]
Holzbox 1 6,00 Kaufland 6,00
Modelcraft Standard-Servo RS 2 2 5,95 Conrad 11,90
Kippschalter 1 2,42 Conrad 2,42
Batterie 9V 1 1,99 Conrad 1,99
Batterieclip 1 0,13 Reichelt 0,13
Arduino UNO (Atmel ATmega328) 1 4,00 Watterott 4,00
Standardquarz 16 MHz 1 0,15 Reichelt 0,15
Spannungsregler 7805 1 0,24 Reichelt 0,24
Kondensator 100uF 2 0,04 Reichelt 0,08
Kondensator 22pF 2 0,05 Reichelt 0,10
Kondensator 100nF 2 0,05 Reichelt 0,10
Kondensator 1000uF 1 0,25 Reichelt 0,25
Transistor PNP MPSA64 1 0,06 Reichelt 0,06
Transistor NPN BV547C 1 0,06 Reichelt 0,06
Widerstand 10KΏ 3 0,03 Reichelt 0,09
Widerstand 4,7KΏ 1 0,03 Reichelt 0,03
Widerstand 1KΏ 1 0,03 Reichelt 0,03
Widerstand 150Ώ 1 0,03 Reichelt 0,03
Stiftleiste 1 0,10 Reichelt 0,10
Streifenrasterplatine 50x100 1 0,49 Reichelt 0,49
LED blau 1 0,16 eBay 0,16
        28,44

 

Platinen

   

 

Bilder

      

 

Sourcecode

 // Arduino 1.01

include <Servo.h>
include <Bounce.h>
define MINARMDEG 0
define MAXARMDEG 84
define MINLIDDEG 0
define MAXLIDDEG 21
define WAIT 4
Servo servoArm; // Servo Object for Arm Servo servoLid; // Servo Object for Lid

const int ledPin = 13; // LED Pin const int powerPin = 2; // Power Pin const int servoArmPin = 4; // Servo Arm const int servoLidPin = 19; // Servo Lid const int switchMaster = 3; // Master Switch const int switchFun = 8; // Switch between Standard and Fun int armPos = MAXARMDEG; // position of arm int lidPos = MAXLIDDEG; // position of lid int valSwitchFun = HIGH; // Value of the fun switch int valSwitch = HIGH; // Value of the master switch int play; // animation int first = 0; // first animation (animation has not been interrupted)

Bounce bouncerMaster = Bounce(switchMaster, 10);


void setup() {

 // Read fun switch
 pinMode(switchFun, INPUT);
 int valSwitchFun = digitalRead(switchFun);
 if (valSwitchFun == HIGH) { // fun mode: get random animation
   randomSeed(analogRead(0));
   play = random(0, 11);
 } else {
   play = 8;        // standard mode: set standard animation
 }
 pinMode(powerPin, OUTPUT);
 digitalWrite(powerPin, HIGH);
 pinMode(ledPin, OUTPUT);
 digitalWrite(ledPin, LOW);
 pinMode(switchMaster, INPUT);
 servoArm.attach(servoArmPin);  // attache servo to servo object 
 servoArm.write(0);
 servoLid.attach(servoLidPin);  // attache servo to servo object 
 servoLid.write(0);
}


void loop() {

 bouncerMaster.update();
 valSwitch = bouncerMaster.read(); // get master switch position
 if (valSwitch == HIGH)
 {
   if (first == 1) { // run standard animation if first animation has been interrupted
     play = 0;
   }
   armPos = MAXARMDEG;
   lidPos = MAXLIDDEG;
   switch(play) { // opening animation
   case 0: // Standard
     moveLid(lidPos, 0);
     moveArm(armPos, 0);
     break;
   case 1:
     moveLid(lidPos, 20);
     moveArm(42, 50);
     moveArm(armPos, 0);
     break;
   case 2:
     moveLid(lidPos, 0);
     moveArm(42, 0);
     moveArm(armPos-14, 50);
     moveArm(armPos+14, 0);
     break;
   case 3:
     moveLid(lidPos, 0);
     moveArm(armPos, 0);
     break;
   case 4:
     moveLid(lidPos, 50);
     myDelay(500);
     moveLid(0, 0);
     myDelay(500);
     moveLid(lidPos+10, 0);
     moveArm(42, 50);
     moveArm(armPos, 0);
     break;
   case 5:
     moveLid(lidPos, 0);
     moveArm(armPos, 0);
     break;
   case 6:
     moveLid(lidPos, 50);
     moveArm(armPos-14, 50);
     moveArm(armPos+14, 0);
     break;
   case 7:
     moveLid(lidPos, 0);
     moveArm(armPos-7, 0);
     moveArm(0, 0);
     moveLid(0, 0);
     myDelay(1000);
     moveLid(lidPos, 0);
     moveArm(42, 50);
     moveArm(armPos+7, 0);
     break;
   case 8:
     moveLid(lidPos, 0);
     myDelay(500);
     moveArm(armPos, 0);
     break;
   case 9:
     moveLid(lidPos, 5);
     myDelay(300);
     moveLid(0, 4);
     myDelay(200);
     moveLid(14, 4);
     moveLid(0, 4);
     moveLid(14, 4);
     moveLid(0, 4);
     moveLid(14, 4);
     moveArm(armPos, 0);
     break;
   case 10:
     moveLid(14, 4);
     myDelay(100);
     moveLid(0, 0);
     myDelay(1000);
     moveLid(lidPos, 0);
     moveArm(armPos, 0);
     break;
   }
 }
 else // closing animation
 {
   first = 1;
   armPos = MINARMDEG;
   lidPos = MINLIDDEG;
   switch(play) {
   case 0: // Standard
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 1:
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 2:
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 3:
     myDelay(3000);
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 4:
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 5:
     moveArm(60, 2);
     moveArm(84, 2);
     moveArm(60, 2);
     moveArm(84, 2);
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 6:
     moveArm(armPos, 50);
     moveLid(lidPos, 0);
     delay(500);
     break;
   case 7:
     moveArm(armPos, 50);
     moveLid(lidPos, 0);
     break;
   case 8:
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 9:
     moveArm(armPos, 0);
     moveLid(lidPos, 0);
     break;
   case 10:
     moveArm(60, 50);
     moveArm(armPos, 0);
     moveLid(lidPos-14, 0);
     break;
   }
 }
 valSwitch = digitalRead(switchMaster);
 // Power off
 if (servoArm.read() == MINARMDEG && servoLid.read() == MINLIDDEG && valSwitch == LOW) {
   digitalWrite(powerPin, LOW);
   for(;;); // for debugging with power over USB-to-serial-adapter
 }
}

// move arm to position within the specified time void moveLid(int degree, int speed) {

 int curDegree = servoLid.read();
 while (curDegree != degree) {
   if (curDegree < degree) {
     curDegree++;
   }
   else {
     curDegree--;
   }
   servoLid.write(curDegree);
   delay(WAIT + speed);
   int curVal = digitalRead(switchMaster);
   if (curVal != val) {
     break;
   }
 } 
}

// move lid to position within the specified time void moveArm(int degree, int speed) {

 int curDegree = servoArm.read();
 while (curDegree != degree) {
   if (curDegree < degree) {
     curDegree++;
   }
   else {
     curDegree--;
   }
   servoArm.write(curDegree);
   delay(WAIT + speed);
   int curVal = digitalRead(switchMaster);
   if (curVal != val) {
     break;
   }
 } 
}

// delay (can be interrupted by manual switch change) void myDelay(int msec) {

 long myTime = 0;
 do {
   delay(1);
   myTime++;
   int curVal = digitalRead(switchMaster);
   if (curVal != val) {
     break;
   }
 } 
 while(myTime <= msec);
}

 

Video