Table of Contents

Pixy2 Python tutorial

Pixy2 can be used in combination with different hardware platforms, which makes it such a versatile and powerful device. Among these platforms are widely used platforms like Raspberry Pi and LEGO Mindstorms EV3. If you like to program in Python or MicroPython on any of these platforms, this is your resource to find out how.

Each platform has its own characteristics. The way of communicating between Pixy2 and the platform is an important one. For instance, using Raspberry Pi communication goes via USB. If your using LEGO Mindstorms EV3 then you have to use I2C serial communication and connect Pixy2 with the cable delivered with the LEGO version of Pixy2.

In this tutorial we will describe the following platforms:

This tutorial belongs to Pixy2 and Pixy2.1. If you own the previous Pixy, go to the chapter “Pixy for LEGO Mindstorms” in the tutorial over here, written by one of our customers which explains how to use Pixy on LEGO Mindstorms EV3.

LEGO Mindstorms EV3

Python3

If you like to program in Python3, then ev3dev is your best choice. Ev3dev is a Debian Linux-based operating system that runs on several LEGO® Mindstorms compatible platforms including the LEGO® MINDSTORMS EV3 and the Raspberry Pi-powered BrickPi and PiStorms. Just write the image of the ev3dev operating system on a SD-card, put in in your EV3-brick and turn it on. The ev3dev website gives a clear explanation how to use it. To follow this tutorial you need a basic understanding of ev3dev.

MicroPython

A plus for using MicroPython on your EV3 is that it runs a lot faster. If you want to use MicroPython then PyBricks is the best solution. PyBricks is approved by the LEGO Group and you can find downloads on their LEGO Education website. If you like to use the latest version of PyBricks, you better download it from the PyBricks website. Follow the instructions on the EV3 installation page.

pixycamev3

To make programming more easy for you, we developed a Python API to use Pixy2 on the EV3. To use this API you have to install module pixycamev3. The same API can be used with both Python3 and MicroPython. The only difference is the way you install the API. When installed, using our API with Python3 is exactly the same as with MicroPython. But first you have to setup Pixy2.

Setting up Pixy2

First configure Pixy2 to communicate over I2C. For this you can use the PixyMon tool. You can find a full reference of PixyMon here. Connect Pixy2 with the USB cable to your computer and run PixyMon. In PixyMon open the configure dialog and select the Interface tab.

If you don't see the Interface tab, you're probably not running the right firmware on Pixy2. Be sure to run the stock version, instead of the LEGO version. See this page on how to install firmware on Pixy2.

Set Data out port to I2C and I2C address to 0x54 (or any other address you like). Save your settings, close the configure dialog, close PixyMon and detach Pixy2 from your computer.

Installing pixycamev3

This Python API works both with Python3 and MicroPython. There are two ways you can walk to use the API:

1. Installing with ''pip''

At the moment this method only works for Python3.

First login to your EV3 using ssh. Run the following command in a terminal window on your computer:

$ ssh [email protected]

where robot is the default username in ev3dev and xxx.xxx.xxx.xxx is the IP-address of your EV3. You will be asked for a password. The default password is maker. Be sure to use you're own combination of username and password if you changed the default in ev3dev.

When logged in to EV3, you can install the API package on your EV3 with:

$ python3 -m pip install pixycamev3

This takes about four minutes on the EV3. pip is not installed out-of-the-box on ev3dev. You can install pip with:

$ sudo apt install python3-pip

Beware this takes about 18 minutes on the EV3! But you can use pip later on to install other python packages when needed.

When package pixycamev3 is installed you're ready to program! Go to the next paragraph Using Python API.

2. Adding the API to your project folder

This method works for both Python3 and MicroPython.

In your project folder create a new folder pixycamev3. Visit the repository on Github. Add the file pixy2.py to your folder pixycamev3. The easiest way is to open this file in Github and click on the Raw button right above the code window. Then select all text of the file and copy it to a new file named pixy2.py in your pixycamev3 folder.

Your project folder structure should look like this:

project
  ├── pixycamev3
  │     └── pixy2.py
  └── main.py

The file pixy2.py works for both Python and MicroPython. When you copied the file you're ready to program!

Using pixycamev3

The main object you will need is the Pixy2 class. This object contains all the properties and methods you need to use Pixy2. So first you have to load this object from the pixy2 module:

class Pixy2
Parameters:
port The sensor port on the EV3 to which Pixy2 is connected.
Valid values in range 1 to 4.
i2c_address The I2C address you set in the Pixy2.
Returns:
Pixy2 object
Example:
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

Object Pixy2 contains the following methods:

