Skip to content

Commit

Permalink
Merge pull request #1103 from WildernessLabs/bug/ct-interface
Browse files Browse the repository at this point in the history
CTs are ICurrentSensors
  • Loading branch information
adrianstevens authored Dec 27, 2024
2 parents eaf9d4a + 55b2512 commit 44201f8
Showing 1 changed file with 129 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -1,157 +1,157 @@
using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors.Power
namespace Meadow.Foundation.Sensors.Power;

/// <summary>
/// Represents a general Current Transducer (CT) sensor
/// </summary>
public partial class CurrentTransducer : SamplingSensorBase<Current>, ICurrentSensor
{
/// <summary>
/// Represents a general Current Transducer (CT) sensor
/// The analog input port connected to the transducer
/// </summary>
protected IAnalogInputPort AnalogPort { get; private set; } = default!;

/// <summary>
/// The maximum voltage the CT outputs
/// </summary>
protected Voltage MaxVoltage { get; private set; } = default!;

/// <summary>
/// The sensed current at the maximum output voltage
/// </summary>
protected Current MaxCurrent { get; private set; } = default!;

/// <summary>
/// The minimum voltage the CT outputs
/// </summary>
protected Voltage MinVoltage { get; private set; } = default!;

/// <summary>
/// The sensed current at the minimum output voltage
/// </summary>
public partial class CurrentTransducer : SamplingSensorBase<Current>
protected Current MinCurrent { get; private set; } = default!;

/// <summary>
/// The minimum output voltage
/// </summary>
protected Current MinVoltageDelta { get; private set; } = default!;

/// <summary>
/// The last sensed Current
/// </summary>
public Current? Current { get; protected set; }

/// <summary>
/// Creates a new CurrentTransducer instance
/// </summary>
/// <param name="analogPort">The analog input port connected to the transducer</param>
/// <param name="maxVoltage">The maximum voltage the CT outputs</param>
/// <param name="maxCurrent">The sensed current at the maximum output voltage</param>
/// <param name="minVoltage">The minimum voltage the CT outputs</param>
/// <param name="minCurrent">The sensed current at the minimum output voltage</param>
public CurrentTransducer(IAnalogInputPort analogPort, Voltage maxVoltage, Current maxCurrent, Voltage? minVoltage = null, Current? minCurrent = null)
{
/// <summary>
/// The analog input port connected to the transducer
/// </summary>
protected IAnalogInputPort AnalogPort { get; private set; } = default!;

/// <summary>
/// The maximum voltage the CT outputs
/// </summary>
protected Voltage MaxVoltage { get; private set; } = default!;

/// <summary>
/// The sensed current at the maximum output voltage
/// </summary>
protected Current MaxCurrent { get; private set; } = default!;

/// <summary>
/// The minimum voltage the CT outputs
/// </summary>
protected Voltage MinVoltage { get; private set; } = default!;

/// <summary>
/// The sensed current at the minimum output voltage
/// </summary>
protected Current MinCurrent { get; private set; } = default!;

/// <summary>
/// The minimum output voltage
/// </summary>
protected Current MinVoltageDelta { get; private set; } = default!;

/// <summary>
/// The last sensed Current
/// </summary>
public Current? Current { get; protected set; }

/// <summary>
/// Creates a new CurrentTransducer instance
/// </summary>
/// <param name="analogPort">The analog input port connected to the transducer</param>
/// <param name="maxVoltage">The maximum voltage the CT outputs</param>
/// <param name="maxCurrent">The sensed current at the maximum output voltage</param>
/// <param name="minVoltage">The minimum voltage the CT outputs</param>
/// <param name="minCurrent">The sensed current at the minimum output voltage</param>
public CurrentTransducer(IAnalogInputPort analogPort, Voltage maxVoltage, Current maxCurrent, Voltage? minVoltage = null, Current? minCurrent = null)
{
Initialize(analogPort, maxVoltage, maxCurrent, minVoltage, minCurrent);
}
Initialize(analogPort, maxVoltage, maxCurrent, minVoltage, minCurrent);
}

/// <summary>
/// Creates a new CurrentTransducer instance
/// </summary>
protected CurrentTransducer()
{
}
/// <summary>
/// Creates a new CurrentTransducer instance
/// </summary>
protected CurrentTransducer()
{
}

/// <summary>
/// Initializes the CurrentTransducer instance
/// Use this method when a derived class must do pre-initialization work
/// </summary>
/// <param name="analogPort">The analog input port connected to the transducer</param>
/// <param name="maxVoltage">The maximum voltage the CT outputs</param>
/// <param name="maxCurrent">The sensed current at the maximum output voltage</param>
/// <param name="minVoltage">The minimum voltage the CT outputs</param>
/// <param name="minCurrent">The sensed current at the minimum output voltage</param>
protected virtual void Initialize(IAnalogInputPort analogPort, Voltage maxVoltage, Current maxCurrent, Voltage? minVoltage = null, Current? minCurrent = null)
{
AnalogPort = analogPort;
MaxVoltage = maxVoltage;
MaxCurrent = maxCurrent;
MinVoltage = minVoltage ?? new Voltage(0, Voltage.UnitType.Volts);
MinCurrent = minCurrent ?? new Current(0, Units.Current.UnitType.Amps);

AnalogPort.Subscribe
(
IAnalogInputPort.CreateObserver(
result =>
/// <summary>
/// Initializes the CurrentTransducer instance
/// Use this method when a derived class must do pre-initialization work
/// </summary>
/// <param name="analogPort">The analog input port connected to the transducer</param>
/// <param name="maxVoltage">The maximum voltage the CT outputs</param>
/// <param name="maxCurrent">The sensed current at the maximum output voltage</param>
/// <param name="minVoltage">The minimum voltage the CT outputs</param>
/// <param name="minCurrent">The sensed current at the minimum output voltage</param>
protected virtual void Initialize(IAnalogInputPort analogPort, Voltage maxVoltage, Current maxCurrent, Voltage? minVoltage = null, Current? minCurrent = null)
{
AnalogPort = analogPort;
MaxVoltage = maxVoltage;
MaxCurrent = maxCurrent;
MinVoltage = minVoltage ?? new Voltage(0, Voltage.UnitType.Volts);
MinCurrent = minCurrent ?? new Current(0, Units.Current.UnitType.Amps);

AnalogPort.Subscribe
(
IAnalogInputPort.CreateObserver(
result =>
{
ChangeResult<Current> changeResult = new()
{
ChangeResult<Current> changeResult = new()
{
New = ConvertVoltageToCurrent(result.New),
Old = Current
};
Current = changeResult.New;
RaiseEventsAndNotify(changeResult);
}
)
);
}
New = ConvertVoltageToCurrent(result.New),
Old = Current
};
Current = changeResult.New;
RaiseEventsAndNotify(changeResult);
}
)
);
}

