Der CarduBot ist ein einfacher Roboter mit 2 Rädern, dessen Chassis sich einfach aus einem Stück Karton zurechtschneiden lässt. Der CarduBot Line Follower (Linienverfolger) kann in dieser einfachsten Version mit nur 2 Lichtsensoren einer (z.B. mit schwarzem Isolierband) am Boden aufgeklebten Linie folgen.

Derzeit ruckelt der Bot noch recht heftig. Die aktuelle Version des Arduino Sketch verwendet einen reinen On/Off-Algorithmus, d.h. bei einer festgestellten Abweichung von der Linie wird diese direkt und mit voller Kraft wieder angesteuert. Ein neuer Arduino Sketch mit ansatzweiser Verwendung eines PID-Regler-Algorithmus ist in Arbeit, bei nur 2 Lichtsensoren ist das aber schwierig, da zu wenig Informationen über die Position der Linie vorliegen.

Eine Übersicht über Hardware und Software des CarduBot:

Und hier eine längere Testfahrt:

Derzeit bin ich noch dabei, verschiedene Chassis- und Aufbauvarianten zu testen. Eine genaue Dokumentation samt Vorlagen zum Selbstdrucken- und basteln gibt es in Kürze hier.

Ein genauerer Blick auf den Aufbau des CarduBot Linea genannten Line Followers:

CarduBot - erster Testaufbau
CarduBot Cardboard Arduino Line Follower

Folgende Bauteile werden derzeit benötigt:

– Arduino Uno
– Adafruit Motor Shield v2 (Exp-Tech)
– 2 DC Getriebemotoren, z.B. von Dagu (Exp-Tech)
– 2 passende Räder (Exp-Tech)
– 2 x Sparkfun Line Sensor Digital (Exp-Tech)
– Battery Pack für mind. 4 AA-Batterien
– einige Jumperkabel und ein kleines Breadboard
– Karton, Hartschaumplatte, Laubsägeholz o.ä. für das „Chassis“
– Kleber oder Heißklebepistole
– etwas schwarzes Isolierband für die Linie

Bei den Bauteilen gibt es noch viel Luft für Vereinfachungen, mit denen auch die Kosten (in dieser Version rund 50€) deutlich gesenkt werden können. Ganz ohne Löten geht es derzeit leider noch nicht, das Adafruit Motor Shield und die Line Sensoren erfordern ein paar einfache Lötarbeiten zur Befestigung der Stiftleisten.

Hinweise zum Aufbau:

Das Chassis des CarduBot lässt sich aus einigen Stücken Karton oder Hartschaumplatte einfach zusammenkleben. Ich verwende dazu am liebsten Heißkleber. Die Größe der Grundplatte berechnet man am besten so, dass zwischen den beiden aufgeklebten Getriebemotorenmotoren ein Batteriepack für 4xAA Batterien Platz findet.

Auf die beiden Motoren kann man dann ein weiteres Kartonstück aufkleben, das als Träger für den Arduino Uno samt aufgestecktem Adafruit Motor Shield v2 dient. Diese kann man entweder mit etwas Gummiband befestigen oder sich aus Karton eine kleine Box bauen. Damit der Roboter gut geradeaus fährt, klebt man hinten mittig ein kleine Stütze aus Karton auf, alternativ kann man auch ein Stützrad (Exp-Tech) verwenden.

Die beiden Liniensensoren werden vorne angeklebt, zwischen den Sensoren sollte ca. 2 cm Abstand sein, der Abstand der Sensoren vom Untergrund sollte ca. 8-10mm betragen. Den optimalen Abstand für gute Messwerte kann man über den seriellen Monitor mit ein paar Testmessungen ermitteln.

Die Verkabelung des Bots ist denkbar einfach:

  • 4xAA Batteriepack an den Power-Anschluss des Motor Shield
  • Die beiden Getriebemotoren an die Ports M1 und M2 des Motor Shield. Sollte sich  ein Motor in die falsche Richtung drehen, dann einfach die Anschlusskabel vertauschen.
  • Die beiden Sparkfun Line Sensoren benötigen 5V und GND vom Motor Shield. Die Datenleitungen kommen an die Digitalpins 2 und 3.
  • Dann den folgenden Code aufspielen und über den seriellen Monitor der Arduino IDE einen vernünftigen Wert für die Weiß/Schwarz-Grenze SENSOR_THRESHOLD ermitteln.

 

