Commits

iorodeo  committed 8b50785

Worked on added ability to handle custom single LED PCB. Updateded firmware,
serial libraray, and worked on updating GUI. Basic program has been modified,
still need to finish modifiying the plotting and measurement programs.

  • Participants
  • Parent commits 4d46e3e

Comments (0)

Files changed (15)

File firmware/Colorimeter.cpp

 const uint8_t EEPROM_CAL_BLUE = 8;
 const uint8_t EEPROM_CAL_WHITE = 12;
 
+const unsigned int DEFAULT_NUM_SAMPLES = 5000;
+const SensorMode DEFAULT_SENSOR_MODE = COLOR_SPECIFIC;
 
 Colorimeter::Colorimeter() {
     numSamples = DEFAULT_NUM_SAMPLES;
     calibration.green = 1; 
     calibration.blue = 1;
     calibration.white = 1;
+    sensorMode = DEFAULT_SENSOR_MODE;
 }
 
 void Colorimeter::initialize() {
             COLOR_SENSOR_S3, 
             COLOR_SENSOR_FO
             );
-
 }
 
 // Sample frequency methods 
 // ----------------------------------------------------------------------------
 uint32_t Colorimeter::getFrequencyRed() {
     led.setRed();
-    sensor.setChannelRed();
+    if (sensorMode == COLOR_SPECIFIC) {
+        sensor.setChannelRed();
+    }
+    else {
+        sensor.setChannelClear();
+    }
     return sensor.getFrequency(numSamples);
 }
 
 uint32_t Colorimeter::getFrequencyGreen() {
     led.setGreen();
-    sensor.setChannelGreen();
+    if (sensorMode == COLOR_SPECIFIC) {
+        sensor.setChannelGreen();
+    }
+    else {
+        sensor.setChannelClear();
+    }
     return sensor.getFrequency(numSamples);
 }
 
 uint32_t Colorimeter::getFrequencyBlue() {
     led.setBlue();
-    sensor.setChannelBlue();
+    if (sensorMode == COLOR_SPECIFIC) {
+        sensor.setChannelBlue();
+    }
+    else {
+        sensor.setChannelClear();
+    }
     return sensor.getFrequency(numSamples);
 }
 
     led.setWhite();
     sensor.setChannelClear();
     return sensor.getFrequency(numSamples);
+} 
+
+void Colorimeter::getMeasurement() {
+    getMeasurementRed();
+    getMeasurementGreen();
+    getMeasurementBlue();
+    getMeasurementWhite();
 }
 
+void Colorimeter::getMeasurementRed() {
+    frequency.red = getFrequencyRed();
+    led.setOff();
+    transmission.red = freq2trans(calibration.red, frequency.red);
+    absorbance.red = trans2absorb(transmission.red);
+}
 
