PixyMon and Arduino
The goals for this project are to introduce you to the CMUcam5 Pixy and show how easy it is to implement a camera into your DIY projects, even in a complex electromechanical system like a wheeled autonomous robot. Pixy is a flexible, compact, adjustable, and easy to setup camera sensor that has the ability to detect and send information about certain types of objects. We will cover the basics of the camera and learn how to communicate between Pixy and Arduino in general.
Figure 1. CMUcam5 Pixy Camera
CMUcam5 Pixy is a small, easy-to-use, low-cost and open-source camera. It has it’s own processor and it outputs what it detects 50 times per second. It can also connect to Arduino, Raspberry Pi and many more. It uses very popular interfaces like SPI, I2C, UART, and USB. It has a custom program which allows you to connect to devices, and you can download it free here.
Setting up Pixy
Download the software PixyMon here and install it. While it’s installing, connect Pixy by USB and check if the RGB Led is lighting up.
Open PixyMon and make sure your Pixy is connected via USB. If everything is connected correctly, it will output what the camera sees. For example, I placed a purple lid as a test object to check Pixy camera’s output.
Figure 2: Pixy Raw image output
By going to the Action submenu and clicking Set Signature 1, the video should freeze and you can select what color/object you want to detect using the camera.
After marking the color/object the video will start playing and the camera sensor will detect the color/object as shown on Figure 3. You can setup up to 7 objects/colors you want at the same time. If you mark them correctly and setup the visual field there should be no problems detecting multiple objects/colors.
Figure 3: Pixy’s vision with detection
To clear your preset signatures you can use Action-> Clear All Signatures or by choosing Clear Signature you can clear signatures one by one (Enter the number of the signature in the console).
By adjusting Settings -> Signature 1, you can modify the size of the Pixy’s field-of-view.
There is a custom library for using Pixy with your Arduino. I’m using an Arduino Uno but you can use any version you have. The library is very useful; it provides beginners with simple examples and the experts with great platforms for development.
Let’s first setup an object for detecting, similar to what we did earlier at the setup of the camera.
Download Arduino libraries here (under “Arduino libraries and examples”) [http://www.cmucam.org/attachments/download/1157/arduino_pixy-0.1.7.zip]; this will allow communication between your Arduino and the Pixy camera. Then, add it to your libraries in Arduino IDE (Sketch->Include Library->Add .zip Library)
Open up a simple Example called hello_world by going to Example->Pixy->hello_world.
Upload it to your board and open up the terminal (Tools->Serial Monitor).
At this point, you will see a message that reads “Starting…” followed by information about the detected object.
hello_world code explanation
In the setup() function, the serial and pixy gets initialized and configured.
The loop() function contains several variables which are used for printing and getting the blocks from pixy. With pixy.getBlocks() we can grab the objects that were detected. The if (i%50==0) can be configured for the FPS we want to get info on. If we want 1 information every second we write %1 instead of %50.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/* * explaining the (((pixy.blocks[j].x)/2)+10)-60 * with pixy.blocks[j].x we get the x position of the object detected * we divide it because the max value it can read is 320 * I did the + 10 for small adjustments * the -60 is used for rotating away from the object */ #include <Servo.h> #include <Pixy.h> Servo myservo; // create servo object to control a servo Pixy pixy; // create pixy object for controlling the pixy camera // function for testing the servo void test_camera(){ myservo.write(0); delay(1000); myservo.write(90); delay(1000); myservo.write(180); delay(1000); myservo.write(90); // get the camera centered } void setup() { //Serial.begin(9600); // initialize serial myservo.attach(9); // attaches the servo on pin 9 to the servo object test_camera(); // executing testing for the servo pixy.init(); // initing the pixy camera } void loop() { //variables static int i = 0; int j; uint16_t blocks; char buf[32]; int32_t xpos; // grabing the blocks blocks = pixy.getBlocks(); // If there are detect blocks if (blocks) { i++; // we are using 50FPS if (i%50==0) { sprintf(buf, "Detected %d:\n", blocks); for (j=0; j<blocks; j++) { sprintf(buf, " block %d: ", j); //Serial.println((((pixy.blocks[j].x)/2)+10)-60); //print out to what position will the servo go // this is used so the servo can't get stuck at minimum and maximum values if(((((pixy.blocks[j].x)/2)+10)-60) > 180 || ((((pixy.blocks[j].x)/2)+10)-60) < 0 ) { myservo.write(90); // if at min or max go to the middle } else{ // if there is no problem with min and max myservo.write((((pixy.blocks[j].x)/2)+10)-60); } } } } } |
sprintf(buf, “Detected %d:\n”, blocks); outputs the current object detected by the ID and it puts the necessary data into the buffer. In the for loop we are getting all sorts of information about the object, width, height, x, y, and signature.
Now that Pixy is successfully connected to Arduino, I’m going to do a simple experiment by attaching the Pixy to a servo and have the servo turn away when the camera sees a certain type of color/object.
For this experiment, I will set the Pixy to detect a round-shaped purple container and program so that the servo turns away from it whenever the container comes into its visual field.
The construction:
Figure 4: The finished construction
I am using the S06NF servo and small screws to attach the servo to the camera, as shown in Figure 5.
Figure 5: Camera attached to the servo motor
For the hardware part only the simple wiring is left. Connect the SPI cable to the camera and the servo to the Arduino. I’m using pin 9 for controlling the servo.
Figure 6: The wiring diagram
WARNING!
Don’t forget to connect the GND’s together. If you don’t connect the Power supply, Servo and Arduino GND together, the servo will freak out!
Here, I’m using an old adapter for 5V powersupply.
In this tutorial, we covered the basics of the PixyMon camera and have developed a simple servo driven application. Instead of chasing an object, we have created a system that turns away when it detects an object. In Part 2, we will expand on this concept more in depth to develop an interactive system with multiple servos to control the orientation of a table using a ball as an object.
If you have any comments or questions, please leave them for us at Google +. Follow us there;