예제 #1
0
        /// <summary>
        ///     Reads the compensation data.
        /// </summary>
        /// <remarks>
        ///     The compensation data is written to the chip at the time of manufacture and cannot be changed.
        ///     This information is used to convert the readings from the sensor into actual temperature,
        ///     pressure and humidity readings.
        ///     From the data sheet, the register addresses and length are:
        ///     Temperature and pressure: start address 0x88, end address 0x9F (length = 24)
        ///     Humidity 1: 0xa1, length = 1
        ///     Humidity 2 and 3: start address 0xe1, end address 0xe7, (length = 8)
        /// </remarks>
        private void ReadCompensationData()
        {
            var temperatureAndPressureData = _bme280.ReadRegisters(0x88, 24);
            var humidityData1    = _bme280.ReadRegisters(0xa1, 1);
            var humidityData2To6 = _bme280.ReadRegisters(0xe1, 7);

            _compensationData.T1 = (ushort)(temperatureAndPressureData[0] + (temperatureAndPressureData[1] << 8));
            _compensationData.T2 = (short)(temperatureAndPressureData[2] + (temperatureAndPressureData[3] << 8));
            _compensationData.T3 = (short)(temperatureAndPressureData[4] + (temperatureAndPressureData[5] << 8));
            //
            _compensationData.P1 = (ushort)(temperatureAndPressureData[6] + (temperatureAndPressureData[7] << 8));
            _compensationData.P2 = (short)(temperatureAndPressureData[8] + (temperatureAndPressureData[9] << 8));
            _compensationData.P3 = (short)(temperatureAndPressureData[10] + (temperatureAndPressureData[11] << 8));
            _compensationData.P4 = (short)(temperatureAndPressureData[12] + (temperatureAndPressureData[13] << 8));
            _compensationData.P5 = (short)(temperatureAndPressureData[14] + (temperatureAndPressureData[15] << 8));
            _compensationData.P6 = (short)(temperatureAndPressureData[16] + (temperatureAndPressureData[17] << 8));
            _compensationData.P7 = (short)(temperatureAndPressureData[18] + (temperatureAndPressureData[19] << 8));
            _compensationData.P8 = (short)(temperatureAndPressureData[20] + (temperatureAndPressureData[21] << 8));
            _compensationData.P9 = (short)(temperatureAndPressureData[22] + (temperatureAndPressureData[23] << 8));
            //
            _compensationData.H1 = humidityData1[0];
            _compensationData.H2 = (short)(humidityData2To6[0] + (humidityData2To6[1] << 8));
            _compensationData.H3 = humidityData2To6[2];
            _compensationData.H4 = (short)((humidityData2To6[3] << 4) + (humidityData2To6[4] & 0xf));
            _compensationData.H5 = (short)(((humidityData2To6[4] & 0xf) >> 4) + (humidityData2To6[5] << 4));
            _compensationData.H6 = (sbyte)humidityData2To6[6];
        }
예제 #2
0
        /// <summary>
        ///     Create a new TMP102 object using the default configuration for the sensor.
        /// </summary>
        /// <param name="address">I2C address of the sensor.</param>
        /// <param name="speed">Speed of the communication with the sensor.</param>
        public TMP102(byte address = 0x48, ushort speed = 100, ushort updateInterval = MinimumPollingPeriod,
                      float temperatureChangeNotificationThreshold = 0.001F)
        {
            if ((speed < 10) || (speed > 1000))
            {
                throw new ArgumentOutOfRangeException(nameof(speed), "Speed should be 10 KHz to 3,400 KHz.");
            }
            if (temperatureChangeNotificationThreshold < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(temperatureChangeNotificationThreshold), "Temperature threshold should be >= 0");
            }
            if ((updateInterval != 0) && (updateInterval < MinimumPollingPeriod))
            {
                throw new ArgumentOutOfRangeException(nameof(updateInterval), "Update period should be 0 or >= than " + MinimumPollingPeriod);
            }

            TemperatureChangeNotificationThreshold = temperatureChangeNotificationThreshold;
            _updateInterval = updateInterval;

            _tmp102 = new I2CBus(address, speed);
            var configuration = _tmp102.ReadRegisters(0x01, 2);

            _sensorResolution = (configuration[1] & 0x10) > 0
                ? Resolution.Resolution13Bits
                : Resolution.Resolution12Bits;
            if (updateInterval > 0)
            {
                StartUpdating();
            }
            else
            {
                Update();
            }
        }