/// <summary>
/// Converts an output voltage from the CT to a sensed current using linear interpolation
/// </summary>
/// <param name="voltage">The ADC voltage read by the AnalogPort</param>
/// <returns>The current being sensed by the CT</returns>
protected virtual Current ConvertVoltageToCurrent(Voltage voltage)
{
// the default implementation just does a simple linear conversion
return new Current(
(MaxCurrent.Amps - MinCurrent.Amps) /
(MaxVoltage.Volts - MinVoltage.Volts)
* voltage.Volts);
}
/// <summary>
/// Converts an output voltage from the CT to a sensed current using linear interpolation
/// </summary>
/// <param name="voltage">The ADC voltage read by the AnalogPort</param>
/// <returns>The current being sensed by the CT</returns>
protected virtual Current ConvertVoltageToCurrent(Voltage voltage)
{
// the default implementation just does a simple linear conversion
return new Current(
(MaxCurrent.Amps - MinCurrent.Amps) /
(MaxVoltage.Volts - MinVoltage.Volts)
* voltage.Volts);
}

///<inheritdoc/>
protected override async Task<Current> ReadSensor()
{
var adc = await AnalogPort.Read();
var newCurrent = ConvertVoltageToCurrent(adc);
Current = newCurrent;
return newCurrent;
}
///<inheritdoc/>
protected override async Task<Current> ReadSensor()
{
var adc = await AnalogPort.Read();
var newCurrent = ConvertVoltageToCurrent(adc);
Current = newCurrent;
return newCurrent;
}

///<inheritdoc/>
public override void StartUpdating(TimeSpan? updateInterval = null)
///<inheritdoc/>
public override void StartUpdating(TimeSpan? updateInterval = null)
{
lock (samplingLock)
{
lock (samplingLock)
{
if (IsSampling) return;
IsSampling = true;
if (IsSampling) return;
IsSampling = true;

base.SamplingTokenSource = new CancellationTokenSource();
CancellationToken ct = SamplingTokenSource.Token;
base.SamplingTokenSource = new CancellationTokenSource();
CancellationToken ct = SamplingTokenSource.Token;

AnalogPort.StartUpdating(updateInterval);
}
AnalogPort.StartUpdating(updateInterval);
}
}

///<inheritdoc/>
public override void StopUpdating()
///<inheritdoc/>
public override void StopUpdating()
{
lock (samplingLock)
{
lock (samplingLock)
{
if (!IsSampling) return;
if (!IsSampling) return;

AnalogPort.StopUpdating();
AnalogPort.StopUpdating();

SamplingTokenSource?.Cancel();
SamplingTokenSource?.Cancel();

// state machine
IsSampling = false;
}
// state machine
IsSampling = false;
}
}
}

0 comments on commit 44201f8

Please sign in to comment.