Zachary Holloway
Published © GPL3+

MSP432P401R Driver for Pixy2

This is a driver with user-friendly functions that provides interface between the Pixy2 and the MSP432P401R microcontroller.

BeginnerProtip250
MSP432P401R Driver for Pixy2

Things used in this project

Story

Read more

Schematics

README

README

Code

pixy2_uart_header.h

C/C++
Include this file along with pixy2_uart_driver.c in your project to utilize the functions described in the header.
/*
 * pixy2_uart_header.h
 *
 *  Created on: Mar 3, 2019
 *      Author: Zachary Holloway
 */

#ifndef PIXY2_UART_HEADER_H_
#define PIXY2_UART_HEADER_H_

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

#include <stdint.h>

#define ON                                      (1)
#define OFF                                     (0)
#define PIXY2_CHECKSUM_SYNC                     (0xC1AF)
#define PIXY2_NO_CHECKSUM_SYNC                  (0xC1AE)
#define PIXY2_TYPE_REQUEST_CHANGE_PROGRAM       (0x02)
#define PIXY2_TYPE_REQUEST_RESOLUTION           (0x0C)
#define PIXY2_TYPE_RESPONSE_RESOLUTION          (0x0D)
#define PIXY2_TYPE_REQUEST_VERSION              (0x0E)
#define PIXY2_TYPE_RESPONSE_VERSION             (0x0F)
#define PIXY2_TYPE_RESPONSE_RESULT              (0x01)
#define PIXY2_TYPE_RESPONSE_ERROR               (0x03)
#define PIXY2_TYPE_REQUEST_BRIGHTNESS           (0x10)
#define PIXY2_TYPE_REQUEST_SERVO                (0x12)
#define PIXY2_TYPE_REQUEST_LED                  (0x14)
#define PIXY2_TYPE_REQUEST_LAMP                 (0x16)
#define PIXY2_TYPE_REQUEST_FPS                  (0x18)
#define PIXY2_TYPE_REQUEST_BLOCKS               (0x20)
#define PIXY2_TYPE_REQUEST_MAIN_FEATURES        (0x30)
#define PIXY2_TYPE_REQUEST_MODE                 (0x54)
#define PIXY2_TYPE_REQUEST_NEXT_TURN            (0x58)
#define PIXY2_TYPE_REQUEST_DEFAULT_TURN         (0x60)
#define PIXY2_TYPE_REQUEST_REVERSE_VECTOR       (0x62)
#define PIXY2_TYPE_REQUEST_RGB                  (0x70)
#define PIXY2_RESULT_OK                         (0)
#define PIXY2_RESULT_ERROR                      (-1)
#define PIXY2_RESULT_BUSY                       (-2)
#define PIXY2_RESULT_CHECKSUM_ERROR             (-3)
#define PIXY2_RESULT_TIMEOUT                    (-4)
#define PIXY2_RESULT_BUTTON_OVERRISE            (-5)
#define PIXY2_RESULT_PROGRAM_CHANGING           (-6)
#define PIXY2_SERVO_MIN_POSITION                (0)
#define PIXY2_SERVO_MAX_POSITION                (1000L)
#define PIXY2_SERVO_CENTER_POSITION             ((PIXY2_SERVO_MAX_POSITION-PIXY2_SERVO_MIN_POSITION)/2)

//*************************************************************************************
extern void configUART(void);
//*************************************************************************************
//
// @brief: This function configures all the necessary settings for UART A2.
//
// @return: None.
//
//*************************************************************************************
extern void sendPacket(void);
//*************************************************************************************
//
// @brief: This function is used to send all data packets to the Pixy2 by assigning
//         values to an integer array and filling the TX buffer with data to be sent.
//
// @return: None.
//
//*************************************************************************************
extern void receivePacket(int responseLength);
//*************************************************************************************
//
// @brief: This function is used to receive all data from the Pixy2 in response to
//         a command from the RX buffer and store them in an array.
//
// @return: None.
//
//*************************************************************************************
extern void setCameraBrightness(uint_fast8_t valueBrightness);
//*************************************************************************************
//
// @brief: This function is used to set the level of the camera brightness for the
//         Pixy2.
//
// @param: valueBrightness is the level of camera brightness.
//      Valid values are between 0-255 inclusive.
//
// @return: None.
//*************************************************************************************
extern void setLED(uint_fast8_t valueRed,
                    uint_fast8_t valueGreen,
                    uint_fast8_t valueBlue);
