//=====================================================================
        // Class Constructor
        //=====================================================================
        /// <summary>
        /// Set the address of the luminosity sensor and set the clock speed
        /// </summary>
        public TSL2561BusSensor() : base(BUS_ADDRESS, CLOCK_SPEED)
        {
            // Determine the current timing settings
            byte command = (byte)CommandOptions.CommandBit | (byte)Registers.Timing;

            byte[] options = new byte[1];               // Will hold registry values
            ReadRegister(command, options);

            // Determine the timing settings
            _gain      = (GainOptions)(options[0] & (byte)GainOptions.High);
            _intPeriod = (IntegrationOptions)(options[0] & 0x03);
        }
        //=====================================================================
        // SetTiming
        //=====================================================================
        public void SetTiming(GainOptions gain, IntegrationOptions integration)
        {
            // Set the commands
            byte command = (byte)CommandOptions.CommandBit | (byte)Registers.Timing;
            byte options = (byte)((byte)gain | (byte)integration);

            // Write the timing information
            EnableSensor();
            WriteRegister(command, options);
            DisableSensor();

            // Update the object
            _gain      = gain;
            _intPeriod = integration;
        }
        //=====================================================================
        // readOptimizedLuminosity
        //=====================================================================
        public double readOptimizedLuminosity()
        {
            //-----------------------------------------------------------------
            // Read the sensor measurements
            //-----------------------------------------------------------------
            // Initialize values
            double luminosity  = LUX_ERROR;
            bool   luxCaptured = false;
            UInt16 chan0       = 0;
            UInt16 chan1       = 0;

            // Sensor signal checks
            while (!luxCaptured)
            {
                // Get the measured luminosity in both channels
                chan0 = GetChannelData(Channels.Channel0);
                chan1 = GetChannelData(Channels.Channel1);

                // Evaluate the signal strength
                if ((chan0 == 0xFFFF) || (chan1 == 0xFFFF))                     // Saturated signal
                // Sensor saturated, so adjust timing
                {
                    if (_gain == GainOptions.High)
                    {
                        _gain = GainOptions.Low;                                                // Lower the gain
                    }
                    else if ((int)_intPeriod > 0)
                    {
                        --_intPeriod;                                                   // Reduce the integration time
                    }
                    else
                    {
                        luxCaptured = true;                             // Can't make any further adjustments
                    }
                }
                else if ((chan0 < 10) || (chan1 < 10))                          // Low signal
                // Low signal, so again try adjusting timing
                {
                    if ((int)_intPeriod < 2)
                    {
                        ++_intPeriod;                                           // Increase the integration time
                    }
                    else if (_gain == GainOptions.Low)
                    {
                        _gain = GainOptions.High;                                                       // Increase the gain
                    }
                    else
                    {
                        luminosity  = readLuminosity();                         // The measured value is the best one
                        luxCaptured = true;
                    }
                }
                else
                {
                    luxCaptured = true;                         // Signal is fine, return from loop and calculate
                }
                // Make adjustments if needed
                if (!luxCaptured)
                {
                    SetTiming(_gain, _intPeriod);                               // A bit crude, but fine for now
                }
            }

            if (chan0 != 0)                     // Check for division by zero
            //-----------------------------------------------------------------
            // Determine scaling
            //-----------------------------------------------------------------
            {
                double scale;

                // First, account for integration time
                switch (_intPeriod)
                {
                case IntegrationOptions.Short:
                    scale = 402.0 / 13.7;
                    break;

                case IntegrationOptions.Medium:
                    scale = 402.0 / 101.0;
                    break;

                default:
                    scale = 1.0;
                    break;
                }

                // Adjust for gain
                if (_gain == GainOptions.Low)
                {
                    scale *= 16.0;
                }

                //-----------------------------------------------------------------
                // Calculate luminosity
                //-----------------------------------------------------------------
                // Scale the readings
                double d0 = scale * chan0;
                double d1 = scale * chan1;

                // Calculation from the TSL2561 datasheet
                double ratio = (double)chan1 / (double)chan0;
                if (ratio <= 0.5)
                {
                    luminosity = 0.0304 * d0 - 0.062 * System.Math.Pow(ratio, 1.4) * d0;
                }
                else if (ratio <= 0.61)
                {
                    luminosity = 0.0224 * d0 - 0.031 * d1;
                }
                else if (ratio <= 0.8)
                {
                    luminosity = 0.0128 * d0 - 0.0153 * d1;
                }
                else if (ratio <= 1.3)
                {
                    luminosity = 0.00146 * d0 - 0.00112 * d1;
                }
                else
                {
                    luminosity = 0.0;
                }
            }
            else
            {
                luminosity = 0.0;                       // Set luminosity to zero
            }
            return(luminosity);
        }