Pixy-Roboter mit Arduino

Pixy-Arduino-Robot

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.

Pixy-Arduino-Robot-open

 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.

DRV8835 Arduino Steckbrett

 

Pixy-Arduino-Robot-top

 

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

 

2 Replies to “Pixy-Roboter mit Arduino”

    • 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.

Schreibe einen Kommentar

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

*

Bitte löse folgende Rechenaufgabe * Time limit is exhausted. Please reload CAPTCHA.