I have made my own pan-tilt by supergluing two of those cheap 9g servos together and used another 9g servo simply as a 90 degree support (see picture below).
I have got pixy moving when it sees a yellow tennis ball, however it seems scared when it tries to look at the ball. Vertically, it is head-thrashing quite vigorously like at a death metal concert whilst maintaining correct height on average. Horizontally, it is very confused.
What I have attempted to do is combine the hello world (Arduino) example with the code for operating 2 servos found at
http://www.robotoid.com/appnotes/arduino-operating-two-servos.html.
The hello world example tells me that the centre detection positions of pixy are horizontally, 0 to about 320 (left to right) and vertically 0 to 199 (up to down), whereas testing the servos previously I found they point in my preferred way horizontally 180 to 0 (left to right) and vertically 30 to 130 (up to down). In an attempt to scale the pixy coordinates to approximately match the servos I included the following calcs in the part of the code where it tells the servo where to move to.
Vertical: servo y value will be = 30+pixy/2
Horizontal: servo x value will be = pixy/-2
Therefore, I have the following two lines of code:
servoVert.write(30+(pixy.blocks[j].y)/2);
servoHori.write((pixy.blocks[j].x)/-2);
The code on the robotoid site that I modified was:
servoLeft.write(0);
servoRight.write(180);
Maybe this modification is just totally the wrong way to code. I also realise that as Pixy turns, the coordinates that it detects will change. Maybe that is the source of the erraticism? I didn’t want to buy the Pixy pan-tilt mechanism yet because this is a challenge I wanted to do. Would somebody know how to fix this please. Maybe a whole different approach? Pixy is getting tired.
You can see in the full code below that I combined parts of the robotoid 2 servo code with Hello World.
// http://cmucam.org/projects/cmucam5/wiki/Hooking_up_Pixy_to_a_Microcontroller_(like_an_Arduino)
//
// It prints the detected blocks once per second because printing all of the
// blocks for all 50 frames per second would overwhelm the Arduino’s serial port.
//
#include <SPI.h>
#include <Pixy.h>
// This is the main Pixy object
Pixy pixy;
// **********************************************************************
//from http://www.robotoid.com/appnotes/arduino-operating-two-servos.html
#include <Servo.h>
Servo servoVert; // Define vertical servo
Servo servoHori; // Define horizontal servo
// **********************************************************************
void setup()
{
// **********************************************************************
//from http://www.robotoid.com/appnotes/arduino-operating-two-servos.html
servoVert.attach(10); // Set left servo to digital pin 10
servoHori.attach(9); // Set right servo to digital pin 9
// **********************************************************************
Serial.begin(9600);
Serial.print(“Starting…\n”);
pixy.init();
}
void loop()
{
static int i = -90;
int j;
uint16_t blocks;
char buf[32];
// grab blocks!
blocks = pixy.getBlocks();
// If there are detect blocks, print them!
if (blocks)
{
i++;
// **********************************************************************
//from http://www.robotoid.com/appnotes/arduino-operating-two-servos.html
// If there are detect blocks, move servos!
{
servoVert.write(30+(pixy.blocks[j].y)/2);
servoHori.write((pixy.blocks[j].x)/-2);
}
// **********************************************************************
// do this (print) every 50 frames because printing every
// frame would bog down the Arduino
if (i%50==0)
{
sprintf(buf, "Detected %d:\n", blocks);
Serial.print(buf);
for (j=0; j<blocks; j++)
{
sprintf(buf, " block %d: ", j);
Serial.print(buf);
pixy.blocks[j].print();
}
}
}
}