Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Characteristic Locus
Inheritance object ObservableBase<double> SamplingSensorBase<double> > Fc28
Implements IObservable<IChangeResult<double>> IMoistureSensor ISamplingSensor<double> ISensor<double>
Inherited Members SamplingSensorBase<double>.samplingLock SamplingSensorBase<double>.RaiseEventsAndNotify(IChangeResult<double>) SamplingSensorBase<double>.Read() SamplingSensorBase<double>.SamplingTokenSource SamplingSensorBase<double>.Conditions SamplingSensorBase<double>.IsSampling SamplingSensorBase<double>.UpdateInterval SamplingSensorBase<double>.Updated ObservableBase<double>.NotifyObservers(IChangeResult<double>) ObservableBase<double>.Subscribe(IObserver<IChangeResult<double>>) ObservableBase<double>.CreateObserver(Action<IChangeResult<double>>, Predicate<IChangeResult<double>>) ObservableBase<double>.observers object.Equals(object) object.Equals(object, object) object.GetHashCode() object.GetType() object.MemberwiseClone() object.ReferenceEquals(object, object) object.ToString()
Namespace Meadow.Foundation.Sensors.Moisture
Assembly Fc28.dll

Syntax

public class Fc28 : SamplingSensorBase<double>, IObservable<IChangeResult<double>>, IMoistureSensor, ISamplingSensor<double>, ISensor<double>

Constructors

Fc28(IAnalogInputPort, IDigitalOutputPort, Voltage?, Voltage?)

Creates a FC28 soil moisture sensor object with the specified analog pin and digital pin

Declaration
public Fc28(IAnalogInputPort analogInputPort, IDigitalOutputPort digitalOutputPort, Voltage? minimumVoltageCalibration, Voltage? maximumVoltageCalibration)

Parameters

Type Name Description
IAnalogInputPort analogInputPort

Analog input port connected

IDigitalOutputPort digitalOutputPort

Digital output port connected

Voltage? minimumVoltageCalibration

Minimum Voltage Calibration value

Voltage? maximumVoltageCalibration

Maximum Voltage Calibration value

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Fc28(IPin, IPin, Voltage?, Voltage?, TimeSpan?, int, TimeSpan?)

Creates a FC28 soil moisture sensor object with the specified analog pin, digital pin and IO device

Declaration
public Fc28(IPin analogInputPin, IPin digitalOutputPin, Voltage? minimumVoltageCalibration, Voltage? maximumVoltageCalibration, TimeSpan? updateInterval = null, int sampleCount = 5, TimeSpan? sampleInterval = null)

Parameters

Type Name Description
IPin analogInputPin

Analog input pin connected

IPin digitalOutputPin

Digital output pin connected

Voltage? minimumVoltageCalibration

Minimum Voltage Calibration value

Voltage? maximumVoltageCalibration

Maximum Voltage Calibration value

TimeSpan? updateInterval

The time, to wait between sets of sample readings. This value determines how oftenChanged events are raised and IObservable consumers are notified.

int sampleCount

How many samples to take during a given reading. These are automatically averaged to reduce noise.

TimeSpan? sampleInterval

The time, to wait in between samples during a reading.

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Properties

AnalogInputPort

Returns the analog input port

Declaration
protected IAnalogInputPort AnalogInputPort { get; }

Property Value

Type Description
IAnalogInputPort

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

DigitalOutputPort

Returns the digital output port

Declaration
protected IDigitalOutputPort DigitalOutputPort { get; }

Property Value

Type Description
IDigitalOutputPort

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

IsDisposed

Is the object disposed

Declaration
public bool IsDisposed { get; }

Property Value

Type Description
bool

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

MaximumVoltageCalibration

Voltage value of most moist soil. Default of 3.3V

Declaration
public Voltage MaximumVoltageCalibration { get; set; }

Property Value

Type Description
Voltage

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

MinimumVoltageCalibration

Voltage value of most dry soil. Default of 0V

Declaration
public Voltage MinimumVoltageCalibration { get; set; }

Property Value

Type Description
Voltage

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Moisture

Last value read from the moisture sensor

Declaration
public double? Moisture { get; }

Property Value

Type Description
double?

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Methods

Dispose()

FC-28-D Soil Hygrometer Detection Module + Soil Moisture Sensor

Declaration
public void Dispose()

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Dispose(bool)

