<< return to Pixycam.com

Problem with Arduino Pixy Library

Hey guys!

I’m running latest version of pixy firmwhare, (2.0.8), latest pixy mon (2.0.6 windows), and arduino library 0.1.7
Pixy is powered trough USB socket, and connected to Arduino DUE via UART interface.

after returning blocks, I get “cs error” every single time, and a few "reorder"s now and then, but thats not what bothers me.
I modified line 225 Serial.println(“cs error”); to Serial.println(F(“cs error”)); and line 159 Serial.println(F(“reorder”)); to
Serial.println(F(“reorder”)); To save RAM, I used F() macro to put these printout statements into flash. Even without F() macro, im still getting "cs error"s and “reorder”. If i comment these println statements out, an interesting thing happens. Pixy stops returning ALL blocks, it only returns the first block. If signature 1 is available, it returns first block of that. If signature 1 and 2 is available, 1 block of signature 2 is returned. If signatures 2, 3, and 7 are detected, only one block 2 is returned and so on.

I want to get rid of Serial.println() statements in the TPixy.h, and I dont know how to do that without bricking the library. Any suggestions?

Best,

Vadim.

Hello Vadim,
The cs error and reorder messages are normally very rare. But we haven’t done much testing with the DUE and UART interface. (Why aren’t you using SPI and the ICSP connector on the DUE?)

At any rate, feel free to post your code and we’ll take a look.

Edward

I can confirm this issue for the Due.
It’s not rare, it’ regular !

reorder
Detected 1:
block 0: sig: 2 x: 283 y: 180 width: 14 height: 3 angle 0
reorder
Detected 2:
block 0: sig: 2 x: 108 y: 187 width: 7 height: 10 angle 0
block 1: sig: 3 x: 75 y: 174 width: 7 height: 9 angle 0
cs error
Detected 2:
block 0: sig: 2 x: 109 y: 188 width: 8 height: 12 angle 0
block 1: sig: 3 x: 97 y: 178 width: 8 height: 6 angle 0
cs error
reorder
Detected 3:
block 0: sig: 2 x: 109 y: 188 width: 8 height: 10 angle 0
block 1: sig: 3 x: 75 y: 174 width: 8 height: 10 angle 0
block 2: sig: 3 x: 96 y: 176 width: 9 height: 8 angle 0
cs error
Detected 2:
block 0: sig: 2 x: 108 y: 189 width: 7 height: 6 angle 0
block 1: sig: 3 x: 97 y: 176 width: 8 height: 8 angle 0
cs error
Detected 3:
block 0: sig: 2 x: 109 y: 187 width: 8 height: 9 angle 0
block 1: sig: 3 x: 75 y: 174 width: 8 height: 9 angle 0
block 2: sig: 3 x: 97 y: 175 width: 8 height: 3 angle 0
cs error
Detected 2:
block 0: sig: 2 x: 109 y: 187 width: 8 height: 10 angle 0
block 1: sig: 3 x: 97 y: 176 width: 8 height: 9 angle 0
cs error

Detected 7:
block 0: sig: 1 x: 128 y: 100 width: 16 height: 32 angle 0
block 1: sig: 1 x: 256 y: 124 width: 38 height: 5 angle 0
block 2: sig: 1 x: 290 y: 118 width: 28 height: 6 angle 0
block 3: sig: 1 x: 225 y: 136 width: 21 height: 14 angle 0
block 4: sig: 2 x: 67 y: 162 width: 92 height: 19 angle 0
block 5: sig: 2 x: 13 y: 145 width: 12 height: 10 angle 0
block 6: sig: 2 x: 130 y: 27 width: 12 height: 4 angle 0
Detected 3:
block 0: sig: 1 x: 127 y: 100 width: 17 height: 32 angle 0
block 1: sig: 1 x: 261 y: 125 width: 86 height: 19 angle 0
block 2: sig: 2 x: 74 y: 165 width: 75 height: 20 angle 0
reorder
reorder
reorder
reorder
reorder
Detected 7:
block 0: sig: 1 x: 129 y: 107 width: 16 height: 18 angle 0
block 1: sig: 1 x: 249 y: 128 width: 62 height: 14 angle 0
block 2: sig: 1 x: 131 y: 85 width: 13 height: 3 angle 0
block 3: sig: 1 x: 293 y: 117 width: 22 height: 3 angle 0
block 4: sig: 1 x: 212 y: 141 width: 8 height: 4 angle 0
block 5: sig: 2 x: 62 y: 165 width: 104 height: 18 angle 0
block 6: sig: 2 x: 129 y: 27 width: 13 height: 4 angle 0
Detected 6:
block 0: sig: 1 x: 129 y: 101 width: 18 height: 32 angle 0
block 1: sig: 1 x: 260 y: 125 width: 79 height: 18 angle 0
block 2: sig: 1 x: 212 y: 141 width: 8 height: 4 angle 0
block 3: sig: 2 x: 60 y: 168 width: 112 height: 27 angle 0
block 4: sig: 2 x: 25 y: 146 width: 15 height: 3 angle 0
block 5: sig: 2 x: 82 y: 147 width: 10 height: 2 angle 0
reorder

