Remarks

Capacitive
Status
Source code GitHub
NuGet package

Capacitive Soil Moisture sensor is a simple breakout for measuring the moisture in soil and similar materials. This sensor measures moisture levels by capacitive sensing, rather then resistive sensing like other types of moisture sensor such as the FC-28.

Capacitive sensing means measuring the dielectrum that is formed by the soil and the water is the most important factor that forms the dielectrum. Even though this kind of sensor might be a little pricier, it is made of corrosion resistant material giving it a longer service of life than a resistive sensor.

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

public class MeadowApp : App<F7Micro, MeadowApp>
{
    Capacitive _Capacitive;

    public MeadowApp()
    {
        // create a new Capacitive sensor object connected to analog pin A01
        _Capacitive = new Capacitive(Device.Pins.A01);

        Run();
    }

    async Task Run()
    {
        while (true)
        {
            float moisture = await _Capacitive.Read();
            Console.WriteLine($"Moisture: {0}", moisture);
            Thread.Sleep(1000);
        }
    }
}

Sample projects available on GitHub

Code Example

Capacitive capacitive;

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

    capacitive = new Capacitive(
        analogPort: Device.CreateAnalogInputPort(Device.Pins.A00),
        minimumVoltageCalibration: new Voltage(2.84f),
        maximumVoltageCalibration: new Voltage(1.63f)
    );

    // Example that uses an IObservable subscription to only be notified when the humidity changes by filter defined.
    var consumer = Capacitive.CreateObserver(
        handler: result => {
            // the first time through, old will be null.
            string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a"; // C# 8 pattern matching
            Console.WriteLine($"Subscribed - " +
                $"new: {result.New}, " +
                $"old: {oldValue}");
        },
        filter: null
    );
    capacitive.Subscribe(consumer);

    // classical .NET events can also be used:
    capacitive.HumidityUpdated += (sender, result) =>
    {   // the first time through, old will be null.
        string oldValue = (result.Old is { } old) ? $"{old:n2}" : "n/a"; // C# 8 pattern matching
        Console.WriteLine($"Updated - New: {result.New}, Old: {oldValue}");
    };

    // Get an initial reading.
    ReadMoisture().Wait();

    // Spin up the sampling thread so that events are raised and IObservable notifications are sent.
    capacitive.StartUpdating(TimeSpan.FromSeconds(5));
}

protected async Task ReadMoisture()
{
    var moisture = await capacitive.Read();
    Console.WriteLine($"Moisture New Value { moisture }");            
}

Sample project(s) available on GitHub

Wiring Example

Characteristic Locus
Inheritance System.Object ObservableBase<System.Double> SensorBase<System.Double> > Capacitive
Implements IMoistureSensor
Inherited Members SensorBase<Double>.Updated SensorBase<Double>.samplingLock SensorBase<Double>.SamplingTokenSource SensorBase<Double>.Conditions SensorBase<Double>.IsSampling SensorBase<Double>.UpdateInterval SensorBase<Double>.RaiseEventsAndNotify(IChangeResult<>) SensorBase<Double>.Read() ObservableBase<Double>.observers ObservableBase<Double>.NotifyObservers(IChangeResult<>) Meadow.Foundation.ObservableBase<System.Double>.Subscribe(IObserver<>) Meadow.Foundation.ObservableBase<System.Double>.CreateObserver(Action<>, System.Nullable<Predicate<IChangeResult<UNIT>>>)
Namespace Meadow.Foundation.Sensors.Moisture
Assembly Capacitive.dll

Syntax

public class Capacitive : SensorBase<double>, IMoistureSensor

Constructors

Capacitive(IAnalogInputController, IPin, Nullable<Voltage>, Nullable<Voltage>, Int32, Int32)

Creates a Capacitive soil moisture sensor object with the specified analog pin and a IO device.

Declaration
public Capacitive(IAnalogInputController device, IPin analogPin, Voltage? minimumVoltageCalibration, Voltage? maximumVoltageCalibration, int sampleCount = 5, int sampleIntervalMs = 40)

Parameters

Type Name Description
IAnalogInputController device

The IAnalogInputController to create the port on.

IPin analogPin

Analog pin the temperature sensor is connected to.

System.Nullable<Voltage> minimumVoltageCalibration
System.Nullable<Voltage> maximumVoltageCalibration
System.Int32 sampleCount

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

System.Int32 sampleIntervalMs

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

Capacitive(IAnalogInputPort, Nullable<Voltage>, Nullable<Voltage>)

Creates a Capacitive soil moisture sensor object with the especified AnalogInputPort.

Declaration
public Capacitive(IAnalogInputPort analogPort, Voltage? minimumVoltageCalibration, Voltage? maximumVoltageCalibration)

Parameters

Type Name Description
IAnalogInputPort analogPort
System.Nullable<Voltage> minimumVoltageCalibration
System.Nullable<Voltage> maximumVoltageCalibration

Properties

AnalogInputPort

Returns the analog input port

Declaration
public IAnalogInputPort AnalogInputPort { get; protected set; }

Property Value

Type Description
IAnalogInputPort

MaximumVoltageCalibration

Voltage value of most moist soil. Default of 3.3V.

Declaration
public Voltage MaximumVoltageCalibration { get; set; }

Property Value

Type Description
Voltage

MinimumVoltageCalibration

Voltage value of most dry soil. Default of 0V.

Declaration
public Voltage MinimumVoltageCalibration { get; set; }

Property Value

Type Description
Voltage

Moisture

Last value read from the moisture sensor.

Declaration
public double? Moisture { get; protected set; }

Property Value

Type Description
System.Nullable<System.Double>

Methods

RaiseChangedAndNotify(IChangeResult<Double>)

Declaration
protected void RaiseChangedAndNotify(IChangeResult<double> changeResult)

Parameters

Type Name Description
IChangeResult<System.Double> changeResult

ReadSensor()

Declaration
protected override Task<double> ReadSensor()

Returns

Type Description
Task<System.Double>

Overrides

Meadow.Foundation.SensorBase<System.Double>.ReadSensor()

StartUpdating(TimeSpan)

Starts continuously sampling the sensor.

This method also starts raising Updated events and IObservable subscribers getting notified. Use the standbyDuration parameter to specify how often events and notifications are raised/sent.

Declaration
public void StartUpdating(TimeSpan updateInterval)

Parameters

Type Name Description
TimeSpan updateInterval

A TimeSpan that specifies how long to wait between readings. This value influences how often *Updated events are raised and IObservable consumers are notified. The default is 5 seconds.

StopUpdating()

Stops sampling the sensor.

Declaration
public void StopUpdating()

VoltageToMoisture(Voltage)

Declaration
protected double VoltageToMoisture(Voltage voltage)

Parameters

Type Name Description
Voltage voltage

Returns

Type Description
System.Double

Events

HumidityUpdated

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

Declaration
public event EventHandler<IChangeResult<double>> HumidityUpdated

Event Type

Type Description
EventHandler<IChangeResult<System.Double>>