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

MSLL-driver.h

Go to the documentation of this file.
00001 /*!@addtogroup mindsensors
00002  * @{
00003  * @defgroup msll LineLeader Sensor
00004  * LineLeader Sensor
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: MSLL-driver.h 48 2011-02-13 20:35:38Z xander $
00010  */
00011 
00012 #ifndef __MSLL_H__
00013 #define __MSLL_H__
00014 
00015 /** \file MSLL-driver.h
00016  * \brief Mindsensors Line Tracking Sensor
00017  *
00018  * MSLL-driver.h provides an API for the Mindsensors Line Tracking Sensor.
00019  *
00020  * Changelog:
00021  *  - 0.1 Initial       TFR<br>
00022  *  - 0.2 Added ability to read multi-ubyte values for raw, white and black thresholds.<br>
00023  *  - 0.3 Added PID factor registers (Read/Write), Added new commands 'S'napShot, 'R'eset,
00024  *      and changed function and method names to be more C++ like.<br>
00025  *  - 0.4 Modified to conform to new "naming standard" and be part of the driver suite.<br>
00026  *       changed all (int) casts to ubyteToInt() calls.<br>
00027  *       all direct I2C calls changed to readI2C() and writeI2C() calls.
00028  *  - 0.5 Bug in LLreadSteering fixed
00029  *  - 0.6 Added LLreadSensorUncalibrated
00030  *
00031  * License: You may use this code as you wish, provided you give credit where it's due.
00032  *
00033  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 2.00 AND HIGHER.
00034  * \author Thom Roach
00035  * \author Xander Soldaat (version 0.4+)
00036  * \date 29 October 2009
00037  * \version 0.6
00038  * \example MSLL-test2.c
00039  * \example MSLL-test3.c
00040  * \example MSLL-test4.c
00041  */
00042 
00043 #pragma systemFile
00044 
00045 #ifndef __COMMON_H__
00046         #include "common.h"
00047 #endif
00048 
00049 //*******************************************************************************
00050 // REGISTER LOCATIONS AND COMMANDS for the Line Leader Sensor
00051 //*******************************************************************************
00052 #define LL_I2C_ADDR             0x02  /*!< I2C address used by the LL */
00053 #define LL_CMD_REG              0x41  /*!< Register used for issuing commands */
00054 
00055 #define LL_SETPOINT       0x45  /*!< average value considered center of line (def=45) */
00056 #define LL_KP_VALUE                     0x46  /*!< P value of PID control */
00057 #define LL_KI_VALUE                     0X47  /*!< I value of PID control */
00058 #define LL_KD_VALUE                     0X48  /*!< D value of PID control */
00059 #define LL_KP_FACTOR      0x61  /*!< P factor for P value of PID control */
00060 #define LL_KI_FACTOR      0X62  /*!< I factor for I value of PID control */
00061 #define LL_KD_FACTOR      0X63  /*!< D factor for D value of PID control */
00062 
00063 #define LL_READ_STEERING        0x42  /*!< steering value for simple mode line following */
00064 #define LL_READ_AVERAGE         0X43  /*!< weighted average value for all sensors in array */
00065 #define LL_READ_RESULT          0X44  /*!< 1 or 0 for line or no line for all 8 sensors */
00066 #define LL_SENSOR_RAW           0X49  /*!< ubyte array (8) with raw value for each sensor */
00067 #define LL_WHITE_LIMIT          0X51  /*!< ubyte array (8) with raw value of white calibration for each sensor */
00068 #define LL_BLACK_LIMIT          0X59  /*!< ubyte array (8) with raw value of black calibration for each sensor */
00069 #define LL_SENSOR_UNCAL   0x74  /*!< ubyte array (16) with uncalibrated sensor data */
00070 
00071 tByteArray LL_I2CRequest;       /*!< Array to hold I2C command data */
00072 tByteArray LL_I2CReply;         /*!< Array to hold I2C reply data */
00073 ubyte oneByte;
00074 
00075 //*******************************************************************************
00076 // PUBLIC Line Leader functions
00077 //*******************************************************************************
00078 bool LLinit(tSensors link);                                         /*!< Set up Line Leader sensor type */
00079 bool LLwakeUp(tSensors link);                                                       /*!< Wake sensor from sleep mode */
00080 bool LLsleep(tSensors link);                                                        /*!< Sleep to conserve power when not in use */
00081 
00082 bool LLinvertLineColor(tSensors link);                    /*!< Inverts detected line color */
00083 bool LLresetLineColor(tSensors link);                     /*!< Resets line color to dark on light bkgrnd */
00084 bool LLtakeSnapshot(tSensors link);                       /*!< takes a snapshot to determine line color */
00085 
00086 bool LLcalWhite(tSensors link);                           /*!< Set white threshold for light area */
00087 bool LLcalBlack(tSensors link);                           /*!< Set black threshold for dark area */
00088 
00089 bool LLsetPoint(tSensors link, ubyte data);                /*!< WRITE mid-point or center of line value */
00090 int LLsetPoint(tSensors link);                            /*!< READ SetPoint value */
00091 
00092 bool LLsetKp(tSensors link, ubyte data, ubyte factor);      /*!< WRITE Kp value */
00093 int LLreadKp(tSensors link);                              /*!< READ Kp value */
00094 int LLreadKpFactor(tSensors link);                        /*!< READ p factor value */
00095 
00096 bool LLsetKi(tSensors link, ubyte data, ubyte factor);      /*!< WRITE Ki value */
00097 int LLreadKi(tSensors link);                              /*!< READ Ki value */
00098 int LLreadKiFactor(tSensors link);                        /*!< READ i factor value */
00099 
00100 bool LLsetKd(tSensors link, ubyte data, ubyte factor);      /*!< WRITE Kd value */
00101 int LLreadKd(tSensors link);                              /*!< READ Kd value */
00102 int LLreadKdFactor(tSensors link);                        /*!< READ d factor value */
00103 
00104 int LLreadSteering(tSensors link);                        /*!< Read internally calculated steering value */
00105 int LLreadAverage(tSensors link);                         /*!< Read weighted sensor array average value */
00106 int LLreadResult(tSensors link);                                            /*!< Read boolean sensor array values for all sensors */
00107 bool LLreadSensorRaw(tSensors link, tByteArray &pMsg);    /*!< Return array of raw light values (8 bytes) */
00108 bool LLreadSensorUncalibrated (tSensors link, tIntArray &sensorValues);  /*!< Return array of raw uncalibrated light values (8 ints) */
00109 bool LLreadWhiteThresh(tSensors link, tByteArray &pMsg);  /*!< Return array of white thresholds (8 bytes) */
00110 bool LLreadBlackThresh(tSensors link, tByteArray &pMsg);  /*!< Return array of black thresholds (8 bytes) */
00111 
00112 //*******************************************************************************
00113 // INTERNAL USE ONLY - Line Leader functions - used by the above
00114 //*******************************************************************************
00115 bool _lineLeader_cmd(tSensors link, ubyte cmd);                      /*!< Send a command to the Line Leader */
00116 bool _lineLeader_write(tSensors link, ubyte regToWrite, ubyte data);  /*!< Write to a Line Leader Register */
00117 bool _lineLeader_read(tSensors link, ubyte regToRead, ubyte &retval); /*!< Read one ubyte from a Line Leader Register */
00118 bool _lineLeader_read(tSensors link, ubyte regToRead, int numBytes, tByteArray &pDataMsg);  /*!< Read data from a Line Leader Register */
00119 
00120 //*******************************************************************************
00121 // FUNCTION DEFINITIONS
00122 //*******************************************************************************
00123 /**
00124  * This function sends a command to the lineleader over I2C.
00125  *
00126  * Note: this is an internal function and should not be called directly.
00127  * @param link the sensor port number
00128  * @param cmd the command to be sent
00129  * @return true if no error occured, false if it did
00130 
00131 PRELIMINARY COMMANDS FROM NXC LIB CODE
00132  - A American frequency compensation
00133  - B for black calibration
00134  - D sensor power down
00135  - E European frequency compensation
00136  - I invert line color
00137  - P power on sensor
00138  - R reset line color to dark
00139  - S snapshot to determine line color
00140  - U Universal frequency compensation (default)
00141  - S setpoint based on snapshot (automatically set's invert if needed)
00142  - W White balance
00143  */
00144 bool _lineLeader_cmd(tSensors link, ubyte cmd) {
00145   LL_I2CRequest[0] = 3;             // Message size
00146   LL_I2CRequest[1] = LL_I2C_ADDR;   // I2C Address
00147   LL_I2CRequest[2] = LL_CMD_REG;    // Register used for issuing commands
00148   LL_I2CRequest[3] = cmd;           // Command to be executed
00149 
00150   return writeI2C(link, LL_I2CRequest, 0);
00151 }
00152 
00153 
00154 /**
00155  * This function writes data to a register in the LL sensor over I2C.
00156  *
00157  * Note: this is an internal function and should not be called directly.
00158  * @param link the sensor port number
00159  * @param regToWrite the register to write to
00160  * @param data the value to write to the register
00161  * @return true if no error occured, false if it did
00162  */
00163 
00164 bool _lineLeader_write(tSensors link, ubyte regToWrite, ubyte data) {
00165 
00166   memset(LL_I2CRequest, 0, sizeof(tByteArray));
00167         LL_I2CRequest[0] = 3;             // Message size
00168   LL_I2CRequest[1] = LL_I2C_ADDR;   // I2C Address
00169   LL_I2CRequest[2] = regToWrite;    // Register address to set
00170   LL_I2CRequest[3] = data;          // value to place in register address
00171 
00172   if (!writeI2C(link, LL_I2CRequest, 0))
00173                 return false;
00174         return true;
00175 }
00176 
00177 
00178 /**
00179  * This function reads one ubyte from a register in the LL sensor over I2C.
00180  *
00181  * Note: this is an internal function and should not be called directly.
00182  * @param link the sensor port number
00183  * @param regToRead the register to read from
00184  * @param retval the ubyte in which to store the reply
00185  * @return true if no error occured, false if it did
00186  */
00187 bool _lineLeader_read(tSensors link, ubyte regToRead, ubyte &retval) {
00188         memset(LL_I2CRequest, 0, sizeof(LL_I2CRequest));
00189         LL_I2CRequest[0] =  2;
00190         LL_I2CRequest[1] =  LL_I2C_ADDR;
00191         LL_I2CRequest[2] =  regToRead;
00192 
00193   if (!writeI2C(link, LL_I2CRequest, 1))
00194     return false;
00195 
00196   if (!readI2C(link, LL_I2CReply, 1))
00197     return false;
00198 
00199   retval = (int)LL_I2CReply[0];
00200   return true;
00201 }
00202 
00203 
00204 /**
00205  * This function reads multiple bytes from a register in the LL sensor over I2C.
00206  *
00207  * Note: this is an internal function and should not be called directly.
00208  * @param link the sensor port number
00209  * @param regToRead the register to read from
00210  * @param numBytes the number of bytes to read
00211  * @param pDataMsg tByteArray to store reply
00212  * @return true if no error occured, false if it did
00213  */
00214 bool _lineLeader_read(tSensors link, ubyte regToRead, int numBytes, tByteArray &pDataMsg) {
00215         memset(LL_I2CRequest, 0, sizeof(tByteArray));
00216         memset(pDataMsg, 0, sizeof(tByteArray));
00217 
00218         LL_I2CRequest[0] =  2;
00219         LL_I2CRequest[1] =  LL_I2C_ADDR;
00220         LL_I2CRequest[2] =  regToRead;
00221 
00222 
00223   if (!writeI2C(link, LL_I2CRequest, numBytes))
00224     return false;
00225 
00226   if (!readI2C(link, LL_I2CReply, numBytes))
00227     return false;
00228 
00229   // copy the result into the array to be returned.
00230   memcpy(pDataMsg, LL_I2CReply, sizeof(tByteArray));
00231   return true;
00232 }
00233 
00234 
00235 /**
00236  * This function initializes the line leader to prepare for use.
00237  * Issuing a command also wakes the line leader as needed.
00238  * @param link the sensor port number
00239  * @return true if no error occured, false if it did
00240  */
00241 bool LLinit(tSensors link) {
00242         nI2CBytesReady[link] = 0;
00243         SensorType[link] = sensorI2CCustom9V;
00244         if (!LLwakeUp(link))
00245           return false;
00246         if (!LLresetLineColor(link))
00247           return false;
00248         return true;
00249 }
00250 
00251 
00252 /**
00253  * This function wakes the line leader to prepare for use.
00254  * Issuing a command also wakes the line leader as needed.
00255  * @param link the sensor port number
00256  * @return true if no error occured, false if it did
00257  */
00258 bool LLwakeUp(tSensors link) {
00259   if (!_lineLeader_cmd(link, 'P')) // Sort by size
00260     return false;
00261   return true;
00262 }
00263 
00264 
00265 /**
00266  * This function puts the line leader to sleep conserve power.
00267  * @param link the sensor port number
00268  * @return true if no error occured, false if it did
00269  */
00270 bool LLsleep(tSensors link) {
00271   if (!_lineLeader_cmd(link, 'D')) // Sort by size
00272     return false;
00273   return true;
00274 }
00275 
00276 
00277 /**
00278  * the function toggles from dark line on light to light line on dark and back.
00279  * @param link the sensor port number
00280  * @return true if no error occured, false if it did
00281  */
00282 bool LLinvertLineColor(tSensors link) {
00283   if (!_lineLeader_cmd(link, 'I')) // invert motors
00284     return false;
00285   return true;
00286 }
00287 
00288 
00289 /**
00290  * the function resets to default of sensing a dark line on light background
00291  * @param link the sensor port number
00292  * @return true if no error occured, false if it did
00293  */
00294 bool LLresetLineColor(tSensors link) {
00295   if (!_lineLeader_cmd(link, 'R')) // reset the color to black
00296     return false;
00297   return true;
00298 }
00299 
00300 
00301 /**
00302  * This function takes a snapshot of the line under the sensor
00303  * and tracks that position in subsequent tracking operations.
00304  * Also this function will set inversion if it sees white line
00305  * on dark background
00306  * @param link the sensor port number
00307  * @return true if no error occured, false if it did
00308  */
00309 bool LLtakeSnapshot(tSensors link) {
00310   if (!_lineLeader_cmd(link, 'S')) // take a snapshot
00311     return false;
00312   return true;
00313 }
00314 
00315 
00316 /**
00317  * This function calibrates the white threshold for each sensor in the array.
00318  * Place the array over the white surface with all sensors on the white
00319  * area.  Execute this command to set white values internally.
00320  * @param link the sensor port number
00321  * @return true if no error occured, false if it did
00322  */
00323 bool LLcalWhite(tSensors link) {
00324   if (!_lineLeader_cmd(link, 'W')) // calibrate white
00325     return false;
00326   return true;
00327 }
00328 
00329 
00330 /**
00331  * This function calibrates the black threshold for each sensor in the array.
00332  * Place the array over the white surface with all sensors on the black
00333  * area.  Execute this command to set black values internally.
00334  * @param link the sensor port number
00335  * @return true if no error occured, false if it did
00336  */
00337 bool LLcalBlack(tSensors link) {
00338   if (!_lineLeader_cmd(link, 'B')) // calibrate black
00339     return false;
00340   return true;
00341 }
00342 
00343 
00344 /**
00345  * The set point is used by internally (or externally) by the sensor to
00346  * determine the middle of the sensor over a line.  This value is compared to
00347  * the average value to help the robot know if it is left or right of center.
00348  * @param link the sensor port number
00349  * @param data - the value to set the set point to
00350  * @return true if no error occured, false if it did
00351  */
00352 bool LLsetPoint(tSensors link, ubyte data){
00353         return _lineLeader_write(link, LL_SETPOINT, data);
00354 }
00355 
00356 
00357 /**
00358  * This function reads the setpoint value from the sensor
00359  * @param link the sensor port number
00360  * @return value of setpoint
00361  */
00362 int LLsetPoint(tSensors link){
00363         _lineLeader_read(link, LL_KP_VALUE, oneByte);
00364         return (int)oneByte;
00365 }
00366 
00367 
00368 /*
00369  * The following parameters (kp,ki,kd) are specific
00370  * to your robot. They will change based on robot design,
00371  * it's traction with mat, weight, wheel size, wheel spacing,
00372  * sensor distance from wheels, etc, etc.
00373  *
00374  * Tune them as best as you can for your robot.<br>
00375  * Note, in general,<br>
00376  *  kp will be a high value near 1.0 (30/32)<br>
00377  *  ki will be zero or very low value (0.01), and<br>
00378  *  kd will be a low value near 0.25 (8/32)<br>
00379  *
00380  * If you wish to learn more about Kp, Ki, Kd, please
00381  * read the user guide.<br>
00382  * An excellent explanation of PID is also offered at:
00383  * http://en.wikipedia.org/wiki/PID_controller
00384  *
00385  * p:25/32,i:0, d:8/32
00386  */
00387 
00388 
00389 
00390 /**
00391  * Set the "Kp" value for the sensor's internal PID calculations.<br>
00392  * This value is usually set close to 1.0  default 25/32<br>
00393  * EXPECTED VALUES: 0 to 255<br>
00394  * DEFAULT VALUE: 25<br>
00395  * EXPECTED FACTORS: 1 to 255<br>
00396  * DEFAULT FACTOR: 32
00397  * @param link the sensor port number
00398  * @param data - the value to set Kp
00399  * @param factor - the Kp factor where p = Kp/Kpfactor
00400  * @return true if no error occured, false if it did
00401  */
00402 bool LLsetKp(tSensors link, ubyte data, ubyte factor){
00403         _lineLeader_write(link, LL_KP_VALUE, data);
00404         if ( factor == 0 ) factor = 1;
00405         _lineLeader_write(link, LL_KP_FACTOR, factor);
00406   return true;
00407 }
00408 
00409 
00410 /**
00411  * Read the "Kp" value from the sensor.
00412  * @param link the sensor port number
00413  * @return Kp value from the sensor
00414  */
00415 int LLreadKp(tSensors link) {
00416         _lineLeader_read(link, LL_KP_VALUE, oneByte);
00417         return (int) oneByte;
00418 }
00419 
00420 
00421 /**
00422  * Read the "Kp factor" value from the sensor.
00423  * @param link the sensor port number
00424  * @return Kp factor value from the sensor
00425  */
00426 int LLreadKpFactor(tSensors link) {
00427         if (_lineLeader_read(link, LL_KP_FACTOR, oneByte))
00428                 return (int)oneByte;
00429         else
00430           return 0;
00431 }
00432 
00433 
00434 /**
00435  * Set the "Ki" value for the sensor's internal PID calculations.<br>
00436  * This value is usually set close to 0  default 0/1<br>
00437  * EXPECTED VALUES: 0 to 255<br>
00438  * DEFAULT VALUE: 0<br>
00439  * EXPECTED FACTORS: 1 to 255<br>
00440  * DEFAULT FACTOR: 1
00441  * @param link the sensor port number
00442  * @param data - the value to set Ki
00443  * @param factor - the Ki factor where i = Ki/Kifactor
00444  * @return true if no error occured, false if it did
00445  */
00446 bool LLsetKi(tSensors link, ubyte data, ubyte factor){
00447   _lineLeader_write(link, LL_KI_VALUE, data);
00448         if ( factor == 0 ) factor = 1;
00449         _lineLeader_write(link, LL_KI_FACTOR, factor);
00450   return true;
00451 }
00452 
00453 
00454 /**
00455  * Read the "Ki" value from the sensor.
00456  * @param link the sensor port number
00457  * @return Ki value from the sensor
00458  */
00459 int LLreadKi(tSensors link) {
00460         _lineLeader_read(link, LL_KI_VALUE, oneByte);
00461         return (int)oneByte;
00462 }
00463 
00464 
00465 /**
00466  * Read the "Ki factor" value from the sensor.
00467  * @param link the sensor port number
00468  * @return Ki factor value from the sensor
00469  */
00470 int LLreadKiFactor(tSensors link) {
00471         if (_lineLeader_read(link, LL_KI_FACTOR, oneByte))
00472           return (int)oneByte;
00473         else
00474           return 0;
00475 }
00476 
00477 
00478 /**
00479  * Set the "Kd" value for the sensor's internal PID calculations.<br>
00480  * This value is usually set lower to stabilize default 8/32<br>
00481  * EXPECTED VALUES: 0 to 255<br>
00482  * DEFAULT VALUE: 8<br>
00483  * EXPECTED VALUES: 1 to 255<br>
00484  * DEFAULT FACTOR: 32
00485  * @param link the sensor port number
00486  * @param data - the value to set Kd
00487  * @param factor - the Kd factor where d = Kd/Kdfactor
00488  * @return true if no error occured, false if it did
00489  */
00490 bool LLsetKd(tSensors link, ubyte data, ubyte factor){
00491   _lineLeader_write(link, LL_KD_VALUE, data);
00492         if ( factor == 0 ) factor = 1;
00493         _lineLeader_write(link, LL_KD_FACTOR, factor);
00494   return true;
00495 }
00496 
00497 
00498 /**
00499  * Read the "Kd" value from the sensor.
00500  * @param link the sensor port number
00501  * @return Kd value from the sensor
00502  */
00503 int LLreadKd(tSensors link) {
00504         _lineLeader_read(link, LL_KD_VALUE, oneByte);
00505         return (int)oneByte;
00506 }
00507 
00508 
00509 /**
00510  * Read the "Kd factor" value from the sensor.
00511  * @param link the sensor port number
00512  * @return Kd factor value from the sensor
00513  */
00514 int LLreadKdFactor(tSensors link) {
00515         if (_lineLeader_read(link, LL_KD_FACTOR, oneByte))
00516           return (int)oneByte;
00517         else
00518           return 0;
00519 }
00520 
00521 
00522 /**
00523  * Read the "Steering" value from the sensor.  This value is calculated internally
00524  * and can directly be used to set turning values for the robot's motors.<br>
00525  * EXPECTED VALUES: -100 to 100 (-101=ERROR)
00526  * @param link the sensor port number (range: -100 to 100)
00527  * @return steering value from the sensor, -101 for error
00528  */
00529 int LLreadSteering(tSensors link) {
00530         if (_lineLeader_read(link, LL_READ_STEERING, oneByte))
00531           return (int)(0xFF & oneByte);
00532         else
00533           return -101;
00534 }
00535 
00536 
00537 /**
00538  * Read the Weighted "Average" value from the sensor.  This value is calculated
00539  * internally by the sensor where each of the eight sensors is either triggered or not
00540  * and multiplied by a a factor to help determine if the line is left, right or
00541  * on center of the line (according to the set point).<br>
00542  * EXPECTED VALUES: 0-80 (-1=ERROR)<br>
00543  * <pre> SENSOR:       0    1    2    3    4    5    6    7
00544  * MULTIPLIER:  10   20   30   40   50   60   70   80</pre>
00545  * FORMULA: Sum(Weighted Values)/Number sensors on line<br>
00546  * Ex. if sensor 0 and 1 are over a line, the average is:<br>
00547  *     (10 + 20 + 0 + 0 + 0 + 0 + 0 + 0)/2 = 15<br>
00548  *     in this case 30 < 45 (set point) so the bot is left of center
00549  * @param link the sensor port number
00550  * @return average sensor value or -1 for error
00551  */
00552 int LLreadAverage(tSensors link) {
00553         if (_lineLeader_read(link, LL_READ_AVERAGE, oneByte))
00554           return (int)oneByte;
00555         else
00556           return -1;
00557 }
00558 
00559 
00560 /**
00561  * Read a ubyte with each bit equal to a sensor.<br>
00562  * 1 = Line<br>
00563  * 0 = No Line<br>
00564  * <pre> SENSOR:      0    1    2    3    4    5    6    7
00565  * MULTIPLIER:  1    2    4    8    16   32   64   128</pre>
00566  * To determine if a given sensor is over a line or not, use binary math
00567  * to test each bit.<br>
00568  * A returned value of 3 means sensor 0 and 1 are over a line.
00569  * @param link the sensor port number
00570  * @return RESULT value from the sensor with 8 bits of data; NO ERROR CODE
00571  */
00572 int LLreadResult(tSensors link) {
00573   _lineLeader_read(link, LL_READ_RESULT, oneByte);
00574   return (int)oneByte;
00575 }
00576 
00577 
00578 /**
00579  * Read the "Raw Sensor" values from the Line Leader.  Amount of light or dark
00580  * each sensor sees.  Typically between 0-20.  0=black, 100=white
00581  * @param link the sensor port number
00582  * @param &pMsg is 8 bytes returned.  One for each sensor with raw value.
00583  * @return true if no error occured, false if it did
00584  */
00585 bool LLreadSensorRaw(tSensors link, tByteArray &pMsg) {
00586         return _lineLeader_read(link, LL_SENSOR_RAW, 8, pMsg);
00587 }
00588 
00589 
00590 /**
00591  * Read the uncalibrated sensor values from the Line Leader.  Each sensor returns a 16 bit
00592  * value.
00593  * @param link the sensor port number
00594  * @param sensorValues is 8 bytes returned.  One for each sensor with raw value.
00595  * @return true if no error occured, false if it did
00596  */
00597 bool LLreadSensorUncalibrated (tSensors link, tIntArray &sensorValues) {
00598   tByteArray sensorData;
00599 
00600   if (!_lineLeader_read(link, LL_SENSOR_UNCAL, 16, sensorData)) {
00601     return false;
00602   }
00603 
00604   for (int i = 0; i < 8; i++) {
00605     sensorValues[i] = (0xFF & sensorData[(i*2)]) + ((0xFF & sensorData[((i*2)+1)]) << 8);
00606   }
00607 
00608   return true;
00609 }
00610 
00611 
00612 /**
00613  * Read the "White Threshold" values from the Line Leader for each sensor.<br>
00614  * Each of the eight sensors has a value.  Raw values greater then this threshold
00615  * equal white (area).<br>
00616  * The values are set when calibrating the white points for the sensor.
00617  * @param link the sensor port number
00618  * @param &pMsg is 8 bytes returned.  One for each sensor with Threshold.
00619  * @return true if no error occured, false if it did
00620  */
00621 bool LLreadWhiteThresh(tSensors link, tByteArray &pMsg) {
00622         return _lineLeader_read(link, LL_WHITE_LIMIT, 8, pMsg);
00623 }
00624 
00625 
00626 /**
00627  * Read the "Black Threshold" values from the Line Leader for each sensor.<br>
00628  * Each of the eight sensors has a value.  Raw values less then this threshold
00629  * equal black (line).<br>
00630  * The values are set when calibrating the black points for the sensor.
00631  * @param link the sensor port number
00632  * @param &pMsg is 8 bytes returned.  One for each sensor with Threshold.
00633  * @return true if no error occured, false if it did
00634  */
00635 bool LLreadBlackThresh(tSensors link, tByteArray &pMsg) {
00636         return _lineLeader_read(link, LL_BLACK_LIMIT, 8, pMsg);
00637 }
00638 
00639 
00640 #endif // __MSLL_H__
00641 
00642 /*
00643  * $Id: MSLL-driver.h 48 2011-02-13 20:35:38Z xander $
00644  */
00645 /* @} */
00646 /* @} */