Pixy for Propeller?
Jim the Hermit
Posts: 79
I have the new pixy (CMUcam5) but I have no idea how to use it for the propeller (or the stamp for that matter).
Is anybody working on this?
Is anybody working on this?
Comments
They have all the info up on the wiki: http://www.cmucam.org/projects/cmucam5/wiki/Pixy_Serial_Protocol
You should be able to use one of my serial drivers that has a large FIFO buffer to easy process the data: http://obex.parallax.com/object/246
http://www.cmucam.org/projects/cmucam5/wiki
Everything you need to know is there on the wiki.
All I can find is how to read a packet from the Pixy. I don't see any way of setting the Pixy's modes.
I see Pixymon Configuration Parameters but I don's see how to use these parameters from a microcontroller? Do I have to use the PC to interface with the Pixy prior to using a Propeller over a serial line? I'm guessing yes.
I was hoping to find a list of commands the Propeller could issue to configure the Pixy on its own.
I'm learning the Pixy likes a lot of light and very bright (saturated) colors.
I wrote a program for the Propeller to monitor the tx line of the Pixy and display the data to a terminal window.
These three methods are the guts of the program.
I initially only saw zero data returned, as in eight bits of 0. Apparently the Pixy streams zeros when it doesn't have anything to say.
I used the program PixyMon to set the output to UART and to change the baud to 115,200 (from 19,200).
Here are some other changes I made.
In the "General" tab is used these settings.
Since I was just receiving zeros, I decided to change the settings and changed the saturation from 15.0 to 5.0.
I trained the Pixy with two signatures (#1 and #2) I used Post It notes as the targets. It usually takes me a couple of attempts to capture the target since I'm not sure which combination of actions will result in a captured target. At some point the program will let you drag the mouse over a captured image to select the target.
With these changes, I was able to capture a few blips of data.
The value "syncError" is a count of how many characters were received which didn't lead to valid packet.
I was only able to capture a few valid packets before the evening light dimmed to the point where it no long assisted the indoor light enough for a valid capture.
I'll give this a try again when I have some better lighting.
The attached program will display the packet data but each packet will be displayed over top of the previous packet (deleting the previous packet's data).
You have to make the changes shown above with PixyMon and train a few signature before the Pixy will output anything the Propeller can read.
The maximum brightness is 232. I found a setting of 80 worked pretty well.
The saturation value is important in how picky the Pixy should be about the color. It seems like somewhere between 5 and 10 worked pretty well with some colors. I'm presently using a setting of 7 for the saturation.
I reduced the number of objects to 2 and I'm only going to teach a single signature for my next experiment with the Pixy.
I'm gong to modify the code to output data about two objects at a time.
Yes, but you did say:
Which I don't completely agree with. Plus you're here and I don't want to gripe to people I don't know.
Yes, I think you're right.
I may start asking questions on the Pixy forum if I can't find the answers in the Wiki or past Pixy forum threads.
I wanted to try hooking it up to a Quickstart board and run it using pfth, but the serial methods are going to take some time for me to understand. I have an Activity Bot and realized that the Activity Board has a 4 channel ADC, The Pixy can send voltage proportional to X or Y position, and the C Learning tutorials have a couple of ADC examples. So I decided to try using the AB.
One big limitation of the Pixy is that it only has one ADC interface so can only send either x data or y data. Since I want to use this with the robot, I chose the X data (interface mode 3).
I didn't have a lot of time for this so my setup was not ideal. I was working on a card table (shake shake shake). Pixy was leaning up against a box. And I was holding a light blue pen cap as the object of interest. Also the lighting was florescent.
I used the Simple IDE C program "Measure Volts" (below) from the Simple Circuits section of the C Learning tutorial. That program uses ADC channels 2 and 3 to read voltage. Pixy sends the voltage proportional to the X position ranging from 0 volts full Left to 3.3 v full Right. I connected Pixy Pin #3 (v out) to ACT Brd ADC 3, Pixy Pin 6 (GND) to AB GND. I also attached Pixy Pin #1 to ADC 2.
Pixy pin 1 is high (3.3v) when the color is detected and 0 when not. I found testing that helped clean up the data when the object was near the extreme Left or Right of the Pixy field of view. I modified the printing near the end of the code to only print the ADC3 voltage if ADC2 voltage was >1.
Because of the shakiness of my setup the voltage values printed out did have some jitter. When I did everything I could to minimize the shakes, the data was quite good with the variations in the 3rd or 4th decimal place.
Next I've got to work up the commands to use those readings to rotate the Activity Bot to track the object.
Tom
Thanks for posting what you've done.
I don't suppose I could talk you into posting some output from the Program?
Since you're using C, I wonder if you could just port the Arduino code into Propeller C?
Even without porting the full code, You might be able to make better use of the Pixy with the UART using C.
Either way (UART or ADC), I hope you keep us updated on your progress.
Duane,
The output from the code above was just the voltage values (approx 0 to approx 3.3). Using simple IDE I ran the code using the run with terminal.
I've quickly looked at the Arduino code. But quite frankly, I'm a C novice and figuring out the Arduino code is going to take some time and learning on my part. Once of the concerns I have using the UART is that the Pixy just continuously sends values. I'd be more comfortable if I could send it a command to start sending the values for a specific signature. But I'll keep working on it. One reason why I'd like to use pfth for this is that it is easier for me to see the format of the data (I have the Pixy info from he wiki) and modify things in real time.
My first step will be to use the Spin code you posted, and I will probably have some questions for you. I still have to play with the configuration settings that you described. I found that with the lighting I had, it was necessary to raise brightness to 120 to get consistent readings.
I think that the Arduino code has commands to set the Pixy configuration, like Pixymon does, so there are some good reasons to try to figure it out.
One of my problems is that I tend to jump ahead before fully working out the basics. So I'm already starting to work on methods to rotate the Activity bot to drive to a stationary object (should be pretty easy), and then to rotate to follow a moving object (steady motion and then random motion). I realize that there are folks here for whom that would be almost trivial, but its more new ground for me.
I'll keep updating.
Tom
I haven't seen these codes myself. As far as I can tell, there are a lot of configuration parameters that have to be set with the Pixymon program. IMO, this aspect of the Pixy is very bothersome.
I tried to figure out the UART. I tried Duane's Spin code from post 5 and got very inconsistent results. Some times I would get some values, other times all zeros.
Tonight I tried using Forth (pfth version) to see if I could decipher what the Pixy UART was putting out. I have a routine that I used to debug a bluetooth serial connection. I have a forth word (bt>str) that simply does an FDS_Read (fds_rx) and stores the byte received in a string array and repeats. Once the array is filled the word ends. Then I use a forth word (.bt) that prints out the byte values. That way I can see the how the sending device formats the block. Because of the size of the Pixy block (14 bytes) I increased the array size to 129 bytes, so I could catch at least a few blocks.
First thing I found out was that I received a couple of initial bytes and then just zeros if I had Pixymon running. So I closed that program.
Once I did that I initially tried using my normal baud rate of 115200.
These are the results I got:
I looked for the Pixy sync word aa55 (or 55 aa, LSB first). If you search through the above, you will see only one instance of that, and it appears to be an incomplete block. I guessed that 115200 baud might be too fast and characters were being lost. So I tried the Pixy default of 19200 baud.
The results from that were:
I put in some line feeds to set off the complete blocks. There are a number of complete 14 byte blocks starting with 55 aa. (I have to try a slower baud to see if the results get better). However, at the begining and end of the buffer there are values that don't make any sense or are partial blocks. The Pixy wiki states that if Pixy is transmitting a block and the next cycle of data starts, it will just discard the data from the previous block. That makes decoding more complex. Again, I wish that they had written the firmware so that the user could start and stop transmission blocks remotely rather than just having Pixy bang away.
Next I took a couple of blocks and translated them into decimal to see if they made any sense.
Here's one:
It appears that the results are reasonable. Now that am getting some consistent results I'll have to try with a more controlled set up (instead of me just waving a flower in front of the lens). Then the next thing is to try to use the serial objects in either spin or C to try to collect the data and make use of it.
I have also done a little more with the ADC method in C, translating the x-location (from voltage) into a command to rotate the Activity Bot. I have to do some work on the robot (replace Ping with Pixy) and see how it works.
Tom
I tried a more controlled test. I mounted 3 pieces of different size non-glossy colored paper rectangles on a white board, and trained Pixy for each color. Then kept everything in a fixed location.
The pixy wiki states that Pixy will transmit a new frame of data every 20 ms and can send data on 135 objects per frame (approx 1 per 0.15 ms). I calculated that at 19200 baud, Pixy would send 3 objects worth (14 byte blocks - 2 sync bytes 55, aa and 12 data bytes) of data in each frame. Each Frame starts with 4 hex bytes: 55, aa, 55, aa and then the data from the first block, followed by 55, aa starting the second block, etc. Pixy sends the data in decreasing order of size of each block.
At 19200 baud, I got some data that looked good, but less than 50% of the blocks were ok. The rest seemed to be blocks with data out of order, wrong number of data bytes, etc. It seemed as though Pixy was sending data faster than pfth could handle it (simply put it into an element in a character array and test for the maximum number of bytes in the array.) I have used pfth with Full Duplex Serial at 115200 baud from a bluetooth device, but the BT device sends the data packets at a relatively slow speed (e.g. speed of typing).
Since decreasing the baud rate of the Pixy serial connection from 115200 to 19200 enabled getting some correct data blocks, I lowered the baud rate one more step to 9600. Using that I got reliable data almost all of the time. But because of the reduced baud rate Pixy was only able to send 1 block of data per frame. And since the Pixy priority is to send the data block for the largest item first, that is the only data that can be received.
From what Dave Hein has written, pfth is not the fastest language around. I will have to try in both Spin and C to see if they are fast enough to use with FDS. I will also have to learn how to use the Pixy SPI and I2C interface to see how they work.
I tried using C with Simple IDE. It was a very simple program (see below): open the serial port, read a byte, print it on the terminal.
I was able to read 5 blocks of data per frame accurately at 19200 baud with the Pixymon program not running. The next thing to do is to sync data collection and interpretation with the Pixy sync bytes. I'll also try some tests with higher baud with Pixymon off.
Tom
Thanks for sharing your experiences using it!
Dave
In the following column in excel, next to the first byte for each word (LSB) -- for example in cell D5, I entered the following =(256*D6)+D5, so I could have all the word values sent and check the checksum for accuracy.
I got the following results. Note that in some cases, after sending a complete block of data, there would be a series of zeros without a starting sync word. Based on the pixy documentation, this indicates no signatures detected. I was doing this test in a medium well lit room, and I could see when using Pixymon that sometimes the signatures would flicker.
I tried 57600 baud, but there were many errors.
My conclusions from the results below are that if I have to use CMM to fit a program, I would restrict the baud to 14400 if I wanted no errors. If I had good error detection in my software, I'd use 16800. If I could use LMM, I'd choose 19200 or 38400.
Tom
Mem Model
Optmization
Baud
B/F max
B/F min
B/F typical
Num Err
CMM
Size
14400
3
1
2
0
CMM
Size
16800
4
2
2
1
CMM
Speed
16800
3
2
2
1
LMM
Size
16800
3
2
2
0
LMM
Speed
19200
3
2
2
0
LMM
Speed
38400
6
1
4
0
Note that I did try to find the first sync word and then start reading values from Pixy, but there was enough of a delay that the first 2 or 3 words after the sync were lost. So that's why I read everything and then truncate.
Tom
Here's the code:
The demo just prints out the pixywords in the terminal. It uses a while(1) loop and prints "end of data" between pixy data collections.
Tom
Here's the code:
So my pixy arrived today. The install instructions for linux failed me at
Once I get that resolved, I will start on adding pixy to LittleRobot.
Good Good
Next is to control ActivityBot motion to track the laser dot, but that's gong to take some time to figure out how I want to mount the PIXY and include whiskers or Ping to keep the Bot from running into things.
Tom
http://forums.parallax.com/showthread.php/155208-Open-Propeller-Project-5-BlocklyProp?p=1276733#post1276733
The c program below has the ActivityBot track and more towards an object with a defined color signature. My intent was to have it work with a laser pointer, shining it in the direction I want the bot to go. But at any distance greater than about 1 foot the dot is too small for Pixy to track.
However, it will go towards an object with the defined color signature. If there are two objects, it might have a nervous breakdown since I am using the adc method which only sends the voltage corresponding to the x-position of the largest visualization of the defined color (Pixy interface mode 3)
I mounted the Pixy rigidly to the front of the activitybot. I ran Pixy pin 1 to abot adc0, pin 2 to +5v, pin3 to adc1, pin 6 to gnd.
I trained Pixy using Pixymon before I connected the pins above.
Load the program using 'load EEPROM and run' with the abot switch set to position 1. Once loaded set switch to position 2 and it will start moving.
So I retrained pixy on red and it worked and my son was impressed.
The code is below, and the instructions are in the previous post.
Tom
Tom
http://forums.parallax.com/showthread.php/156970-Bluetooth-App-to-control-ActivityBot
The initial release is here https://github.com/imbinary/parallax-pixy . I run the code in a cog and access the data from the blocks struct. One gotcha I encountered was not having enough light when testing, and not detecting anything so assumed the code was broken :frown:.
Connect the Pixy like so
pixyCMU5
Propeller activity
PIN 1
PIN 14
PIN 2
5v
PIN 3
PIN 15
PIN 4
PIN 13
PIN 6
GND
or modify pixy.c to suit your needs.
I run pixy in a cog and access the data as shown in the code below.
Hopefully this helps someone else get started.
imbinary
I've had the same (lack of) light problem with the Pixy.
Thanks for posting your code and welcome to the forums.
I hope you share more details about your project with us sometime.
Thanks for the code. As you can see from the code above, my knowledge of C and interfacing is pretty elementary. I've been wanting to try using the Pixy SPI interface, but had no idea how to start. I'm going to try to work through the code to understand what you have done, and hopefully I'll learn.
Thanks again,
Tom