//*************************************************************************************
//
// @brief: This function is used to set the color of the RGB LED on the front Pixy2.
//
// @param: valueRed is the control of the red color level for the RGB LED.
//      Valid values are between 0-255 inclusive.
//
// @param: valueGreen is the control of the green color level for the RGB LED.
//      Valid values are Valid values are between 0-255 inclusive.
//
// @param: valueBlue is the control of the blue color level for the RGB LED.
//      Valid values are Valid values are between 0-255 inclusive.
//
// @return: None.
//
//*************************************************************************************
extern void setLamp(uint_fast8_t upperLamp,
                    uint_fast8_t lowerLamp);
//*************************************************************************************
//
// @brief: This function is used to turn the lamps of the Pixy2 for additional lighting.
//
// @param: upperLamp is the control for the two white LEDs along the top of the
//         Pixy2.
//      Valid values are:
//      - 0 (Turn lamp off)
//      - 1 (Turn lamp on)
//
// @param: lowerLamp is the control for turning on all channels of the bottom RGB LED of
// the Pixy2.
//      Valid values are:
//      - 0 (Turn lamp off)
//      - 1 (Turn lamp on)
//
// @return: None.
//
//*************************************************************************************
extern void setServos(uint_fast16_t panValue,
                    uint_fast16_t tiltValue);
//*************************************************************************************
//
// @brief: This function is used to set the pan and tilt servos to a desired position.
//
// @param: panValue is the position of the pan servo (looking around).
//      Valid values are between 0-1000 inclusive.
//
// @param: panValue is the position of the tilt servo (looking up and down).
//      Valid values are between 0-1000 inclusive.
//
// @return: None.
//
//*************************************************************************************
extern void setMode(uint_fast8_t mode);
//*************************************************************************************
//
// @brief: This function is used to set the mode of line-tracking while running the
//         line-tracking API.
//
// @param: mode is a variable which is a bitwise ORing of the following bits:
//              - LINE_MODE_TURN_DELAYED (1, LSB)
//              - LINE_MODE_MANUAL_SELECT_VECTOR (2)
//              - LINE_MODE_WHITE_LINE (4, MSB)
//         The resulting value will be between 0-7 inclusive.
//
// @return: None.
//
//*************************************************************************************
extern int getMainFeatures(uint_fast8_t features, int featuresData[]);
//*************************************************************************************
//
// @brief: This function is used to get data of main features in view of the Pixy2.
//
// @param: features is the type of feature to return data from. It is a bitwise ORing
//         of the following bits:
//              - VECTORS (1, LSB)
//              - INTERSECTIONS (2)
//              - BARCODES (4, MSB)
//         The resulting value will be between 0-7 inclusive.
//
// @param: featuresData is the array in which the feature data will be stored.
//
// @return: featuresData array.
//          featuresData[0] is the first type of main feature.
//          featuresData[1] is the length of data from the type of first feature.
//          featuresData[2] through featuresData[2+featuresData[1]] is the data from
//          the first feature.
//          NOTE: This format will continue for each of the types of main features
//          visible when this function is called.
//
//
//*************************************************************************************
extern void setNextTurn(uint_fast8_t nextTurnAngle);
//*************************************************************************************
//
// @brief: This function is used to set the angle of the next turn while running the
//         line-tracking API.
//
// @param: nextTurnAngle is the angle which the next turn will have.
//         Valid values are between -180 and 180 inclusive.
//         NOTE: Pixy2 interprets 90 degrees as a left turn and -90 degrees as a right
//               turn.
//
// @return: None.
//
//*************************************************************************************
extern void setDefaultTurn(uint_fast8_t defaultTurnAngle);
//*************************************************************************************
//
// @brief: This function is used to set the angle of the default turn while running the
//         line-tracking API.
//
// @param: defaultTurnAngle is the angle which the next turn will have.
//         Valid values are between -180 and 180 inclusive.
//         NOTE: Pixy2 interprets 90 degrees as a left turn and -90 degrees as a right
//               turn.
//
// @return: None.
//
//*************************************************************************************
extern void reverseVector(void);
//*************************************************************************************
//
// @brief: This function is used to reverse the current direction of travel.
//
// @param: None.
//
// @return: None.
//
//*************************************************************************************
extern int getResolution(int resolutionData[]);
//*************************************************************************************
//
// @brief: This function retrieves the resolution from the Pixy2.
//
// @param: resolutionData is an array in which the frame width and height will be 
//         stored.
//
// @return: resolutionData array.
//          resolutionData[0] is the frame width.
//          resolutionData[1] is the frame height.
//
//*************************************************************************************
extern int getFPS(void);
//*************************************************************************************
//
// @brief: This function retrieves the current FPS from the Pixy2.
//
// @param: None.
//
// @return: FPS (32 bit integer)
//
//*************************************************************************************
//
//*************************************************************************************
extern int getBlocks(int sigmap, int maxBlocks);
//*************************************************************************************
//
// @brief: This function retrieves data regarding blocks of color signature sigmap
//         while in color connected components mode.
//
// @param: sigmap indicates what signature to receive data from.
//         Valid values are between 0-255 inclusive. 255 is a special case where
//         all color signatures are available.
//
// @param: maxBlocks indicates the maximum number of blocks to return.
//         Valid values are between 0-255 inclusive.
//
// @return: blocksData array. (n indicates the number of blocks detected)
//          blocksData[0+8n] is the color signature of the block.
//          blocksData[1+8n] is the X center of the block in pixels.
//          blocksData[2+8n] is the Y center of the block in pixels.
//          blocksData[3+8n] is the width of the blocks in pixels.
//          blocksData[4+8n] is the height of the blocks in pixels.
//          blocksData[5+8n] is the angle of the color code in degrees.
//          blocksData[6+8n] is the tracking index of the block.
//          blocksData[7+8n] is the age of the block (number of frames it has been
//          tracked).
//
//*************************************************************************************
//

