Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Characteristic Locus
Inheritance object ObservableBase<(Concentration? Co2, Concentration? Voc)> SamplingSensorBase<(Concentration? Co2, Concentration? Voc)> PollingSensorBase<(Concentration? Co2, Concentration? Voc)> ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)> > Ccs811
Implements IObservable<IChangeResult<(Concentration? Co2, Concentration? Voc)>> ISamplingSensor<(Concentration? Co2, Concentration? Voc)> ISensor<(Concentration? Co2, Concentration? Voc)> IDisposable ICo2Sensor IVocSensor ISamplingSensor<Concentration> ISensor<Concentration> II2cPeripheral
Inherited Members ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.Init(int, int) ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.Dispose(bool) ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.Dispose() ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.BusComms ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.ReadBuffer ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>.WriteBuffer PollingSensorBase<(Concentration? Co2, Concentration? Voc)>.StartUpdating(TimeSpan?) PollingSensorBase<(Concentration? Co2, Concentration? Voc)>.StopUpdating() SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.samplingLock SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.ReadSensor() SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.RaiseEventsAndNotify(IChangeResult<(Concentration? Co2, Concentration? Voc)>) SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.Read() SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.SamplingTokenSource SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.Conditions SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.IsSampling SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.UpdateInterval SamplingSensorBase<(Concentration? Co2, Concentration? Voc)>.Updated ObservableBase<(Concentration? Co2, Concentration? Voc)>.NotifyObservers(IChangeResult<(Concentration? Co2, Concentration? Voc)>) ObservableBase<(Concentration? Co2, Concentration? Voc)>.Subscribe(IObserver<IChangeResult<(Concentration? Co2, Concentration? Voc)>>) ObservableBase<(Concentration? Co2, Concentration? Voc)>.CreateObserver(Action<IChangeResult<(Concentration? Co2, Concentration? Voc)>>, Predicate<IChangeResult<(Concentration? Co2, Concentration? Voc)>>) ObservableBase<(Concentration? Co2, Concentration? Voc)>.observers object.Equals(object) object.Equals(object, object) object.GetHashCode() object.GetType() object.MemberwiseClone() object.ReferenceEquals(object, object) object.ToString()
Namespace Meadow.Foundation.Sensors.Atmospheric
Assembly Ccs811.dll

Syntax

public class Ccs811 : ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>, IObservable<IChangeResult<(Concentration? Co2, Concentration? Voc)>>, ISamplingSensor<(Concentration? Co2, Concentration? Voc)>, ISensor<(Concentration? Co2, Concentration? Voc)>, IDisposable, ICo2Sensor, IVocSensor, ISamplingSensor<Concentration>, ISensor<Concentration>, II2cPeripheral

Constructors

Ccs811(II2cBus, Addresses)

Create a new Ccs811 object

Declaration
public Ccs811(II2cBus i2cBus, Ccs811.Addresses address = Addresses.Address_0x5A)

Parameters

Type Name Description
II2cBus i2cBus

The I2C bus

Ccs811.Addresses address

The I2C address

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Ccs811(II2cBus, byte)

Create a new Ccs811 object

Declaration
public Ccs811(II2cBus i2cBus, byte address)

Parameters

Type Name Description
II2cBus i2cBus

The I2C bus

byte address

The I2C address

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Properties

Co2

The measured CO2 concentration

Declaration
public Concentration? Co2 { get; }

Property Value

Type Description
Concentration?

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

DefaultI2cAddress

The default I2C address for the peripheral

Declaration
public byte DefaultI2cAddress { get; }

Property Value

Type Description
byte

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Voc

The measured VOC concentration

Declaration
public Concentration? Voc { get; }

Property Value

Type Description
Concentration?

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Methods

GetBaseline()

Get baseline value

Declaration
public ushort GetBaseline()

Returns

Type Description
ushort

The baseline value

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

GetMeasurementMode()

Get the current measurement mode

Declaration
public Ccs811.MeasurementMode GetMeasurementMode()

