Was anyone here lucky enough to communicate with pixy using spi on any gadgeteer board?
Nope, I am still waiting for an update to the firmware so it can detect more complex stuff.
Will definately be interested! ;D
I have one of these nut I haven’t taken it out of the box yet. Looking forward to hearing you guys get it working.
I received my pixy and tested the Arduino code, I tried to port it to .netmf but nothing is working. There are differences in the SPI libraries between Arduino and .Net that I don’t know about it. If someone interested please inspect the following code. It is almost 1 to 1 translation from arduino to .net
using System;
using Microsoft.SPOT;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.SocketInterfaces;
using Microsoft.SPOT.Hardware;
using Gadgeteer.SocketInterfaces;
namespace Gadgeteer.Modules.AM
{
/// <summary>
/// A PixySPI module for Microsoft .NET Gadgeteer
/// </summary>
public class PixySPI : GTM.Module
{
private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000;
private static void DelayMicroseconds(int microSeconds)
{
long stopTicks = DateTime.Now.Ticks +
(microSeconds * TicksPerMicrosecond);
while (DateTime.Now.Ticks < stopTicks) { }
}
Socket _socket;
GTI.Spi _spi;
GTI.SpiConfiguration _config;
LinkSPI spidriver;
// Note: A constructor summary is auto-generated by the doc builder.
/// <summary></summary>
/// <param name="socketNumber">The socket that this module is plugged in to.</param>
/// <param name="socketNumberTwo">The second socket that this module is plugged in to.</param>
public PixySPI(int socketNumber)
{
_socket = Socket.GetSocket(socketNumber, true, this, null);
_socket.EnsureTypeIsSupported('S', this);
_spi = SocketInterfaces.SpiFactory.Create(_socket, _config, SpiSharing.Shared, _socket, Gadgeteer.Socket.Pin.Six, this);
spidriver = new LinkSPI(_spi);
skipStart = false;
blockCount = 0;
blockArraySize = PIXY_INITIAL_ARRAYSIZE;
blocks = new Block[blockArraySize];
}
private class LinkSPI
{
static byte PIXY_SYNC_BYTE = 0x5a;
static byte PIXY_SYNC_BYTE_DATA = 0x5b;
static byte PIXY_OUTBUF_SIZE = 6;
byte[] outBuf = new byte[PIXY_OUTBUF_SIZE];
byte outLen;
byte outIndex;
GTI.Spi _spi;
public LinkSPI(GTI.Spi spi)
{
outLen = 0;
_spi = spi;
}
public UInt16 GetWord()
{
// ordering is different because Pixy is sending 16 bits through SPI
// instead of 2 bytes in a 16-bit word as with I2C
UInt16 w;
byte c, cout = 0;
byte[] recieveBuffer = new byte[2];
if (outLen > 0)
{
cout = outBuf[outIndex++];
if (outIndex == outLen)
outLen = 0;
_spi.WriteRead(new byte[] { PIXY_SYNC_BYTE_DATA, cout }, recieveBuffer);
//w = _spi.transfer(PIXY_SYNC_BYTE_DATA);
}
else
{
_spi.WriteRead(new byte[] { PIXY_SYNC_BYTE, cout }, recieveBuffer);
//w = _spi.transfer(PIXY_SYNC_BYTE);
}
w = (UInt16)(((UInt16)recieveBuffer[0]) << 8);
w |= recieveBuffer[1];
//w <<= 8;
//c = _spi.transfer(cout);
//w |= c;
return w;
}
public byte GetByte()
{
byte[] buffer = new byte[1];
_spi.WriteRead(new byte[] { 0x00 }, buffer);
return buffer[0];
}
public int send(byte[] data, byte len)
{
if (len > PIXY_OUTBUF_SIZE || outLen != 0)
return -1;
//memcpy(outBuf, data, len);
data.CopyTo(outBuf, 0);
outLen = len;
outIndex = 0;
return len;
}
}
public Block[] blocks
{
get;
private set;
}
bool skipStart;
ushort blockCount;
ushort blockArraySize;
static byte PIXY_INITIAL_ARRAYSIZE = 30;
static byte PIXY_MAXIMUM_ARRAYSIZE = 130;
static ushort PIXY_START_WORD = 0xaa55;
static ushort PIXY_START_WORDX = 0x55aa;
static byte PIXY_DEFAULT_ADDR = 0x54; // I2C
public struct Block
{
public void Print()
{
//char[] buf = new char[64];
//sprintf(buf, "sig: %d x: %d y: %d width: %d height: %d\n", signature, x, y, width, height);
string buf = "sig: " + signature + " x: " + x + " y: " + y + " width: " + width + " height: " + height;
//Serial.print(buf);
Debug.Print(buf);
}
public ushort signature;
public ushort x;
public ushort y;
public ushort width;
public ushort height;
}
bool GetStart()
{
ushort w, lastw;
lastw = 0xffff;
while (true)
{
w = spidriver.GetWord();
if (w == 0 && lastw == 0)
{
DelayMicroseconds(10);
return false;
}
else if (w == PIXY_START_WORD && lastw == PIXY_START_WORD)
return true;
else if (w == PIXY_START_WORDX)
{
//Serial.println("reorder");
DebugPrint("Reorder");
spidriver.GetByte(); // resync
}
lastw = w;
}
}
void Resize()
{
Block[] newBlocks;
blockArraySize += PIXY_INITIAL_ARRAYSIZE;
newBlocks = new Block[blockArraySize];
//memcpy(newBlocks, blocks, sizeof(Block)*blockCount);
blocks.CopyTo(newBlocks, 0);
blocks = newBlocks;
}
//public int SetServos(ushort s0, ushort s1)
//{
// byte[] outBuf = new byte[6];
// outBuf[0] = 0x00;
// outBuf[1] = 0xff;
// var temp = GetBytes(s0);
// outBuf[2] = temp[0];
// outBuf[3] = temp[1];
// //*(uint16_t *)(outBuf + 2) = s0;
// temp = GetBytes(s1);
// outBuf[4] = temp[0];
// outBuf[5] = temp[1];
// //*(uint16_t *)(outBuf + 4) = s1;
// return spidriver.send(outBuf, 6);
//}
public static byte[] GetBytes(ushort value)
{
return new byte[2] { (byte)(value & 0xFF), (byte)((value >> 8) & 0xFF) };
}
public ushort GetBlocks(ushort maxBlocks)
{
byte i;
ushort w, checksum, sum;
Block block = new Block();
if (!skipStart)
{
if (GetStart() == false)
{
return 0;
}
}
else
{
skipStart = false;
}
for (blockCount = 0; blockCount < maxBlocks && blockCount < PIXY_MAXIMUM_ARRAYSIZE; )
{
checksum = spidriver.GetWord();
if (checksum == PIXY_START_WORD) // we've reached the beginning of the next frame
{
skipStart = true;
//Serial.println("skip");
return blockCount;
}
else if (checksum == 0)
{
return blockCount;
}
if (blockCount > blockArraySize)
{
Resize();
}
blocks[blockCount] = block;
//for (i=0, sum=0; i<sizeof(Block)/sizeof(uint16_t); i++)
for (i = 0, sum = 0; i < 5; i++)
{
w = spidriver.GetWord();
sum += w;
block.signature = w;
w = spidriver.GetWord();
sum += w;
block.x = w;
w = spidriver.GetWord();
sum += w;
block.y = w;
w = spidriver.GetWord();
sum += w;
block.width = w;
w = spidriver.GetWord();
sum += w;
block.height = w;
//*((uint16_t *)block + i) = w;
}
if (checksum == sum)
{
blockCount++;
}
else
{
//Serial.println("cs error");
DebugPrint("checksum error");
}
w = spidriver.GetWord();
if (w != PIXY_START_WORD)
{
return blockCount;
}
}
return blockCount;
}
}
}
I am thinking of buying one of these cams. Did anyone get it working yet? I am happy to try and debug the c# code if required. Looks like the board supports i2c, spi, and uart. I wonder if any of these other protocols have been tried?
Also, did the wiring connection work with a standard gadgeteer cable, or was some adjustment required to the pins?
Thank you!
I bought one and I finally got PixyCam working and debugged. I have posted full code solution on codeshare:
https://www.ghielectronics.com/community/codeshare/entry/1017
Welcome to 50fps robot vision and object detection using .NET MF 4.3!
Enjoy!