// // 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 "Arduino.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 }; struct Block { // print block structure! void print() { int i, j; char buf[128], sig[6], d; bool flag; if (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 = (signature>>i)&0x07; if (d>0 && !flag) flag = true; if (flag) sig[j++] = d + '0'; } sig[j] = '\0'; sprintf(buf, "CC block! sig: %s (%d decimal) x: %d y: %d width: %d height: %d angle %d\n", sig, signature, x, y, width, height, angle); } else // regular block. Note, angle is always zero, so no need to print sprintf(buf, "sig: %d x: %d y: %d width: %d height: %d\n", signature, x, y, width, height); Serial.print(buf); } uint16_t signature; uint16_t x; uint16_t y; uint16_t width; uint16_t height; uint16_t angle; }; template class TPixy { public: TPixy(uint16_t arg=PIXY_DEFAULT_ARGVAL); ~TPixy(); uint16_t getBlocks(uint16_t maxBlocks=1000); int8_t setServos(uint16_t s0, uint16_t s1); int8_t setBrightness(uint8_t brightness); int8_t setLED(uint8_t r, uint8_t g, uint8_t b); void init(); Block *blocks; private: boolean getStart(); void resize(); LinkType link; boolean skipStart; BlockType blockType; uint16_t blockCount; uint16_t blockArraySize; }; template TPixy::TPixy(uint16_t arg) { skipStart = false; blockCount = 0; blockArraySize = PIXY_INITIAL_ARRAYSIZE; blocks = (Block *)malloc(sizeof(Block)*blockArraySize); link.setArg(arg); } template void TPixy::init() { link.init(); } template TPixy::~TPixy() { free(blocks); } template boolean TPixy::getStart() { uint16_t w, lastw; lastw = 0xffff; while(true) { w = link.getWord(); if (w==0 && lastw==0) { delayMicroseconds(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) { Serial.println("reorder"); link.getByte(); // resync } lastw = w; } } template void TPixy::resize() { blockArraySize += PIXY_INITIAL_ARRAYSIZE; blocks = (Block *)realloc(blocks, sizeof(Block)*blockArraySize); } template uint16_t TPixy::getBlocks(uint16_t maxBlocks) { uint8_t i; uint16_t w, checksum, sum; Block *block; if (!skipStart) { if (getStart()==false) return 0; } else skipStart = false; for(blockCount=0; blockCountblockArraySize) resize(); block = blocks + blockCount; for (i=0, sum=0; i=5) // skip { block->angle = 0; break; } w = link.getWord(); sum += w; *((uint16_t *)block + i) = w; } if (checksum==sum) blockCount++; else Serial.println("cs error"); w = link.getWord(); if (w==PIXY_START_WORD) blockType = NORMAL_BLOCK; else if (w==PIXY_START_WORD_CC) blockType = CC_BLOCK; else return blockCount; } } template int8_t TPixy::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 int8_t TPixy::setBrightness(uint8_t brightness) { uint8_t outBuf[3]; outBuf[0] = 0x00; outBuf[1] = 0xfe; outBuf[2] = brightness; return link.send(outBuf, 3); } template int8_t TPixy::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