From eb36c9ee06f59830bab693f941c5cab4b7baa321 Mon Sep 17 00:00:00 2001 From: Chris Tacke Date: Wed, 1 Jan 2025 17:00:26 -0600 Subject: [PATCH] implement signal analyzer in platforms --- .../Hardware/SoftDigitalSignalAnalyzer.cs | 132 ------------------ .../desktop/Meadow.Desktop/Desktop.cs | 3 + .../linux/Meadow.Linux/Linux.cs | 6 + Source/implementations/mac/Meadow.Mac/Mac.cs | 5 + .../windows/Meadow.Windows/Windows.cs | 5 + 5 files changed, 19 insertions(+), 132 deletions(-) delete mode 100644 Source/Meadow.Core/Hardware/SoftDigitalSignalAnalyzer.cs diff --git a/Source/Meadow.Core/Hardware/SoftDigitalSignalAnalyzer.cs b/Source/Meadow.Core/Hardware/SoftDigitalSignalAnalyzer.cs deleted file mode 100644 index 607a48891..000000000 --- a/Source/Meadow.Core/Hardware/SoftDigitalSignalAnalyzer.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Meadow.Units; -using System; -using System.Linq; - -namespace Meadow.Hardware; - -/// -/// Implements frequency and duty cycle analysis of digital signals using software-based timing measurements. -/// -public class SoftDigitalSignalAnalyzer : IDigitalSignalAnalyzer, IDisposable -{ - private IDigitalInterruptPort _inputPort; - private bool _portCreated = false; - private bool _captureDutyCycle = false; - private readonly CircularBuffer _periodQueue = new(10); - private int _mostRecentPeriod; - private int _rising; - private int _falling; - private double _duty; - - /// - /// Returns true if the analyzer has been disposed - /// - public bool IsDisposed { get; private set; } - - /// - /// Initializes a new instance of the class to monitor a single digital input pin. - /// - /// The digital input pin to monitor. - /// The digital input pin's resistor mode. - /// Whether or not to capture duty cycle. Not capturing it is more efficient and allows faster frequency capture - public SoftDigitalSignalAnalyzer(IPin pin, ResistorMode resistorMode = ResistorMode.InternalPullDown, bool captureDutyCycle = true) - { - var edge = captureDutyCycle ? InterruptMode.EdgeBoth : InterruptMode.EdgeRising; - - _inputPort = pin.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode); - _portCreated = true; - _captureDutyCycle = captureDutyCycle; - Initialize(); - } - - /// - /// Initializes a new instance of the class to monitor a digital input port. - /// - /// The digital interrupt port to monitor. - /// Whether or not to capture duty cycle. Not capturing it is more efficient and allows faster frequency capture - public SoftDigitalSignalAnalyzer(IDigitalInterruptPort port, bool captureDutyCycle = true) - { - _inputPort = port; - _captureDutyCycle = captureDutyCycle; - Initialize(); - } - - private void Initialize() - { - _inputPort.Changed += OnInterrupt; - } - - private void OnInterrupt(object sender, DigitalPortResult e) - { - switch (e.New.State) - { - case false: - if (_captureDutyCycle) - { - _falling = Environment.TickCount; - } - break; - case true: - var now = Environment.TickCount; - _mostRecentPeriod = Math.Abs(now - _rising); - _periodQueue.Append(_mostRecentPeriod); - if (_captureDutyCycle) - { - _duty = 1.0 - ((now - _falling) / (double)_mostRecentPeriod); - } - _rising = now; - - - break; - } - } - - /// - public double GetDutyCycle() - { - return _duty; - } - - /// - public Frequency GetMeanFrequency() - { - if (_periodQueue.Count == 0) { return Frequency.Zero; } - - return new Frequency(1000d / _periodQueue.Average(), Frequency.UnitType.Hertz); - } - - /// - public Frequency GetFrequency() - { - if (_mostRecentPeriod == 0) return Frequency.Zero; - - return new Frequency(1000d / _mostRecentPeriod); - } - - /// - protected virtual void Dispose(bool disposing) - { - if (!IsDisposed) - { - if (disposing) - { - _inputPort.Changed -= OnInterrupt; - - if (_portCreated) - { - _inputPort.Dispose(); - } - } - - IsDisposed = true; - } - } - - /// - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } -} diff --git a/Source/implementations/desktop/Meadow.Desktop/Desktop.cs b/Source/implementations/desktop/Meadow.Desktop/Desktop.cs index 551dab06d..0298a2cf0 100644 --- a/Source/implementations/desktop/Meadow.Desktop/Desktop.cs +++ b/Source/implementations/desktop/Meadow.Desktop/Desktop.cs @@ -131,6 +131,9 @@ public void WatchdogReset() /// public ICounter CreateCounter(IPin pin, InterruptMode edge) => _implementation.CreateCounter(pin, edge); + /// + public IDigitalSignalAnalyzer CreateDigitalSignalAnalyzer(IPin pin, bool captureDutyCycle) + => _implementation.CreateDigitalSignalAnalyzer(pin, captureDutyCycle); } diff --git a/Source/implementations/linux/Meadow.Linux/Linux.cs b/Source/implementations/linux/Meadow.Linux/Linux.cs index faac4a004..110cbbf6f 100644 --- a/Source/implementations/linux/Meadow.Linux/Linux.cs +++ b/Source/implementations/linux/Meadow.Linux/Linux.cs @@ -310,6 +310,12 @@ internal static string ExecuteCommandLine(string command, string args) return process?.StandardOutput.ReadToEnd() ?? string.Empty; } + /// + public IDigitalSignalAnalyzer CreateDigitalSignalAnalyzer(IPin pin, bool captureDutyCycle) + { + return new SoftDigitalSignalAnalyzer(pin, captureDutyCycle: captureDutyCycle); + } + // ---------------------------------------------- // ---------------------------------------------- // ----- BELOW HERE ARE NOT YET IMPLEMENTED ----- diff --git a/Source/implementations/mac/Meadow.Mac/Mac.cs b/Source/implementations/mac/Meadow.Mac/Mac.cs index 76b2a7dd9..e0e1d7daf 100644 --- a/Source/implementations/mac/Meadow.Mac/Mac.cs +++ b/Source/implementations/mac/Meadow.Mac/Mac.cs @@ -108,6 +108,11 @@ public IDigitalOutputPort CreateDigitalOutputPort(IPin pin, bool initialState = throw new NotSupportedException("Add an IO Expander to your platform"); } + /// + public IDigitalSignalAnalyzer CreateDigitalSignalAnalyzer(IPin pin, bool captureDutyCycle) + { + throw new NotSupportedException("Add an IO Expander to your platform"); + } /// public ISerialPort CreateSerialPort(string portName, int baudRate = 9600, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One, int readBufferSize = 1024) diff --git a/Source/implementations/windows/Meadow.Windows/Windows.cs b/Source/implementations/windows/Meadow.Windows/Windows.cs index 2051209b9..d5cfdde67 100644 --- a/Source/implementations/windows/Meadow.Windows/Windows.cs +++ b/Source/implementations/windows/Meadow.Windows/Windows.cs @@ -95,6 +95,11 @@ public IDigitalOutputPort CreateDigitalOutputPort(IPin pin, bool initialState = throw new NotSupportedException("Add an IO Expander to your platform"); } + /// + public IDigitalSignalAnalyzer CreateDigitalSignalAnalyzer(IPin pin, bool captureDutyCycle) + { + throw new NotSupportedException("Add an IO Expander to your platform"); + } public ISerialPort CreateSerialPort(string portName, int baudRate = 9600, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One, int readBufferSize = 1024) {