-void Colorimeter::getMeasurement() {
-    frequency.red = getFrequencyRed();
+void Colorimeter::getMeasurementGreen() {
     frequency.green = getFrequencyGreen();
+    led.setOff();
+    transmission.green = freq2trans(calibration.green, frequency.green);
+    absorbance.green = trans2absorb(transmission.green);
+}
+
+void Colorimeter::getMeasurementBlue() {
     frequency.blue = getFrequencyBlue();
+    led.setOff();
+    transmission.blue = freq2trans(calibration.blue, frequency.blue);
+    absorbance.blue = trans2absorb(transmission.blue); 
+}
+
+void Colorimeter::getMeasurementWhite() {
     frequency.white = getFrequencyWhite();
     led.setOff();
-
-    transmission.red = freq2trans(calibration.red, frequency.red);
-    transmission.green = freq2trans(calibration.green, frequency.green);
-    transmission.blue = freq2trans(calibration.blue, frequency.blue);
     transmission.white = freq2trans(calibration.white, frequency.white);
-
-    absorbance.red = trans2absorb(transmission.red);
-    absorbance.green = trans2absorb(transmission.green);
-    absorbance.blue = trans2absorb(transmission.blue); 
     absorbance.white = trans2absorb(transmission.white);
 }
 
 // Calibration methods // ----------------------------------------------------------------------------
 void Colorimeter::calibrate() {
+    calibrateRed();
+    calibrateGreen();
+    calibrateBlue();
+    calibrateWhite();
+}
+
+void Colorimeter::calibrateRed() {
     calibration.red = getFrequencyRed();
+    led.setOff();
+}
+
+void Colorimeter::calibrateGreen() {
     calibration.green = getFrequencyGreen();
+    led.setOff();
+}
+
+void Colorimeter::calibrateBlue() {
     calibration.blue = getFrequencyBlue();
+    led.setOff();
+}
+
+void Colorimeter::calibrateWhite() {
     calibration.white = getFrequencyWhite();
     led.setOff();
 }
 
 void Colorimeter::EEPROM_saveCalibration() {
+    EEPROM_saveCalibrationRed();
+    EEPROM_saveCalibrationGreen();
+    EEPROM_saveCalibrationBlue();
+    EEPROM_saveCalibrationWhite();
+}
+
+void Colorimeter::EEPROM_saveCalibrationRed() {
     EEPROM_writeAnything(EEPROM_CAL_RED,calibration.red);
+}
+
+void Colorimeter::EEPROM_saveCalibrationGreen() {
     EEPROM_writeAnything(EEPROM_CAL_GREEN,calibration.green);
+}
+
+void Colorimeter::EEPROM_saveCalibrationBlue() {
     EEPROM_writeAnything(EEPROM_CAL_BLUE,calibration.blue);
+}
+
+void Colorimeter::EEPROM_saveCalibrationWhite() {
     EEPROM_writeAnything(EEPROM_CAL_WHITE,calibration.white);
 }
-
 void Colorimeter::EEPROM_loadCalibration() {
     EEPROM_readAnything(EEPROM_CAL_RED,calibration.red);
     EEPROM_readAnything(EEPROM_CAL_GREEN,calibration.green);
 
 bool Colorimeter::checkCalibration() {
     bool flag = true;
+    flag &= checkCalibrationRed();
+    flag &= checkCalibrationGreen();
+    flag &= checkCalibrationBlue();
+    flag &= checkCalibrationWhite();
+    return flag;
+}
+
+bool Colorimeter::checkCalibrationRed() {
+    bool flag = true;
     if (calibration.red == 0) {
         flag = false;
     }
+    return flag;
+}
+
+bool Colorimeter::checkCalibrationGreen() {
+    bool flag = true;
     if (calibration.green == 0) {
         flag = false;
     }
+    return flag;
+}
+
+bool Colorimeter::checkCalibrationBlue() {
+    bool flag = true;
     if (calibration.blue == 0) {
         flag = false;
     }
+    return flag;
+}
+
+bool Colorimeter::checkCalibrationWhite() {
+    bool flag = true;
     if (calibration.white == 0) {
         flag = false;
     }
     return flag;
 }
 
+void Colorimeter::setSensorMode(SensorMode mode) {
+    sensorMode = mode;
+}
 
 // Utility functions
 // ----------------------------------------------------------------------------

File firmware/Colorimeter.h

 #include "ColorSensor.h"
 #include "RGBLed.h"
 
-#define DEFAULT_NUM_SAMPLES 5000
+enum SensorMode {
+    COLOR_SPECIFIC=0,
+    COLOR_INDEPENDENT,
+};
+
+extern const unsigned int DEFAULT_NUM_SAMPLES; 
+extern const SensorMode DEFAULT_SENSOR_MODE; 
 
 template <class T>
 class ColorimeterData {
         Colorimeter();
         void initialize();
 
-        RGBLed led;
-        ColorSensor sensor;
-
         uint32_t getFrequencyRed();
         uint32_t getFrequencyGreen();
         uint32_t getFrequencyBlue();
         uint32_t getFrequencyWhite();
+
         void getMeasurement();
+        void getMeasurementRed();
+        void getMeasurementGreen();
+        void getMeasurementBlue();
+        void getMeasurementWhite();
 
         void calibrate();
+        void calibrateRed();
+        void calibrateGreen();
+        void calibrateBlue();
+        void calibrateWhite();
+
         bool checkCalibration();
+        bool checkCalibrationRed();
+        bool checkCalibrationGreen();
+        bool checkCalibrationBlue();
+        bool checkCalibrationWhite();
+
         void EEPROM_saveCalibration();
+        void EEPROM_saveCalibrationRed();
+        void EEPROM_saveCalibrationGreen();
+        void EEPROM_saveCalibrationBlue();
+        void EEPROM_saveCalibrationWhite();
         void EEPROM_loadCalibration();
 
+        void setSensorMode(SensorMode mode);
+
+        RGBLed led;
+        ColorSensor sensor;
         uint16_t numSamples;
+        SensorMode sensorMode;
+
         ColorimeterData<uint32_t> calibration;
         ColorimeterData<uint32_t> frequency; 
         ColorimeterData<float> transmission;

File firmware/SerialHandler.cpp

 #include "SerialHandler.h"
 #include "Streaming.h"
 
+// Constants
+// ----------------------------------------------------------------------------
+const int CMD_CALIBRATE=0;
+const int CMD_GET_MEASUREMENT=1;
+const int CMD_SET_NUM_SAMPLES=2;
+const int CMD_GET_NUM_SAMPLES=3;
+const int CMD_GET_CALIBRATION=4;
+
+const int CMD_CALIBRATE_RED=5;
+const int CMD_CALIBRATE_GREEN=6;
+const int CMD_CALIBRATE_BLUE=7;
+const int CMD_CALIBRATE_WHITE=8;
+
+const int CMD_GET_MEASUREMENT_RED=9;
+const int CMD_GET_MEASUREMENT_GREEN=10;
+const int CMD_GET_MEASUREMENT_BLUE=11;
+const int CMD_GET_MEASUREMENT_WHITE=12;
+
+const int CMD_SET_MODE_COLOR_SPECIFIC=13;
+const int CMD_SET_MODE_COLOR_INDEPENDENT=14;
+const int CMD_GET_SENSOR_MODE = 15;
+
+const int RSP_ERROR = 0;
+const int RSP_SUCCESS = 1;
+
 const uint8_t DBL_STR_LEN = 30;
 const uint8_t DBL_PREC = 12;
 
+
+
+// Methods
+// ----------------------------------------------------------------------------
 void SerialHandler::processInput() { 
     while (Serial.available() > 0) {
         process(Serial.read());
             sendCalibration();
             break;
 
+        case CMD_CALIBRATE_RED:
+            calibrateRed();
+            break;
+
+        case CMD_CALIBRATE_GREEN:
+            calibrateGreen();
+            break;
+
+        case CMD_CALIBRATE_BLUE:
+            calibrateBlue();
+            break;
+
+        case CMD_CALIBRATE_WHITE:
+            calibrateWhite();
+            break;
+
+        case CMD_GET_MEASUREMENT_RED:
+            sendMeasurementRed();
+            break;
+
+        case CMD_GET_MEASUREMENT_GREEN:
+            sendMeasurementGreen();
+            break;
+
+        case CMD_GET_MEASUREMENT_BLUE:
+            sendMeasurementBlue();
+            break;
+
+        case CMD_GET_MEASUREMENT_WHITE:
+            sendMeasurementWhite();
+            break;
+
+        case CMD_SET_MODE_COLOR_SPECIFIC:
+            setModeColorSpecific();
+            break;
+
+        case CMD_SET_MODE_COLOR_INDEPENDENT:
+            setModeColorIndependent();
+            break;
+
+        case CMD_GET_SENSOR_MODE:
+            sendSensorMode();
+            break;
+
         default:
             unknownCmd();
             break;
     }
 }
 
+void SerialHandler::calibrateRed() {
+    colorimeter.calibrateRed();
+    if (colorimeter.checkCalibrationRed()) {
+        colorimeter.EEPROM_saveCalibrationRed();
+        Serial << '[' << RSP_SUCCESS << ']' << endl;
+    }
+    else {
+        Serial << '[' << RSP_ERROR; 
+        Serial << ',' << "calibration failed";
+        Serial << ']' << endl;
+    }
+}
+
+void SerialHandler::calibrateGreen() {
+    colorimeter.calibrateGreen();
+    if (colorimeter.checkCalibrationGreen()) {
+        colorimeter.EEPROM_saveCalibrationGreen();
+        Serial << '[' << RSP_SUCCESS << ']' << endl;
+    }
+    else {
+        Serial << '[' << RSP_ERROR; 
+        Serial << ',' << "calibration failed";
+        Serial << ']' << endl;
+    }
+}
+
+void SerialHandler::calibrateBlue() {
+    colorimeter.calibrateBlue();
+    if (colorimeter.checkCalibrationBlue()) {
+        colorimeter.EEPROM_saveCalibrationBlue();
+        Serial << '[' << RSP_SUCCESS << ']' << endl;
+    }
+    else {
+        Serial << '[' << RSP_ERROR; 
+        Serial << ',' << "calibration failed";
+        Serial << ']' << endl;
+    }
+}
+
+void SerialHandler::calibrateWhite() {
+    colorimeter.calibrateWhite();
+    if (colorimeter.checkCalibrationWhite()) {
+        colorimeter.EEPROM_saveCalibrationWhite();
+        Serial << '[' << RSP_SUCCESS << ']' << endl;
+    }
+    else {
+        Serial << '[' << RSP_ERROR; 
+        Serial << ',' << "calibration failed";
+        Serial << ']' << endl;
+    }
+}
+
 void SerialHandler::sendMeasurement() { 
     char valueStr[DBL_STR_LEN];
 
 
 void SerialHandler::setNumSamples() {
     long numSamples;
-
     numSamples = readLong(1);
     if ((numSamples > 0) && (numSamples <= 65535)) {
         colorimeter.numSamples = (uint16_t) numSamples;
     Serial << ']' << endl;
 }
 
+void SerialHandler::sendMeasurementRed() {
+    char valueStr[DBL_STR_LEN];
+    colorimeter.getMeasurementRed();
+    Serial << '[' << RSP_SUCCESS;
+    Serial << ',' << _DEC(colorimeter.frequency.red);
+    dtostre(colorimeter.transmission.red, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    dtostre(colorimeter.absorbance.red, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    Serial << ']' << endl;
+}
+
+void SerialHandler::sendMeasurementGreen() {
+    char valueStr[DBL_STR_LEN];
+    colorimeter.getMeasurementGreen();
+    Serial << '[' << RSP_SUCCESS;
+    Serial << ',' << _DEC(colorimeter.frequency.green);
+    dtostre(colorimeter.transmission.green, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    dtostre(colorimeter.absorbance.green, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    Serial << ']' << endl;
+}
+
+void SerialHandler::sendMeasurementBlue() {
+    char valueStr[DBL_STR_LEN];
+    colorimeter.getMeasurementBlue();
+    Serial << '[' << RSP_SUCCESS;
+    Serial << ',' << _DEC(colorimeter.frequency.blue);
+    dtostre(colorimeter.transmission.blue, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    dtostre(colorimeter.absorbance.blue, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    Serial << ']' << endl;
+}
+
+void SerialHandler::sendMeasurementWhite() {
+    char valueStr[DBL_STR_LEN];
+    colorimeter.getMeasurementWhite();
+    Serial << '[' << RSP_SUCCESS;
+    Serial << ',' << _DEC(colorimeter.frequency.white);
+    dtostre(colorimeter.transmission.white, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    dtostre(colorimeter.absorbance.white, valueStr, DBL_PREC, 0);
+    Serial << ',' << valueStr;
+    Serial << ']' << endl;
+}
+
+void SerialHandler::setModeColorSpecific() {
+    colorimeter.setSensorMode(COLOR_SPECIFIC);
+    Serial << '[' << RSP_SUCCESS << ']' << endl;
+}
+
+void SerialHandler::setModeColorIndependent() {
+    colorimeter.setSensorMode(COLOR_INDEPENDENT);
+    Serial << '[' << RSP_SUCCESS << ']' << endl;
+}
+
+void SerialHandler::sendSensorMode() {
+    Serial << '[' << RSP_SUCCESS;
+    Serial << ',' << _DEC(colorimeter.sensorMode);
+    Serial << ']' << endl;
+}
+
 void SerialHandler::unknownCmd() { 
     // un-recognized command. Send error message.
     Serial << '[' << RSP_ERROR;

File firmware/SerialHandler.h

 #include "SerialReceiver.h"
 #include "Colorimeter.h"
 
-const int CMD_CALIBRATE=0;
-const int CMD_GET_MEASUREMENT=1;
-const int CMD_SET_NUM_SAMPLES=2;
-const int CMD_GET_NUM_SAMPLES=3;
-const int CMD_GET_CALIBRATION=4;
-
-const int RSP_ERROR = 0;
-const int RSP_SUCCESS = 1;
 
 class SerialHandler: public SerialReceiver {
     public:
     private:
         void switchYard();
         void calibrate();
+        void calibrateRed();
+        void calibrateGreen();
+        void calibrateBlue();
+        void calibrateWhite();
         void sendMeasurement();
         void setNumSamples();
         void sendNumSamples();
         void sendCalibration();
+        void sendMeasurementRed();
+        void sendMeasurementGreen();
+        void sendMeasurementBlue();
+        void sendMeasurementWhite();
+        void setModeColorSpecific();
+        void setModeColorIndependent();
+        void sendSensorMode();
         void unknownCmd();
 };
 

File python/Colorimeter/colorimeter/colorimeter_serial.py

 CMD_GET_NUM_SAMPLES = 3
 CMD_GET_CALIBRATION = 4
 
+CMD_CALIBRATE_RED = 5 
+CMD_CALIBRATE_GREEN = 6
+CMD_CALIBRATE_BLUE = 7
+CMD_CALIBRATE_WHITE = 8
+
+CMD_GET_MEASUREMENT_RED = 9
+CMD_GET_MEASUREMENT_GREEN = 10
+CMD_GET_MEASUREMENT_BLUE = 11
+CMD_GET_MEASUREMENT_WHITE = 12
+
+CMD_SET_MODE_COLOR_SPECIFIC = 13
+CMD_SET_MODE_COLOR_INDEPENDENT = 14
+CMD_GET_SENSOR_MODE = 15
+
+SENSOR_MODE_COLOR_SPECIFIC = 0
+SENSOR_MODE_COLOR_INDEPENDENT = 1
+
 RSP_ERROR = 0
 RSP_SUCCESS = 1
 
         
     def calibrate(self):
         """
-        Calibrate the colorimeter.
+        Calibrate the colorimeter (all channels).
         """
         cmd = '[{0}]'.format(CMD_CALIBRATE) 
         rsp = self.sendCmd(cmd)
 
+    def calibrateRed(self):
+        """
+        Calibrate the red channel of the colorimeter
+        """
+        cmd = '[{0}]'.format(CMD_CALIBRATE_RED)
+        rsp = self.sendCmd(cmd)
+
+    def calibrateGreen(self):
+        """
+        Calibrate the green channel of the colorimeter
+        """
+        cmd = '[{0}]'.format(CMD_CALIBRATE_GREEN)
+        rsp = self.sendCmd(cmd)
+
+    def calibrateBlue(self):
+        """
+        Calibrate the blue channe of the colorimeter
+        """
+        cmd = '[{0}]'.format(CMD_CALIBRATE_BLUE)
+        rsp = self.sendCmd(cmd)
+
+    def calibrateWhite(self):
+        """
+        Calibrate the white channel of the colorimeter
+        """
+        cmd = '[{0}]'.format(CMD_CALIBRATE_WHITE)
+        rsp = self.sendCmd(cmd)
+
     def getCalibration(self):
         """
         Get the current calibration freqeuncy values.
         absorb = tuple(rsp[9:])
         return freq, trans, absorb
 
+    def getMeasurementRed(self):
+        """
+        Get a measurement from the red channel
+        """
+        cmd = '[{0}]'.format(CMD_GET_MEASUREMENT_RED)
+        rsp = self.sendCmd(cmd)
+        freq, trans, absorb = rsp[1:4]
+        return freq, trans, absorb
+
+    def getMeasurementGreen(self):
+        """
+        Get a measurement from the green channel
+        """
+        cmd = '[{0}]'.format(CMD_GET_MEASUREMENT_GREEN)
+        rsp = self.sendCmd(cmd)
+        freq, trans, absorb = rsp[1:4]
+        return freq, trans, absorb
+
+    def getMeasurementBlue(self):
+        """
+        Get a measurement from the blue channel
+        """
+        cmd = '[{0}]'.format(CMD_GET_MEASUREMENT_BLUE)
+        rsp = self.sendCmd(cmd)
+        freq, trans, absorb = rsp[1:4]
+        return freq, trans, absorb
+
+    def getMeasurementWhite(self):
+        """
+        Get a measurement from the white channel
+        """
+        cmd = '[{0}]'.format(CMD_GET_MEASUREMENT_WHITE)
+        rsp = self.sendCmd(cmd)
+        freq, trans, absorb = rsp[1:4]
+        return freq, trans, absorb
+
     def setNumSamples(self,value):
         """
         Set the number of samples aquired per measurement.
         numSamples = rsp[1]
         return numSamples
 
+    def setSensorModeColorSpecific(self):
+        """
+        Set the sensor to color specific mode. In this mode it will use the 
+        red/green/blue/clear color channel of the sensor when using the 
+        red/green/blue/white led.
+        """
+        cmd = '[{0}]'.format(CMD_SET_MODE_COLOR_SPECIFIC)
+        rsp = self.sendCmd(cmd)
+
+    def setSensorModeColorIndependent(self):
+        """
+        Set the sensor to color independent mode. In this mode the clear
+        (unfiltered) channel of the light sensor is used regardless of the led
+        selected.
+        """
+        cmd = '[{0}]'.format(CMD_SET_MODE_COLOR_INDEPENDENT)
+        rsp = self.sendCmd(cmd)
+
+    def getSensorMode(self):
+        """
+        Returns the current color sensor mode setting.
+        """
+        cmd = '[{0}]'.format(CMD_GET_SENSOR_MODE)
+        rsp = self.sendCmd(cmd)
+        sensorMode = rsp[1]
+        return sensorMode
+
     def printMeasurement(self):
         """
         Test function. Gets a measurement and pretty prints it.

File python/Colorimeter/colorimeter/constants.py

 import os
 
 # Development
-DEVEL_FAKE_MEASURE = False 
-#DEVEL_FAKE_MEASURE = True 
+#DEVEL_FAKE_MEASURE = False 
+DEVEL_FAKE_MEASURE = True 
 
 # Serial ports
 DFLT_PORT_WINDOWS = 'com1' 

File python/Colorimeter/colorimeter/gui/basic/basic.py

             callback = functools.partial(self.colorCheckBox_Callback,color)
             checkBox.stateChanged.connect(callback)
 
+    def initialize(self):
+        super(BasicMainWindow,self).initialize()
+        self.measValues = None
+        self.numSamples = None
+        self.aboutText = constants.BASIC_ABOUT_TEXT
+        self.samplesValidator = QtGui.QIntValidator(0,2**16-1,self.samplesLineEdit)
+        self.samplesLineEdit.setValidator(self.samplesValidator)
+        for name in constants.COLOR2LED_DICT:
+            checkBox = getattr(self,'{0}CheckBox'.format(name))
+            checkBox.setCheckState(QtCore.Qt.Checked)
+        self.plotCheckBox.setCheckState(QtCore.Qt.Checked)
+        self.updateWidgetEnabled()
+
+    def standardRgbLed_Callback(self): 
+        changed = super(BasicMainWindow,self).standardRgbLed_Callback()
+        if changed:
+            self.transmissionTextEdit.setText('')
+            self.absorbanceTextEdit.setText('')
+            self.measValues = None
+        self.updateWidgetEnabled()
+
+    def customLed_Callback(self): 
+        changed = super(BasicMainWindow,self).customLed_Callback()
+        if changed:
+            self.transmissionTextEdit.setText('')
+            self.absorbanceTextEdit.setText('')
+            self.measValues = None
+            self.closeFigure()
+        self.updateWidgetEnabled()
+
     def colorCheckBox_Callback(self,color):
         self.updateResultsDisplay()
         if self.plotCheckBox.isChecked():
         else:
             self.updatePlot(create=True)
 
-    def initialize(self):
-        super(BasicMainWindow,self).initialize()
-        self.measValues = None
-        self.numSamples = None
-        self.aboutText = constants.BASIC_ABOUT_TEXT
-        self.samplesValidator = QtGui.QIntValidator(0,2**16-1,self.samplesLineEdit)
-        self.samplesLineEdit.setValidator(self.samplesValidator)
-        for name in constants.COLOR2LED_DICT:
-            checkBox = getattr(self,'{0}CheckBox'.format(name))
-            checkBox.setCheckState(QtCore.Qt.Checked)
-        self.plotCheckBox.setCheckState(QtCore.Qt.Checked)
-        self.updateWidgetEnabled()
-
     def connectClicked_Callback(self):
         super(BasicMainWindow,self).connectClicked_Callback()
         if self.dev is None:
     def calibrateClicked_Callback(self):
         super(BasicMainWindow,self).calibrateClicked_Callback()
         if self.isCalibrated:
-            freq = None  
-            tran = 1.0, 1.0, 1.0, 1.0
-            abso = 0.0, 0.0, 0.0, 0.0
+            if self.isStandardRgbLedMode():
+                freq = None  
+                tran = 1.0, 1.0, 1.0, 1.0
+                abso = 0.0, 0.0, 0.0, 0.0
+            else:
+                freq = None
+                tran = 1.0
+                abso = 0.0
             self.measValues = freq, tran, abso
         self.updateResultsDisplay()
 
 
     def measureClicked_Callback(self):
         super(BasicMainWindow,self).measureClicked_Callback()
-        self.updatePlot(create=True)
+        if self.isStandardRgbLedMode():
+            self.updatePlot(create=True)
         self.updateResultsDisplay()
 
     def getMeasurement(self):
         if constants.DEVEL_FAKE_MEASURE:
-            freqValues = tuple(numpy.random.random((4,)))
-            tranValues = tuple(numpy.random.random((4,)))
-            absoValues = tuple(numpy.random.random((4,)))
-            self.measValues = freqValues, tranValues, absoValues
+            if self.isStandardRgbLedMode():
+                freqValues = tuple(numpy.random.random((4,)))
+                tranValues = tuple(numpy.random.random((4,)))
+                absoValues = tuple(numpy.random.random((4,)))
+                self.measValues = freqValues, tranValues, absoValues
+            else:
+                freqValues = numpy.random.random((1,))[0]
+                tranValues = numpy.random.random((1,))[0]
+                absoValues = numpy.random.random((1,))[0]
+                self.measValues = freqValues, tranValues, absoValues
         else:
+            if self.isStandardRgbLedMode():
+                measurementFunc = self.dev.getMeasurement
+            else:
+                measurementFunc = self.dev.getMeasurementBlue
+
             try:
-                freqValues, tranValues, absoValues = self.dev.getMeasurement()
+                freqValues, tranValues, absoValues = measurementFunc()
                 self.measValues = freqValues, tranValues, absoValues
             except IOError, e:
                 msgTitle = 'Measurement Error:'
             self.absorbanceTextEdit.setText('')
         else:
             freqValues, tranValues, absoValues = self.measValues
-            tranStrList, absoStrList = [], []
-            colorNames = sorted(constants.COLOR2LED_DICT)
-            for c in colorNames:
-                n = constants.COLOR2LED_DICT[c] 
-                if self.isColorChecked(c):
-                    tranStrList.append('{0}:\t{1:1.3f}'.format(c, tranValues[n]))
-                    absoStrList.append('{0}:\t{1:1.3f}'.format(c, absoValues[n]))
-            tranStr = os.linesep.join(tranStrList)
-            absoStr = os.linesep.join(absoStrList)
+            if self.isStandardRgbLedMode():
+                tranStrList, absoStrList = [], []
+                colorNames = sorted(constants.COLOR2LED_DICT)
+                for c in colorNames:
+                    n = constants.COLOR2LED_DICT[c] 
+                    if self.isColorChecked(c):
+                        tranStrList.append('{0}:\t{1:1.3f}'.format(c, tranValues[n]))
+                        absoStrList.append('{0}:\t{1:1.3f}'.format(c, absoValues[n]))
+                tranStr = os.linesep.join(tranStrList)
+                absoStr = os.linesep.join(absoStrList)
+            else:
+                tranStr = 'custom led: \t{0:1.3f}'.format(tranValues)
+                absoStr = 'custom led: \t{0:1.3f}'.format(absoValues)
             self.transmissionTextEdit.setText(tranStr)
             self.absorbanceTextEdit.setText(absoStr)
 
         self.plotCheckBox.setEnabled(False)
 
     def updateWidgetEnabled(self):
+        super(BasicMainWindow,self).updateWidgetEnabled()
         if self.dev is None:
             self.transmissionTextEdit.setEnabled(False)
             self.absorbanceTextEdit.setEnabled(False)
             self.whiteCheckBox.setEnabled(False)
             self.portLineEdit.setEnabled(True)
             self.plotCheckBox.setEnabled(False)
+            self.ledsLabel.setEnabled(False)
             self.statusbar.showMessage('Not Connected')
         else:
             self.transmissionTextEdit.setEnabled(True)
             self.portLineEdit.setEnabled(False)
             if self.isCalibrated:
                 self.measurePushButton.setEnabled(True)
+            else:
+                self.measurePushButton.setEnabled(False)
+            if self.isCalibrated and self.isStandardRgbLedMode(): 
                 self.redCheckBox.setEnabled(True)
                 self.greenCheckBox.setEnabled(True)
                 self.blueCheckBox.setEnabled(True)
                 self.whiteCheckBox.setEnabled(True)
                 self.plotCheckBox.setEnabled(True)
-            self.statusbar.showMessage('Connected, Mode: Stopped')
+            else:
+                self.redCheckBox.setEnabled(False)
+                self.greenCheckBox.setEnabled(False)
+                self.blueCheckBox.setEnabled(False)
+                self.whiteCheckBox.setEnabled(False)
+                self.plotCheckBox.setEnabled(False)
+            self.statusbar.showMessage('Connected, Stopped')
 
 def padString(x,n):
     if len(x) < n:

File python/Colorimeter/colorimeter/gui/basic/basic.ui

    <rect>
     <x>0</x>
     <y>0</y>
-    <width>646</width>
-    <height>396</height>
+    <width>682</width>
+    <height>389</height>
    </rect>
   </property>
   <property name="windowTitle">
      </widget>
     </item>
     <item>
-     <widget class="QWidget" name="widget_3" native="true">
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <widget class="QWidget" name="widget_5" native="true">
+      <layout class="QHBoxLayout" name="horizontalLayout_5">
        <item>
         <widget class="QLabel" name="label_2">
          <property name="sizePolicy">
           </sizepolicy>
          </property>
          <property name="text">
-          <string>Samples   </string>
+          <string>Samples    </string>
          </property>
         </widget>
        </item>
         </widget>
        </item>
        <item>
-        <spacer name="horizontalSpacer_2">
+        <spacer name="horizontalSpacer_6">
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>40</width>
+           <width>143</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QLabel" name="ledsLabel">
+         <property name="text">
+          <string>LEDs</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>10</width>
            <height>20</height>
           </size>
          </property>
      </widget>
     </item>
     <item>
-     <widget class="Line" name="line">
+     <widget class="Line" name="line_3">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>646</width>
+     <width>682</width>
      <height>23</height>
     </rect>
    </property>
-   <widget class="QMenu" name="menu_File">
+   <widget class="QMenu" name="menuFile">
     <property name="title">
      <string>&amp;File</string>
     </property>
     </property>
     <addaction name="actionAbout"/>
    </widget>
-   <addaction name="menu_File"/>
+   <widget class="QMenu" name="menuMode">
+    <property name="title">
+     <string>&amp;Mode</string>
+    </property>
+    <addaction name="actionStandardRgbLed"/>
+    <addaction name="actionCustomLed"/>
+   </widget>
+   <addaction name="menuFile"/>
+   <addaction name="menuMode"/>
    <addaction name="menu_Help"/>
   </widget>
   <widget class="QStatusBar" name="statusbar"/>
     <string>About</string>
    </property>
   </action>
+  <action name="actionStandardRgbLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Standard RGB LED</string>
+   </property>
+  </action>
+  <action name="actionCustomLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Custom LED</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections/>

File python/Colorimeter/colorimeter/gui/basic/basic_ui.py

 
 # Form implementation generated from reading ui file 'basic.ui'
 #
-# Created: Thu Jul 26 11:14:19 2012
+# Created: Sun Apr 14 19:51:07 2013
 #      by: PyQt4 UI code generator 4.7.2
 #
 # WARNING! All changes made in this file will be lost!
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
-        MainWindow.resize(646, 396)
+        MainWindow.resize(682, 389)
         self.centralwidget = QtGui.QWidget(MainWindow)
         self.centralwidget.setObjectName("centralwidget")
         self.verticalLayout_5 = QtGui.QVBoxLayout(self.centralwidget)
         self.verticalLayout_4.addWidget(self.absorbanceGroupBox)
         self.horizontalLayout_2.addWidget(self.frame_2)
         self.verticalLayout_5.addWidget(self.widget_2)
-        self.widget_3 = QtGui.QWidget(self.centralwidget)
-        self.widget_3.setObjectName("widget_3")
-        self.horizontalLayout_3 = QtGui.QHBoxLayout(self.widget_3)
-        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
-        self.label_2 = QtGui.QLabel(self.widget_3)
+        self.widget_5 = QtGui.QWidget(self.centralwidget)
+        self.widget_5.setObjectName("widget_5")
+        self.horizontalLayout_5 = QtGui.QHBoxLayout(self.widget_5)
+        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+        self.label_2 = QtGui.QLabel(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Preferred)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
         self.label_2.setSizePolicy(sizePolicy)
         self.label_2.setObjectName("label_2")
-        self.horizontalLayout_3.addWidget(self.label_2)
-        self.samplesLineEdit = QtGui.QLineEdit(self.widget_3)
+        self.horizontalLayout_5.addWidget(self.label_2)
+        self.samplesLineEdit = QtGui.QLineEdit(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         self.samplesLineEdit.setSizePolicy(sizePolicy)
         self.samplesLineEdit.setMaximumSize(QtCore.QSize(100, 16777215))
         self.samplesLineEdit.setObjectName("samplesLineEdit")
-        self.horizontalLayout_3.addWidget(self.samplesLineEdit)
-        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.horizontalLayout_3.addItem(spacerItem)
-        self.redCheckBox = QtGui.QCheckBox(self.widget_3)
+        self.horizontalLayout_5.addWidget(self.samplesLineEdit)
+        spacerItem = QtGui.QSpacerItem(143, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem)
+        self.ledsLabel = QtGui.QLabel(self.widget_5)
+        self.ledsLabel.setObjectName("ledsLabel")
+        self.horizontalLayout_5.addWidget(self.ledsLabel)
+        spacerItem1 = QtGui.QSpacerItem(10, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem1)
+        self.redCheckBox = QtGui.QCheckBox(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         self.redCheckBox.setMaximumSize(QtCore.QSize(65, 16777215))
         self.redCheckBox.setChecked(True)
         self.redCheckBox.setObjectName("redCheckBox")
-        self.horizontalLayout_3.addWidget(self.redCheckBox)
-        self.greenCheckBox = QtGui.QCheckBox(self.widget_3)
+        self.horizontalLayout_5.addWidget(self.redCheckBox)
+        self.greenCheckBox = QtGui.QCheckBox(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         self.greenCheckBox.setMaximumSize(QtCore.QSize(65, 16777215))
         self.greenCheckBox.setChecked(True)
         self.greenCheckBox.setObjectName("greenCheckBox")
-        self.horizontalLayout_3.addWidget(self.greenCheckBox)
-        self.blueCheckBox = QtGui.QCheckBox(self.widget_3)
+        self.horizontalLayout_5.addWidget(self.greenCheckBox)
+        self.blueCheckBox = QtGui.QCheckBox(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         self.blueCheckBox.setMaximumSize(QtCore.QSize(65, 16777215))
         self.blueCheckBox.setChecked(True)
         self.blueCheckBox.setObjectName("blueCheckBox")
-        self.horizontalLayout_3.addWidget(self.blueCheckBox)
-        self.whiteCheckBox = QtGui.QCheckBox(self.widget_3)
+        self.horizontalLayout_5.addWidget(self.blueCheckBox)
+        self.whiteCheckBox = QtGui.QCheckBox(self.widget_5)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         self.whiteCheckBox.setMaximumSize(QtCore.QSize(65, 16777215))
         self.whiteCheckBox.setChecked(True)
         self.whiteCheckBox.setObjectName("whiteCheckBox")
-        self.horizontalLayout_3.addWidget(self.whiteCheckBox)
-        self.verticalLayout_5.addWidget(self.widget_3)
-        self.line = QtGui.QFrame(self.centralwidget)
-        self.line.setFrameShape(QtGui.QFrame.HLine)
-        self.line.setFrameShadow(QtGui.QFrame.Sunken)
-        self.line.setObjectName("line")
-        self.verticalLayout_5.addWidget(self.line)
+        self.horizontalLayout_5.addWidget(self.whiteCheckBox)
+        self.verticalLayout_5.addWidget(self.widget_5)
+        self.line_3 = QtGui.QFrame(self.centralwidget)
+        self.line_3.setFrameShape(QtGui.QFrame.HLine)
+        self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
+        self.line_3.setObjectName("line_3")
+        self.verticalLayout_5.addWidget(self.line_3)
         self.widget = QtGui.QWidget(self.centralwidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         self.connectPushButton = QtGui.QPushButton(self.widget)
         self.connectPushButton.setObjectName("connectPushButton")
         self.horizontalLayout.addWidget(self.connectPushButton)
-        spacerItem1 = QtGui.QSpacerItem(322, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.horizontalLayout.addItem(spacerItem1)
+        spacerItem2 = QtGui.QSpacerItem(322, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem2)
         self.calibratePushButton = QtGui.QPushButton(self.widget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         self.verticalLayout_5.addWidget(self.widget)
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(MainWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 646, 23))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 682, 23))
         self.menubar.setObjectName("menubar")
-        self.menu_File = QtGui.QMenu(self.menubar)
-        self.menu_File.setObjectName("menu_File")
+        self.menuFile = QtGui.QMenu(self.menubar)
+        self.menuFile.setObjectName("menuFile")
         self.menu_Help = QtGui.QMenu(self.menubar)
         self.menu_Help.setObjectName("menu_Help")
+        self.menuMode = QtGui.QMenu(self.menubar)
+        self.menuMode.setObjectName("menuMode")
         MainWindow.setMenuBar(self.menubar)
         self.statusbar = QtGui.QStatusBar(MainWindow)
         self.statusbar.setObjectName("statusbar")
         self.actionSave.setObjectName("actionSave")
         self.actionAbout = QtGui.QAction(MainWindow)
         self.actionAbout.setObjectName("actionAbout")
-        self.menu_File.addAction(self.actionSave)
+        self.actionStandardRgbLed = QtGui.QAction(MainWindow)
+        self.actionStandardRgbLed.setCheckable(True)
+        self.actionStandardRgbLed.setObjectName("actionStandardRgbLed")
+        self.actionCustomLed = QtGui.QAction(MainWindow)
+        self.actionCustomLed.setCheckable(True)
+        self.actionCustomLed.setObjectName("actionCustomLed")
+        self.menuFile.addAction(self.actionSave)
         self.menu_Help.addAction(self.actionAbout)
-        self.menubar.addAction(self.menu_File.menuAction())
+        self.menuMode.addAction(self.actionStandardRgbLed)
+        self.menuMode.addAction(self.actionCustomLed)
+        self.menubar.addAction(self.menuFile.menuAction())
+        self.menubar.addAction(self.menuMode.menuAction())
         self.menubar.addAction(self.menu_Help.menuAction())
 
         self.retranslateUi(MainWindow)
         MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Colorimeter Basic", None, QtGui.QApplication.UnicodeUTF8))
         self.transmissionGroupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Transmittance", None, QtGui.QApplication.UnicodeUTF8))
         self.absorbanceGroupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Absorbance", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("MainWindow", "Samples   ", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("MainWindow", "Samples    ", None, QtGui.QApplication.UnicodeUTF8))
+        self.ledsLabel.setText(QtGui.QApplication.translate("MainWindow", "LEDs", None, QtGui.QApplication.UnicodeUTF8))
         self.redCheckBox.setText(QtGui.QApplication.translate("MainWindow", "red", None, QtGui.QApplication.UnicodeUTF8))
         self.greenCheckBox.setText(QtGui.QApplication.translate("MainWindow", "green", None, QtGui.QApplication.UnicodeUTF8))
         self.blueCheckBox.setText(QtGui.QApplication.translate("MainWindow", "blue", None, QtGui.QApplication.UnicodeUTF8))
         self.calibratePushButton.setText(QtGui.QApplication.translate("MainWindow", "Calibrate", None, QtGui.QApplication.UnicodeUTF8))
         self.measurePushButton.setText(QtGui.QApplication.translate("MainWindow", "Measure", None, QtGui.QApplication.UnicodeUTF8))
         self.plotCheckBox.setText(QtGui.QApplication.translate("MainWindow", "Plot   ", None, QtGui.QApplication.UnicodeUTF8))
-        self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
         self.menu_Help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuMode.setTitle(QtGui.QApplication.translate("MainWindow", "&Mode", None, QtGui.QApplication.UnicodeUTF8))
         self.actionSave.setText(QtGui.QApplication.translate("MainWindow", "Save...", None, QtGui.QApplication.UnicodeUTF8))
         self.actionAbout.setText(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionStandardRgbLed.setText(QtGui.QApplication.translate("MainWindow", "Standard RGB LED", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionCustomLed.setText(QtGui.QApplication.translate("MainWindow", "Custom LED", None, QtGui.QApplication.UnicodeUTF8))
 

File python/Colorimeter/colorimeter/gui/measure/measure.ui

    <rect>
     <x>0</x>
     <y>0</y>
-    <width>589</width>
+    <width>600</width>
     <height>537</height>
    </rect>
   </property>
         </widget>
        </item>
        <item>
+        <spacer name="horizontalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>15</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
         <widget class="QRadioButton" name="redRadioButton">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>589</width>
+     <width>600</width>
      <height>23</height>
     </rect>
    </property>
      <addaction name="actionSampleUnitsUM"/>
      <addaction name="actionSampleUnitsPPM"/>
     </widget>
+    <addaction name="menuSample_Units"/>
     <addaction name="menuInclude"/>
     <addaction name="actionEditTestSolutions"/>
-    <addaction name="menuSample_Units"/>
    </widget>
    <widget class="QMenu" name="menu_Help">
     <property name="title">
     </property>
     <addaction name="actionAbout"/>
    </widget>
+   <widget class="QMenu" name="menuMode">
+    <property name="title">
+     <string>&amp;Mode</string>
+    </property>
+    <addaction name="actionStandardRgbLed"/>
+    <addaction name="actionCustomLed"/>
+   </widget>
    <addaction name="menuFile"/>
+   <addaction name="menuMode"/>
    <addaction name="menuOptions"/>
    <addaction name="menu_Help"/>
   </widget>
     <string>ppm</string>
    </property>
   </action>
+  <action name="actionStandardRgbLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Standard RGB LED</string>
+   </property>
+  </action>
+  <action name="actionCustomLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Custom LED</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>

File python/Colorimeter/colorimeter/gui/measure/measure_ui.py

 
 # Form implementation generated from reading ui file 'measure.ui'
 #
-# Created: Wed Dec 19 18:16:45 2012
+# Created: Sun Apr 14 19:52:02 2013
 #      by: PyQt4 UI code generator 4.7.2
 #
 # WARNING! All changes made in this file will be lost!
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
-        MainWindow.resize(589, 537)
+        MainWindow.resize(600, 537)
         self.centralwidget = QtGui.QWidget(MainWindow)
         self.centralwidget.setObjectName("centralwidget")
         self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
         self.label_3 = QtGui.QLabel(self.coeffLEDWidget)
         self.label_3.setObjectName("label_3")
         self.horizontalLayout_2.addWidget(self.label_3)
+        spacerItem3 = QtGui.QSpacerItem(15, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_2.addItem(spacerItem3)
         self.redRadioButton = QtGui.QRadioButton(self.coeffLEDWidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         self.whiteRadioButton = QtGui.QRadioButton(self.coeffLEDWidget)
         self.whiteRadioButton.setObjectName("whiteRadioButton")
         self.horizontalLayout_2.addWidget(self.whiteRadioButton)
-        spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.horizontalLayout_2.addItem(spacerItem3)
+        spacerItem4 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_2.addItem(spacerItem4)
         self.verticalLayout.addWidget(self.coeffLEDWidget)
         self.line_3 = QtGui.QFrame(self.centralwidget)
         self.line_3.setFrameShape(QtGui.QFrame.HLine)
         self.clearPushButton = QtGui.QPushButton(self.widget_3)
         self.clearPushButton.setObjectName("clearPushButton")
         self.horizontalLayout_3.addWidget(self.clearPushButton)
-        spacerItem4 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.horizontalLayout_3.addItem(spacerItem4)
+        spacerItem5 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_3.addItem(spacerItem5)
         self.measurePushButton = QtGui.QPushButton(self.widget_3)
         self.measurePushButton.setObjectName("measurePushButton")
         self.horizontalLayout_3.addWidget(self.measurePushButton)
         self.verticalLayout.addWidget(self.widget_3)
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(MainWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 589, 23))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 600, 23))
         self.menubar.setObjectName("menubar")
         self.menuFile = QtGui.QMenu(self.menubar)
         self.menuFile.setObjectName("menuFile")
         self.menuSample_Units.setObjectName("menuSample_Units")
         self.menu_Help = QtGui.QMenu(self.menubar)
         self.menu_Help.setObjectName("menu_Help")
+        self.menuMode = QtGui.QMenu(self.menubar)
+        self.menuMode.setObjectName("menuMode")
         MainWindow.setMenuBar(self.menubar)
         self.statusbar = QtGui.QStatusBar(MainWindow)
         self.statusbar.setObjectName("statusbar")
         self.actionSampleUnitsPPM = QtGui.QAction(MainWindow)
         self.actionSampleUnitsPPM.setCheckable(True)
         self.actionSampleUnitsPPM.setObjectName("actionSampleUnitsPPM")
+        self.actionStandardRgbLed = QtGui.QAction(MainWindow)
+        self.actionStandardRgbLed.setCheckable(True)
+        self.actionStandardRgbLed.setObjectName("actionStandardRgbLed")
+        self.actionCustomLed = QtGui.QAction(MainWindow)
+        self.actionCustomLed.setCheckable(True)
+        self.actionCustomLed.setObjectName("actionCustomLed")
         self.menuFile.addAction(self.actionSave)
         self.menuFile.addAction(self.actionLoad)
         self.menuInclude.addAction(self.actionIncludeUserTestSolutions)
         self.menuInclude.addAction(self.actionIncludeDefaultTestSolutions)
         self.menuSample_Units.addAction(self.actionSampleUnitsUM)
         self.menuSample_Units.addAction(self.actionSampleUnitsPPM)
+        self.menuOptions.addAction(self.menuSample_Units.menuAction())
         self.menuOptions.addAction(self.menuInclude.menuAction())
         self.menuOptions.addAction(self.actionEditTestSolutions)
-        self.menuOptions.addAction(self.menuSample_Units.menuAction())
         self.menu_Help.addAction(self.actionAbout)
+        self.menuMode.addAction(self.actionStandardRgbLed)
+        self.menuMode.addAction(self.actionCustomLed)
         self.menubar.addAction(self.menuFile.menuAction())
+        self.menubar.addAction(self.menuMode.menuAction())
         self.menubar.addAction(self.menuOptions.menuAction())
         self.menubar.addAction(self.menu_Help.menuAction())
 
         self.menuInclude.setTitle(QtGui.QApplication.translate("MainWindow", "Include", None, QtGui.QApplication.UnicodeUTF8))
         self.menuSample_Units.setTitle(QtGui.QApplication.translate("MainWindow", "Sample Units", None, QtGui.QApplication.UnicodeUTF8))
         self.menu_Help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuMode.setTitle(QtGui.QApplication.translate("MainWindow", "&Mode", None, QtGui.QApplication.UnicodeUTF8))
         self.actionReloadTestSolutions.setText(QtGui.QApplication.translate("MainWindow", "Reload Test Solutions", None, QtGui.QApplication.UnicodeUTF8))
         self.actionIncludeUserTestSolutions.setText(QtGui.QApplication.translate("MainWindow", "User Test Solutions", None, QtGui.QApplication.UnicodeUTF8))
         self.actionIncludeDefaultTestSolutions.setText(QtGui.QApplication.translate("MainWindow", "Default Test Solutions", None, QtGui.QApplication.UnicodeUTF8))
         self.actionAbout.setText(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
         self.actionSampleUnitsUM.setText(QtGui.QApplication.translate("MainWindow", "uM", None, QtGui.QApplication.UnicodeUTF8))
         self.actionSampleUnitsPPM.setText(QtGui.QApplication.translate("MainWindow", "ppm", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionStandardRgbLed.setText(QtGui.QApplication.translate("MainWindow", "Standard RGB LED", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionCustomLed.setText(QtGui.QApplication.translate("MainWindow", "Custom LED", None, QtGui.QApplication.UnicodeUTF8))
 
 from colorimeter.table_widget import ColorimeterTableWidget

File python/Colorimeter/colorimeter/gui/plot/plot.py

         itemDelegate = DoubleItemDelegate(self.tableWidget)
         self.tableWidget.setItemDelegateForColumn(0,itemDelegate)
 
+    def initialize(self):
+        super(PlotMainWindow,self).initialize()
+        self.aboutText = constants.PLOT_ABOUT_TEXT
+        self.noValueSymbol = constants.NO_VALUE_SYMBOL_NUMBER
+        self.tableWidget.clean(setup=True)
+        self.tableWidget.updateFunc = self.updatePlot
+        self.updateWidgetEnabled()
+        self.setFitType('linear',None)
+        self.setConcentrationUnits('uM')
+
     def importData_Callback(self):
         userSolutionDict = import_export.loadUserTestSolutionDict(self.userHome,tag='U')
         dfltSolutionDict = import_export.loadDefaultTestSolutionDict(tag='D')
         self.updateWidgetEnabled()
         self.updatePlot(create=False)
         
-    def initialize(self):
-        super(PlotMainWindow,self).initialize()
-        self.aboutText = constants.PLOT_ABOUT_TEXT
-        self.noValueSymbol = constants.NO_VALUE_SYMBOL_NUMBER
-        self.tableWidget.clean(setup=True)
-        self.tableWidget.updateFunc = self.updatePlot
-        self.updateWidgetEnabled()
-        self.setFitType('linear',None)
-        self.setConcentrationUnits('uM')
-
     def exportData_Callback(self):
         dataList = self.tableWidget.getData()
         fitType, fitParams = self.getFitTypeAndParams()
 
         import_export.exportTestSolutionData(self.userHome,dataDict)
 
+
     def fitTypeChanged_Callback(self):
         self.updatePlot()
 

File python/Colorimeter/colorimeter/gui/plot/plot.ui

     </property>
     <addaction name="actionAbout"/>
    </widget>
+   <widget class="QMenu" name="menuMode">
+    <property name="title">
+     <string>&amp;Mode</string>
+    </property>
+    <addaction name="actionStandardRgbLed"/>
+    <addaction name="actionCustomLed"/>
+   </widget>
    <addaction name="menuFile"/>
+   <addaction name="menuMode"/>
    <addaction name="menuOptions"/>
    <addaction name="menu_Help"/>
   </widget>
     <string>Polynomial (order=5)</string>
    </property>
   </action>
+  <action name="actionStandardRgbLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Standard RGB LED</string>
+   </property>
+  </action>
+  <action name="actionCustomLed">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Custom LED</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>

File python/Colorimeter/colorimeter/gui/plot/plot_ui.py

 
 # Form implementation generated from reading ui file 'plot.ui'
 #
-# Created: Tue Dec 18 17:20:59 2012
+# Created: Sun Apr 14 19:48:43 2013
 #      by: PyQt4 UI code generator 4.7.2
 #
 # WARNING! All changes made in this file will be lost!
         self.menuConcentrationUnits.setObjectName("menuConcentrationUnits")
         self.menu_Help = QtGui.QMenu(self.menubar)
         self.menu_Help.setObjectName("menu_Help")
+        self.menuMode = QtGui.QMenu(self.menubar)
+        self.menuMode.setObjectName("menuMode")
         MainWindow.setMenuBar(self.menubar)
         self.statusbar = QtGui.QStatusBar(MainWindow)
         self.statusbar.setObjectName("statusbar")
         self.actionFitTypePolynomial5 = QtGui.QAction(MainWindow)
         self.actionFitTypePolynomial5.setCheckable(True)
         self.actionFitTypePolynomial5.setObjectName("actionFitTypePolynomial5")
+        self.actionStandardRgbLed = QtGui.QAction(MainWindow)
+        self.actionStandardRgbLed.setCheckable(True)
+        self.actionStandardRgbLed.setObjectName("actionStandardRgbLed")
+        self.actionCustomLed = QtGui.QAction(MainWindow)
+        self.actionCustomLed.setCheckable(True)
+        self.actionCustomLed.setObjectName("actionCustomLed")
         self.menuFile.addAction(self.actionSave)
         self.menuFile.addAction(self.actionLoad)
         self.menuFitType.addAction(self.actionFitTypeLinear)
         self.menuOptions.addAction(self.menuFitType.menuAction())
         self.menuOptions.addAction(self.menuConcentrationUnits.menuAction())
         self.menu_Help.addAction(self.actionAbout)
+        self.menuMode.addAction(self.actionStandardRgbLed)
+        self.menuMode.addAction(self.actionCustomLed)
         self.menubar.addAction(self.menuFile.menuAction())
+        self.menubar.addAction(self.menuMode.menuAction())
         self.menubar.addAction(self.menuOptions.menuAction())
         self.menubar.addAction(self.menu_Help.menuAction())
 
         self.menuFitType.setTitle(QtGui.QApplication.translate("MainWindow", "Fit Type", None, QtGui.QApplication.UnicodeUTF8))
         self.menuConcentrationUnits.setTitle(QtGui.QApplication.translate("MainWindow", "Concentration Units", None, QtGui.QApplication.UnicodeUTF8))
         self.menu_Help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuMode.setTitle(QtGui.QApplication.translate("MainWindow", "&Mode", None, QtGui.QApplication.UnicodeUTF8))
         self.actionSave.setText(QtGui.QApplication.translate("MainWindow", "Save...", None, QtGui.QApplication.UnicodeUTF8))
         self.action_About.setText(QtGui.QApplication.translate("MainWindow", "About...", None, QtGui.QApplication.UnicodeUTF8))
         self.actionLoad.setText(QtGui.QApplication.translate("MainWindow", "Load...", None, QtGui.QApplication.UnicodeUTF8))
         self.actionFitTypePolynomial3.setText(QtGui.QApplication.translate("MainWindow", "Polynomial (order=3)", None, QtGui.QApplication.UnicodeUTF8))
         self.actionFitTypePolynomial4.setText(QtGui.QApplication.translate("MainWindow", "Polynomial (order=4)", None, QtGui.QApplication.UnicodeUTF8))
         self.actionFitTypePolynomial5.setText(QtGui.QApplication.translate("MainWindow", "Polynomial (order=5)", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionStandardRgbLed.setText(QtGui.QApplication.translate("MainWindow", "Standard RGB LED", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionCustomLed.setText(QtGui.QApplication.translate("MainWindow", "Custom LED", None, QtGui.QApplication.UnicodeUTF8))
 
 from colorimeter.table_widget import ColorimeterTableWidget

File python/Colorimeter/colorimeter/main_window.py

         self.actionAbout.triggered.connect(self.about_Callback)
         self.actionSave.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_A)
 
+        self.modeActionGroup = QtGui.QActionGroup(self)
+        self.modeActionGroup.addAction(self.actionStandardRgbLed)
+        self.modeActionGroup.addAction(self.actionCustomLed)
+        self.modeActionGroup.setExclusive(True)
+        self.actionStandardRgbLed.setChecked(True)
+        self.actionStandardRgbLed.triggered.connect(self.standardRgbLed_Callback)
+        self.actionCustomLed.triggered.connect(self.customLed_Callback)
+
     def initialize(self):
         self.setAppSize()
         self.dev = None
         self.isCalibrated = False
         self.aboutCaption = 'About'
         self.aboutText = 'About Default Text'
+        self.sensorMode = 'standard'
 
         # Set default port based on system
         osType = platform.system()
         self.lastSaveDir = self.userHome
         self.statusbar.showMessage('Not Connected')
         self.portLineEdit.setText(self.port) 
+
         if constants.DEVEL_FAKE_MEASURE: 
             msgTitle = 'Development'
             msgText = 'Development mode fake measure is enabled'
 
     def connectClicked_Callback(self):
         if self.dev == None:
-            try:
-                self.dev = Colorimeter(self.port)
-                self.numSamples = self.dev.getNumSamples()
+            if constants.DEVEL_FAKE_MEASURE:
+                self.dev = 'dummy' 
                 connected = True
-            except Exception, e:
-                msgTitle = 'Connection Error'
-                msgText = 'unable to connect to device: {0}'.format(str(e))
-                QtGui.QMessageBox.warning(self,msgTitle, msgText)
+            else:
+                try:
+                    self.dev = Colorimeter(self.port)
+                    self.numSamples = self.dev.getNumSamples()
+                    connected = True
+                except Exception, e:
+                    msgTitle = 'Connection Error'
+                    msgText = 'unable to connect to device: {0}'.format(str(e))
+                    QtGui.QMessageBox.warning(self,msgTitle, msgText)
+                    self.connectPushButton.setText('Connect')
+                    self.statusbar.showMessage('Not Connected')
+                    connected = False
+                    self.dev = None
+        else:
+            if constants.DEVEL_FAKE_MEASURE:
+                self.dev = None
+            else:
                 self.connectPushButton.setText('Connect')
-                self.statusbar.showMessage('Not Connected')
-                connected = False
-                self.dev = None
-        else:
-            self.connectPushButton.setText('Connect')
-            try:
-                self.cleanUpAndCloseDevice()
-            except Exception, e:
-                QtGui.QMessageBox.critical(self,'Error', str(e))
+                try:
+                    self.cleanUpAndCloseDevice()
+                except Exception, e:
+                    QtGui.QMessageBox.critical(self,'Error', str(e))
             connected = False
 
         self.updateWidgetEnabled()
     def calibratePressed_Callback(self):
         self.measurePushButton.setEnabled(False)
         self.calibratePushButton.setFlat(True)
-        self.statusbar.showMessage('Connected, Mode: Calibrating...')
+        self.statusbar.showMessage('Connected, Calibrating...')
 
     def calibrateClicked_Callback(self):
         if not constants.DEVEL_FAKE_MEASURE: 
     def measurePressed_Callback(self):
         self.calibratePushButton.setEnabled(False)
         self.measurePushButton.setFlat(True)
-        self.statusbar.showMessage('Connected, Mode: Measuring...')
+        self.statusbar.showMessage('Connected, Measuring...')
 
     def measureClicked_Callback(self):
         self.getMeasurement()
         self.measurePushButton.setFlat(False)
         self.updateWidgetEnabled()
 
+    def getMeasurement():
+        pass
+
     def portChanged_Callback(self):
         self.port = str(self.portLineEdit.text())
 
                 )
         QtGui.QMessageBox.about(self,self.aboutCaption, aboutText)
 
+    def standardRgbLed_Callback(self): 
+        changed = False
+        if (self.dev is not None) and (self.sensorMode != 'standard'):
+            reply = QtGui.QMessageBox.question(
+                    self, 
+                    'Message', 
+                    'Changing sensor mode will clear all data. Continue?', 
+                    QtGui.QMessageBox.Yes, 
+                    QtGui.QMessageBox.No
+                    )
+            if reply == QtGui.QMessageBox.Yes:
+                if not constants.DEVEL_FAKE_MEASURE:    
+                    self.dev.setSensorModeColorSpecific()
+                self.isCalibrated = False
+                self.sensorMode = 'standard'
+                changed = True
+            else:
+                self.actionCustomLed.setChecked(True)
+            self.updateWidgetEnabled()
+        return changed
+
+    def customLed_Callback(self):
+        changed = False
+        if (self.dev is not None) and (self.sensorMode != 'custom'):
+            reply = QtGui.QMessageBox.question(
+                    self, 
+                    'Message', 
+                    'Changing sensor mode will clear all data. Continue?', 
+                    QtGui.QMessageBox.Yes, 
+                    QtGui.QMessageBox.No
+                    )
+            if reply == QtGui.QMessageBox.Yes:
+                if not constants.DEVEL_FAKE_MEASURE: 
+                    self.dev.setSensorModeColorIndependent()
+                self.isCalibrated = False
+                self.sensorMode = 'custom'
+                changed = True
+            else:
+                self.actionStandardRgbLed.setChecked(True)
+            self.updateWidgetEnabled()
+        return changed
+
+    def isStandardRgbLedMode(self):
+        return self.actionStandardRgbLed.isChecked()
+
+    def isCustomLedMode(self):
+        return self.actionCustomLed.isChecked()
+
     def haveData(self):
         return False
 
         event.accept()
 
     def cleanUpAndCloseDevice(self):
-        self.dev.close()
+        if not constants.DEVEL_FAKE_MEASURE:    
+            self.dev.close()
         self.dev = None
 
+    def updateWidgetEnabled(self):
+        if self.dev is None:
+            self.actionStandardRgbLed.setEnabled(False)
+            self.actionCustomLed.setEnabled(False)
+        else:
+            self.actionStandardRgbLed.setEnabled(True)
+            self.actionCustomLed.setEnabled(True)
+
     def main(self):
         self.show()
 
                 msgText = 'Unable to create data directory, {0}\n{1}'.format(userTestSolutionDir,str(e))
                 QtGui.QMessageBox.warning(self,msgTitle, msgText)
 
+    def standardRgbLed_Callback(self): 
+        changed = super(MainWindowWithTable,self).standardRgbLed_Callback()
+        if changed:
+            self.tableWidget.clean(True,'')
+        self.updateWidgetEnabled()
+
+    def customLed_Callback(self): 
+        changed = super(MainWindowWithTable,self).customLed_Callback()
+        if changed:
+            self.tableWidget.clean(True,'')
+        self.updateWidgetEnabled()
+
     def loadFile_Callback(self):
         """
         Load data in table from a text file.
         super(MainWindowWithTable,self).measureClicked_Callback()
         self.updatePlot(create=False)
 
+
     def setLEDColor(self,color):
         button = getattr(self,'{0}RadioButton'.format(color))
         button.setChecked(True)
         return self.tableWidget.measIndex > 0
 
     def updateWidgetEnabled(self):
+        super(MainWindowWithTable,self).updateWidgetEnabled()
         if self.dev is None:
             self.measurePushButton.setEnabled(False)
             self.calibratePushButton.setEnabled(False)
                     self.clearPushButton.setEnabled(False)
                 self.measurePushButton.setEnabled(False)
             self.portLineEdit.setEnabled(False)
-            self.statusbar.showMessage('Connected, Mode: Stopped')
+            self.statusbar.showMessage('Connected, Stopped')
 
-