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

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