예제 #3
0
        /// <summary>
        ///     Update the temperature and pressure from the sensor and set the Pressure property.
        /// </summary>
        public void Update()
        {
            //
            //  Tell the sensor to take a temperature and pressure reading, wait for
            //  3ms (see section 2.2 of the datasheet) and then read the ADC values.
            //
            _mpl115a2.WriteBytes(new byte[] { Registers.StartConversion, 0x00 });
            Thread.Sleep(5);
            var data = _mpl115a2.ReadRegisters(Registers.PressureMSB, 4);
            //
            //  Extract the sensor data, note that this is a 10-bit reading so move
            //  the data right 6 bits (see section 3.1 of the datasheet).
            //
            var pressure    = (ushort)(((data[0] << 8) + data[1]) >> 6);
            var temperature = (ushort)(((data[2] << 8) + data[3]) >> 6);

            Temperature = (float)((temperature - 498.0) / -5.35) + 25;
            //
            //  Now use the calculations in section 3.2 to determine the
            //  current pressure reading.
            //
            const double PRESSURE_CONSTANT   = 65.0 / 1023.0;
            var          compensatedPressure = _coefficients.A0 + ((_coefficients.B1 + (_coefficients.C12 * temperature))
                                                                   * pressure) + (_coefficients.B2 * temperature);

            Pressure = (float)(PRESSURE_CONSTANT * compensatedPressure) + 50;
        }
예제 #4
0
        /// <summary>
        ///     Read the six sensor bytes and set the values for the X, Y and Z acceleration.
        /// </summary>
        /// <remarks>
        ///     All six acceleration registers should be read at the same time to ensure consistency
        ///     of the measurements.
        /// </remarks>
        public void Update()
        {
            var data = _adxl345.ReadRegisters(Registers.X0, 6);

            X = (short)(data[0] + (data[1] << 8));
            Y = (short)(data[2] + (data[3] << 8));
            Z = (short)(data[4] + (data[5] << 8));
            if ((_updateInterval != 0) &&
                ((Math.Abs(X - _lastX) > AccelerationChangeNotificationThreshold) ||
                 (Math.Abs(Y - _lastY) > AccelerationChangeNotificationThreshold) ||
                 (Math.Abs(Z - _lastZ) > AccelerationChangeNotificationThreshold)))
            {
                Vector lastNotifiedReading = new Vector(_lastX, _lastY, _lastZ);
                Vector currentReading      = new Vector(X, Y, Z);
                _lastX = X;
                _lastY = Y;
                _lastZ = Z;
                AccelerationChanged(this, new SensorVectorEventArgs(lastNotifiedReading, currentReading));
            }
        }
예제 #5
0
        /// <summary>
        ///     Force the sensor to make a reading and update the relevant properties.
        /// </summary>
        public void Update()
        {
            int temp = 0;

            //
            //  Get the humidity first.
            //
            _groveTH02.WriteRegister(Registers.Config, StartMeasurement);
            //
            //  Maximum conversion time should be 40ms but loop just in case
            //  it takes longer.
            //
            Thread.Sleep(40);
            while ((_groveTH02.ReadRegister(Registers.Status) & 0x01) > 0)
            {
                ;
            }
            byte[] data = _groveTH02.ReadRegisters(Registers.DataHigh, 2);
            temp     = data[0] << 8;
            temp    |= data[1];
            temp   >>= 4;
            Humidity = (((float)temp) / 16) - 24;
            //
            //  Now get the temperature.
            //
            _groveTH02.WriteRegister(Registers.Config, StartMeasurement | MeasureTemperature);
            //
            //  Maximum conversion time should be 40ms but loop just in case
            //  it takes longer.
            //
            Thread.Sleep(40);
            while ((_groveTH02.ReadRegister(Registers.Status) & 0x01) > 0)
            {
                ;
            }
            data        = _groveTH02.ReadRegisters(Registers.DataHigh, 2);
            temp        = data[0] << 8;
            temp       |= data[1];
            temp      >>= 2;
            Temperature = (((float)temp) / 32) - 50;
        }
예제 #6
0
        /// <summary>
        ///     Update the Temperature property.
        /// </summary>
        public void Update()
        {
            var temperatureData = _tmp102.ReadRegisters(0x00, 2);
            var sensorReading   = 0;

            if (SensorResolution == Resolution.Resolution12Bits)
            {
                sensorReading = (temperatureData[0] << 4) | (temperatureData[1] >> 4);
            }
            else
            {
                sensorReading = (temperatureData[0] << 5) | (temperatureData[1] >> 3);
            }
            Temperature = (float)(sensorReading * 0.0625);
        }
