Nachdem ich etwas mit der Pixy CMUCam5 rumgespielt habe, wollte ich das auch als ein Sensor für einen Roboter ausprobieren. Das Pan-Tilt Modul habe ich ich weggelassen. D.h. die Kamera kann sich nur vor, zurück, links und rechts bewegen, was für meinen Test vollkommen ausreicht.
Mechanik
Das Fahrgestell besteht aus folgenden Tamiya Teilen:
- Tamiya 70157 Universal Plate Set (2 Stk)
- Tamiya Kettensatz
- Tamiya 70168 Double Motor Getriebebox
Auf den Aufbau des Chassis möchte ich nicht näher eingehen. Die Anleitung liegt den Sets bei. Es hat allerdings etwas gedauert, bis ich eine Idee hatte, wie man die zweite Platte am Chassis befestigen kann.

Elektronik
Versorgt wird der Roboter mit 5x AA Eneloop Akkus. Es ist auch empfehlenswert Akkus statt Batterien zu nehmen. Allein die Kamera kann schon gut über 200mA ziehen + die Motoren ziehen auch einiges an Strom. Mit Akkus wird man länger Spaß haben. Als Mikrocontroller (-Board) wird ein Arduino UNO eingesetzt und als Treiber der DRV8835. Die Verbindung zwischen Treiber und Arduino erfolgt auf einem Steckbrett. Ich wollte hier nichts fest verlöten, da der Roboter einfach nur ein Testaufbau ist. Wenn ich damit genug rumgespielt habe, wird das Fahrgestell für andere Sachen als Testplattform verwendet.
Die Verdrahtung auf dem Steckbrett ist ist dieselbe, wie in diesem Artikel, wo ich die Ansteuerung des Treibers kurz erklärt habe. Trotzdem hier nochmal die Fritzing-Grafik.


Programmierung
Nachdem man eine Signatur angelernt hat (siehe dazu: https://5volt-junkie.net/pixy-arduino/), kann man die Position des Objektes im Programm auswerten und dementsprechend die Motoren ansteuern.
Der Roboter versucht das Objekt in der Mitte der x-Achse zu behalten und einen bestimmten Abstand zum Objekt zu halten. Ist das Objekt zu nah, währt der Roboter rückwärts und wenn es zu weit weg ist, fährt er näher ran. Für die Größe des Objektes wird seine Fläche mit einer einfachen Formel ausgerechnet: Breite x Höhe = Fläche.
Die Soll-Fläche (area), die man selber vergeben muss, wird mit der Ist-Fläche verglichen. Dabei muss die Differenz größer als 200px sein. Das ist dafür da, damit der Roboter nicht ständig hin und her zuckt und sich erst in Bewegung setzt, wenn das Objekt erheblich weit/nah ist.
Ähnlich ist es auch bei der x-Achse gelöst. D.h. wenn das Objekt nur um 1px nach links oder rechts verschoben wurde, macht der Roboter erstmal nichts.
Variablen anpassen
In dem Programm gibt es mehrere Variablen, die an eigene Bedürfnisse angepasst werden sollen/können. U.A. maxArea und minArea. Diese Werte werden durch die Größe des Objektes beeinflusst und welchen Abstand der Roboter zu diesem Objekt halten soll.
Je nach gewünschter Geschwindigkeit, kann auch der Wert speed angepasst werden.
//Pixy arduino robot
//Arduino IDE 1.0.6
#include <SPI.h>
#include <Pixy.h>
Pixy pixy;
int signature = 0;
int x = 0; //positon x axis
int y = 0; //position y axis
int width = 0; //object's width
int height = 0; //object's height
int area = 0;
int maxArea = 1000; //max object area
int minArea = 800; //min object area
int Xmin = 140; //min x position
int Xmax = 180; //max x position
int aPhase = 2; //aPhase on Pin D2
int aEnable = 3; //aEnable on Pin D3
int bPhase = 4; //bPhase on Pin D4
int bEnable = 5; //bEnable on Pin D5
int Speed = 50; //motor speed
//drive forward
void forward(){
digitalWrite(aPhase, LOW);
digitalWrite(bPhase, LOW);
analogWrite(aEnable, Speed);
analogWrite(bEnable, Speed);
}
//drive backward
void backward(){
digitalWrite(aPhase, HIGH);
digitalWrite(bPhase, HIGH);
analogWrite(aEnable, Speed);
analogWrite(bEnable, Speed);
}
//rotate right
void turnRight(){
digitalWrite(aPhase, HIGH);
digitalWrite(bPhase, LOW);
analogWrite(aEnable, Speed);
analogWrite(bEnable, Speed);
}
//rotate left
void turnLeft(){
digitalWrite(aPhase, LOW);
digitalWrite(bPhase, HIGH);
analogWrite(aEnable, Speed);
analogWrite(bEnable, Speed);
}
//brake
void brake(){
digitalWrite(aEnable, LOW);
digitalWrite(bEnable, LOW);
}
void setup()
{
//D2 - D5 as output
pinMode(aPhase, OUTPUT);
pinMode(aEnable, OUTPUT);
pinMode(bPhase, OUTPUT);
pinMode(bEnable, OUTPUT);
brake();
Serial.begin(9600);
Serial.print("Starting...\n");
pixy.init();
//start direction test - can be deleted
forward();
delay(1000);
brake();
backward();
delay(1000);
brake();
turnLeft();
delay(1000);
brake();
turnRight();
delay(1000);
brake();
delay(1000);
//end direction test
}
//infinity loop
void loop()
{
static int i = 0;
uint16_t blocks;
blocks = pixy.getBlocks(); //receive data from pixy
signature = pixy.blocks[i].signature; //get object's signature
x = pixy.blocks[i].x; //get x position
y = pixy.blocks[i].y; //get y position
width = pixy.blocks[i].width; //get width
height = pixy.blocks[i].height; //get height
//looking for signature 1
if(signature == 1){
area = width * height; //calculate the object area
//rotate left if x position < max x position
if (x < Xmin){
turnLeft();
}
//rotate right if x position > max x position
else if (x > Xmax){
turnRight();
}
//drive forward if object too small
else if(area < minArea){
forward();
}
//drive backward if object too big
else if(area > maxArea){
backward();
}
//else brake
else if(area > minArea && area < maxArea && x > Xmin && x < Xmax){
brake();
}
}
else{
brake();
}
}
//end

Mein Robot fährt nur vorwärts und folgt nur im Zick-Zack Kurs.
Was mache ich falsch ?
Hi,
überprüfe mal die Verkabelung. Ansonsten kann es sein, dass sich an der Firmware oder Bibliotheken von Pixy was geändert hat. Da ich den Roboter aus dieser Anleitung nicht mehr habe, kann ich leider schlecht prüfen, was nicht stimmt.