Ruprecht Altenburger
/
TPixy-Interface
SPI read Pixi Cam V1
Revision 5:d109b094d4bb, committed 2021-08-28
- Comitter:
- altb2
- Date:
- Sat Aug 28 13:03:58 2021 +0000
- Parent:
- 4:478d4d9193a1
- Commit message:
- Pixy Cam V1 Interface with UARt connection. Just connect the TX -> RX pin and power supply (see Pixy cam doc)
Changed in this revision
diff -r 478d4d9193a1 -r d109b094d4bb Pixy.cpp --- a/Pixy.cpp Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -#include "Pixy.h" - -ServoLoop::ServoLoop(int32_t pgain, int32_t dgain) -{ - m_pos = PIXY_RCS_CENTER_POS; - m_pgain = pgain; - m_dgain = dgain; - m_prevError = 0x80000000L; -} - -void ServoLoop::update(int32_t error) -{ - long int vel; - if (m_prevError != 0x80000000) { - vel = (error*m_pgain + (error - m_prevError)*m_dgain) >> 10; - m_pos += vel; - if (m_pos > PIXY_RCS_MAX_POS) { - m_pos = PIXY_RCS_MAX_POS; - } else if (m_pos < PIXY_RCS_MIN_POS) { - m_pos = PIXY_RCS_MIN_POS; - } - } - m_prevError = error; -} -
diff -r 478d4d9193a1 -r d109b094d4bb Pixy.h --- a/Pixy.h Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -#ifndef _PIXY_H -#define _PIXY_H - -#include "TPixy.h" -#include "TPixyInterface.h" - -#define X_CENTER ((PIXY_MAX_X-PIXY_MIN_X)/2) -#define Y_CENTER ((PIXY_MAX_Y-PIXY_MIN_Y)/2) - -/** The SPI Pixy interface for the Pixy camera - * @code - * #include "Pixy.h" - * Serial serial(USBTX, USBRX); - * SPI spi(p5, p6, p7); - * PixySPI pixy(&spi, &serial); - * - * int main() { - * runPanTiltDemo(); - * } - * @endcode - */ - -class PixySPI : public TPixy<PixyInterfaceSPI> -{ -public: - /** Constructor for the PixySPI class - * Instantiates a Pixy object that communicates via an SPI connection - * @param SPI* spi the pointer to the SPI connection - * @param Serial* serialOut the optional serial output pointer to print out Pixy camera data - * @param int arg an optional integer argument used for custom implementations of the Pixy library - */ - PixySPI(SPI* spi, BufferedSerial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL) : - TPixy<PixyInterfaceSPI>((new PixyInterfaceSPI(spi)), serialOut, arg) {} -}; - - -/* Not Implemented */ -/* -class PixyI2C : TPixy<PixyInterfaceI2C> { - public: - PixyI2C(I2C* i2c, Serial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL) : i2cInterface(i2c), TPixy<PixyInterfaceI2C>(i2cInterface, serialOut, arg); - private: - TPixyInterface<I2C>* i2cInterface; - }; - */ - -class ServoLoop -{ -public: - /** Constructor for a ServoLoop object - * Creates a ServoLoop object for easy control of the Pixy servos - * @param pgain the proportional gain for the control - * @param dgain the derivative gain for the control - */ - ServoLoop(int32_t pgain, int32_t dgain); - /** Update method for a ServoLoop object - * Updates the m_pos variable for setting a Pixy servo - * @param error the error between the center of the camera and the position of the tracking color - */ - void update(int32_t error); - - int32_t m_pos; - int32_t m_prevError; - int32_t m_pgain; - int32_t m_dgain; -}; - -/** Basic Pan/Tilt Demo code - * Runs the Pan/Tilt demo code - * @param pixy the pointer to the pixy object to run the demo on - * @param serial the optional serial pointer to display output to - */ -template <class TPixyInterface> void runPanTiltDemo(TPixy<TPixyInterface>* pixy, BufferedSerial* serial = NULL) -{ - ServoLoop panLoop(-150, -300); - ServoLoop tiltLoop(200, 250); - { - printf("Starting...\n"); - } - static int i = 0; - int j; - uint16_t blocks; - int32_t panError, tiltError; - pixy->init(); - while(true) { - blocks = pixy->getBlocks(); - if (blocks) { - i++; - if (i % 5 == 0 ) { - printf("Detected %d:\n", blocks); - //toPC.printf(buf); - for (j = 0; j < blocks; j++) { - printf(" block %d: ", j); - pixy->printBlock(pixy->blocks[j]); - } - } - } - } -} -#endif \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb TPixy.h --- a/TPixy.h Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,304 +0,0 @@ -// -// begin license header -// -// This file is part of Pixy CMUcam5 or "Pixy" for short -// -// All Pixy source code is provided under the terms of the -// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html). -// Those wishing to use Pixy source code, software and/or -// technologies under different licensing terms should contact us at -// cmucam@cs.cmu.edu. Such licensing terms are available for -// all portions of the Pixy codebase presented here. -// -// end license header -// -// This file is for defining the Block struct and the Pixy template class. -// (TPixy). TPixy takes a communication link as a template parameter so that -// all communication modes (SPI, I2C and UART) can share the same code. -// - -#ifndef _TPIXY_H -#define _TPIXY_H - -#include "mbed.h" -#include "TPixyInterface.h" - -// Communication/misc parameters -#define PIXY_INITIAL_ARRAYSIZE 30 -#define PIXY_MAXIMUM_ARRAYSIZE 130 -#define PIXY_START_WORD 0xaa55 -#define PIXY_START_WORD_CC 0xaa56 -#define PIXY_START_WORDX 0x55aa -#define PIXY_MAX_SIGNATURE 7 -#define PIXY_DEFAULT_ARGVAL 0xffff - -// Pixy x-y position values -#define PIXY_MIN_X 0L -#define PIXY_MAX_X 319L -#define PIXY_MIN_Y 0L -#define PIXY_MAX_Y 199L - -// RC-servo values -#define PIXY_RCS_MIN_POS 0L -#define PIXY_RCS_MAX_POS 1000L -#define PIXY_RCS_CENTER_POS ((PIXY_RCS_MAX_POS-PIXY_RCS_MIN_POS)/2) - -enum BlockType { - NORMAL_BLOCK, - CC_BLOCK -}; - -/** A structure for containing Block data - * signature the signature of the block - * x the x position of the block on the screen - * y the y position of the block on the screen - * width the width of the block on the screen - * height the height of the block on the screen - * angle the angle of the block - */ -struct Block { - uint16_t signature; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; - uint16_t angle; -}; - -/** The superclass handler for the Pixy camera from a given connection handler (SPI, I2C, etc) - * Used for instantiating a Pixy object that interfaces via an abtritrary connection handler - */ -template <class TPixyInterface> class TPixy -{ -public: - BufferedSerial* serial; - Block *blocks; - - /** Creates a TPixy object with a given connection handler - * @param type the pointer to the interface connection handler - * @param serialOut the optional serial output pointer to print out Pixy camera data - * @param arg an optional integer argument used for custom implementations of the Pixy library - */ - TPixy(TPixyInterface* type, BufferedSerial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL); - ~TPixy(); - - /** Prints the given Block out to the given serial port - * @param &block the Block to print - */ - void printBlock(Block &block); - /** Returns the number of Blocks found in the current view and updates all Blocks' info - * @param maxBlocks the maximum number of Blocks to search for - * @return the number of Blocks found - */ - uint16_t getBlocks(uint16_t maxBlocks = 1000); - /** Sets the PWM value of the Pixy servos - * @param s0 the value of the left servo - * @param s1 the value of the right servo - * @return the interface return value for sending the servo command - */ - int8_t setServos(uint16_t s0, uint16_t s1); - /** Sets the brightness of the Pixy RGB LED - * @param brightness the brightness of the LED - * @return the interface return value for sending the brightness command - */ - int8_t setBrightness(uint8_t brightness); - /** Sets the color of the Pixy RGB LED - * @param r the red color value - * @param g the green color value - * @param b the blue color value - */ - int8_t setLED(uint8_t r, uint8_t g, uint8_t b); - /** Initializes the Pixy - */ - void init(); - -private: - TPixyInterface* link; - BlockType blockType; - /** Returns if the Pixy is ready to receive/send a message - */ - bool getStart(); - /** Resizes the block array to add an additional block - */ - void resize(); - bool skipStart; - uint16_t blockCount; - uint16_t blockArraySize; -}; - -template <class TPixyInterface> void TPixy<TPixyInterface>::init() -{ - link->init(); -} - - -template <class TPixyInterface> TPixy<TPixyInterface>::TPixy(TPixyInterface* type, BufferedSerial* serialOut, uint16_t arg) : serial(serialOut), link(type) -{ - skipStart = false; - blockCount = 0; - blockArraySize = PIXY_INITIAL_ARRAYSIZE; - blocks = (Block *)malloc(sizeof(Block)*blockArraySize); - link->setArg(arg); -} - -template <class TPixyInterface> void TPixy<TPixyInterface>::printBlock(Block &block) -{ - int i, j; - char sig[6], d; - bool flag; - if (block.signature > PIXY_MAX_SIGNATURE) { // color code! (CC) - // convert signature number to an octal string - for (i = 12, j = 0, flag = false; i >= 0; i -= 3) { - d = (block.signature >> i) & 0x07; - if (d > 0 && !flag) { - flag = true; - } - if (flag) { - sig[j++] = d + '0'; - } - } - sig[j] = '\0'; - { - printf("CC block! sig: %s (%d decimal) x: %d y: %d width: %d height: %d angle %d\n", sig, block.signature, block.x, block.y, block.width, block.height, block.angle); - } - } //else {}// regular block. Note, angle is always zero, so no need to print - printf("sig: %d x: %d y: %d width: %d height: %d\n", block.signature, block.x, block.y, block.width, block.height); -} - -template <class TPixyInterface> TPixy<TPixyInterface>::~TPixy() -{ - free(blocks); -} - -template <class TPixyInterface> bool TPixy<TPixyInterface>::getStart() -{ - uint16_t w, lastw; - lastw = 0xffff; - while(true) { - w = link->getWord(); - if (w == 0 && lastw == 0) { - ThisThread::sleep_for(10); - return false; - } else if (w == PIXY_START_WORD && lastw == PIXY_START_WORD) { - blockType = NORMAL_BLOCK; - return true; - } else if (w == PIXY_START_WORD_CC && lastw == PIXY_START_WORD) { - blockType = CC_BLOCK; - return true; - } else if (w == PIXY_START_WORDX) { - if (serial != NULL) { - printf("reorder"); - } - link->getByte(); // resync - } - lastw = w; - } -} - -template <class TPixyInterface> void TPixy<TPixyInterface>::resize() -{ - blockArraySize += PIXY_INITIAL_ARRAYSIZE; - blocks = (Block *)realloc(blocks, sizeof(Block)*blockArraySize); -} - -template <class TPixyInterface> uint16_t TPixy<TPixyInterface>::getBlocks(uint16_t maxBlocks) -{ - uint8_t i; - uint16_t w, checksum, sum; - Block *block; - - if (!skipStart) { - if (getStart() == false) { - printf("- 0 -\r\n"); - return 0; - } - } else { - skipStart = false; - } - for(blockCount = 0; blockCount < maxBlocks && blockCount < PIXY_MAXIMUM_ARRAYSIZE;) - { - checksum = link->getWord(); - if (checksum == PIXY_START_WORD) { // we've reached the beginning of the next frame - skipStart = true; - blockType = NORMAL_BLOCK; - if(1) { - printf("skip"); - } - printf("- 1 -\r\n"); - return blockCount; - } else if (checksum == PIXY_START_WORD_CC) { - skipStart = true; - blockType = CC_BLOCK; - printf("- 2 -\r\n"); - return blockCount; - } else if (checksum == 0) { - printf("- 3 -\r\n"); - return blockCount; - } - if (blockCount > blockArraySize) { - resize(); - } - block = blocks + blockCount; - - for (i = 0, sum = 0; i < sizeof(Block)/sizeof(uint16_t); i++) { - if (blockType == NORMAL_BLOCK && i >= 5) { // skip - block->angle = 0; - break; - } - w = link->getWord(); - sum += w; - *((uint16_t *)block + i) = w; - } - - if (checksum == sum) { - blockCount++; - } else { - w = link->getWord(); - if (serial != NULL) { - printf("cs error"); - } - } - if (w == PIXY_START_WORD) { - blockType = NORMAL_BLOCK; - } else if (w == PIXY_START_WORD_CC) { - blockType = CC_BLOCK; - } else { - printf("- 4 -\r\n"); - return blockCount; - } - } - printf("- 5 -\r\n"); - return blockCount; -} - -template <class TPixyInterface> int8_t TPixy<TPixyInterface>::setServos(uint16_t s0, uint16_t s1) -{ - uint8_t outBuf[6]; - outBuf[0] = 0x00; - outBuf[1] = 0xff; - *(uint16_t *)(outBuf + 2) = s0; - *(uint16_t *)(outBuf + 4) = s1; - return link->send(outBuf, 6); -} - -template <class TPixyInterface> int8_t TPixy<TPixyInterface>::setBrightness(uint8_t brightness) -{ - uint8_t outBuf[3]; - outBuf[0] = 0x00; - outBuf[1] = 0xfe; - outBuf[2] = brightness; - return link->send(outBuf, 3); -} - -template <class TPixyInterface> int8_t TPixy<TPixyInterface>::setLED(uint8_t r, uint8_t g, uint8_t b) -{ - uint8_t outBuf[5]; - outBuf[0] = 0x00; - outBuf[1] = 0xfd; - outBuf[2] = r; - outBuf[3] = g; - outBuf[4] = b; - return link->send(outBuf, 5); -} - -#endif \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb TPixyInterface.cpp --- a/TPixyInterface.cpp Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -#include "TPixyInterface.h" - -PixyInterfaceSPI::PixyInterfaceSPI(SPI* interface) : TPixyInterface(), spi(interface) {} - -void PixyInterfaceSPI::init() -{ - spi->frequency(1000000); -} - -uint16_t PixyInterfaceSPI::getWord() -{ - // ordering is different (big endian) because Pixy is sending 16 bits through SPI - // instead of 2 bytes in a 16-bit word as with I2C - uint16_t w; - if (inQ.read(&w)) { - return w; - } - return getWordHw(); -} - -uint8_t PixyInterfaceSPI::getByte() -{ - //return SPI.transfer(0x00); - return spi->write(0x00); -} - -int8_t PixyInterfaceSPI::send(uint8_t *data, uint8_t len) -{ - int i; - // check to see if we have enough space in our circular queue - if (outQ.freeLen() < len) { - return -1; - } - for (i = 0; i < len; i++) { - outQ.write(data[i]); - } - flushSend(); - return len; -} - -void PixyInterfaceSPI::setArg(uint16_t arg) {} - -uint16_t PixyInterfaceSPI::getWordHw() -{ - // ordering is different (big endian) because Pixy is sending 16 bits through SPI - // instead of 2 bytes in a 16-bit word as with I2C - uint16_t w; - uint8_t c, c_out = 0; - - if (outQ.read(&c_out)) { - w = spi->write(PIXY_SYNC_BYTE_DATA); - //w = SPI.transfer(PIXY_SYNC_BYTE_DATA); - } else { - w = spi->write(PIXY_SYNC_BYTE); - //w = SPI.transfer(PIXY_SYNC_BYTE); - } - w <<= 8; - c = spi->write(c_out); - //c = SPI.transfer(cout); - w |= c; - return w; -} - -void PixyInterfaceSPI::flushSend() -{ - uint16_t w; - while(outQ.len) { - w = getWordHw(); - inQ.write(w); - } -} - - - - -template <class BufType> CircularQ<BufType>::CircularQ() -{ - len = 0; - writeIndex = 0; - readIndex = 0; -} - -template <class BufType> bool CircularQ<BufType>::read(BufType *c) -{ - if (len) { - *c = buf[readIndex++]; - len--; - if (readIndex == PIXY_BUF_SIZE) { - readIndex = 0; - } - return true; - } else { - return false; - } -} - -template <class BufType> uint8_t CircularQ<BufType>::freeLen() -{ - return PIXY_BUF_SIZE - len; -} - -template <class BufType> bool CircularQ<BufType>::write(BufType c) -{ - if (freeLen() == 0) { - return false; - } - buf[writeIndex++] = c; - len++; - if (writeIndex == PIXY_BUF_SIZE) { - writeIndex = 0; - } - return true; -} \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb TPixyInterface.h --- a/TPixyInterface.h Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -// -// begin license header -// -// This file is part of Pixy CMUcam5 or "Pixy" for short -// -// All Pixy source code is provided under the terms of the -// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html). -// Those wishing to use Pixy source code, software and/or -// technologies under different licensing terms should contact us at -// cmucam@cs.cmu.edu. Such licensing terms are available for -// all portions of the Pixy codebase presented here. -// -// end license header -// -// This file is for defining the SPI-related classes. It's called Pixy.h instead -// of Pixy_SPI.h because it's the default/recommended communication method -// with Arduino. This class assumes you are using the ICSP connector to talk to -// Pixy from your Arduino. For more information go to: -// -//http://cmucam.org/projects/cmucam5/wiki/Hooking_up_Pixy_to_a_Microcontroller_(like_an_Arduino) -// - -#ifndef _TPIXY_INTERFACE_H -#define _TPIXY_INTERFACE_H - -#include "TPixy.h" - -#define PIXY_SYNC_BYTE 0x5a -#define PIXY_SYNC_BYTE_DATA 0x5b -#define PIXY_BUF_SIZE 16 - -/** An interface for communicating between the Pixy and a specific hardware interface - */ -class TPixyInterface -{ -public: - /** Creates a TPixyInterface - */ - TPixyInterface() {} - /** Initializes a TPixyInterface - */ - virtual void init() = 0; - /** Sends the given data to the Pixy with a given data length - * @param data the data to send - * @param len the length of the data to send - * @return the interface return signal - */ - virtual int8_t send(uint8_t *data, uint8_t len) = 0; - /** Sets an argument for the interface to use - * @param arg the argument to use - */ - virtual void setArg(uint16_t arg) = 0; - /** Reads a word from the interface - * @return the word read from the interface - */ - virtual uint16_t getWord() = 0; - /** Reads a byte from the interface - * @return the byte read from the interface - */ - virtual uint8_t getByte() = 0; -}; - - -template <class BufType> class CircularQ -{ -public: - BufType buf[PIXY_BUF_SIZE]; - uint8_t len; - uint8_t writeIndex; - uint8_t readIndex; - - CircularQ(); - bool read(BufType *c); - uint8_t freeLen(); - bool write(BufType c); -}; - -/** An interface for communicating between the Pixy via an SPI interface - */ -class PixyInterfaceSPI : TPixyInterface -{ -public: - SPI* spi; - /** Constructs a PixyInterfaceSPI object - * @param interface the SPI pointer - */ - PixyInterfaceSPI(SPI* interface); - /** Initializes the PixyInterfaceSPI - */ - virtual void init(); - /** Reads a word from the interface - * @return the word read from the interface - */ - virtual uint16_t getWord(); - /** Reads a byte from the interface - * @return the byte read from the interface - */ - virtual uint8_t getByte(); - /** Sends the given data to the Pixy with a given data length - * @param data the data to send - * @param len the length of the data to send - * @return the interface return signal - */ - virtual int8_t send(uint8_t *data, uint8_t len); - /** Sets an argument for the interface to use [unused] - * @param arg the argument to use - */ - virtual void setArg(uint16_t arg); - -private: - // we need a little circular queues for both directions - CircularQ<uint8_t> outQ; - CircularQ<uint16_t> inQ; - - uint16_t getWordHw(); - void flushSend(); -}; - - -/* -class PixyInterfaceI2C : TPixyInterface -{ -public: - SPI* spi; - PixyInterfaceI2C(I2C* interface); - virtual void init(); - virtual uint16_t getWord(); - virtual uint8_t getByte(); - virtual int8_t send(uint8_t *data, uint8_t len); - virtual void setArg(uint16_t arg); - -private: - // we need a little circular queues for both directions - CircularQ<uint8_t> outQ; - CircularQ<uint16_t> inQ; - - uint16_t getWordHw(); - void flushSend(); -};*/ - -#endif
diff -r 478d4d9193a1 -r d109b094d4bb main.cpp --- a/main.cpp Mon Aug 23 11:26:37 2021 +0000 +++ b/main.cpp Sat Aug 28 13:03:58 2021 +0000 @@ -1,17 +1,36 @@ #include "mbed.h" -#include "pixySPI.h" +#include "pixyUART.h" //SPI spi(PC_12, PC_11, PC_10); -pixySPI pixy(PC_12, PC_11, PC_10,10); +BufferedSerial uart(PA_9,PA_10,115200); +pixyUART pixy(&uart); +uint8_t buffer[200]; static BufferedSerial serial_port(USBTX, USBRX,115200); int main(void) { printf("Start\r\n"); + uart.set_blocking(false); + uart.set_format( + /* bits */ 8, + /* parity */ BufferedSerial::None, + /* stop bit */ 1); + Timer ti; + ti.reset(); + ti.start(); + uint8_t kk=0; while(1) { - ThisThread::sleep_for(200); + ThisThread::sleep_for(20); pixy.capture(); - ThisThread::sleep_for(200); - printf("NumBlocks: %d\r\n",pixy.getNumBlocks()); + if(ti.read() > .25 && pixy.captured_blocks>0) + { + ti.reset(); + printf("captBl: %d\r\n",pixy.captured_blocks); + for(int k=0;k<pixy.captured_blocks;k++) + { + printf("sig: %d x: %d y: %d \r\n",pixy.blocks[k].signature,pixy.blocks[k].x,pixy.blocks[k].y); + } + printf("\r\n- - - - - - - - - \r\n"); + } } //pixy.blocks[0].printBlock(); } \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb pixySPI.cpp --- a/pixySPI.cpp Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ - - -#include "pixySPI.h" - -pixySPI::pixySPI(PinName mosi, PinName miso, PinName sclk, int nBlocks) - :spi(mosi,miso,sclk) -{ - spi.format(8,0); //8bits mode 0 - spi.frequency(100000); //set the frequency in Hz - sync=0xAA55; //start word of a frame coming from the pixy - //blocks=new Block[nBlocks]; //allocate space for the blocks - //numBlocks=nBlocks; - numBlocks=NUM_BLOCKS; - bestX=CENTER_X; - bestY=CENTER_Y; -} - -pixySPI::~pixySPI() -{ - //delete blocks; -} - - -short pixySPI::readTwoBytesLSB() -{ - short out; - char read[2]= {0,0}; - read[0]=spi.write(0x00); - read[1]=spi.write(0x00); - out=(((short)read[0]) << 8) | read[1]; - return out; -} - - -//this doesn't work -void pixySPI::readNBytes(char* buf, int num) -{ - for (int i=0; i<num; i++) { - char byte=spi.write(0x00); - memcpy(buf+i, &byte, 1); - } -} - -void pixySPI::capture() -{ - memset(blocks, 0, numBlocks*sizeof(Block)); //destroy the old targets - //rec_blocks = 0; - for (i=0; i<numBlocks; ++i) { - // printf("block %d\n", i); - Block* out=&blocks[i]; - out->signature=INVALID_BLOCK; - uint16_t checksum=0; - //first we need to detect the start of a block. They all start with 0xAA55 - char frame[2]= {0,0}; //this is a 2 byte running frame of what is being recieved. It's like a first-in-last-out queue - //debug->printf("looking for valid signature\n"); - Timer t; - t.start(); - while (memcmp((char*)&sync, frame, 2)!=0) { - frame[0]=frame[1]; //move byte down - frame[1]=spi.write(0x00); //get next byte. - if (t.read_ms()>5) - { - t.stop(); - return; - } - } - //printf("target\n\n"); - spi.write(0x00); - //ok so we got a valid signature - //these didn't end up working - //readNBytes((char*)(&checksum), 2); //get the checksum - //readNBytes((char*)(&out), sizeof(Block)); //get the rest of the data - checksum=readTwoBytesLSB(); - out->signature=readTwoBytesLSB(); - out->x=readTwoBytesLSB(); - out->y=readTwoBytesLSB(); - out->width=readTwoBytesLSB(); - out->height=readTwoBytesLSB(); - - if (checksum!=(out->x+out->y+out->signature+out->width+out->height) || checksum==0) { - //debug->printf("checksum doesn't add up %d\n", checksum); - out->signature=INVALID_BLOCK; //used for invalid signatures - } - //printf("found block\n"); - if (blocks[0].signature!=INVALID_BLOCK) - { - //mutex->lock(); - bestX=blocks[0].x; - bestY=blocks[0].y; - //mutex->unlock(); - } - } - return; -} - -Block* pixySPI::getBlocks() -{ - return blocks; -} - -int pixySPI::getNumBlocks() -{ - return i; -} - -int pixySPI::getBestX() -{ - if (bestX>640) - return 640; - else if (bestX<0) - return 0; - else - return bestX; -} - -int pixySPI::getBestY() -{ - if (bestY>400) - return 400; - else if (bestY<0) - return 0; - else - return bestY; -} - -char pixySPI::getRawData() -{ - return spi.write(0x00); -} \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb pixySPI.h --- a/pixySPI.h Mon Aug 23 11:26:37 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -#pragma once -#include "mbed.h" - -#define INVALID_BLOCK 20 -#define CENTER_X 160 -#define CENTER_Y 100 -#define NUM_BLOCKS 10 -//a class to aid in SPI communication with the pixy camera - -//this details the object block format of returned data as described in -//http://www.cmucam.org/projects/cmucam5/wiki/Pixy_Serial_Protocol - -//blatantly stole this from their code -struct Block -{ - uint16_t signature; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; -}; - -class pixySPI -{ -private: - SPI spi; - //SPI spi(p5, p6, p7); // mosi, miso, sclk - short sync; //the block signature. 16 bits - short readTwoBytesLSB(); - void readNBytes(char* buf, int num); - Block blocks[NUM_BLOCKS]; //where the blocks are stored - int numBlocks; //amt - int bestX; - int bestY; - int i; -public: - pixySPI(PinName mosi,PinName miso,PinName sclk, int nBlocks); - ~pixySPI(); - void capture(); //fills in the blocks pointer - char getRawData(); - Block* getBlocks(); - int getNumBlocks(); - int getBestX(); - int getBestY(); -}; \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb pixyUART.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixyUART.cpp Sat Aug 28 13:03:58 2021 +0000 @@ -0,0 +1,109 @@ + + +#include "pixyUART.h" + +pixyUART::pixyUART(BufferedSerial *com) +{ + sync=0xAA55; //start word of a frame coming from the pixy + //blocks=new Block[nBlocks]; //allocate space for the blocks + //numBlocks=nBlocks; + numBlocks=NUM_BLOCKS; + uart = com; +} + +pixyUART::~pixyUART() +{ + //delete blocks; +} + + +int8_t pixyUART::readTwoBytesLSB(uint16_t *out) +{ + int32_t num = uart->read(buffer, 2); + if(num>0) + { + *out=buffer[0]+256*buffer[1]; + return 1; + } + else + return -1; +} + + +void pixyUART::capture() +{ + memset(blocks, 0, numBlocks*sizeof(Block)); //destroy the old targets + captured_blocks = 0; + Timer ti; + ti.reset(); + ti.start(); + uint8_t got_data; + for (int i=0; i<numBlocks; i++) { + Block* out=&blocks[captured_blocks]; + out->signature=INVALID_BLOCK; + uint16_t checksum=0; + //first we need to detect the start of a block. They all start with 0xAA55 + char frame[2]= {0,0}; //this is a 2 byte running frame of what is being recieved. It's like a first-in-last-out queue + //debug->printf("looking for valid signature\n"); + int32_t num = 1; + while(memcmp((char*)&sync, frame, 2)!=0) + { + frame[0] = frame[1]; //move byte down + num = uart->read(&frame[1],1); //get next byte. + //printf("%d ",frame[1]); + if(num<=0) + { + break; + } + } + if(i==0) + ti.reset(); + if(ti.read()>.015) + break; + //printf(" / "); + while(memcmp((char*)&sync, frame, 2)==0) + { + num = uart->read(frame,2); //get next byte. + //printf("%d %d",frame[0],frame[1]); + if(num<=0) + { + break; + } + } + //printf(" . "); + checksum = frame[0]+256*frame[1]; + got_data = readTwoBytesLSB(&out->signature); + if(got_data<0) + break; + got_data = readTwoBytesLSB(&out->x); + if(got_data<0) + break; + got_data = readTwoBytesLSB(&out->y); + if(got_data<0) + break; + got_data = readTwoBytesLSB(&out->width); + if(got_data<0) + break; + got_data = readTwoBytesLSB(&out->height); + if(got_data<0) + break; +//printf("cs: %d i: %d x: %d y: %d w: %d h: %d\r\n",checksum,out->signature,out->x,out->y,out->width,out->height); + if (checksum!=(out->x+out->y+out->signature+out->width+out->height) || checksum==0) { + //debug->printf("checksum doesn't add up %d\n", checksum); + out->signature=INVALID_BLOCK; //used for invalid signatures + } + else + { + captured_blocks++; + } + + } + return; +} + +Block* pixyUART::getBlocks() +{ + return blocks; +} + + \ No newline at end of file
diff -r 478d4d9193a1 -r d109b094d4bb pixyUART.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixyUART.h Sat Aug 28 13:03:58 2021 +0000 @@ -0,0 +1,39 @@ +#pragma once +#include "mbed.h" + +#define INVALID_BLOCK 20 +#define CENTER_X 160 +#define CENTER_Y 100 +#define NUM_BLOCKS 10 +//a class to aid in SPI communication with the pixy camera + +//this details the object block format of returned data as described in +//http://www.cmucam.org/projects/cmucam5/wiki/Pixy_Serial_Protocol + +//blatantly stole this from their code +struct Block +{ + uint16_t signature; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; +}; + +class pixyUART +{ +private: + BufferedSerial *uart; + short sync; //the block signature. 16 bits + int8_t readTwoBytesLSB(uint16_t *); + void readNBytes(char* buf, int num); + int numBlocks; //amt + uint8_t buffer[200]; +public: + pixyUART(BufferedSerial * ); + ~pixyUART(); + void capture(); //fills in the blocks pointer + Block* getBlocks(); + int captured_blocks; + Block blocks[NUM_BLOCKS]; //where the blocks are stored +}; \ No newline at end of file