Der allererste Code für den Line Follower, noch sehr simpel und wackelig:

// CarduBot Linea - Line Follower Prototype - v0.1
// 2015, makerblog.at
 
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
 
// Motor Shield Objekt erzeugen
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Beide Motoren mit den Ports am Shield verbinden
Adafruit_DCMotor *rightMotor = AFMS.getMotor(2);
Adafruit_DCMotor *leftMotor = AFMS.getMotor(1);
 
// Pins für die digitalen Lichtsensoren
int rightSensorPin = 2;
int leftSensorPin = 3;
 
int rightSensorValue = 0;
int leftSensorValue = 0;
 
// Je nach Untergrund den Threshold für die Helligkeit anpassen. Messwerte werden über
// den seriellen Monitor ausgegeben!
const int SENSOR_THRESHOLD = 2000; // > 2000 = black
const int MOTOR_SPEED_FORWARD = 120;
const int MOTOR_SPEED_BACKWARD = 100;
const int MOTOR_SPEED_TURN = 90;
 
void setup() {
 Serial.begin(9600); // set up Serial library at 9600 bps
 Serial.println("CarduBot Linea - Sensor Values");
 
 // Motorshield starten und Motoren initialisieren
 AFMS.begin();
 rightMotor->setSpeed(150);
 rightMotor->run(FORWARD);
 rightMotor->run(RELEASE);
 leftMotor->setSpeed(150);
 leftMotor->run(FORWARD);
 leftMotor->run(RELEASE);
}
 
void loop() {
 
 // Sensorwerte auslesen (ca. zwischen 0 und 3000, je höher desto dunkler)
 rightSensorValue = readLineSensor(rightSensorPin);
 leftSensorValue = readLineSensor(leftSensorPin);
 
 // Debug-Ausgabe am seriellen Monitor
 Serial.print(rightSensorValue);
 Serial.print("; ");
 Serial.println(leftSensorValue);
 
 // Beide Sensoren hell (=schwarze Linie in der Mitte) => geradeaus
 if ((rightSensorValue < SENSOR_THRESHOLD) && (leftSensorValue < SENSOR_THRESHOLD)) {
 driveForward();
 }
 
 // Rechter Sensor dunkel => nach Rechts drehen, damit Linie wieder mittig
 if ((rightSensorValue > SENSOR_THRESHOLD) && (leftSensorValue < SENSOR_THRESHOLD)) {
 turnRight();
 delay(5); 
 }
 
 // Linker Sensor dunkel => nach Links drehen, damit Linie wieder mittig
 if ((rightSensorValue < SENSOR_THRESHOLD) && (leftSensorValue > SENSOR_THRESHOLD)) {
 turnLeft();
 delay(5); 
 }
 
 // Beide Sensoren dunkel (z.B. Stopplinie) = Boxenstopp
 if ((rightSensorValue > SENSOR_THRESHOLD) && (leftSensorValue > SENSOR_THRESHOLD)) {
 stopMotors();
 }
}
 
// Motoransteuerung
void driveForward () {
 rightMotor->run(FORWARD);
 leftMotor->run(FORWARD);
 rightMotor->setSpeed(MOTOR_SPEED_FORWARD);
 leftMotor->setSpeed(MOTOR_SPEED_FORWARD);
}
 
void stopMotors () {
 rightMotor->setSpeed(0);
 leftMotor->setSpeed(0);
 rightMotor->run(RELEASE);
 leftMotor->run(RELEASE);
}
 
void turnRight() {
 rightMotor->setSpeed(MOTOR_SPEED_TURN);
 leftMotor->setSpeed(MOTOR_SPEED_TURN); 
 rightMotor->run(BACKWARD);
 leftMotor->run(FORWARD);
}
 
void turnLeft() {
 rightMotor->setSpeed(MOTOR_SPEED_TURN);
 leftMotor->setSpeed(MOTOR_SPEED_TURN); 
 rightMotor->run(FORWARD);
 leftMotor->run(BACKWARD);
}
 
