<< return to Pixycam.com

reading pixy data to dspic33f using spi

Hi there,
I am confused about four, very fundamental things when I try to read data from pixy using 4-wire spi protocol:
(1) Can I see the cooked video feed from usb while I get object data from pixy using ss, sck, sdo pins for a single stationary object?
(2) If I don’t use the usb port (one blog claims that the processing may be too overwhelming for pixy to send usb and spi data together), how am I going to introduce a single object to pixy? I bet you would say to use the white button, but how?
(3) The power supply for the camera is 5V but the logic levels are 3.3V? Correct?
(4) The last is the dumbest question: If I connect SS to 0V, and sck to an external clock, would I repeatedly get the start word followed by the checksum, signature etc. in a repeated fashion for a single stationary object?
I intend to use Microchip dspic33f for the processor which I already know how to use its spi interface.
Many thanks.

Ok, I figured out a couple of things since I posted my original question. However, majority of the issues are still unanswered.
At the moment, I have a usb connection and seeing a single steady object on the camera. It detects a single object with a signature code of s=1. I have connected the camera to dspic33f using the spi pins on the back of the camera (SS to SS, SCK to SCK, SDO on the camera to SDI on the dspic33f). I initiate the process by lowering the SS pin and stating the SCK. There is a burst of 8 clock periods during which I expect a byte from pixy, each bit delivered at the negative edge of SCK. The SS signal is low during these 8 clock periods, then it goes high momentarily before going low again to receive the second 8 bits of data. This scenario repeats itself 12 times to receive the complete object data. My controller’s spi unit works with bytes not 16-bit words so I know that I have to do post-processing later on. The SCK frequency is about 30KHz. However, there is not a single data coming from pixy, no start byte, no signature, nothing. Perhaps, I am overclocking the pixy since it needs only 5KHz to deliver data for a single object. Do I have to go down in frequency on my processor to match the frequencies?
I read all the articles on Wiki and examined the sample code given. But, my case is very simple: I just need to see some bytes coming out of pixy. Do I need to change the default configuration on the camera? I have no clue where to go from here. I would appreciate any suggestions.

Hello Windsurfer,
If you are not using an Arduino with SPI, you should use the “SPI with SS” mode. There is more information here:

http://cmucam.org/projects/cmucam5/wiki/Interface_Pane

Hope this helps!

Edward

Hello Ed,

Thanks for the answer. However, I did all that, my interface is set at spi with ss in the data output port in the configuration window, but I don’t have any data from pixy. As I said my earlier blog, the current SCK frequency from the pic processor is 35KHz on my logic analyzer, you would need only 5KHz to get a single object data. At this point, I just want to get raw data. Later on, I do more programming to parse the data.

Below is a portion of my code. There are processor-compliant names like SPI1STATbits.SPITBF etc.that relates to the spi rx/tx buffer in the processor. The 2 function calls sends/gets 8 bit data from the device. The for loop is to collect the initial 12 bytes of data into byte[12] array (later on I will do another for loop to get more object data).
Do I have to do anything with signature labels, tuning or max blocks (max blocks and max blocks per signature are set 1000 by default) in the configuration window? Right now, usb is providing the power to the camera and giving a video feed on my pc screen. I connected spi wires between the cpu and pixy. What do you suggest I should do? I am truly stuck here :slight_smile: Take care.

.
.
.

unsigned char SPI_Transmit (unsigned char TxValue)
{
while (SPI1STATbits.SPITBF == 1); // Wait until the TX buffer is empty due to a prior process
SPI1BUF = TxValue; // When empty, send the byte to the TX buffer
while (SPI1STATbits.SPIRBF == 0); // As valid bits shifts out of the SDO port, junk bits are received from the SDI port
// Wait until the RX buffer is full of junk data
return SPI1BUF; // When full, read the junk data in RX buffer through SPI1BUF
}

unsigned char SPI_Receive ()
{
while(SPI1STATbits.SPITBF == 1); // Wait until the TX buffer is empty due to a prior process
SPI1BUF = 0x00; // When empty, send the junk byte (0x00) to the TX buffer
while(SPI1STATbits.SPIRBF == 0); // As junk bits shifts out of the SDO port, valid bits are received from the SDI port
// Wait until the RX buffer is full of valid data
return SPI1BUF; // When full, read the valid data in RX buffer through SPI1BUF
}
.
.
.
unsigned int i;
unsigned int byte [12];

