Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

hitechnic-colour-v2.h

Go to the documentation of this file.
00001 /*!@addtogroup HiTechnic
00002  * @{
00003  * @defgroup htcs2 Color Sensor V2
00004  * HiTechnic Color Sensor V2
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: hitechnic-colour-v2.h 133 2013-03-10 15:15:38Z xander $
00010  */
00011 
00012 #ifndef __HTCS2_H__
00013 #define __HTCS2_H__
00014 /** \file hitechnic-colour-v2.h
00015  * \brief HiTechnic Color Sensor V2 driver
00016  *
00017  * HTCS22-driver.h provides an API for the HiTechnic Color Sensor driver.
00018  *
00019  * Changelog:
00020  * - 0.1: Initial release
00021  * - 0.2: Use new calls in common.h that don't require SPORT/MPORT macros
00022  *        Removed usage of ubyteToInt();
00023  * - 0.3: Replaced array structs with typedefs
00024  * - 0.4: Added HTCSreadHSV(), thanks Mike Henning, Max Bareiss
00025  *
00026  * Credits:
00027  * - Big thanks to HiTechnic for providing me with the hardware necessary to write and test this.
00028  *
00029  * License: You may use this code as you wish, provided you give credit where its due.
00030  *
00031  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 3.59 AND HIGHER. 
00032 
00033  * \author Xander Soldaat (xander_at_botbench.com)
00034  * \date 27 April 2011
00035  * \version 0.4
00036  * \example hitechnic-colour-v2-test1.c
00037  * \example hitechnic-colour-v2-test2.c
00038  * \example hitechnic-colour-v2-SMUX-test1.c
00039  */
00040 
00041 #pragma systemFile
00042 
00043 #ifndef __COMMON_H__
00044 #include "common.h"
00045 #endif
00046 
00047 #ifndef __LIGHT_COMMON_H__
00048 #include "common-light.h"
00049 #endif
00050 
00051 #define HTCS2_I2C_ADDR        0x02      /*!< HTCS2 I2C device address */
00052 #define HTCS2_CMD_REG         0x41      /*!< Command register */
00053 #define HTCS2_OFFSET          0x42      /*!< Offset for data registers */
00054 
00055 // Values contained by registers in active mode
00056 #define HTCS2_COLNUM_REG      0x00      /*!< Color number */
00057 #define HTCS2_RED_REG         0x01      /*!< Red reading */
00058 #define HTCS2_GREEN_REG       0x02      /*!< Green reading */
00059 #define HTCS2_BLUE_REG        0x03      /*!< Blue reading */
00060 #define HTCS2_WHITE_REG       0x04      /*!< White channel reading */
00061 #define HTCS2_COL_INDEX_REG   0x05      /*!< Color index number */
00062 #define HTCS2_RED_NORM_REG    0x06      /*!< Normalised red reading */
00063 #define HTCS2_GREEN_NORM_REG  0x07      /*!< Normalised green reading */
00064 #define HTCS2_BLUE_NORM_REG   0x08      /*!< Normalised blue reading */
00065 
00066 // Values contained by registers in passive and raw mode
00067 #define HTCS2_RED_MSB         0x00      /*!< Raw red reading - MSB */
00068 #define HTCS2_RED_LSB         0x00      /*!< Raw red reading - LSB */
00069 #define HTCS2_GREEN_MSB       0x00      /*!< Raw green reading - MSB */
00070 #define HTCS2_GREEN_LSB       0x00      /*!< Raw green reading - LSB */
00071 #define HTCS2_BLUE_MSB        0x00      /*!< Raw blue reading - MSB */
00072 #define HTCS2_BLUE_LSB        0x00      /*!< Raw blue reading - LSB */
00073 #define HTCS2_WHITE_MSB       0x00      /*!< Raw white channel reading - MSB */
00074 #define HTCS2_WHITE_LSB       0x00      /*!< Raw white channel reading - LSB */
00075 
00076 // Different modes
00077 #define HTCS2_MODE_ACTIVE     0x00      /*!< Use ambient light cancellation */
00078 #define HTCS2_MODE_PASSIVE    0x01      /*!< Disable ambient light cancellation */
00079 #define HTCS2_MODE_RAW        0x03      /*!< Raw data from light sensor */
00080 #define HTCS2_MODE_50HZ       0x35      /*!< Set sensor to 50Hz cancellation mode */
00081 #define HTCS2_MODE_60HZ       0x36      /*!< Set sensor to 60Hz cancellation mode */
00082 
00083 
00084 int HTCS2readColor(tSensors link);
00085 bool HTCS2readRGB(tSensors link, int &red, int &green, int &blue);
00086 bool HTCS2readHSV(tSensors link, float &hue, float &saturation, float &value);
00087 bool HTCS2readWhite(tSensors link, int &white);
00088 bool HTCS2readNormRGB(tSensors link, int &red, int &green, int &blue);
00089 bool HTCS2readRawRGB(tSensors link, bool passive, long &red, long &green, long &blue);
00090 bool HTCS2readRawWhite(tSensors link, bool passive, long &white);
00091 bool _HTCSsendCommand(tSensors link, byte command);
00092 
00093 #ifdef __HTSMUX_SUPPORT__
00094 int HTCS2readColor(tMUXSensor muxsensor);
00095 bool HTCS2readRGB(tMUXSensor muxsensor, int &red, int &green, int &blue);
00096 
00097 tConfigParams HTCS2_config = {HTSMUX_CHAN_I2C, 4, 0x02, 0x42};  /*!< Array to hold SMUX config data for sensor */
00098 #endif // __HTSMUX_SUPPORT__
00099 
00100 tByteArray HTCS2_I2CRequest;           /*!< Array to hold I2C command data */
00101 tByteArray HTCS2_I2CReply;             /*!< Array to hold I2C reply data */
00102 
00103 /*!< Array to hold sensor modes */
00104 signed byte active_mode[4] = {-1, -1, -1, -1};
00105 
00106 
00107 /**
00108  * Return the color number currently detected.
00109  * @param link the HTCS2 port number
00110  * @return color index number or -1 if an error occurred.
00111  */
00112 int HTCS2readColor(tSensors link) {
00113   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00114 
00115   if (active_mode[link] != HTCS2_MODE_ACTIVE)
00116     _HTCSsendCommand(link, HTCS2_MODE_ACTIVE);
00117 
00118   HTCS2_I2CRequest[0] = 2;                                // Message size
00119   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;                   // I2C Address
00120   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_COLNUM_REG;  // Start colour number register
00121 
00122   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 1))
00123     return -1;
00124 
00125   return HTCS2_I2CReply[0];
00126 }
00127 
00128 
00129 /**
00130  * Return the color number currently detected.
00131  * @param muxsensor the SMUX sensor port number
00132  * @return color index number or -1 if an error occurred.
00133  */
00134 #ifdef __HTSMUX_SUPPORT__
00135 int HTCS2readColor(tMUXSensor muxsensor) {
00136   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00137 
00138   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00139     HTSMUXconfigChannel(muxsensor, HTCS2_config);
00140 
00141   if (!HTSMUXreadPort(muxsensor, HTCS2_I2CReply, 1, HTCS2_COLNUM_REG)) {
00142     return -1;
00143   }
00144 
00145   return HTCS2_I2CReply[0];
00146 }
00147 #endif // __HTSMUX_SUPPORT__
00148 
00149 
00150 /**
00151  * Get the detection levels for the three color components.
00152  * @param link the HTCS2 port number
00153  * @param red the red value
00154  * @param green the green value
00155  * @param blue the blue value
00156  * @return true if no error occured, false if it did
00157  */
00158 bool HTCS2readRGB(tSensors link, int &red, int &green, int &blue) {
00159   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00160 
00161   if (active_mode[link] != HTCS2_MODE_ACTIVE)
00162     _HTCSsendCommand(link, HTCS2_MODE_ACTIVE);
00163 
00164   HTCS2_I2CRequest[0] = 2;                           // Message size
00165   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;               // I2C Address
00166   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_RED_REG;  // Start red sensor value
00167 
00168   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 3))
00169     return false;
00170 
00171   red = HTCS2_I2CReply[0];
00172   green = HTCS2_I2CReply[1];
00173   blue = HTCS2_I2CReply[2];
00174 
00175   return true;
00176 }
00177 
00178 
00179 /**
00180  * Get the detection levels for the three color components.
00181  * @param muxsensor the SMUX sensor port number
00182  * @param red the red value
00183  * @param green the green value
00184  * @param blue the blue value
00185  * @return true if no error occured, false if it did
00186  */
00187 #ifdef __HTSMUX_SUPPORT__
00188 bool HTCS2readRGB(tMUXSensor muxsensor, int &red, int &green, int &blue) {
00189   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00190 
00191   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00192     HTSMUXconfigChannel(muxsensor, HTCS2_config);
00193 
00194   if (!HTSMUXreadPort(muxsensor, HTCS2_I2CReply, 3, HTCS2_RED_REG)) {
00195     return false;
00196   }
00197 
00198   red = HTCS2_I2CReply[0];
00199   green = HTCS2_I2CReply[1];
00200   blue = HTCS2_I2CReply[2];
00201 
00202   return true;
00203 }
00204 #endif // __HTSMUX_SUPPORT__
00205 
00206 
00207 /**
00208  * Get the detection levels for the hue, saturation, value components.
00209  * @param link the HTCS port number
00210  * @param hue the hue output value (from 0 to 365, or -1 if n/a)
00211  * @param saturation the saruration output value (from 0 to 100, or -1 if n/a)
00212  * @param value the value output value (from 0 to 100)
00213  * @return true if no error occured, false if it did
00214 
00215  */
00216 bool HTCS2readHSV(tSensors link, float &hue, float &saturation, float &value) {
00217   int red,green,blue;
00218 
00219   bool ret = HTCS2readRGB(link, red, green, blue);
00220   RGBtoHSV(red,green,blue, hue, saturation, value);
00221 
00222   return ret;
00223 }
00224 
00225 
00226 /**
00227  * Get the detection levels for the hue, saturation, value components.
00228  * @param muxsensor the SMUX sensor port number
00229  * @param hue the hue output value (from 0 to 365, or -1 if n/a)
00230  * @param saturation the saruration output value (from 0 to 100, or -1 if n/a)
00231  * @param value the value output value (from 0 to 100)
00232  * @return true if no error occured, false if it did
00233  */
00234 #ifdef __HTSMUX_SUPPORT__
00235 bool HTCS2readHSV(tMUXSensor muxsensor, float &hue, float &saturation, float &value) {
00236   int red,green,blue;
00237 
00238   bool ret = HTCS2readRGB(muxsensor, red, green, blue);
00239   RGBtoHSV(red,green,blue, hue, saturation, value);
00240 
00241   return ret;
00242 }
00243 #endif // __HTSMUX_SUPPORT__
00244 
00245 
00246 /**
00247  * Get the detection level for the white channel.
00248  * @param link the HTCS2 port number
00249  * @param white the white channel value
00250  * @return true if no error occured, false if it did
00251  */
00252 bool HTCS2readWhite(tSensors link, int &white) {
00253   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00254 
00255   if (active_mode[link] != HTCS2_MODE_ACTIVE)
00256     _HTCSsendCommand(link, HTCS2_MODE_ACTIVE);
00257 
00258   HTCS2_I2CRequest[0] = 2;                           // Message size
00259   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;               // I2C Address
00260   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_RED_REG;  // Start red sensor value
00261 
00262   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 1))
00263     return false;
00264 
00265   white = HTCS2_I2CReply[0];
00266 
00267   return true;
00268 }
00269 
00270 
00271 /**
00272  * Get the normalised RGB readings. The normalization sets the highest
00273  * value of the three Red, Green and Blue reading to 255 and adjusts the
00274  * other two proportionately.
00275  * @param link the HTCS2 port number
00276  * @param red the red value
00277  * @param green the green value
00278  * @param blue the blue value
00279  * @return true if no error occured, false if it did
00280  */
00281 bool HTCS2readNormRGB(tSensors link, int &red, int &green, int &blue) {
00282   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00283 
00284   HTCS2_I2CRequest[0] = 2;                               // Message size
00285   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;                   // I2C Address
00286   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_RED_NORM_REG; // Start red normalised sensor values
00287 
00288   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 3))
00289     return false;
00290 
00291   red = HTCS2_I2CReply[0];
00292   green = HTCS2_I2CReply[1];
00293   blue = HTCS2_I2CReply[2];
00294 
00295   return true;
00296 }
00297 
00298 
00299 /**
00300  * Get the raw RGB readings, these are unsigned 16 bit values.
00301  * These values will only fit in a long
00302  * @param link the HTCS2 port number
00303  * @param passive when set to true, it will not use the builtin white LED and use ambient light instead
00304  * @param red the red value
00305  * @param green the green value
00306  * @param blue the blue value
00307  * @return true if no error occured, false if it did
00308  */
00309 bool HTCS2readRawRGB(tSensors link, bool passive, long &red, long &green, long &blue) {
00310   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00311 
00312   if (passive && (active_mode[link] != HTCS2_MODE_PASSIVE))
00313     _HTCSsendCommand(link, HTCS2_MODE_PASSIVE);
00314   else if (!passive && (active_mode[link] != HTCS2_MODE_RAW))
00315     _HTCSsendCommand(link, HTCS2_MODE_RAW);
00316 
00317   HTCS2_I2CRequest[0] = 2;                               // Message size
00318   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;                   // I2C Address
00319   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_RED_MSB;  // Start red raw sensor value
00320 
00321   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 8))
00322     return false;
00323 
00324   red =   (long)HTCS2_I2CReply[0] * 256 + HTCS2_I2CReply[1];
00325   green = (long)HTCS2_I2CReply[2] * 256 + HTCS2_I2CReply[3];
00326   blue =  (long)HTCS2_I2CReply[4] * 256 + HTCS2_I2CReply[5];
00327 
00328   return true;
00329 }
00330 
00331 
00332 /**
00333  * Get the raw white channel reading, is and unsigned 16 bit value.
00334  * This value will only fit in a long
00335  * @param link the HTCS2 port number
00336  * @param passive when set to true, it will not use the builtin white LED and use ambient light instead
00337  * @param white the white value
00338  * @return true if no error occured, false if it did
00339  */
00340 bool HTCS2readRawWhite(tSensors link, bool passive, long &white) {
00341   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00342 
00343   if (passive && (active_mode[link] != HTCS2_MODE_PASSIVE))
00344     _HTCSsendCommand(link, HTCS2_MODE_PASSIVE);
00345   else if (!passive && (active_mode[link] != HTCS2_MODE_RAW))
00346     _HTCSsendCommand(link, HTCS2_MODE_RAW);
00347 
00348   HTCS2_I2CRequest[0] = 2;                               // Message size
00349   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;                   // I2C Address
00350   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_WHITE_MSB;  // Start red raw sensor value
00351 
00352   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 2))
00353     return false;
00354 
00355   white = (long)HTCS2_I2CReply[0] * 256 + HTCS2_I2CReply[1];
00356 
00357   return true;
00358 }
00359 
00360 
00361 /**
00362  * Return the color index number currently detected. This is a single
00363  * 6 bit number color index. Bits 5 and 4 encode the red signal level,
00364  * bits 3 and 2 encode the green signal level and bits 1 and 0 encode
00365  * the blue signal levels.
00366  * @param link the HTCS2 port number
00367  * @return color index number or -1 if an error occurred.
00368  */
00369 int HTCS2readColorIndex(tSensors link) {
00370   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00371 
00372   if (active_mode[link] != HTCS2_MODE_ACTIVE)
00373     _HTCSsendCommand(link, HTCS2_MODE_ACTIVE);
00374 
00375   HTCS2_I2CRequest[0] = 2;                                // Message size
00376   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;                    // I2C Address
00377   HTCS2_I2CRequest[2] = HTCS2_OFFSET + HTCS2_COL_INDEX_REG; // Start colour index register
00378 
00379   if (!writeI2C(link, HTCS2_I2CRequest, HTCS2_I2CReply, 1))
00380     return -1;
00381 
00382   return HTCS2_I2CReply[0];
00383 }
00384 
00385 
00386 /**
00387  * Send a command to the sensor to change its mode.
00388  * @param link the HTCS2 port number
00389  * @param command the command to be sent
00390  * @return true if no error occured, false if it did
00391  */
00392 bool _HTCSsendCommand(tSensors link, byte command) {
00393   memset(HTCS2_I2CRequest, 0, sizeof(tByteArray));
00394 
00395   HTCS2_I2CRequest[0] = 3;                  // Message size
00396   HTCS2_I2CRequest[1] = HTCS2_I2C_ADDR;     // I2C Address
00397   HTCS2_I2CRequest[2] = HTCS2_CMD_REG;      // Start colour index register
00398   HTCS2_I2CRequest[3] = command;
00399 
00400   if (command < 30)
00401     active_mode[link] = command;
00402 
00403   return writeI2C(link, HTCS2_I2CRequest);
00404 }
00405 
00406 #endif // __HTCS2_H__
00407 
00408 /*
00409  * $Id: hitechnic-colour-v2.h 133 2013-03-10 15:15:38Z xander $
00410  */
00411 /* @} */
00412 /* @} */