示例#1
0
        public void ConversionRoundTrip()
        {
            VolumeConcentration decimalfraction = VolumeConcentration.FromDecimalFractions(1);

            AssertEx.EqualTolerance(1, VolumeConcentration.FromCentilitersPerLiter(decimalfraction.CentilitersPerLiter).DecimalFractions, CentilitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromCentilitersPerMililiter(decimalfraction.CentilitersPerMililiter).DecimalFractions, CentilitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromDecilitersPerLiter(decimalfraction.DecilitersPerLiter).DecimalFractions, DecilitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromDecilitersPerMililiter(decimalfraction.DecilitersPerMililiter).DecimalFractions, DecilitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromDecimalFractions(decimalfraction.DecimalFractions).DecimalFractions, DecimalFractionsTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromLitersPerLiter(decimalfraction.LitersPerLiter).DecimalFractions, LitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromLitersPerMililiter(decimalfraction.LitersPerMililiter).DecimalFractions, LitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromMicrolitersPerLiter(decimalfraction.MicrolitersPerLiter).DecimalFractions, MicrolitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromMicrolitersPerMililiter(decimalfraction.MicrolitersPerMililiter).DecimalFractions, MicrolitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromMillilitersPerLiter(decimalfraction.MillilitersPerLiter).DecimalFractions, MillilitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromMillilitersPerMililiter(decimalfraction.MillilitersPerMililiter).DecimalFractions, MillilitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromNanolitersPerLiter(decimalfraction.NanolitersPerLiter).DecimalFractions, NanolitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromNanolitersPerMililiter(decimalfraction.NanolitersPerMililiter).DecimalFractions, NanolitersPerMililiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPartsPerBillion(decimalfraction.PartsPerBillion).DecimalFractions, PartsPerBillionTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPartsPerMillion(decimalfraction.PartsPerMillion).DecimalFractions, PartsPerMillionTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPartsPerThousand(decimalfraction.PartsPerThousand).DecimalFractions, PartsPerThousandTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPartsPerTrillion(decimalfraction.PartsPerTrillion).DecimalFractions, PartsPerTrillionTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPercent(decimalfraction.Percent).DecimalFractions, PercentTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPicolitersPerLiter(decimalfraction.PicolitersPerLiter).DecimalFractions, PicolitersPerLiterTolerance);
            AssertEx.EqualTolerance(1, VolumeConcentration.FromPicolitersPerMililiter(decimalfraction.PicolitersPerMililiter).DecimalFractions, PicolitersPerMililiterTolerance);
        }
示例#2
0
        /// <summary>
        /// Read the equivalent CO2 in ppm and equivalent Total Volatile Compound in ppb
        /// </summary>
        /// <param name="equivalentCO2">The equivalent CO2 (eCO2) output range for CCS811 is from
        /// 400ppm up to 29206ppm.</param>
        /// <param name="equivalentTotalVolatileOrganicCompound">The equivalent Total Volatile Organic Compound (eTVOC)
        /// output range for CCS811 is from 0ppb up to 32768ppb</param>
        /// <param name="rawCurrentSelected">Raw data containing the value of the
        /// current through the sensor(0μA to 63μA)</param>
        /// <param name="rawAdcReading">Raw data containing  the
        /// readings of the voltage across the sensor with the selected
        /// current(1023 = 1.65V) where 1023 is the maximum value</param>
        /// <returns>True if success</returns>
        public bool TryReadGasData(out VolumeConcentration equivalentCO2, out VolumeConcentration equivalentTotalVolatileOrganicCompound, out ElectricCurrent rawCurrentSelected, out int rawAdcReading)
        {
            int equivalentCO2InPpm = -1;
            int equivalentTotalVolatileOrganicCompoundInPpb = -1;
            int rawCurrent = -1;

            rawAdcReading = -1;
            Span <byte> toRead = stackalloc byte[8];

            ReadRegister(Register.ALG_RESULT_DATA, toRead);
            if (toRead[5] != (byte)Error.NoError)
            {
                equivalentCO2 = VolumeConcentration.Zero;
                equivalentTotalVolatileOrganicCompound = VolumeConcentration.Zero;
                rawCurrentSelected = ElectricCurrent.Zero;
                return(false);
            }

            equivalentCO2InPpm = BinaryPrimitives.ReadInt16BigEndian(toRead.Slice(0, 2));
            equivalentTotalVolatileOrganicCompoundInPpb = BinaryPrimitives.ReadInt16BigEndian(toRead.Slice(2, 2));
            rawCurrent    = toRead[6] >> 2;
            rawAdcReading = ((toRead[6] & 0b0000_0011) << 2) + toRead[7];
            equivalentCO2 = VolumeConcentration.FromPartsPerMillion(equivalentCO2InPpm);
            equivalentTotalVolatileOrganicCompound = VolumeConcentration.FromPartsPerBillion(equivalentTotalVolatileOrganicCompoundInPpb);
            rawCurrentSelected = ElectricCurrent.FromMicroamperes(rawCurrent);
            return((equivalentCO2InPpm >= 400) && (equivalentCO2InPpm <= 29206) && (equivalentTotalVolatileOrganicCompoundInPpb >= 0) && (equivalentTotalVolatileOrganicCompoundInPpb <= 32768));
        }