for (i = 0; i < 12; i++) // Take 12 bytes of data from an single steady object
{
LATBbits.LATB6 = 0; // Lower SS for object data reception
byte [i] = SPI_Receive (); // Read from the high start to low height byte
LATBbits.LATB6 = 1; // Raise SS for object data completion
}
.
.
.

Hi Ed,

After I sent you my code, I made some changes in the configuration window and also in my code.
In the config window, I changed the signature label to 1, I tuned the signature so the box around the object is steady now. I also changed the max blocks to 1 and max blocks per signature to 1.
In my code, I changed the SCK frequency to 3.6KHz. I cannot tune SCK at exactly 4.8KHz (the next step is 7.2KHz). However, this didn’t really matter in getting the sync code, 0xAA55. I left the earlier function calls for spi transmit and receive the same, but I changed the last part of the program as follows:
.
.
unsigned int i;
unsigned int byte [12];

LATBbits.LATB6 = 0; // Lower SS for object data reception

for (i = 0; i < 12; i++) // Take 12 bytes of data from an single steady object
{
byte [i] = SPI_Receive (); // Read from the high start to low height byte
}

LATBbits.LATB6 = 1; // Raise SS for object data completion
.
.
As a result, I got the sync code, 0xAA55, from the pixy. However, the rest of the 10 bytes for the object are all 0xFF (please screenshot attachment of the logic analyzer).

I am still in trouble because I cannot get anywhere from here (all my ideas are exhausted).
I would appreciate if you can help!
Take care.

Ahmet

Hello,
You also need to toggle the SS signal for each byte. That is, it needs to go high then low before you receive the next byte.

Edward

Dear Ed,

I also did what you are suggesting in my first attempt. Please see the sample code below and what I get from the camera as a screenshot image.
LATBbits.LATB6 = 0 lowers the SS and LATBbits.LATB6 = 1 raises SS for EACH of the 12 bytes. All I am getting for each byte is 0xAA.
So, these are the possible scenarios why things are not working:
(1) May be this is a bad camera?
(2) Firmware problem?
(3) May be I should not connect USB to to the camera and see the image (and object box) when I am trying to acquire object data through SPI?
(4) The frequency of SCK during acquisition needs to match perfectly (I use 3.6KHz, camera needs 4.8KHz)?
(5) I need to send a sync word 0x5A00 before receiving a meaningful byte from the camera?
Please see the screenshot image!! I have been on this for the past week or so, and I really don’t know what else to do. My processor and the SPI protocol I employ works with many memory devices (sram, flash) and peripherals (accelerometer, gyroscope, microphone etc that use SPI).
Please help out!
Take care.

Ahmet

unsigned int i;
unsigned int byte[12];

for (i = 0; i < 12; i++) // Get 12 bytes of data from an single steady object
{
LATBbits.LATB6 = 0; // Lower SS for object data reception
byte[i] = SPI_Receive();
LATBbits.LATB6 = 1; // Raise SS for object data completion
}

Hello,
You don’t need to send sync bytes (0x5A) if you are using “SPI with SS” communication mode. Hmmm… other things to verify:

Make sure also that you are in Default mode if you have USB hooked up, otherwise no data will be sent over. And of course, Pixy needs to be detecting an object (check the LED – it will illuminate when it detects something).

Edward

Hi Ed,

I was not in default mode but in the cooked mode (how shall I know?). Things started happening when I switched the modes.
Please don’t take it negatively but this device is a little frustrating to work on. Here is why:

(1) When USB is connected to the device
I had no data from the device WITHOUT the sync code (you said I don’t need it because I supply SS).
However, when I turned on the sync (0x5A followed by 0x00), I started getting the 0xAA55 followed by the rest of the object data.
But, at times I got lots of 0xAA55 one after another before seeing the rest of block data. Now, I know I need to do cleaning!

(2) When USB is disconnected and an external 5V supply is connected to the camera
I still give the device 0x5A followed by 0x00, but I got no response from the device (0xFFFF). No change whatever I did.

(3) USB is back on the device
The same thing. Nada! No data is from the device, all 0xFFFF.

I have no idea why this device is so finicky. I have to use the camera without USB so standalone mode is really important.
Do you have any idea? Please don’t lose hope on me. Any feedback is useful.
Here is the part of the code:


unsigned char SPI_Exchange (unsigned char Value)
{
while (SPI1STATbits.SPITBF == 1); // Wait until the TX buffer is empty due to a prior process
SPI1BUF = Value; // When empty, send the sync byte to the TX buffer
while (SPI1STATbits.SPIRBF == 0); // As sync bits shifts out of the SDO port of the CPU, pixy bits are received from the SDI port
// Wait until the RX buffer is full of pixy data
return SPI1BUF; // When full, read the pixy data in RX buffer through SPI1BUF
}

while (1)
{
LATBbits.LATB6 = 0; // Lower SS for object data reception
SPI_Exchange(0x5A);
SPI_Exchange(0x00);
LATBbits.LATB6 = 1; // Raise SS for object data completion
}

Take care,

Ahmet

Hello Ahmet,
Here is some information on the different modes:

http://cmucam.org/projects/cmucam5/wiki/PixyMon_Overview – in particular you should watch the video on this page.

Pixy will switch to cooked mode by default when you plug in USB and PixyMon is running (because this is what most users want when running PixyMon).

Edward

Hi Edward,

My problem is not with the usb or with the pixymon running in default mode. I am getting sensible data this way now.
I am having trouble when I use only spi signals, SS, SCK, MOSI, MISO, and powering the camera with a 5V external supply (pin 2) without any usb connection.
Can you possibly propose something about this? There is not much information or video when the pixy is not using usb and disconnected from the PC.
Have a good weekend.

Ahmet

Hello Ahmet,
The USB connection should not make any difference other than providing a 5V power supply. Can you describe your 5V power supply setup? Note that Pixy needs 150mA of current at 5V, which is too much for many linear regulators, particularly the ones used by many Arduino boards. You might want to look at the 5V supply with a scope.

There are some notes about powering Pixy here:
http://cmucam.org/projects/cmucam5/wiki/Powering_Pixy

Edward

Dear Ed,

I was also thinking that usb was there only to supply the current but nothing else.
Anyhow, I am using an external old HP power supply that has 2 terminals. Both change between 0 and 20V with a regulated current of 2A.
The +5V goes to pin 2 or the pixy, and ground goes to pin 6 (although I could have connected the ground to pin 8 or pin 10).
However, now you mention it I think I should check with an ammeter the DC current going to pixy. Any other suggestions?

One crucial thing that I need to know: When you remove the usb cable and connect the camera to the cpu only with the spi wires and 5V supply, how does the camera know that it needs to be default mode but not in raw or cooked modes?
The only thing I do is to push the white button when I put the object in front of the camera. The LED on pixy changes to red, indicating that it sees a red ball.
But, I have no idea what mode pixy is in. Any way to check it without pixymon??

Again many thanks, Ed.

Ahmet

Hello Ahmet,
Raw and cooked modes are only available when the USB cable is plugged in and PixyMon is running. As soon as you either unplug the USB cable or exit PixyMon, Pixy goes into default mode. So in other words, your Pixy is in default mode when connected to your CPU.

If your Pixy is behaving differently with your power supply vs being powered through USB, it’s a good indicator that the problem is in the power supply domain. The usual suspects are noise in the supply, sagging voltage, or both.

Edward

Hello Ed,

Finally, it started working without the usb :slight_smile:
After powering up the controller, the camera and the logic analyzer, I run the program at least 7 times before the camera showed any sign of life. In the first 4 tries it showed no sign, all 0xFFFF. In the fifth time it responded once to an SCK edge. Then in the sixth, two responses. Then finally it showed the full data. All connections, including the power is solid. I cannot explain this erratic behavior. Do you have any idea?

Ahmet

Hello Ahmet,
Hmm, that is indeed odd. I don’t think I asked this before – what version of firmware are you running?

Assuming you’re running the latest (2.0.19) and still having issues, we could send you a new Pixy to swap in to help rule out hardware issues.

Edward

Hi Ed,

Yes, I think I did update the firmware but I am terrible with update stuff. I always push the wrong buttons :slight_smile:
How would I find out what version is currently on the chip?
I tried to find the version number through pixymon, but couldn’t get anywhere.
Please let me know how.

Ahmet

Hello Ahmet,
Bring up PixyMon with your Pixy plugged in and then select Help->About. It will display the PixyMon version and the firmware version.

Edward

Hi Ed,

Ok, I got it. I will let you know if I encounter the same problems.

Ahmet