get_version()
Description:
Get the firmware and hardware version of Pixy2.
Parameters:
None
Returns:
Pixy2Version object:
hardware Hardware version (int)
firmware Firmware version (str)
firmware_type Firmware type (int)
Example:
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Get version
version = pixy2.get_version()
print('Hardware: ', version.hardware)
print('Firmware: ', version.firmware)
get_resolution()
Description:
Get the current frame resolution of Pixy2.
Parameters:
None
Returns:
PixyResolution object:
width Frame width (int)
height Frame height (int)
Example:
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Get frame resolution
resolution = pixy2.get_resolution()
print('Frame width:  ', resolution.width)
print('Frame height: ', resolution.height)
set_lamp(upper, lower)
Description:
Turn the leds of Pixy2 on or off.
Parameters:
upper Upper leds: 0 = off, 1 = on
lower Lower led: 0 = off, 1 = on
Returns:
None
Example:
from time import sleep
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Turn upper leds on for 2 seconds, then turn off
pixy2.set_lamp(1, 0)
sleep(2)
pixy2.set_lamp(0, 0)
set_mode(mode)
Description:
Set mode for Pixy2 (for linetracking)
Parameters:
mode Desired mode:
Pixy2Mode.LINE_MODE_DEFAULT
Pixy2Mode.LINE_MODE_TURN_DELAYED
Pixy2Mode.LINE_MODE_MANUAL_SELECT_VECTOR
Pixy2Mode.LINE_MODE_WHITE_LINE
Returns:
None
Example:
from pixycamev3.pixy2 import Pixy2, Pixy2Mode

pixy2 = Pixy2(port=1, i2c_address=0x54)
mode = Pixy2Mode()

pixy2.set_mode = mode.LINE_MODE_MANUAL_SELECT_VECTOR
get_blocks(mode)
Description:
Gets all detected blocks in the most recent frame.
Parameters:
sigmap Sigmap of all 7 signatures for which you wish to receive block data.
For example, if you are only interested in block data from
signature 1, then sigmap=1. If you are interested inbock data from
signatures 1 and 2, then sigmap=3 (1+2).
max_blocks The maximum number of blocks you wish to receive.
Returns:
nr_blocks Number of detected blocks
blocks List of Block objects (length = nr_blocks):
sig Signature or color code number
x_center X location of the center of the block
y_center Y location of the center of the block
width Width of the block
height Height of the block
angle Angle of color code in degrees
tracking_index Tracking index of the block
age The number of frames the block has been tracked
Example:
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Track blocks with signature 1, request just 1 block
while True:
    nr_blocks, blocks = pixy2.get_blocks(1, 1)
    # Extract data of first (and only) block
    if nr_blocks >= 1:
        sig = blocks[0].sig
        x = blocks[0].x_center
        y = blocks[0].y_center
        w = blocks[0].width
        y = blocks[0].height
get_line_tracking_data()
Description:
Get linetracking data (MainFeatures) in the most recent frame.
Parameters:
None
Returns
MainFeatures object:
error Data error when value True
length_of_payload Number of bytes in payload
number_of_vectors Number of vectors detected
number_of_intersections Number of intersections detected
number_of_barcodes Number of barcodes detected
vectors List with Vector objects (length numberofvectors)
intersections List with Intersection objects (length numberofintersections)
barcodes List with Barcode objects (length numberofbarcodes)
Vector object:
x0 X location startpoint vector
y0 Y location startpoint vector
x1 X location endpoint vector
y1 Y location endpoint vector
index Index of vector in array
flags Internal state, used for testing/debugging
Intersection object:
x X location of intersection
y Y location of intersection
nr_of_branches Number of branches starting at this intersection
branches Array with Branch objects (length numberofbranches)
Barcode object:
x X location center of barcode
y Y location center of barcode
flags Internal state, used for testing/debugging
code Number of barcode (see Pixy2 wiki)
Branch object:
index Index in array
angle Angle of branch
angle_byte1 Byte1 of angle
angle_byte2 Byte2 of angle
Example:
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Detect barcodes and print their number
while True:
    data = pixy2.get_linetracking_data()
    if not data.error:
        for i in range(0, data.number_of_barcodes)
            print('Barcode number: ', data.barcodes[i].code)
set_next_turn(angle)
Description:
Set direction for turn at the next intersection. After this intersection
Pixy2 will choose it's default turn again.
Parameters:
angle Direction to choose at the next intersection (-180, 180 degrees)
Returns:
None
Example:
from time import sleep
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Set next turn to 90 degrees
pixy2.set_next_turn(90)
set_default_turn(angle)
Description:
Set default direction for all intersections.
Parameters:
angle Default direction (-180, 180 degrees)
Returns:
None
Example:
from time import sleep
from pixycamev3.pixy2 import Pixy2

pixy2 = Pixy2(port=1, i2c_address=0x54)

# Set default turn to 0 degrees (straight on)
pixy2.set_default_turn(0)

Examples

You'll find more practical sample code in the Github repository.

Rasberry Pi

<Work in progress>