Not sure if it will work for you, but did you once try to clock UART to 38400 ?

Hello Vadim,
We’re looking into this and will get back to you.

Edward./

Hello Edward!
Im seeing exactly what Helmut posted, but I think that im seeing a little less of reorder prinouts and more “cs errors”.
Anyhow, there is even a bigger issue.
Im running a standard/latest library/pixymon/firmwhare as described above. I poll pixy and I get blocks with regular cs and reorder errors.
Then at some point, I stop polling pixy and immediately turn the power to pixy off via relay. Due waits for about an hour, then turns the relay back on,
i wait a few seconds to let pixy power up and start polling it again. I dont get any blocks back!

Usually, Pixy powers on and starts returning data normally as expected. When it doesnt, it appears that the only way to reset it is to turn the power to everything off and on.

I wrote a function in my main to deal with this case and here is what I tried
@
void checkCamera(){
// poll camera, see if we get anything back. If not, something is wrong. Attempt to restart
unsigned long now = millis();
while(1){//dumb fix
while ( millis() - now < 8000){//read camera for at least 8 seconds
GetDetectedSigs(); //this method polls camera and stores information, like x,y coordinates
if(blocks ){ //are there ANY blocks?
return; //everything is cool
}
delay(100); //slow down polling
}
Relay.PowerOff(); //turn off power to pixy
delay(2000);
Relay.PowerOn(); //turn on power to pixy
delay(1000);
pixy.init(); //try to reinitialize pixy camera. THis line was commented out in earlier testing , doesnt fix it
delay(5000);

}
}
@
To summarize, i tried turning power to pixy on and off, even call pixy.init() again. IT looks like there are linking issues.
Ive been using pixy for a long time, almost since it was released on a market and my vision code has not been modified alot.
I have not had this issue before upgrading to new firmware.
I will try bumping up UART higher and let you know it goes.

Thank you!

Hello Vadim,
I’m not sure what your setup is, but it’s sometimes possible for Pixy to receive power through the I/O connector even when you cut power to the power connector.

As an experiment you might try unplugging all cables while Pixy is off.

Edward

Maybe you can try to clock UART to 115200.

The lower baudrate you set, the more “cs error” and “reorder” occurred.

Jamie

Hey guys!
First things first, thank you all for helping me figure out how to fix this issue.

I tried changing UART speed to 9600 and 115200 baud rates and didnt see any improvements.
I dont believe that Pixy is still getting powered trough I/O connector when I cut the power.
I power pixy trough a USB socket (i give it regulated 5V) and cut the +5v with a solid state relay.
The ground on the USB is still connected to my circuit. On my I/O connector, I have rx/tx pins connected
and pin 10 (GND) grounded. I dont think that rx/tx pin source a significant amount of current (if any).
I tried disconnecting signal ground (pin 10, maybe there are ground loops or something else funny going on).
Pixy still works but the bug is not fixed.

I think that there is a problem with how pixy links with DUE. I found a way to brick a pixy last night.
I first polled pixy for a while and it was returning data. Then, i had DUe do something else and not talk to
pixy whatsoever. During that time window, I yanked out power from pixy. Shortly after, DUE was trying to get blocks
from pixy and it looked like the DUE froze waiting for blocks…The due resumed running right after I plugged pixy power back on.

I still dont know why pixy just stops returning data sometimes. I know that Pixy is seeing signatures because its LED light is changing and blinking
as its seeing things around

There is something with @blocks = pixy.getBlocks();@ that doesnt work on DUE. DUE’s code gets stuck on @blocks = pixy.getBlocks();@ if pixy loses power.
I temporarily fixed this problem by taking a second microcontroller (arduino FIO) and connecting it to DUE via software serial. Before calling @getBlocks@ I have due send a certain hex byte to FIO, and then FIO expects another byte back. If the next byte does not arrives, FIO resets DUE and power cycles pixy by flipping some transistors on and off. This is a super duct tape solution but it works. I downgraded pixy firmware down to 1.0.2 betta and seeing this happen as well.

Hello Vadim,
You are saying the getBlocks() will not return if Pixy loses power. I’m pretty sure this is because Pixy is not returning any data and your Arduino is stuck waiting for data. Or maybe you are saying that if you interrupt power to Pixy, getBlocks() will not return, even though power to Pixy is restored? Please confirm.

Edward

Hello Edward!