Dispose of the object

Declaration
protected virtual void Dispose(bool disposing)

Parameters

Type Name Description
bool disposing

Is disposing

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

RaiseChangedAndNotify(IChangeResult<double>)

Raise change events for subscribers

Declaration
protected void RaiseChangedAndNotify(IChangeResult<double> changeResult)

Parameters

Type Name Description
IChangeResult<double> changeResult

The change result with the current sensor data

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

ReadSensor()

Reads data from the sensor

Declaration
protected override Task<double> ReadSensor()

Returns

Type Description
Task<double>

The latest sensor reading

Overrides

Meadow.Foundation.SamplingSensorBase<double>.ReadSensor()

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

StartUpdating(TimeSpan?)

Starts continuously sampling the sensor

Declaration
public override void StartUpdating(TimeSpan? updateInterval)

Parameters

Type Name Description
TimeSpan? updateInterval

Overrides

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

StopUpdating()

Stops sampling the sensor

Declaration
public override void StopUpdating()

Overrides

Meadow.Foundation.SamplingSensorBase<double>.StopUpdating()

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

VoltageToMoisture(Voltage)

Converts voltage to moisture value, ranging from 0 (most dry) to 1 (most wet)

Declaration
protected double VoltageToMoisture(Voltage voltage)

Parameters

Type Name Description
Voltage voltage

Returns

Type Description
double

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example

Events

MoistureUpdated

Raised when a new sensor reading has been made. To enable, call StartUpdating().

Declaration
public event EventHandler<IChangeResult<double>> MoistureUpdated

Event Type

Type Description
EventHandler<IChangeResult<double>>

Remarks

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

FC-28 Soil Moisture Sensor is a simple breakout for measuring the moisture in soil and similar materials. The sensor has two probes and measures the resistance between them, which means this sensor is of type Resistive. Since water is conductive, as moisture in the soil increases, the resistance decreases allowing the sensor to determine soil humidity.

The biggest issue of this sensor is the corrosion of the probes, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors. A work-around to prolong the life of the probes is to not constantly have the sensor powered on, but activate it every time the sensor will perform a read using a digital output port connected to the VCC pin. The code and circuit example shows you how to use it.

The following example shows how read the soil moisture every second:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Fc28 fc28;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        fc28 = new Fc28(
            Device.CreateAnalogInputPort(Device.Pins.A01),
            Device.CreateDigitalOutputPort(Device.Pins.D15),
            minimumVoltageCalibration: 3.24f,
            maximumVoltageCalibration: 2.25f
        );

        TestFC28Updating();
    }

    void TestFC28Updating() 
    {
        Console.WriteLine("TestFC28Updating...");

        fc28.Subscribe(new FilterableObserver<FloatChangeResult, float>(
            h => { Console.WriteLine($"Moisture values: {Math.Truncate(h.New)}, old: {Math.Truncate(h.Old)}, delta: {h.DeltaPercent}"); },
            e => { return true; }
        ));

        fc28.Updated += (object sender, FloatChangeResult e) =>
        {
            Console.WriteLine($"Moisture Updated: {e.New}");
        };

        fc28.StartUpdating();
    }
}

Sample projects available on GitHub

Code Example

Fc28 fc28;

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

    fc28 = new Fc28(
        Device.CreateAnalogInputPort(Device.Pins.A01, 5, TimeSpan.FromMilliseconds(40), new Voltage(3.3, Voltage.UnitType.Volts)),
        Device.CreateDigitalOutputPort(Device.Pins.D15),
        minimumVoltageCalibration: new Voltage(3.24f, VU.Volts),
        maximumVoltageCalibration: new Voltage(2.25f, VU.Volts)
    );

    var consumer = Fc28.CreateObserver(
        handler: result =>
        {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a";
            Resolver.Log.Info($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    fc28.Subscribe(consumer);

    fc28.MoistureUpdated += (object sender, IChangeResult<double> e) =>
    {
        Resolver.Log.Info($"Moisture Updated: {e.New}");
    };

    return Task.CompletedTask;
}

public async override Task Run()
{
    var moisture = await fc28.Read();
    Resolver.Log.Info($"Moisture Value {moisture}");

    fc28.StartUpdating(TimeSpan.FromMilliseconds(5000));
}

Sample project(s) available on GitHub

Wiring Example