#ifdef __cplusplus
}
#endif

#endif /* PIXY2_UART_HEADER_H_ */

pixy2_uart_driver.c

C/C++
Include this along with pixy2_uart_header.h in your project to utilize the functions described in the header.
#include "ti/devices/msp432p4xx/inc/msp.h"
#include "pixy2_uart_header.h"
#include "stdio.h"


int commandBuffer[20];
int responseBuffer[20];
int resolutionData[2];
uint8_t rxBuffer[1024];
uint16_t bufferIndex = 0;

void sendPacket (void) {
    int i;
    int length = sizeof(commandBuffer);
    for (i = 0; i < length; i++){
        while (!(EUSCI_A2->IFG & EUSCI_A_IFG_TXIFG));
        EUSCI_A2->TXBUF = commandBuffer[i];
    }
    memset(commandBuffer, 0, sizeof(commandBuffer));
}

void receivePacket (int responseLength) {
    int i;
    memset(responseBuffer, 0, sizeof(responseBuffer));
    for (i = 0; i < responseLength; i++){
            while (!(EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG));
            responseBuffer[i] = EUSCI_A2->RXBUF;
        }
}

void setCameraBrightness (uint_fast8_t valueBrightness) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_BRIGHTNESS;
    commandBuffer[3] = 1;
    commandBuffer[4] = valueBrightness;
    sendPacket();
}

void setLED (uint_fast8_t valueRed, uint_fast8_t valueGreen, uint_fast8_t valueBlue) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_LED;
    commandBuffer[3] = 3;
    commandBuffer[4] = valueRed;
    commandBuffer[5] = valueGreen;
    commandBuffer[6] = valueBlue;
    sendPacket();
}

void setLamp (uint_fast8_t lowerLamp, uint_fast8_t upperLamp) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_LAMP;
    commandBuffer[3] = 2;
    commandBuffer[4] = lowerLamp;
    commandBuffer[5] = upperLamp;
    sendPacket();
}

void setServos (uint_fast16_t panValue, uint_fast16_t tiltValue) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_SERVO;
    commandBuffer[3] = 4;
    commandBuffer[4] = panValue & 0xFF;
    commandBuffer[5] = panValue >> 8;
    commandBuffer[6] = tiltValue & 0xFF;
    commandBuffer[7] = tiltValue >> 8;
    sendPacket();
}

void setMode (uint_fast8_t mode) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_MODE;
    commandBuffer[3] = 1;
    commandBuffer[4] = mode;
    sendPacket();
}

int getMainFeatures (uint_fast8_t features, int featuresData[]) {
    int i, count;
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_MAIN_FEATURES;
    commandBuffer[3] = 2;
    commandBuffer[4] = 1;
    commandBuffer[5] = features;
    sendPacket();
    featuresData[0] = rxBuffer[6];
    featuresData[1] = rxBuffer[7];
    for (i = 0; i < featuresData[1]; i++){
        featuresData[2+i] = rxBuffer[8+i];
    }
    count = count + i;
    featuresData[3+count] = rxBuffer[9+count];
    featuresData[4+count] = rxBuffer[10+count];
    for (i = 0; i < featuresData[4+count]; i++){
        featuresData[5+count+i] = rxBuffer[11+count+i];
    }
    count = count + i;
    featuresData[6+count] = rxBuffer[12+count];
    featuresData[7+count] = rxBuffer[13+count];
    for (i = 0; i < featuresData[7+count]; i++){
        featuresData[8+count+i] = rxBuffer[14+count+i];
    }
    return featuresData;
}