So there are two different ways Due gets stuck in
Way #1;

  1. Arduino DUE has power, pixy has power via USB socket (both vcc and gnd are connected), I/O connector has UART serial pins and GND wired up

  2. Arduino calls getBlocks(), pixy returns data, everything is working as epxected

  3. Arduino stops calling getBlocks(), delay(ten seconds) or do something else in a mean time

  4. while Arduino is not calling getBlocks(), pull out USB power so that pixy is unpowered

  5. Eventually the code will attempt to run this
    @
    Serial.println(“Foo”);
    blocks=getBlocks();
    Serial.println(“Bar”);
    @
    Foo will print, Bar will not. The code is stuck in @getBlocks()@ function call

  6. plug in USB power again so that pixy is powered.

  7. At this point the code exits @getBlocks()@ and “Bar” will be printed. After this, sometimes pixy will not return ANY data back forever and the only
    way to fix the problem is to hold down Arduino’s reset button for me (which will also kill the power to pixy since I have a normally open relay which kills power to pixy). Holding reset buttons restarts everything.
    Again to reiterate, after this happens getBlocks() is not returning any data and the arduino is not stuck in a function call. My robot drives around blindly. Pixy is definitely seeing signatures because LED is changing lights but nothing is getting returned;

Way #2;
I have a switch which disconnects the battery from the circuit. When I turn the switch ON, sometimes pixy bricks instantly.
When this happen, arduino freezes (im actually not sure if it gets stuck in getBlocks() here ), and the LED on pixy gets stuck showing super bright white light. If you show pixy known colors, the LED is not changing colors, pixy looks bricked. Turning switch off and on fixes the problem

Hello Vadim,
In Way #1, it is a strange case of removing power from Pixy. Pixy may be receiving insufficient power through the I/O port after you unplug USB and it may explain what you are seeing.

In Way #2, is everthing being powered through the battery? How is Pixy receiving power? (See item 1: http://cmucam.org/projects/cmucam5/wiki/My_pantilt_is_acting_sort_of_crazy)

Edward

Vadim,

When you’re modifying the Pixy Arduino library files, make sure you’re editing the files in your /Arduino/libraries/Pixy folder. When you import the Pixy library, the library sources are copied to this location.

I was able to remove the “reorder” and “cs error” log prints from TPixy.h (see below for code snippets).

TPixy.h:
@188: checksum = link.getWord();@
@189: if (checksum==PIXY_START_WORD) // we’ve reached the beginning of the next frame@
@190: {@
@191: skipStart = true;@
@192: blockType = NORMAL_BLOCK;@
@193: //Serial.println(“skip”);@
@194: return blockCount;@
@195: }@

and…

TPixy.h:
@222: if (checksum==sum)@
@223: blockCount++@
@224:// else@
@225:// Serial.println(“cs error”);@
@226:@

This won’t break the library and will save code space.

Thanks,
John

In summary, John did a fair amount of testing on DUE in UART mode and found no real issues other than FIFO overruns. (so what does that mean?)

In general, the FIFO on the Arduino UARTs (whether it’s DUE or Uno) is not very deep. This means that if you do something in your program besides reading from the UART (like printing a debug message through the serial port), you will likely lose bytes coming from Pixy. And when your Arduino loses bytes, it gets partial object blocks, which result in checksum errors, etc.

The communication code can cope with this just fine, but it results in a message being printed (“cs error” which means checksum error and “reorder” which means it lost byte-sync.) In the next version of the Arduino library we will remove the code that prints these messages. They are there only for debugging, and they have the side-effect of causing more bytes to be lost! So we get into a sort of positive feedback loop of errors.

There are a couple ways to deal with this:

  1. Definitely remove teh code that prints the messages (as John describes above).
  2. Don’t worry about it. The lost bytes are part of UART communication. Unless you dedicate all (or most) of your processor’s time to reading bytes from teh UART port, you are going to lose bytes, but that’s a fair trade-off because you shouldn’t be spending that much time reading from the UART anyway (your processor has more important things to do!)
  3. Reduce the baud rate. This will allow the Arduino’s serial FIFO to fill up more slowly, giving you more time to do other tasks in your program.
  4. Use I2C or SPI interface to communicate with Pixy (if you can). These interfaces don’t have overrun issues because of the extra handshaking they use.
  5. Use an interrupt-driven buffered scheme, which will essentially increase your FIFO size. This is more complicated, but googling around it appears that some people have done this (or similar) for the various Arduinos:

Using interrupt-driven buffering is what’s typically done in these situations (in the embedded world.) It allows the main thread of your processor to do its thing while interrupts occur in the background and data is received and put in a large fifo queue for your processor to deal with when it has time. It also has the advantage that your processor isn’t wasting time busy-waiting for data to arrive.

Hope this helps!