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

lego-light.h

Go to the documentation of this file.
00001 /*!@addtogroup lego
00002  * @{
00003  * @defgroup legols Light Sensor
00004  * Light Sensor
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: lego-light.h 133 2013-03-10 15:15:38Z xander $
00010  */
00011 
00012 #ifndef __LEGOLS_H__
00013 #define __LEGOLS_H__
00014 /** \file lego-light.h
00015  * \brief Lego Light Sensor driver
00016  *
00017  * lego-light.h provides an API for the Lego Light Sensor.
00018  *
00019  * Changelog:
00020  * - 0.1: Initial release
00021  * - 0.2: Make use of new calls for analogue SMUX sensors in common.h
00022  *
00023  * License: You may use this code as you wish, provided you give credit where its due.
00024  *
00025  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 3.59 AND HIGHER. 
00026 
00027  * \author Xander Soldaat (xander_at_botbench.com)
00028  * \date 25 November 2009
00029  * \version 0.2
00030  * \example lego-light-test1.c
00031  * \example lego-light-test2.c
00032  * \example lego-light-SMUX-test1.c
00033  * \example lego-light-SMUX-test2.c
00034  */
00035 
00036 #pragma systemFile
00037 
00038 #ifndef __COMMON_H__
00039 #include "common.h"
00040 #endif
00041 
00042 #define LEGOLSDAT "legols.dat"    /*!< Datafile for Light Sensor calibration info */
00043 
00044 int lslow[16];
00045 int lshigh[16];
00046 
00047 // Globals
00048 //int lslow = 0;                    /*!< Low calibration value */
00049 //int lshigh = 1023;                /*!< High calibration value */
00050 bool legols_calibrated = false;   /*!< Has the sensor been calibrated yet */
00051 
00052 // Function prototypes
00053 int LSvalRaw(tSensors link);
00054 int LSvalNorm(tSensors link);
00055 void LScalLow(tSensors link);
00056 void LScalHigh(tSensors link);
00057 void LSsetActive(tSensors link);
00058 void LSsetInactive(tSensors link);
00059 
00060 #ifdef __HTSMUX_SUPPORT__
00061 int LSvalNorm(tMUXSensor muxsensor);
00062 void LScalLow(tMUXSensor muxsensor);
00063 int LSvalRaw(tMUXSensor muxsensor);
00064 void LScalHigh(tMUXSensor muxsensor);
00065 void LSsetActive(tMUXSensor muxsensor);
00066 void LSsetInactive(tMUXSensor muxsensor);
00067 #endif // __HTSMUX_SUPPORT__
00068 
00069 void _LScheckSensor(tSensors link);
00070 void _LSwriteCalVals();
00071 void _LSreadCalVals();
00072 
00073 
00074 /**
00075  * Read the raw value of the Light Sensor.
00076  * @param link the Light Sensor port number
00077  * @return the raw value of the Light Sensor
00078  */
00079 int LSvalRaw(tSensors link) {
00080   _LScheckSensor(link);
00081 
00082   return SensorRaw[link];
00083 }
00084 
00085 
00086 /**
00087  * Read the raw value of the Light Sensor.
00088  * @param muxsensor the SMUX sensor port number
00089  * @return the raw value of the Light Sensor
00090  */
00091 #ifdef __HTSMUX_SUPPORT__
00092 int LSvalRaw(tMUXSensor muxsensor) {
00093   return 1023 - HTSMUXreadAnalogue(muxsensor);
00094 }
00095 #endif // __HTSMUX_SUPPORT__
00096 
00097 /**
00098  * Read the normalised value of the Light Sensor, based on the low and high values.
00099  * @param link the Light Sensor port number
00100  * @return the normalised value
00101  */
00102 int LSvalNorm(tSensors link) {
00103   long currval = 0;
00104 
00105   _LScheckSensor(link);
00106 
00107   if (!legols_calibrated) {
00108     _LSreadCalVals();
00109   }
00110 
00111   currval = LSvalRaw(link);
00112 
00113   if (currval <= lslow[link * 4])
00114     return 0;
00115   else if (currval >= lshigh[link * 4])
00116     return 100;
00117 
00118   return ((currval - lslow[link * 4]) * 100) / (lshigh[link * 4] - lslow[link * 4]);
00119 }
00120 
00121 
00122 /**
00123  * Read the normalised value of the Light Sensor, based on the low and high values.
00124  * @param muxsensor the SMUX sensor port number
00125  * @return the normalised value
00126  */
00127  #ifdef __HTSMUX_SUPPORT__
00128 int LSvalNorm(tMUXSensor muxsensor) {
00129   long currval = 0;
00130 
00131   if (!legols_calibrated) {
00132     _LSreadCalVals();
00133   }
00134 
00135   currval = LSvalRaw(muxsensor);
00136 
00137   if (currval <= lslow[muxsensor])
00138     return 0;
00139   else if (currval >= lshigh[muxsensor])
00140     return 100;
00141 
00142   return ((currval - lslow[muxsensor]) * 100) / (lshigh[muxsensor] - lslow[muxsensor]);
00143 }
00144 #endif // __HTSMUX_SUPPORT__
00145 
00146 /**
00147  * Calibrate the Light Sensor's low calibration value with the current raw sensor reading.
00148  * @param link the Light Sensor port number
00149  */
00150 void LScalLow(tSensors link) {
00151   _LScheckSensor(link);
00152 
00153   lslow[link * 4] = SensorRaw[link];
00154   _LSwriteCalVals();
00155 }
00156 
00157 
00158 /**
00159  * Calibrate the Light Sensor's low calibration value with the current raw sensor reading.
00160  * @param muxsensor the SMUX sensor port number
00161  */
00162 #ifdef __HTSMUX_SUPPORT__
00163 void LScalLow(tMUXSensor muxsensor) {
00164   lslow[muxsensor] = LSvalRaw(muxsensor);
00165   _LSwriteCalVals();
00166 }
00167 #endif // __HTSMUX_SUPPORT__
00168 
00169 
00170 /**
00171  * Calibrate the Light Sensor's high calibration value with the current raw sensor reading.
00172  * @param link the Light Sensor port number
00173  */
00174 void LScalHigh(tSensors link) {
00175   _LScheckSensor(link);
00176 
00177   lshigh[link * 4] = SensorRaw[link];
00178   _LSwriteCalVals();
00179 }
00180 
00181 
00182 /**
00183  * Calibrate the Light Sensor's high calibration value with the current raw sensor reading.
00184  * @param muxsensor the SMUX sensor port number
00185  */
00186 #ifdef __HTSMUX_SUPPORT__
00187 void LScalHigh(tMUXSensor muxsensor) {
00188   lshigh[muxsensor] = LSvalRaw(muxsensor);
00189   _LSwriteCalVals();
00190 }
00191 #endif // __HTSMUX_SUPPORT__
00192 
00193 
00194 /**
00195  * Configure the sensor as a LightActive sensor
00196  * @param link the Light Sensor port number
00197  */
00198 void LSsetActive(tSensors link) {
00199   SensorType[link] = sensorLightActive;
00200   SensorMode[link] = modeRaw;
00201   wait1Msec(5);
00202 }
00203 
00204 
00205 /**
00206  * Configure the sensor as a LightActive sensor
00207  * @param muxsensor the SMUX sensor port number
00208  */
00209 #ifdef __HTSMUX_SUPPORT__
00210 void LSsetActive(tMUXSensor muxsensor) {
00211   HTSMUXsetAnalogueActive(muxsensor);
00212 }
00213 #endif // __HTSMUX_SUPPORT__
00214 
00215 
00216 /**
00217  * Configure the sensor as a LightInactive sensor
00218  * @param link the Light Sensor port number
00219  */
00220 void LSsetInactive(tSensors link) {
00221   SensorType[link] = sensorLightInactive;
00222   SensorMode[link] = modeRaw;
00223   wait1Msec(5);
00224 }
00225 
00226 
00227 /**
00228  * Configure the sensor as a LightInactive sensor
00229  * @param muxsensor the SMUX sensor port number
00230  */
00231 #ifdef __HTSMUX_SUPPORT__
00232 void LSsetInactive(tMUXSensor muxsensor) {
00233   HTSMUXsetAnalogueInactive(muxsensor);
00234 }
00235 #endif // __HTSMUX_SUPPORT__
00236 
00237 
00238 /**
00239  * Check if the sensor is set to raw and that it's been configured as a
00240  * LightActive or Inactive sensor.  If not, set the default to sensorLightInActive.
00241  *
00242  * Note: this is an internal function and should not be called directly
00243  * @param link the Light Sensor port number
00244  */
00245 void _LScheckSensor(tSensors link) {
00246   if (SensorMode[link] != modeRaw &&
00247     ((SensorType[link] != sensorLightActive) ||
00248      (SensorType[link] != sensorLightInactive))) {
00249       LSsetInactive(link);
00250     }
00251 }
00252 
00253 
00254 /**
00255  * Write the low and high calibration values to a data file.
00256  *
00257  * Note: this is an internal function and should not be called directly
00258  */
00259 void _LSwriteCalVals() {
00260   TFileHandle hFileHandle;
00261   TFileIOResult nIoResult;
00262   short nFileSize = 64;
00263 
00264   // Delete the old data file and open a new one for writing
00265   Delete(LEGOLSDAT, nIoResult);
00266   OpenWrite(hFileHandle, nIoResult, LEGOLSDAT, nFileSize);
00267   if (nIoResult != ioRsltSuccess) {
00268     Close(hFileHandle, nIoResult);
00269     eraseDisplay();
00270     nxtDisplayTextLine(3, "W:can't cal file");
00271     PlaySound(soundException);
00272     while(bSoundActive) EndTimeSlice();
00273     wait1Msec(5000);
00274     StopAllTasks();
00275   }
00276 
00277   // Write the low calibration value
00278   for (int i = 0; i < 16; i++) {
00279           WriteShort(hFileHandle, nIoResult, lslow[i]);
00280           // writeDebugStreamLine("W: lslow[%d]: %d", i, lslow[i]);
00281           if (nIoResult != ioRsltSuccess) {
00282             eraseDisplay();
00283             nxtDisplayTextLine(3, "can't write lowval");
00284             PlaySound(soundException);
00285             while(bSoundActive) EndTimeSlice();
00286             wait1Msec(5000);
00287             StopAllTasks();
00288           }
00289         }
00290 
00291   // Write the low calibration value
00292   for (int i = 0; i < 16; i++) {
00293           WriteShort(hFileHandle, nIoResult, lshigh[i]);
00294           // writeDebugStreamLine("W lshigh[%d]: %d", i, lshigh[i]);
00295           if (nIoResult != ioRsltSuccess) {
00296             eraseDisplay();
00297             nxtDisplayTextLine(3, "can't write highval");
00298             PlaySound(soundException);
00299             while(bSoundActive) EndTimeSlice();
00300             wait1Msec(5000);
00301             StopAllTasks();
00302           }
00303         }
00304 
00305   // Close the file
00306   Close(hFileHandle, nIoResult);
00307   if (nIoResult != ioRsltSuccess) {
00308     eraseDisplay();
00309     nxtDisplayTextLine(3, "Can't close");
00310     PlaySound(soundException);
00311     while(bSoundActive) EndTimeSlice();
00312     wait1Msec(5000);
00313     StopAllTasks();
00314   }
00315 }
00316 
00317 /**
00318  * Read the low and high calibration values from a data file.
00319  *
00320  * Note: this is an internal function and should not be called directly
00321  */
00322 void _LSreadCalVals() {
00323   TFileHandle hFileHandle;
00324   TFileIOResult nIoResult;
00325   short nFileSize;
00326 
00327   // Open the data file for reading
00328   legols_calibrated = true;
00329   OpenRead(hFileHandle, nIoResult, LEGOLSDAT, nFileSize);
00330   if (nIoResult != ioRsltSuccess) {
00331     Close(hFileHandle, nIoResult);
00332     // Assign default values
00333                 memset(&lslow[0], 0, sizeof(lslow));
00334                 for (int i = 0; i < 16; i++) {
00335                   lshigh[i] = 1023;
00336                 }
00337                 _LSwriteCalVals();
00338     return;
00339   }
00340 
00341   // Read the low calibration value
00342   for (int i = 0; i < 16; i++) {
00343           ReadShort(hFileHandle, nIoResult, lslow[i]);
00344     // writeDebugStreamLine("R: lslow[%d]: %d", i, lslow[i]);
00345           if (nIoResult != ioRsltSuccess) {
00346                         memset(&lslow[0], 0, sizeof(lslow));
00347                         for (int i = 0; i < 16; i++) {
00348                           lshigh[i] = 1023;
00349                         }
00350                         _LSwriteCalVals();
00351                         return;
00352           }
00353         }
00354 
00355   for (int i = 0; i < 16; i++) {
00356           ReadShort(hFileHandle, nIoResult, lshigh[i]);
00357           // writeDebugStreamLine("R lshigh[%d]: %d", i, lshigh[i]);
00358           if (nIoResult != ioRsltSuccess) {
00359                         memset(&lslow[0], 0, sizeof(lslow));
00360                         for (int i = 0; i < 16; i++) {
00361                           lshigh[i] = 1023;
00362                         }
00363                         _LSwriteCalVals();
00364                         return;
00365           }
00366         }
00367 
00368   Close(hFileHandle, nIoResult);
00369 }
00370 
00371 #endif // __LEGOLS_H__
00372 
00373 /*
00374  * $Id: lego-light.h 133 2013-03-10 15:15:38Z xander $
00375  */
00376 /* @} */
00377 /* @} */