Der Icarus-Roboter

Für die beiden Vorlesungen We make machines not art von Darsha Hewitt und Tangible Programming - An Introduction von Johannes Deich baute ich einen einfachen Roboter, der ständig vor dem Licht flieht.

Ich verband alles, was ich bis dahin über Elektronik-Grundlagen, die Programmierung eines
Arduino-Boards, sowie 3D-Druck gelernt hatte, um meine erste Maschine zu konstruieren.

 

Rahmen

icarus_render
Um eine robuste Arbeitsgrundlage zu erhalten, beschloss ich, den Rahmen in einer 3D-Umgebung zu modellieren und ihn dann mithilfe eines 3D-Druckers zu materialisieren. Dies stellte mein erstes komplexes Druckmodell dar und brachte mir den Produktionsprozess aufwändigerer Druckprojekte näher. Ich entwarf das Modell außerdem mit größtmöglicher Flexibilität, um es auch für zukünftige Projekte verwenden zu können.

Der Rahmen sollte die Basis für jegliche beliebige biaxiale Maschine bieten, mit genug Platz für eine gewöhnliche Steckplatine, sowie Batterien. Er hält die vier Motoren möglichst nah am Boden fest an ihrem Platz. Ich entschied mich außerdem dazu, das Modell mit Lego-Kompatibilität auszustatten, für den Fall, dass ich es mit einer weiteren Platine oder anderen Strukturen ausbauen möchte.

Räder

Da ein Bewegungsapparat mit einer Lenkvorrichtung elektronisch zu schwer zu kontrollieren gewesen wäre, entschied ich mich für eine bidirektionale, den orthogonalen Seitenachsen folgende Fortbewegungsform – via Allseitenräder. Allseitenräder besitzen um ihren Kreisumfang angeordnete, kleine Scheiben, die senkrecht zur Drehrichtung des Rades orientiert sind. Dies erlaubt den Antrieb in ihre natürliche Drehrichtung, während sie zusätzlich seitlich frei rollen können.
Nach ein paar Versionen mit Kinderkrankheiten entwarf ich schließlich ein funktionierendes Design, indem ich die Räder (unter anderem) möglichst klein gestaltete. Die seitliche Bewegung wird durch kleine, hölzerne Kügelchen ermöglicht, die auf einem gespannten Draht sitzen.

Schaltkreise

Für die Konzeption des Schaltkreises unterteilte ich die Funktionen in grundsätzliche Module: Ich benötige vier Fotozellen um die Lichtstärke in jeder Richtung zu messen; daher vier Eingänge, die ihren Widerstand messen. Außerdem brauche ich zwei PWM-gesteuerte Ausgänge um die Motorgeschwindigkeit zu kontrollieren – einen pro Achse. Die PWMs bespeisen jeweils einen Transistor, was mir die Nutzung einer externen Stromquelle für die Motoren ermöglichte (die Motoren sind hungrig nach 12V). Die Drehrichtung der Motoren wird durch ein Relais pro Achse gesteuert, jeweils mit Hilfe eines DPDT-Schalters; damit werden zwei weitere Arduino-Ausgänge benötigt. Schließlich wollte ich noch einen einfachen Potentiometer einarbeiten, der es mir ermöglicht, eine manuelle Resistenz einzustellen. Diese kann mit der Resistenz der Fotozellen verglichen werden, womit ich den Roboter per Hand an die momentane Lichtsituation des Raumes anpassen kann.

Code

Der code ist sehr einfach: Er misst die Eingangssignale des Schaltkreises, vergleicht sie, berechnet die resultierenden Geschwindigkeiten und bespeist die jeweiligen Ausgänge für Richtung und PWM.

Code: Icarus.arduino
//  Define pins on Arduino board
int motorXupPin = 10;
int motorYupPin = 11;
int motorXdirPin = 12;
int motorYdirPin = 13;

int photoYtopPin = 0;
int photoXrightPin = 1;
int photoYbottomPin = 2;
int photoXleftPin = 3;

int potiPin = 5;

//  Variables to store pure input
int photoYtop;
int photoXright;
int photoYbottom;
int photoXleft;

int lightX;
int lightY;
int poti;

//  Setting up variables to store speed
int motorXspeed;
int motorYspeed;

//  Define minimum speed and difference multiplicator
int speedBase = 200;
int speedMod = 15;

//  Setup
void setup(){
  Serial.begin(9600);
  pinMode(motorXupPin, OUTPUT);
  pinMode(motorYupPin, OUTPUT);
  pinMode(motorXdirPin, OUTPUT);
  pinMode(motorYdirPin, OUTPUT);
  pinMode(photoXrightPin, INPUT);
  pinMode(photoYbottomPin, INPUT);
  pinMode(photoXleftPin, INPUT);
  pinMode(potiPin, INPUT);
}

//  Loop
void loop(){

//  Write poti factor
  poti = analogRead(potiPin);
  
//  Measure and store light
  photoYtop = analogRead(photoYtopPin);
  photoXright = analogRead(photoXrightPin);
  photoYbottom = analogRead(photoYbottomPin);
  photoXleft = analogRead(photoXleftPin);
  lightX = max(photoXright, photoXleft);
  lightY = max(photoYtop, photoYbottom);

//  Y: See if there is enough light to trigger movement
  if (lightY <= poti){ analogWrite(motorYupPin, LOW); }
  if (lightY > poti){

// Y: Power up motors with PWM based on light comparison
    motorYspeed = min(speedBase + 
                    (abs(photoYbottom - photoYtop)
                        / speedMod), 255);
    analogWrite(motorYupPin, motorYspeed); 
   
//  Y: Change motor direction by triggering relays
    if (photoYtop >= photoYbottom){
      digitalWrite(motorYdirPin, HIGH);
      }
    if (photoYtop < photoYbottom){
      digitalWrite(motorYdirPin, LOW);
      }
  }

//  X: See if there is enough light to trigger movement
  if (lightX <= poti){ analogWrite(motorXupPin, LOW); }
  if (lightX > poti){

// X: Power up motors with PWM based on light comparison
    motorXspeed = min(speedBase +
                    (abs(photoXright - photoXleft)
                        / speedMod), 255);
    analogWrite(motorXupPin, motorXspeed);

//  X: Change motor direction by triggering relays
    if (photoXleft >= photoXright){
      digitalWrite(motorXdirPin, HIGH);
      }
    if (photoXleft < photoXright){
      digitalWrite(motorXdirPin, LOW);
      }
  }
}

Die fertige Maschine

IMG_5420

Der nächsten (und wahrscheinlich letzte) Schritt ist, eine mobile Stromquelle zu finden, die eine kabellose Fortbewegung ermöglicht. Sobald der Roboter von seinem Kabel befreit ist, kann ich mit den endlosen Input-Möglichkeiten – nicht nur Licht – experimentieren, um ihn zu kontrollieren.

Bevor ich anfing mit dem Arduino zu arbeiten, funktionierte der Roboter-Prototyp auf rein analog elektronischer Basis. Hier ist eine frühe Demonstration davon (im Video kann man außerdem eines der ersten Allseitenrad-Designs erkennen; dieses war noch viel zu groß, was die zur Bewegung notwendige Beschleunigung unmöglich machte):

Komplette Dokumentation für 'We make machines not art' lesen (englisch) Komplette Dokumentation für 'Tangible Programming' lesen (englisch)