<< return to Pixycam.com

Can't find frame/block start bytes using .NET Gadgeteer boards using NETMF and SPI

I’ve successfully created an SPI cable to plug in to a .NET Gadgeteer Raptor board (from GHI electronics), and got the Raptor talking over SPI to the Pixycam/CMUcam5. I’ve converted the Arduino code into C# .NET and it ‘works’ to some extent.

However, while I do see data coming from the cam (I cover the lens an I get no data, I uncover it and I get data), I don’t get a start of frame or block marker (AA 55 hex or 170 85 decimal). When I use PixyMon on my PC, I see an object detected and its signature 1. On the Raptor I do get bytes 170 170 (and 85 85 regularly, but NOT 170 85) and here’s an example of the bytes that follows, any ideas why I am not seeing AA 55 hex or 170 85 decimal? If there anything I need to do in the PixyMon configuration, I have created a signature and it identifies the object OK, and have set the output interface type to zero (SPI with no Slave Select)?

170
170
5
48
0
32
39
128
115
0
152
1
84
85
82
80
45
64
0
0
62
1
160
2
224
11

Would any SPI settings (clock, rising edge sampling, clock idle high/low) or any 2s compliment stuff alter/corrupt the data coming in? I am assuming because I’m seeing data coming from the cam that I have the SPI setting right. I have played about with some of the SPI settings…

SPI.Configuration PixyCamSPIConfig = new SPI.Configuration(
                Cpu.Pin.GPIO_NONE,  //chip select port (was Cpu.Pin.GPIO_Pin1)
                false,              //chip select active state
                0,                  //chip select setup time
                0,                  //chip select hold time
                false,              //clock idle state
                true,               //clock edge
                1000,               //clock kHz (1mhz)
                spiModule           //SPI module defined above
                );

My code to read data is very similar to Arduino code…

    private byte GetByte(byte dataInTheOutQueue)
    {
        byte[] buffer = new byte[1];
        PixyCamSPI.WriteRead(new byte[] { dataInTheOutQueue }, buffer);
        Debug.Print("read byte:" + buffer[0]);
        return buffer[0];
    }

Code to Get start of frame… (never finds the start of frame because it never finds 170 85)…

private const UInt16 PIXY_FRAME_START_WORD = 0xaa55; //2 of these = start of new frame or one of these followed by…
private const UInt16 PIXY_FRAME_START_WORD_CC = 0xaa56; //one of these (cc=colour code object)
private const UInt16 PIXY_START_WORD_WRONG_ORDER = 0x55aa; //need to resync if this is read (one byte out when reading)

    private bool GetStartOfFrame()
    {
        UInt16 w;
        UInt16 lastw = 0xffff;
        Debug.Print("getting start of frame...");
        while (true)
        {
            w = GetWord();
            if (w==0 && lastw==0)
            {
                Thread.Sleep(1);
                return false;
            }
            else if (w==PIXY_FRAME_START_WORD && lastw==PIXY_FRAME_START_WORD)
            {
                _IsColourBlock = false;
                return true;
            }
            else if (w==PIXY_FRAME_START_WORD_CC && lastw==PIXY_FRAME_START_WORD)
            {
                _IsColourBlock = true;
                return true;
            }
            else if (w==PIXY_START_WORD_WRONG_ORDER)
            {
                GetByte(0); // resync
            }
            lastw = w;
        }
    }

Hello Stuart,
Indeed, if you are not getting a start code, there is something amiss. I’m not familiar with your platform, but you might try reducing the datarate. It could be a simple issue of a short fifo (or no fifo) and when you print data, you overrun the fifo. That would be my guess.

Hope this helps!

So, I finally got it working, using SPI! Although I was getting data through I could not find the frame start marker, but when I changed the clock idle state flag from false to true, I get good data!
(If set to true, the SPI clock signal will be set to high while the device is idle; if false, the SPI clock signal will be set to low while the device is idle)

I will post full code once I get all the bugs ironed out (hopefully this week), but in the meantime, the C# .NET code to create the SPI is this…

    public PixyCam(int socketNumber)
    {
        //raptor sockets 1,3, 11 support spi
        Socket spiSocket = Socket.GetSocket(socketNumber, true, this, null);
        spiSocket.EnsureTypeIsSupported('S', this);
        SPI.SPI_module spiModule = spiSocket.SPIModule;
        SPI.Configuration PixyCamSPIConfig = new SPI.Configuration(
            Cpu.Pin.GPIO_NONE,  //chip select port - not required for ICSPI like Arduino no slave select
            false,              //chip select active state - If true, the chip select port will be set to high when accessing the chip; if false, the chip select port will be set to low when accessing the chip
            0,                  //chip select setup time - amount of time that will elapse between the time at which the device is selected and the time at which the clock and the clock data transmission will start
            0,                  //chip select hold time -  specifies the amount of time that the chip select port must remain in the active state before the device is unselected
            true,              //clock idle state - If true, the SPI clock signal will be set to high while the device is idle; if false, the SPI clock signal will be set to low while the device is idle
            true,               //clock edge - If true, data is sampled on the SPI clock rising edge; if false, the data is sampled on the SPI clock falling edge
            1000,               //clock kHz (1mhz) - 1000=1Mhz sampling rate
            spiModule           //SPI module defined above
            );
           SPI PixyCamSPI = new SPI(PixyCamSPIConfig);

}

Hello Stuart,
Nice work! And thanks for offering to share the code!

Edward

Full .NET source code for this solution and a description of how to wire it and getting started can be found here:

https://www.ghielectronics.com/community/codeshare/entry/1017

Pixy CMUcam5 now works on .NET Micro framework mainboards like the Raptor etc. Enjoy!

Hello Stuart,
This is really cool! We just sent this out on Twitter and Facebook. (Hope you don’t mind!)

Edward