示例#3
0
文件: Mhz19b.cs 项目: sameer106/iot
        /// <summary>
        /// Gets the current CO2 concentration from the sensor.
        /// </summary>
        /// <returns>CO2 volume concentration</returns>
        /// <exception cref="IOException">Communication with sensor failed</exception>
        /// <exception cref="TimeoutException">A timeout occurred while communicating with the sensor</exception>
        public VolumeConcentration GetCo2Reading()
        {
            // send read command request
            var request = CreateRequest(Command.ReadCo2Concentration);

            request[(int)MessageFormat.Checksum] = Checksum(request);
            _serialPortStream.Write(request, 0, request.Length);

            // read complete response (9 bytes expected)
            byte[] response = new byte[MessageBytes];

            long endTicks  = DateTime.Now.AddMilliseconds(250).Ticks;
            int  bytesRead = 0;

            while (DateTime.Now.Ticks < endTicks && bytesRead < MessageBytes)
            {
                bytesRead += _serialPortStream.Read(response, bytesRead, response.Length - bytesRead);
                Thread.Sleep(1);
            }

            if (bytesRead < MessageBytes)
            {
                throw new TimeoutException($"Communication with sensor failed.");
            }

            // check response and return calculated concentration if valid
            if (response[(int)MessageFormat.Checksum] == Checksum(response))
            {
                return(VolumeConcentration.FromPartsPerMillion((int)response[(int)MessageFormat.DataHighResponse] * 256 + (int)response[(int)MessageFormat.DataLowResponse]));
            }
            else
            {
                throw new IOException("Invalid response message received from sensor");
            }
        }
示例#4
0
        private bool IsPpmValidThreshold(VolumeConcentration ppm)
        {
            if ((ppm < VolumeConcentration.Zero) || (ppm > VolumeConcentration.FromPartsPerMillion(ushort.MaxValue)))
            {
                return(false);
            }

            return(true);
        }
示例#5
0
        /// <summary>
        /// Set the threshold for the equivalent CO2. The pinInterrupt should be existing so
        /// interruptions are activated. If not, then the function will return false
        /// </summary>
        /// <param name="lowEquivalentCO2">The low value for the threshold</param>
        /// <param name="highEquivalentCO2">The high value for the threshold</param>
        /// <returns>True if success</returns>
        /// <remarks>Difference between the low and high value should be more than 50. This is called
        /// the hysteresis value.</remarks>
        public bool SetThreshold(VolumeConcentration lowEquivalentCO2, VolumeConcentration highEquivalentCO2)
        {
            if (_pinInterruption < 0)
            {
                return(false);
            }

            if (!IsPpmValidThreshold(lowEquivalentCO2))
            {
                throw new ArgumentException($"{lowEquivalentCO2} can only be between 0 and {ushort.MaxValue}");
            }

            if (!IsPpmValidThreshold(highEquivalentCO2))
            {
                throw new ArgumentException($"{highEquivalentCO2} can only be between 0 and {ushort.MaxValue}");
            }

            if (lowEquivalentCO2 > highEquivalentCO2)
            {
                var temp = highEquivalentCO2;
                highEquivalentCO2 = lowEquivalentCO2;
                lowEquivalentCO2  = temp;
            }

            if (highEquivalentCO2 - lowEquivalentCO2 < VolumeConcentration.FromPartsPerMillion(50))
            {
                throw new ArgumentException($"{highEquivalentCO2}-{lowEquivalentCO2} should be more than 50");
            }

            Span <byte> toSend = stackalloc byte[4];

            BinaryPrimitives.WriteUInt16BigEndian(toSend.Slice(0, 2), (ushort)lowEquivalentCO2.PartsPerMillion);
            BinaryPrimitives.WriteUInt16BigEndian(toSend.Slice(2, 2), (ushort)highEquivalentCO2.PartsPerMillion);
            WriteRegister(Register.THRESHOLDS, toSend);
            // Activate the interrupt threshold as well
            byte mode = ReadRegister(Register.MEAS_MODE);

            mode |= 0b0000_0100;
            WriteRegister(Register.MEAS_MODE, mode);

            return(!Status.HasFlag(Status.ERROR));
        }
示例#6
0
        private static void TestThresholdAndInterrupt(Ccs811Sensor ccs811)
        {
            if (!ccs811.InterruptEnable)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error: interrupt needs to be activated to run this test");
                Console.ResetColor();
                return;
            }

            ccs811.MeasurementReady += Ccs811MeasurementReady;
            // Setting up a range where we will see something in a normal environment
            VolumeConcentration low  = VolumeConcentration.FromPartsPerMillion(400);
            VolumeConcentration high = VolumeConcentration.FromPartsPerMillion(600);

            Console.WriteLine($"Setting up {low.PartsPerMillion}-{high.PartsPerMillion} range, in clear environment, that should raise interrupts. Wait 3 minutes and change mode. Blow on the sensor and wait a bit.");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Warning: only the first measurement to cross the threshold is raised.");
            Console.ResetColor();
            ccs811.SetThreshold(low, high);
            DateTime dt = DateTime.Now.AddMinutes(3);

            while (dt > DateTime.Now)
            {
                Thread.Sleep(10);
            }

            low  = VolumeConcentration.FromPartsPerMillion(15000);
            high = VolumeConcentration.FromPartsPerMillion(20000);
            Console.WriteLine($"Changing threshold for {low.PartsPerMillion}-{high.PartsPerMillion}, a non reachable range in clear environment. No measurement should appear in next 3 minutes");
            dt = DateTime.Now.AddMinutes(3);
            ccs811.SetThreshold(low, high);
            while (dt > DateTime.Now)
            {
                Thread.Sleep(10);
            }
        }
 public void NumberToPartsPerMillionTest() =>
 Assert.Equal(VolumeConcentration.FromPartsPerMillion(2), 2.PartsPerMillion());
示例#8
0
 public static VolumeConcentration PartsPerMillion <T>(this T value) =>
 VolumeConcentration.FromPartsPerMillion(Convert.ToDecimal(value));