Returns

Type Description
Ccs811.MeasurementMode

The measurement mode

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Initialize()

Initialize the sensor

Declaration
protected void Initialize()

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Exceptions

Type Condition
Exception

Raised if HW_ID register returns an invalid id

RaiseEventsAndNotify(IChangeResult<(Concentration? Co2, Concentration? Voc)>)

Raise events for subcribers and notify of value changes

Declaration
protected override void RaiseEventsAndNotify(IChangeResult<(Concentration? Co2, Concentration? Voc)> changeResult)

Parameters

Type Name Description
IChangeResult<(Concentration? Co2, Concentration? Voc)> changeResult

The updated sensor data

Overrides

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

ReadSensor()

Reads data from the sensor

Declaration
protected override Task<(Concentration? Co2, Concentration? Voc)> ReadSensor()

Returns

Type Description
Task<(Concentration? Co2, Concentration? Voc)>

The latest sensor reading

Overrides

Meadow.Foundation.SamplingSensorBase<(Meadow.Units.Concentration? Co2, Meadow.Units.Concentration? Voc)>.ReadSensor()

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

SetBaseline(ushort)

Set the baseline value

Declaration
public void SetBaseline(ushort value)

Parameters

Type Name Description
ushort value

The new baseline

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

SetMeasurementMode(MeasurementMode)

Set the Measurement mode

Declaration
public void SetMeasurementMode(Ccs811.MeasurementMode mode)

Parameters

Type Name Description
Ccs811.MeasurementMode mode

The new mode

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

Events

Co2Updated

Event raised when the CO2 concentration value changes

Declaration
public event EventHandler<ChangeResult<Concentration>> Co2Updated

Event Type

Type Description
EventHandler<ChangeResult<Concentration>>

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram:

VocUpdated

Event raised when the VOC concentration value changes

Declaration
public event EventHandler<ChangeResult<Concentration>> VocUpdated

Event Type

Type Description
EventHandler<ChangeResult<Concentration>>

Remarks

Ccs811
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Ccs811

Code Example

Ccs811 sensor;

public override Task Initialize()
{
    Resolver.Log.Info("Initializing...");

    var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
    sensor = new Ccs811(i2cBus);

    var consumer = Ccs811.CreateObserver(
        handler: result =>
        {
            Resolver.Log.Info($"Observer triggered:");
            Resolver.Log.Info($"   new CO2: {result.New.Co2?.PartsPerMillion:N1}ppm, old: {result.Old?.Co2?.PartsPerMillion:N1}ppm.");
            Resolver.Log.Info($"   new VOC: {result.New.Voc?.PartsPerBillion:N1}ppb, old: {result.Old?.Voc?.PartsPerBillion:N1}ppb.");
        },
        filter: result =>
        {
            //c# 8 pattern match syntax. checks for !null and assigns var.
            if (result.Old is { } old)
            {
                return (
                (result.New.Co2.Value - old.Co2.Value).Abs().PartsPerMillion > 1000 // 1000ppm
                  &&
                (result.New.Voc.Value - old.Voc.Value).Abs().PartsPerBillion > 100 // 100ppb
                );
            }
            return false;
        }
    );
    sensor.Subscribe(consumer);

    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"CO2: {result.New.Co2.Value.PartsPerMillion:n1}ppm, VOC: {result.New.Voc.Value.PartsPerBillion:n1}ppb");
    };

    return Task.CompletedTask;
}

public override async Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"  CO2: {result.Co2.Value.PartsPerMillion:n1}ppm");
    Resolver.Log.Info($"  VOC: {result.Voc.Value.PartsPerBillion:n1}ppb");

    sensor.StartUpdating(TimeSpan.FromSeconds(1));
}

Sample project(s) available on GitHub

Wiring Example

To wire a Ccs811 to your Meadow board, connect the following:

Ccs811 Meadow Pin
GND GND
VCC 3V3
SCL D08
SDA D07

It should look like the following diagram: