Skip to content

Commit

Permalink
Update LedBarGraph and PwmLedBarGraph drivers with samples
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgedevs committed Aug 16, 2022
1 parent ebf5813 commit a29d468
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,22 @@ public override async Task Run()

Console.WriteLine("Blinking for 3 seconds...");
ledBarGraph.StartBlink();
await Task.Delay(3000);
await Task.Delay(5000);
ledBarGraph.Stop();

await Task.Delay(1000);

Console.WriteLine("Blinking for 3 seconds...");
ledBarGraph.StartBlink(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
await Task.Delay(3000);
ledBarGraph.StartBlink(TimeSpan.FromSeconds(500), TimeSpan.FromSeconds(500));
await Task.Delay(5000);
ledBarGraph.Stop();

await Task.Delay(1000);

for (int i = 0; i < ledBarGraph.Count; i++)
{
ledBarGraph.SetLed(i, false);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Leds.PwmLedBarGraph_Sample
{
public class MeadowApp : App<F7FeatherV2>
public class MeadowApp : App<F7FeatherV1>
{
//<!=SNIP=>

Expand All @@ -32,7 +32,8 @@ public override Task Initialize()
Device.Pins.D03,
Device.Pins.D02
};
pwmLedBarGraph = new PwmLedBarGraph(Device, pins, new Voltage(3.3));

pwmLedBarGraph = new PwmLedBarGraph(Device, pins, new Voltage(2.2));

return Task.CompletedTask;
}
Expand Down Expand Up @@ -85,24 +86,29 @@ public override async Task Run()

Console.WriteLine("Bar blinking on and off...");
pwmLedBarGraph.StartBlink();
await Task.Delay(3000);
await Task.Delay(5000);
pwmLedBarGraph.Stop();

await Task.Delay(1000);

Console.WriteLine("Bar blinking with high and low brightness...");
pwmLedBarGraph.StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), 1f, 0.25f);
await Task.Delay(3000);
await Task.Delay(5000);
pwmLedBarGraph.Stop();

await Task.Delay(1000);

Console.WriteLine("Bar pulsing...");
pwmLedBarGraph.StartPulse();
await Task.Delay(3000);
await Task.Delay(5000);
pwmLedBarGraph.Stop();

await Task.Delay(1000);

for (int i = pwmLedBarGraph.Count - 1; i >= 0; i--)
{
pwmLedBarGraph.SetLed(i, false);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions Source/Meadow.Foundation.Core/Leds/LedBarGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public double Percentage
/// <summary>
/// Create an LedBarGraph instance from an array of IPins
/// </summary>
/// <param name="device"></param>
/// <param name="pins"></param>
public LedBarGraph(IDigitalOutputController device, IPin[] pins)
{
leds = new Led[pins.Length];
Expand All @@ -57,6 +59,7 @@ public LedBarGraph(IDigitalOutputController device, IPin[] pins)
/// <summary>
/// Create an LedBarGraph instance from an array of IDigitalOutputPort
/// </summary>
/// <param name="ports"></param>
public LedBarGraph(IDigitalOutputPort[] ports)
{
leds = new Led[ports.Length];
Expand Down
149 changes: 131 additions & 18 deletions Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using Meadow.Hardware;
using Meadow.Units;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Foundation.Leds
{
Expand All @@ -10,11 +12,21 @@ namespace Meadow.Foundation.Leds
/// </summary>
public class PwmLedBarGraph
{
private const int NONE_LED_BLINKING = -1;

private Task? animationTask;
private CancellationTokenSource? cancellationTokenSource;

/// <summary>
/// Array to hold pwm leds for bar graph
/// </summary>
protected PwmLed[] pwmLeds;

/// <summary>
/// Index of specific LED blinking
/// </summary>
protected int indexLedBlinking = NONE_LED_BLINKING;

/// <summary>
/// The number of the LEDs in the bar graph
/// </summary>
Expand All @@ -23,12 +35,12 @@ public class PwmLedBarGraph
/// <summary>
/// A value between 0 and 1 that controls the number of LEDs that are activated
/// </summary>
public float Percentage
public double Percentage
{
get => percentage;
set => SetPercentage(percentage = value);
}
float percentage;
double percentage;

/// <summary>
/// Create an LedBarGraph instance for single color LED bar graphs
Expand Down Expand Up @@ -96,14 +108,14 @@ public PwmLedBarGraph(IPwmPort[] ports, Voltage[] forwardVoltage)
/// Set the percentage of LEDs that are on starting from index 0
/// </summary>
/// <param name="percentage">Percentage (Range from 0 - 1)</param>
void SetPercentage(float percentage)
void SetPercentage(double percentage)
{
if (percentage < 0 || percentage > 1)
{
throw new ArgumentOutOfRangeException();
}

float value = percentage * Count;
var value = percentage * Count;

for (int i = 1; i <= Count; i++)
{
Expand Down Expand Up @@ -152,7 +164,7 @@ public void SetLed(int index, bool isOn)
/// </summary>
/// <param name="index"></param>
/// <param name="brightness"></param>
public void SetLedBrightness(int index, float brightness)
public void SetLedBrightness(int index, double brightness)
{
if (index >= Count)
{
Expand All @@ -161,7 +173,7 @@ public void SetLedBrightness(int index, float brightness)

pwmLeds[index].Stop();
pwmLeds[index].IsOn = false;
pwmLeds[index].Brightness = brightness;
pwmLeds[index].Brightness = (float)brightness;
}

/// <summary>
Expand Down Expand Up @@ -242,10 +254,14 @@ public void SetLedPulse(int index, TimeSpan pulseDuration, float highBrightness
/// <param name="lowBrightness">Low brightness.</param>
public void StartBlink(float highBrightness = 1, float lowBrightness = 0)
{
foreach (var pwmLed in pwmLeds)
Stop();

animationTask = new Task(async () =>
{
pwmLed.StartBlink(highBrightness, lowBrightness);
}
cancellationTokenSource = new CancellationTokenSource();
await StartBlinkAsync(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), highBrightness, lowBrightness, cancellationTokenSource.Token);
});
animationTask.Start();
}

/// <summary>
Expand All @@ -257,9 +273,50 @@ public void StartBlink(float highBrightness = 1, float lowBrightness = 0)
/// <param name="lowBrightness">Low brightness.</param>
public void StartBlink(TimeSpan onDuration, TimeSpan offDuration, float highBrightness = 1, float lowBrightness = 0)
{
foreach (var pwmLed in pwmLeds)
Stop();

animationTask = new Task(async () =>
{
cancellationTokenSource = new CancellationTokenSource();
await StartBlinkAsync(onDuration, offDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
});
animationTask.Start();
}

/// <summary>
/// Set LED to blink
/// </summary>
/// <param name="onDuration"></param>
/// <param name="offDuration"></param>
/// <param name="highBrightness"></param>
/// <param name="lowBrightness"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected async Task StartBlinkAsync(TimeSpan onDuration, TimeSpan offDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
{
while (true)
{
pwmLed.StartBlink(onDuration, offDuration, highBrightness, lowBrightness);
if (cancellationToken.IsCancellationRequested)
{
break;
}

foreach (var led in pwmLeds)
{
led.Brightness = highBrightness;
}
await Task.Delay(onDuration);

if (cancellationToken.IsCancellationRequested)
{
break;
}

foreach (var led in pwmLeds)
{
led.Brightness = lowBrightness;
}
await Task.Delay(offDuration);
}
}

Expand All @@ -283,10 +340,14 @@ public void StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
throw new Exception("lowBrightness must be less than highbrightness");
}

foreach (var pwmLed in pwmLeds)
Stop();

animationTask = new Task(async () =>
{
pwmLed.StartPulse(highBrightness, lowBrightness);
}
cancellationTokenSource = new CancellationTokenSource();
await StartPulseAsync(TimeSpan.FromSeconds(1), highBrightness, lowBrightness, cancellationTokenSource.Token);
});
animationTask.Start();
}

/// <summary>
Expand All @@ -310,9 +371,56 @@ public void StartPulse(TimeSpan pulseDuration, float highBrightness = 1, float l
throw new Exception("lowBrightness must be less than highbrightness");
}

foreach (var pwmLed in pwmLeds)
Stop();

animationTask = new Task(async () =>
{
cancellationTokenSource = new CancellationTokenSource();
await StartPulseAsync(pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
});
animationTask.Start();
}

/// <summary>
/// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
/// </summary>
/// <param name="pulseDuration"></param>
/// <param name="highBrightness"></param>
/// <param name="lowBrightness"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected async Task StartPulseAsync(TimeSpan pulseDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
{
float brightness = lowBrightness;
bool ascending = true;
TimeSpan intervalTime = TimeSpan.FromMilliseconds(60); // 60 miliseconds is probably the fastest update we want to do, given that threads are given 20 miliseconds by default.
float steps = (float)(pulseDuration.TotalMilliseconds / intervalTime.TotalMilliseconds);
float delta = (highBrightness - lowBrightness) / steps;

while (true)
{
pwmLed.StartPulse(pulseDuration, highBrightness, lowBrightness);
if (cancellationToken.IsCancellationRequested)
{
break;
}

if (brightness <= lowBrightness)
{
ascending = true;
}
else if (brightness >= highBrightness)
{
ascending = false;
}

brightness += delta * (ascending ? 1 : -1);

foreach (var led in pwmLeds)
{
led.Brightness = Math.Clamp(brightness, 0, 1);
}

await Task.Delay(intervalTime);
}
}

Expand All @@ -321,9 +429,14 @@ public void StartPulse(TimeSpan pulseDuration, float highBrightness = 1, float l
/// </summary>
public void Stop()
{
foreach (var pwmLed in pwmLeds)
if (indexLedBlinking != NONE_LED_BLINKING)
{
pwmLeds[indexLedBlinking].Stop();
indexLedBlinking = NONE_LED_BLINKING;
}
else
{
pwmLed.Stop();
cancellationTokenSource?.Cancel();
}
}
}
Expand Down

0 comments on commit a29d468

Please sign in to comment.