예제 #7
0
        /// <summary>
        ///     Force a read of the current sensor values and update the Temperature
        ///     and Pressure properties.
        /// </summary>
        public void Update()
        {
            //
            //  Force the sensor to make a reading by setting the OST bit in Control
            //  register 1 (see 7.17.1 of the datasheet).
            //
            Standby = false;
            //
            //  Pause until both temperature and pressure readings are available.
            //
            while ((Status & 0x06) != 0x06)
            {
                Thread.Sleep(5);
            }
            Thread.Sleep(100);
            var data = _mpl3115a2.ReadRegisters(Registers.PressureMSB, 5);

            Pressure    = DecodePresssure(data[0], data[1], data[2]);
            Temperature = DecodeTemperature(data[3], data[4]);
        }
예제 #8
0
        /// <summary>
        ///     Create a new MPL115A2 temperature and humidity sensor object.
        /// </summary>
        /// <param name="address">Sensor address (default to 0x60).</param>
        /// <param name="speed">Speed of the I2C interface (default to 100 KHz).</param>
        /// <param name="updateInterval">Number of milliseconds between samples (0 indicates polling to be used)</param>
        /// <param name="temperatureChangeNotificationThreshold">Changes in temperature greater than this value will trigger an event when updatePeriod > 0.</param>
        /// <param name="pressureChangedNotificationThreshold">Changes in pressure greater than this value will trigger an event when updatePeriod > 0.</param>
        public MPL115A2(byte address = 0x60, ushort speed = 100, ushort updateInterval = MinimumPollingPeriod,
                        float temperatureChangeNotificationThreshold = 0.001F, float pressureChangedNotificationThreshold = 10.0F)
        {
            if ((speed < 10) || (speed > 1000))
            {
                throw new ArgumentOutOfRangeException(nameof(speed), "Speed should be 10 KHz to 3,400 KHz.");
            }
            if (temperatureChangeNotificationThreshold < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(temperatureChangeNotificationThreshold), "Temperature threshold should be >= 0");
            }
            if (pressureChangedNotificationThreshold < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pressureChangedNotificationThreshold), "Pressure threshold should be >= 0");
            }
            if ((updateInterval != 0) && (updateInterval < MinimumPollingPeriod))
            {
                throw new ArgumentOutOfRangeException(nameof(updateInterval), "Update period should be 0 or >= than " + MinimumPollingPeriod);
            }

            TemperatureChangeNotificationThreshold = temperatureChangeNotificationThreshold;
            PressureChangeNotificationThreshold    = pressureChangedNotificationThreshold;
            _updateInterval = updateInterval;

            var device = new I2cBus(address, speed);

            _mpl115a2 = device;
            //
            //  Update the compensation data from the sensor.  The location and format of the
            //  compensation data can be found on pages 5 and 6 of the datasheet.
            //
            var data = _mpl115a2.ReadRegisters(Registers.A0MSB, 8);
            var a0   = (short)(ushort)((data[0] << 8) | data[1]);
            var b1   = (short)(ushort)((data[2] << 8) | data[3]);
            var b2   = (short)(ushort)((data[4] << 8) | data[5]);
            var c12  = (short)(ushort)(((data[6] << 8) | data[7]) >> 2);

            //
            //  Convert the raw compensation coefficients from the sensor into the
            //  doubleing point equivalents to speed up the calculations when readings
            //  are made.
            //
            //  Datasheet, section 3.1
            //  a0 is signed with 12 integer bits followed by 3 fractional bits so divide by 2^3 (8)
            //
            _coefficients.A0 = (double)a0 / 8;
            //
            //  b1 is 2 integer bits followed by 7 fractional bits.  The lower bits are all 0
            //  so the format is:
            //      sign i1 I0 F12...F0
            //
            //  So we need to divide by 2^13 (8192)
            //
            _coefficients.B1 = (double)b1 / 8192;
            //
            //  b2 is signed integer (1 bit) followed by 14 fractional bits so divide by 2^14 (16384).
            //
            _coefficients.B2 = (double)b2 / 16384;
            //
            //  c12 is signed with no integer bits but padded with 9 zeroes:
            //      sign 0.000 000 000 f12...f0
            //
            //  So we need to divide by 2^22 (4,194,304) - 13 doubleing point bits
            //  plus 9 leading zeroes.
            //
            _coefficients.C12 = (double)c12 / 4194304;
            if (updateInterval > 0)
            {
                StartUpdating();
            }
            else
            {
                Update();
            }
        }
예제 #9
0
        /// <summary>
        ///     Display the registers.
        /// </summary>
        public void DisplayRegisters()
        {
            var data = _ds323x.ReadRegisters(0, 0x12);

            DebugInformation.DisplayRegisters(0, data);
        }