cette librairie contient les fonctions de base permettant de detecter un objet avec la camera pixy

Dependents:   pixy_base

Files at this revision

API Documentation at this revision

Comitter:
michelmoulin
Date:
Wed Nov 18 13:12:20 2020 +0000
Commit message:
cette version de programme permet d'afficher les coordonnees x et y d'un objet detecte par la camera pixy.

Changed in this revision

Pixy.h Show annotated file Show diff for this revision Revisions of this file
TPixy.h Show annotated file Show diff for this revision Revisions of this file
TPixyInterface.cpp Show annotated file Show diff for this revision Revisions of this file
TPixyInterface.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pixy.h	Wed Nov 18 13:12:20 2020 +0000
@@ -0,0 +1,14 @@
+#ifndef _PIXY_H
+#define _PIXY_H
+
+#include "TPixy.h"
+#include "TPixyInterface.h"
+
+class PixySPI : public TPixy<PixyInterfaceSPI>
+{
+public:
+    PixySPI(SPI* spi, Serial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL) :
+        TPixy<PixyInterfaceSPI>((new PixyInterfaceSPI(spi)), serialOut, arg) {}
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TPixy.h	Wed Nov 18 13:12:20 2020 +0000
@@ -0,0 +1,212 @@
+//
+// 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
+};
+
+struct Block {
+    // print block structure!
+    uint16_t signature;
+    uint16_t x;
+    uint16_t y;
+    uint16_t width;
+    uint16_t height;
+    uint16_t angle;
+};
+
+template <class TPixyInterface> class TPixy
+{
+public:
+    Serial* serial;
+    Block *blocks;
+    
+    TPixy(TPixyInterface* type, Serial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL);
+    ~TPixy();
+
+    uint16_t getBlocks(uint16_t maxBlocks = 1000);
+    int8_t setBrightness(uint8_t brightness);
+    int8_t setLED(uint8_t r, uint8_t g, uint8_t b);
+
+private:
+    TPixyInterface* link;
+    BlockType blockType;
+    bool getStart();
+    void resize();
+    bool skipStart;
+    uint16_t blockCount;
+    uint16_t blockArraySize;
+};
+
+template <class TPixyInterface> TPixy<TPixyInterface>::TPixy(TPixyInterface* type, Serial* 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> 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) {
+            wait_ms(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) {
+                serial->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) {
+            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 (serial != NULL) {
+                serial->printf("skip");
+            }
+            return blockCount;
+        } else if (checksum == PIXY_START_WORD_CC) {
+            skipStart = true;
+            blockType = CC_BLOCK;
+            return blockCount;
+        } else if (checksum == 0) {
+            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) {
+                serial->printf("cs error");
+            }
+        }
+        if (w == PIXY_START_WORD) {
+            blockType = NORMAL_BLOCK;
+        } else if (w == PIXY_START_WORD_CC) {
+            blockType = CC_BLOCK;
+        } else {
+            return blockCount;
+        }
+    }
+    return blockCount;
+}
+
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TPixyInterface.cpp	Wed Nov 18 13:12:20 2020 +0000
@@ -0,0 +1,108 @@
+#include "TPixyInterface.h"
+
+PixyInterfaceSPI::PixyInterfaceSPI(SPI* interface) : TPixyInterface(), spi(interface) {}
+
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TPixyInterface.h	Wed Nov 18 13:12:20 2020 +0000
@@ -0,0 +1,76 @@
+//
+// 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
+
+class TPixyInterface
+{
+public:
+    TPixyInterface() {}
+    virtual int8_t send(uint8_t *data, uint8_t len) = 0;
+    virtual void setArg(uint16_t arg) = 0;
+    virtual uint16_t getWord() = 0;
+    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);
+};
+
+class PixyInterfaceSPI : TPixyInterface
+{
+public:
+    SPI* spi;
+    PixyInterfaceSPI(SPI* interface);
+    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