void setNextTurn (uint_fast16_t nextTurnAngle) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_NEXT_TURN;
    commandBuffer[3] = 2;
    commandBuffer[4] = nextTurnAngle & 0xFF;
    commandBuffer[5] = nextTurnAngle >> 8;
    sendPacket();
}

void setDefaultTurn (uint_fast16_t defaultTurnAngle) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_DEFAULT_TURN;
    commandBuffer[3] = 2;
    commandBuffer[4] = defaultTurnAngle & 0xFF;
    commandBuffer[5] = defaultTurnAngle >> 8;
    sendPacket();
}

void reverseVector (void) {
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_REVERSE_VECTOR;
    commandBuffer[3] = 0;
    sendPacket();
}


int getResolution (int resolutionData[]){
    memset(rxBuffer, 0, sizeof(rxBuffer));
    bufferIndex = 0;
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_RESOLUTION;
    commandBuffer[3] = 1;
    commandBuffer[4] = 69;    // Value does not matter, as long as it is an 8-bit integer
    sendPacket();
    resolutionData[0] = rxBuffer[6] | rxBuffer[7] << 8;
    resolutionData[1] = rxBuffer[8] | rxBuffer[9] << 8;
    return resolutionData;
}

int getFPS (void){
    int FPS;
    memset(rxBuffer, 0, sizeof(rxBuffer));
    bufferIndex = 0;
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_FPS;
    commandBuffer[3] = 0;
    sendPacket();
    FPS = rxBuffer[6] | rxBuffer[7] << 8 | rxBuffer[8] << 16 | rxBuffer[9] << 24;
    return FPS;
}

int getBlocks (int sigmap, int maxBlocks){
    int blockCount;
    int i;
    int blocksData[1024];
    memset(rxBuffer, 0, sizeof(rxBuffer));
    bufferIndex = 0;
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_BLOCKS;
    commandBuffer[3] = 2;
    commandBuffer[4] = sigmap;
    commandBuffer[5] = maxBlocks;
    sendPacket();
    blockCount = rxBuffer[3]/14;
    for (i = 0; i < blockCount; i++){
        blocksData[(i*8)] = rxBuffer[(i*14+6)] | rxBuffer[(i*14+7)] << 8;
        blocksData[(i*8)+1] = rxBuffer[(i*14+8)] | rxBuffer[(i*14+9)] << 8;
        blocksData[(i*8)+2] = rxBuffer[(i*14+10)] | rxBuffer[(i*14+11)] << 8;
        blocksData[(i*8)+3] = rxBuffer[(i*14+12)] | rxBuffer[(i*14+13)] << 8;
        blocksData[(i*8)+4] = rxBuffer[(i*14+14)] | rxBuffer[(i*14+15)] << 8;
        blocksData[(i*8)+5] = rxBuffer[(i*14+16)] | rxBuffer[(i*14+17)] << 8;
        blocksData[(i*8)+6] = rxBuffer[(i*14+18)];
        blocksData[(i*8)+7] = rxBuffer[(i*14+19)];
    }
    return blocksData;
}

int getRGB (int xValue, int yValue, int saturate, int RGBData[]){
    memset(rxBuffer, 0, sizeof(rxBuffer));
    bufferIndex = 0;
    commandBuffer[0] = PIXY2_NO_CHECKSUM_SYNC & 0xFF;
    commandBuffer[1] = PIXY2_NO_CHECKSUM_SYNC >> 8;
    commandBuffer[2] = PIXY2_TYPE_REQUEST_RGB;
    commandBuffer[3] = 5;
    commandBuffer[4] = xValue & 0xFF;
    commandBuffer[5] = xValue >> 8;
    commandBuffer[6] = yValue & 0xFF;
    commandBuffer[7] = yValue >> 8;
    commandBuffer[8] = saturate;
    sendPacket();
    RGBData[0] = rxBuffer[6];
    RGBData[1] = rxBuffer[7];
    RGBData[2] = rxBuffer[8];
    return RGBData;
}

void EUSCIA2_IRQHandler(void)
{
    if (EUSCI_A2->IFG & EUSCI_A_IFG_RXIFG)
    {
        rxBuffer[bufferIndex] = EUSCI_A2->RXBUF;
        bufferIndex++;
        EUSCI_A2->IFG &= ~EUSCI_A_IFG_RXIFG;
    }
}

Credits

Zachary Holloway

Zachary Holloway

1 project • 2 followers
Thanks to University of Texas at Arlington and Texas Instruments.

Comments