// Auslesen der Lichtsensoren
int readLineSensor(int sensorPin){
 pinMode( sensorPin, OUTPUT );
 digitalWrite( sensorPin, HIGH ); 
 delayMicroseconds(10);
 pinMode( sensorPin, INPUT );
 long time = micros();
 // schauen wie lange der Input auf HIGH ist, aber max. 3ms
 while (digitalRead(sensorPin) == HIGH && micros() - time < 3000); 
 int diff = micros() - time;
 return diff;
}

Geplante Verbesserungen:

  • Zur sinnvollen Umsetzung einer PID-Regelung (PID = Proportional – Integral – Differential, hört sich komplizierter an als es hier ist) sollten die beiden Line Sensoren durch ein Line Sensor Array, also eine Reihe von 6-8 Sensoren ersetzt werden. Damit ist eine viel flüssigere Verfolgung der Linie möglich.
  • Zur Kostenreduktion könnte das Adafruit Motor Shield durch einen L293D Motortreiber ersetzt werden. Das würde allerdings die Schaltung etwas komplizierter machen.
  • Für die verwendeten Standardkomponenten möchte ich eine Bastelvorlage zum Ausdrucken für die Kartonteile erstellen.

Fragen und Anregungen zum CarduBot am besten hier als Kommentar hinterlassen.

8 thoughts on “CarduBot Linea – einfacher Line Follower Roboter mit Chassis zum Selberkleben

  • 31. Mai 2016 um 15:28
    Permalink

    Was ist aus den geplanten Verbesserungen geworden?
    Hätte großes Interesse am jetzigen Stand.

    Antworten
    • 11. Juni 2016 um 21:35
      Permalink

      Hi, ich bin noch in der Phase der schrittweisen Verbesserungen des CarduBot. In den nächsten Wochen wird das Projekt auf einer eigenen Website umfassend dokumentiert, Info dazu gibts dann natürlich hier :) Danke für das Interesse!

      Antworten
  • 11. Juni 2016 um 12:33
    Permalink

    Hey, wirklich toller Blog, hat mir bei meinem Projekt sehr weitergeholfen.

    Interessieren würde mich aber auch die Verbesserung über einen PID-Regler. Mein Roboter fährt zwar aber das ganze ist noch ziemlich „abgehakt“, das geht bestimmt besser – eigene Versuche haben bisher nur bedingt zu Erfolg geführt.

    Grüße

    Antworten
    • 11. Juni 2016 um 21:36
      Permalink

      Hi Sascha, an der Umsetzung eines PID-Reglers für die Linienverfolgung (und zusätzlich einer Art „Tempomat“, mit der mehrere CarduBots ohne Kollision auf einem Kreis fahren können) arbeite ich seit einiger Zeit. Jahreszeitlich bedingt ist es derzeit aber draußen meistens lustiger, das kann sich also noch etwas hinziehen…

      Antworten
  • 28. Januar 2017 um 23:16
    Permalink

    Hi,
    geht das auch mit einem Adafruit V1 Motorshield

    Antworten
  • 10. März 2017 um 20:32
    Permalink

    Hallo Herr Dax,
    ich versuche gerade den sketch zu kompilieren und erhalte immer die Fehlermeldung zur library:

    sketch_mar10a.ino:6:45: error: utility/Adafruit_PWMServoDriver.h: No such file or directory

    Was mache ich den falsch?
    Eigentlich dachte ich, dass ich die library richtig importiert habe. Ich bin halt noch Einsteiger.

    Antworten
  • 3. Februar 2019 um 18:20
    Permalink

    guten Tag – bin begeistert von deinen Projekten – insbes auch von den LineFollowing-Dingen.
    All das sieht sehr sehr gut aus – und ich bin derzeit auch dabei Aehnliches zu bauen.

    Mach weiter so – kompliment.

    VG Martrin

    Antworten
    • 3. März 2019 um 22:38
      Permalink

      Vielen Dank Martin! Mit dem CarduBot bzw. Line Follower Projekt wollte ich mich schon lange wieder mal beschäftigen, finde aber leider keine Zeit dazu.

      Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.