diff --git a/Source/Meadow.Foundation.Core.Samples/Audio.PiezoSpeaker_Sample/Audio.PiezoSpeaker_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Audio.PiezoSpeaker_Sample/Audio.PiezoSpeaker_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Audio.PiezoSpeaker_Sample/Audio.PiezoSpeaker_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Audio.PiezoSpeaker_Sample/Audio.PiezoSpeaker_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Generators.SoftPwmPort_Sample/Generators.SoftPwmPort_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Generators.SoftPwmPort_Sample/Generators.SoftPwmPort_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Generators.SoftPwmPort_Sample/Generators.SoftPwmPort_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Generators.SoftPwmPort_Sample/Generators.SoftPwmPort_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/Leds.LedBarGraph_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/Leds.LedBarGraph_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/Leds.LedBarGraph_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/Leds.LedBarGraph_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/MeadowApp.cs
index 988f075e79..12e4e052b7 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.LedBarGraph_Sample/MeadowApp.cs
@@ -48,9 +48,9 @@ public override async Task Run()
Resolver.Log.Info("Turning them on and off for 200ms using SetLed...");
for (int i = 0; i < ledBarGraph.Count; i++)
{
- ledBarGraph.SetLed(i, true);
+ await ledBarGraph.SetLed(i, true);
await Task.Delay(100);
- ledBarGraph.SetLed(i, false);
+ await ledBarGraph.SetLed(i, false);
}
await Task.Delay(1000);
@@ -59,8 +59,7 @@ public override async Task Run()
while (percentage < 1)
{
percentage += 0.10f;
- Resolver.Log.Info($"{percentage}");
- ledBarGraph.Percentage = Math.Min(1.0f, percentage);
+ await ledBarGraph.SetPercentage(Math.Min(1.0f, percentage));
await Task.Delay(100);
}
@@ -70,8 +69,7 @@ public override async Task Run()
while (percentage > 0)
{
percentage -= 0.10f;
- Resolver.Log.Info($"{percentage}");
- ledBarGraph.Percentage = Math.Max(0.0f, percentage);
+ await ledBarGraph.SetPercentage(Math.Max(0.0f, percentage));
await Task.Delay(100);
}
@@ -81,9 +79,8 @@ public override async Task Run()
while (percentage < 1)
{
percentage += 0.10f;
- Resolver.Log.Info($"{percentage}");
- ledBarGraph.Percentage = Math.Min(1.0f, percentage);
- ledBarGraph.StartBlink(ledBarGraph.GetTopLedForPercentage());
+ await ledBarGraph.SetPercentage(Math.Min(1.0f, percentage));
+ await ledBarGraph.StartBlink(ledBarGraph.GetTopLedForPercentage());
await Task.Delay(2000);
}
@@ -93,25 +90,24 @@ public override async Task Run()
while (percentage > 0)
{
percentage -= 0.10f;
- Resolver.Log.Info($"{percentage}");
- ledBarGraph.Percentage = Math.Max(0.0f, percentage);
- ledBarGraph.StartBlink(ledBarGraph.GetTopLedForPercentage());
+ await ledBarGraph.SetPercentage(Math.Max(0.0f, percentage));
+ await ledBarGraph.StartBlink(ledBarGraph.GetTopLedForPercentage());
await Task.Delay(2000);
}
await Task.Delay(1000);
Resolver.Log.Info("Blinking for 5 seconds at 500ms on/off...");
- ledBarGraph.StartBlink();
+ await ledBarGraph.StartBlink();
await Task.Delay(5000);
- ledBarGraph.Stop();
+ await ledBarGraph.StopAnimation();
await Task.Delay(1000);
Resolver.Log.Info("Blinking for 5 seconds at 200ms on/off...");
- ledBarGraph.StartBlink(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(200));
+ await ledBarGraph.StartBlink(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(200));
await Task.Delay(5000);
- ledBarGraph.Stop();
+ await ledBarGraph.StopAnimation();
await Task.Delay(1000);
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/Leds.Led_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/Leds.Led_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/Leds.Led_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/Leds.Led_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/MeadowApp.cs
index bf4f9a81b9..a1303f7ee4 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.Led_Sample/MeadowApp.cs
@@ -1,7 +1,6 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Leds;
-using Meadow.Peripherals.Leds;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -74,17 +73,17 @@ public override async Task Run()
Resolver.Log.Info("Blinking the LEDs for a second each");
foreach (var led in leds)
{
- led.StartBlink();
+ await led.StartBlink();
await Task.Delay(3000);
- led.Stop();
+ await led.StopAnimation();
}
Resolver.Log.Info("Blinking the LEDs for a second each with on (1s) and off (1s)");
foreach (var led in leds)
{
- led.StartBlink(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
+ await led.StartBlink(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
await Task.Delay(3000);
- led.Stop();
+ await led.StopAnimation();
}
await Task.Delay(3000);
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/Leds.PwmLedBarGraph_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/Leds.PwmLedBarGraph_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/Leds.PwmLedBarGraph_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/Leds.PwmLedBarGraph_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/MeadowApp.cs
index aad8f9dce8..9432f55a9f 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLedBarGraph_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Leds;
using Meadow.Hardware;
-using Meadow.Peripherals.Leds;
using Meadow.Units;
using System;
using System.Threading.Tasks;
@@ -50,9 +49,9 @@ public override async Task Run()
Resolver.Log.Info("Turning them on and off for 200ms using SetLed...");
for (int i = 0; i < pwmLedBarGraph.Count; i++)
{
- pwmLedBarGraph.SetLed(i, true);
+ await pwmLedBarGraph.SetLed(i, true);
await Task.Delay(100);
- pwmLedBarGraph.SetLed(i, false);
+ await pwmLedBarGraph.SetLed(i, false);
}
await Task.Delay(1000);
@@ -61,7 +60,7 @@ public override async Task Run()
while (percentage < 1)
{
percentage += 0.01f;
- pwmLedBarGraph.Percentage = Math.Min(1.0f, percentage);
+ await pwmLedBarGraph.SetPercentage(Math.Min(1.0f, percentage));
await Task.Delay(100);
}
@@ -71,30 +70,34 @@ public override async Task Run()
while (percentage > 0)
{
percentage -= 0.01f;
- pwmLedBarGraph.Percentage = Math.Max(0.0f, percentage);
+ await pwmLedBarGraph.SetPercentage(Math.Max(0.0f, percentage));
await Task.Delay(100);
}
await Task.Delay(1000);
Resolver.Log.Info("Blinking for 5 seconds at 500ms on/off...");
- pwmLedBarGraph.StartBlink();
+ await pwmLedBarGraph.StartBlink();
await Task.Delay(5000);
- pwmLedBarGraph.Stop();
+ await pwmLedBarGraph.StopAnimation();
await Task.Delay(1000);
Resolver.Log.Info("Bar blinking with high and low brightness for 5 seconds...");
- pwmLedBarGraph.StartBlink(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(200), 0.75f, 0.25f);
+ await pwmLedBarGraph.StartBlink(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(200), 0.75f, 0.25f);
await Task.Delay(5000);
- pwmLedBarGraph.Stop();
+ await pwmLedBarGraph.StopAnimation();
await Task.Delay(1000);
Resolver.Log.Info("Bar pulsing for 5 seconds...");
- pwmLedBarGraph.StartPulse();
+ await pwmLedBarGraph.StartPulse();
await Task.Delay(5000);
- pwmLedBarGraph.Stop();
+ await pwmLedBarGraph.StopAnimation();
+
+ await Task.Delay(1000);
+
+ await pwmLedBarGraph.SetBrightness(0);
await Task.Delay(1000);
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/Leds.PwmLed_Onboard_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/Leds.PwmLed_Onboard_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/Leds.PwmLed_Onboard_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/Leds.PwmLed_Onboard_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/MeadowApp.cs
index 4db48f0ac5..34b36e656a 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Onboard_Sample/MeadowApp.cs
@@ -21,7 +21,7 @@ public override Task Initialize()
redPwmLed = new PwmLed(Device.Pins.OnboardLedRed, TypicalForwardVoltage.ResistorLimited, CircuitTerminationType.High);
greenPwmLed = new PwmLed(Device.Pins.OnboardLedGreen, TypicalForwardVoltage.ResistorLimited, CircuitTerminationType.High);
bluePwmLed = new PwmLed(Device.Pins.OnboardLedBlue, TypicalForwardVoltage.ResistorLimited, CircuitTerminationType.High);
-
+
return Task.CompletedTask;
}
@@ -29,51 +29,51 @@ public override Task Run()
{
return PulseLeds();
}
-
+
public async Task BrightnessTest(int loopCount)
{
- for (int i = 0; i < loopCount; i++) {
+ for (int i = 0; i < loopCount; i++)
+ {
Resolver.Log.Info("Blue On @ 1.0");
- bluePwmLed.Brightness = 1;
+ bluePwmLed.SetBrightness(1);
await Task.Delay(1000);
Resolver.Log.Info("Blue at 98.5%");
- bluePwmLed.Brightness = 0.985f;
+ bluePwmLed.SetBrightness(0.985f);
await Task.Delay(1000);
Resolver.Log.Info("Blue Off");
- bluePwmLed.Brightness = 0;
+ bluePwmLed.SetBrightness(0);
await Task.Delay(1000);
Resolver.Log.Info("Blue 50%");
- bluePwmLed.Brightness = 0.5f;
+ bluePwmLed.SetBrightness(0.5f);
await Task.Delay(1000);
- bluePwmLed.Stop();
+ await bluePwmLed.StopAnimation();
}
}
public async Task PulseLeds()
{
- while (true)
+ while (true)
{
Resolver.Log.Info("Pulse Red.");
- redPwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.05f);
+ await redPwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.05f);
await Task.Delay(1000);
Resolver.Log.Info("Stop Red.");
- redPwmLed.Stop();
+ await redPwmLed.StopAnimation();
Resolver.Log.Info("Pulse Blue.");
- bluePwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.05f);
+ await bluePwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.05f);
await Task.Delay(2000);
Resolver.Log.Info("Stop Blue.");
- bluePwmLed.Stop();
+ await bluePwmLed.StopAnimation();
Resolver.Log.Info("Pulse Green.");
- greenPwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.0f);
+ await greenPwmLed.StartPulse(TimeSpan.FromMilliseconds(500), lowBrightness: 0.0f);
await Task.Delay(2000);
Resolver.Log.Info("Stop Green.");
- greenPwmLed.Stop();
-
+ await greenPwmLed.StopAnimation();
}
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/Leds.PwmLed_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/Leds.PwmLed_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/Leds.PwmLed_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/Leds.PwmLed_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/MeadowApp.cs
index 0778b2a917..c1e511c8a9 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.PwmLed_Sample/MeadowApp.cs
@@ -1,7 +1,6 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Leds;
-using Meadow.Peripherals.Leds;
using Meadow.Units;
using System;
using System.Collections.Generic;
@@ -62,42 +61,33 @@ public override async Task Run()
await Task.Delay(1000);
- Resolver.Log.Info("Blinking the LED for a bit.");
+ Resolver.Log.Info("Blinking each LED (on 500ms / off 500ms)");
foreach (var pwmLed in pwmLeds)
{
- pwmLed.StartBlink();
+ await pwmLed.StartBlink();
await Task.Delay(3000);
- pwmLed.Stop();
+ await pwmLed.StopAnimation();
}
await Task.Delay(1000);
- Resolver.Log.Info("Blinking the LED for a bit.");
+ Resolver.Log.Info("Blinking each LED (on 1s / off 1s)");
foreach (var pwmLed in pwmLeds)
{
- pwmLed.StartBlink(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
+ await pwmLed.StartBlink(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
await Task.Delay(3000);
- pwmLed.Stop();
+ await pwmLed.StopAnimation();
}
await Task.Delay(1000);
- Resolver.Log.Info("Pulsing the LED for a bit.");
+ Resolver.Log.Info("Pulsing each LED (600ms pulse duration)");
foreach (var pwmLed in pwmLeds)
{
- pwmLed.StartPulse();
+ await pwmLed.StartPulse();
await Task.Delay(1000);
- pwmLed.Stop();
- }
-
- await Task.Delay(1000);
-
- Resolver.Log.Info("Pulsing the LED for a bit.");
- foreach (var pwmLed in pwmLeds)
- {
- pwmLed.StartPulse();
- await Task.Delay(1000);
- pwmLed.Stop();
+ await pwmLed.StopAnimation();
+ pwmLed.IsOn = false;
}
await Task.Delay(1000);
@@ -105,15 +95,15 @@ public override async Task Run()
Resolver.Log.Info("Set brightness the LED for a bit.");
foreach (var pwmLed in pwmLeds)
{
- pwmLed.Brightness = 0.25f;
+ pwmLed.SetBrightness(0.25f);
await Task.Delay(250);
- pwmLed.Brightness = 0.5f;
+ pwmLed.SetBrightness(0.5f);
await Task.Delay(250);
- pwmLed.Brightness = 0.75f;
+ pwmLed.SetBrightness(0.75f);
await Task.Delay(250);
- pwmLed.Brightness = 1.0f;
+ pwmLed.SetBrightness(1.0f);
await Task.Delay(250);
- pwmLed.Stop();
+ pwmLed.IsOn = false;
}
await Task.Delay(1000);
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/Leds.RgbLed_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/Leds.RgbLed_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/Leds.RgbLed_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/Leds.RgbLed_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/MeadowApp.cs
index 4db222ffd5..e5ecbdae97 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbLed_Sample/MeadowApp.cs
@@ -1,10 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Meadow;
+using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Leds;
-using Meadow.Peripherals.Leds;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
namespace Leds.RgbLed_Sample
{
@@ -18,12 +17,6 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- var onRgbLed = new RgbLed(
- redPin: Device.Pins.OnboardLedRed,
- greenPin: Device.Pins.OnboardLedGreen,
- bluePin: Device.Pins.OnboardLedBlue);
- onRgbLed.SetColor(RgbLedColors.Red);
-
rgbLeds = new List
{
new RgbLed(
@@ -44,8 +37,6 @@ public override Task Initialize()
Device.CreateDigitalOutputPort(Device.Pins.D13))
};
- onRgbLed.SetColor(RgbLedColors.Green);
-
return Task.CompletedTask;
}
@@ -67,25 +58,29 @@ public override async Task Run()
await Task.Delay(1000);
- Resolver.Log.Info("Blinking through each color on each RGB LED...");
+ Resolver.Log.Info("Blinking through each color on each RGB LED (on 500ms / off 500ms)...");
foreach (var rgbLed in rgbLeds)
{
for (int i = 0; i < (int)RgbLedColors.count; i++)
{
- rgbLed.StartBlink((RgbLedColors)i);
+ await rgbLed.StartBlink((RgbLedColors)i);
await Task.Delay(3000);
+ await rgbLed.StopAnimation();
+ rgbLed.IsOn = false;
}
}
await Task.Delay(1000);
- Resolver.Log.Info("Blinking through each color on each RGB LED...");
+ Resolver.Log.Info("Blinking through each color on each RGB LED (on 1s / off 1s)...");
foreach (var rgbLed in rgbLeds)
{
for (int i = 0; i < (int)RgbLedColors.count; i++)
{
- rgbLed.StartBlink((RgbLedColors)i, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
+ await rgbLed.StartBlink((RgbLedColors)i, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
await Task.Delay(3000);
+ await rgbLed.StopAnimation();
+ rgbLed.IsOn = false;
}
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/Leds.RgbPwmLed_Onboard_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/Leds.RgbPwmLed_Onboard_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/Leds.RgbPwmLed_Onboard_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/Leds.RgbPwmLed_Onboard_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/MeadowApp.cs
index 102597f7cd..3ba32b9303 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Onboard_Sample/MeadowApp.cs
@@ -2,9 +2,7 @@
using Meadow.Devices;
using Meadow.Foundation;
using Meadow.Foundation.Leds;
-using Meadow.Peripherals.Leds;
using System;
-using System.Threading;
using System.Threading.Tasks;
namespace Leds.RgbPwmLed_Onboard_Sample
@@ -18,48 +16,45 @@ public class MeadowApp : App
public override Task Initialize()
{
Resolver.Log.Info("Creating peripherals...");
-
+
onboardLed = new RgbPwmLed(
Device.Pins.OnboardLedRed,
Device.Pins.OnboardLedGreen,
- Device.Pins.OnboardLedBlue,
- commonType: CommonType.CommonAnode);
+ Device.Pins.OnboardLedBlue);
return Task.CompletedTask;
}
public override Task Run()
{
- TestColors();
-
- RunColors();
-
- return Task.CompletedTask;
+ return TestColors();
}
- public void TestColors()
+ public async Task TestColors()
{
- onboardLed.SetColor(Color.Crimson);
- Thread.Sleep(3000);
- onboardLed.SetColor(Color.MediumPurple);
- Thread.Sleep(3000);
- onboardLed.SetColor(Color.FromHex("#23abe3"));
- }
+ while (true)
+ {
+ Console.WriteLine("SetColor(RgbLedColors.Red);");
+ onboardLed.SetColor(Color.Red);
+ await Task.Delay(3000);
- public void RunColors()
- {
- while (true) {
+ Console.WriteLine("StartPulse();");
+ await onboardLed.StartPulse();
+ await Task.Delay(3000);
+
+ Console.WriteLine("StartPulse(RgbLedColors.Green);");
+ await onboardLed.StartPulse(Color.Green);
+ await Task.Delay(3000);
- // loop through the entire hue spectrum (360 degrees)
- for (int i = 0; i < 360; i++) {
- var hue = ((double)i / 360F);
- Resolver.Log.Info($"Hue: {hue}");
+ Console.WriteLine("SetColor(RgbLedColors.Yellow);");
+ onboardLed.SetColor(Color.Yellow);
+ await Task.Delay(3000);
- // set the color of the RGB
- onboardLed.SetColor(Color.FromHsba((hue), 1, 1));
+ Console.WriteLine("StartPulse(RgbLedColors.Cyan, 200, 200);");
+ await onboardLed.StartPulse(Color.Cyan, TimeSpan.FromMilliseconds(400));
+ await Task.Delay(3000);
- Thread.Sleep(18);
- }
+ await onboardLed.StopAnimation();
}
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/Leds.RgbPwmLed_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/Leds.RgbPwmLed_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/Leds.RgbPwmLed_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/Leds.RgbPwmLed_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/MeadowApp.cs
index fa3e6c945e..d544f220f6 100644
--- a/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Core.Samples/Leds.RgbPwmLed_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation;
using Meadow.Foundation.Leds;
-using Meadow.Peripherals.Leds;
-using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -20,22 +18,16 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- var onRgbLed = new RgbLed(
- redPin: Device.Pins.OnboardLedRed,
- greenPin: Device.Pins.OnboardLedGreen,
- bluePin: Device.Pins.OnboardLedBlue);
- onRgbLed.SetColor(RgbLedColors.Red);
-
rgbPwmLeds = new List()
{
new RgbPwmLed(
Device.Pins.D02,
Device.Pins.D03,
Device.Pins.D04),
- new RgbPwmLed(
- Device.Pins.D05,
- Device.Pins.D06,
- Device.Pins.D07),
+ //new RgbPwmLed(
+ // Device.Pins.D05,
+ // Device.Pins.D06,
+ // Device.Pins.D07),
new RgbPwmLed(
Device.Pins.D08,
Device.Pins.D09,
@@ -46,12 +38,10 @@ public override Task Initialize()
Device.Pins.D13)
};
- onRgbLed.SetColor(RgbLedColors.Green);
-
return Task.CompletedTask;
}
- public override Task Run()
+ public override async Task Run()
{
Resolver.Log.Info("TestRgbPwmLed...");
@@ -77,7 +67,7 @@ public override Task Run()
Resolver.Log.Info($"Red brightness: {i * 0.1f}");
Thread.Sleep(500);
}
- rgbPwmLed.Stop();
+ await rgbPwmLed.StopAnimation();
for (int i = 0; i < 10; i++)
{
@@ -85,7 +75,7 @@ public override Task Run()
Resolver.Log.Info($"Green brightness: {i * 0.1f}");
Thread.Sleep(500);
}
- rgbPwmLed.Stop();
+ await rgbPwmLed.StopAnimation();
for (int i = 0; i < 10; i++)
{
@@ -93,39 +83,33 @@ public override Task Run()
Resolver.Log.Info($"Blue brightness: {i * 0.1f}");
Thread.Sleep(500);
}
- rgbPwmLed.Stop();
+ await rgbPwmLed.StopAnimation();
// Blink
- rgbPwmLed.StartBlink(Color.Red, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), 1f, 0f);
+ await rgbPwmLed.StartBlink(Color.Red);
Resolver.Log.Info("Blinking Red");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
- rgbPwmLed.StartBlink(Color.Green, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), 1f, 0f);
+ await rgbPwmLed.StartBlink(Color.Green);
Resolver.Log.Info("Blinking Green");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
- rgbPwmLed.StartBlink(Color.Blue, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), 1f, 0f);
+ await rgbPwmLed.StartBlink(Color.Blue);
Resolver.Log.Info("Blinking Blue");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
// Pulse
- rgbPwmLed.StartPulse(Color.Red);
+ await rgbPwmLed.StartPulse(Color.Red);
Resolver.Log.Info("Pulsing Red");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
- rgbPwmLed.StartPulse(Color.Green);
+ await rgbPwmLed.StartPulse(Color.Green);
Resolver.Log.Info("Pulsing Green");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
- rgbPwmLed.StartPulse(Color.Blue);
+ await rgbPwmLed.StartPulse(Color.Blue);
Resolver.Log.Info("Pulsing Blue");
Thread.Sleep(3000);
- rgbPwmLed.Stop();
}
}
}
diff --git a/Source/Meadow.Foundation.Core.Samples/Motor.HBridgeMotor_Sample/Motor.HBridgeMotor_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Motor.HBridgeMotor_Sample/Motor.HBridgeMotor_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Motor.HBridgeMotor_Sample/Motor.HBridgeMotor_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Motor.HBridgeMotor_Sample/Motor.HBridgeMotor_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Relays.Relay_Sample/Relays.Relay_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Relays.Relay_Sample/Relays.Relay_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Relays.Relay_Sample/Relays.Relay_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Relays.Relay_Sample/Relays.Relay_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_BasicSample/Sensors.Buttons.PushButton_BasicSample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_BasicSample/Sensors.Buttons.PushButton_BasicSample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_BasicSample/Sensors.Buttons.PushButton_BasicSample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_BasicSample/Sensors.Buttons.PushButton_BasicSample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_Sample/Sensors.Buttons.PushButton_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_Sample/Sensors.Buttons.PushButton_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_Sample/Sensors.Buttons.PushButton_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Buttons.PushButton_Sample/Sensors.Buttons.PushButton_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Environmental.AnalogWaterLevel_Sample/Sensors.Environmental.AnalogWaterLevel_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Environmental.AnalogWaterLevel_Sample/Sensors.Environmental.AnalogWaterLevel_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Environmental.AnalogWaterLevel_Sample/Sensors.Environmental.AnalogWaterLevel_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Environmental.AnalogWaterLevel_Sample/Sensors.Environmental.AnalogWaterLevel_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.HID.AnalogJoystick_Sample/Sensors.HID.AnalogJoystick_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.HID.AnalogJoystick_Sample/Sensors.HID.AnalogJoystick_Sample.csproj
index da9f61d7ac..54ea931c17 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.HID.AnalogJoystick_Sample/Sensors.HID.AnalogJoystick_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.HID.AnalogJoystick_Sample/Sensors.HID.AnalogJoystick_Sample.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.HallEffect_Sample/Sensors.HallEffect_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.HallEffect_Sample/Sensors.HallEffect_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.HallEffect_Sample/Sensors.HallEffect_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.HallEffect_Sample/Sensors.HallEffect_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Light.AnalogLightSensor_Sample/Sensors.Light.AnalogLightSensor_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Light.AnalogLightSensor_Sample/Sensors.Light.AnalogLightSensor_Sample.csproj
index d49a10589f..92c62f04f6 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Light.AnalogLightSensor_Sample/Sensors.Light.AnalogLightSensor_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Light.AnalogLightSensor_Sample/Sensors.Light.AnalogLightSensor_Sample.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoderWithButton_Sample/Sensors.Rotary.RotaryEncoderWithButton_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoderWithButton_Sample/Sensors.Rotary.RotaryEncoderWithButton_Sample.csproj
index 2c2803bf16..36fca71b8f 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoderWithButton_Sample/Sensors.Rotary.RotaryEncoderWithButton_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoderWithButton_Sample/Sensors.Rotary.RotaryEncoderWithButton_Sample.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoder_Sample/Sensors.Rotary.RotaryEncoder_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoder_Sample/Sensors.Rotary.RotaryEncoder_Sample.csproj
index 2c2803bf16..36fca71b8f 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoder_Sample/Sensors.Rotary.RotaryEncoder_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Rotary.RotaryEncoder_Sample/Sensors.Rotary.RotaryEncoder_Sample.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.DipSwitch_Sample/Sensors.Switches.DipSwitch_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.DipSwitch_Sample/Sensors.Switches.DipSwitch_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.DipSwitch_Sample/Sensors.Switches.DipSwitch_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.DipSwitch_Sample/Sensors.Switches.DipSwitch_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpdtSwitch_Sample/Sensors.Switches.SpdtSwitch_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpdtSwitch_Sample/Sensors.Switches.SpdtSwitch_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpdtSwitch_Sample/Sensors.Switches.SpdtSwitch_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpdtSwitch_Sample/Sensors.Switches.SpdtSwitch_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpstSwitch_Sample/Sensors.Switches.SpstSwitch_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpstSwitch_Sample/Sensors.Switches.SpstSwitch_Sample.csproj
index ea265c2bc9..5232cdbf91 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpstSwitch_Sample/Sensors.Switches.SpstSwitch_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Switches.SpstSwitch_Sample/Sensors.Switches.SpstSwitch_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Core.Samples/Sensors.Temperature.AnalogTemperature_Sample/Sensors.Temperature.AnalogTemperature_Sample.csproj b/Source/Meadow.Foundation.Core.Samples/Sensors.Temperature.AnalogTemperature_Sample/Sensors.Temperature.AnalogTemperature_Sample.csproj
index d49a10589f..92c62f04f6 100644
--- a/Source/Meadow.Foundation.Core.Samples/Sensors.Temperature.AnalogTemperature_Sample/Sensors.Temperature.AnalogTemperature_Sample.csproj
+++ b/Source/Meadow.Foundation.Core.Samples/Sensors.Temperature.AnalogTemperature_Sample/Sensors.Temperature.AnalogTemperature_Sample.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Core/Communications/ByteCommsSensorBase.cs b/Source/Meadow.Foundation.Core/Communications/ByteCommsSensorBase.cs
index 2019c3706d..e183cf4a70 100644
--- a/Source/Meadow.Foundation.Core/Communications/ByteCommsSensorBase.cs
+++ b/Source/Meadow.Foundation.Core/Communications/ByteCommsSensorBase.cs
@@ -1,5 +1,6 @@
-using System;
-using Meadow.Hardware;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
namespace Meadow.Foundation
{
@@ -11,9 +12,9 @@ public abstract class ByteCommsSensorBase :
PollingSensorBase, IDisposable where UNIT : struct
{
///
- /// Peripheral object, i.e. an I2CPeripheral or SpiPeripheral
+ /// Bus communications object, i.e. an I2cCommunications or SpiCommunications
///
- protected IByteCommunications? Peripheral { get; set; }
+ protected IByteCommunications? BusComms { get; set; }
///
/// The read buffer
@@ -36,7 +37,7 @@ protected ByteCommsSensorBase(
II2cBus i2cBus, byte address,
int readBufferSize = 8, int writeBufferSize = 8)
{
- Peripheral = new I2cPeripheral(i2cBus, address, readBufferSize, writeBufferSize);
+ BusComms = new I2cCommunications(i2cBus, address, readBufferSize, writeBufferSize);
Init(readBufferSize, writeBufferSize);
}
@@ -45,15 +46,21 @@ protected ByteCommsSensorBase(
///
/// SPI bus object
/// Chip select port
+ /// The SPI bus speed
+ /// The SPI bus mode (0-3)
/// Read buffer size
/// Write buffer size
/// Chip select mode
protected ByteCommsSensorBase(
- ISpiBus spiBus, IDigitalOutputPort? chipSelect,
- int readBufferSize = 8, int writeBufferSize = 8,
+ ISpiBus spiBus,
+ IDigitalOutputPort? chipSelect,
+ Frequency busSpeed,
+ SpiClockConfiguration.Mode busMode = SpiClockConfiguration.Mode.Mode0,
+ int readBufferSize = 8,
+ int writeBufferSize = 8,
ChipSelectMode chipSelectMode = ChipSelectMode.ActiveLow)
{
- Peripheral = new SpiPeripheral(spiBus, chipSelect, readBufferSize, writeBufferSize, chipSelectMode);
+ BusComms = new SpiCommunications(spiBus, chipSelect, busSpeed, busMode, readBufferSize, writeBufferSize, chipSelectMode);
Init(readBufferSize, writeBufferSize);
}
diff --git a/Source/Meadow.Foundation.Core/Communications/I2cPeripheral.cs b/Source/Meadow.Foundation.Core/Communications/I2cCommunications.cs
similarity index 61%
rename from Source/Meadow.Foundation.Core/Communications/I2cPeripheral.cs
rename to Source/Meadow.Foundation.Core/Communications/I2cCommunications.cs
index e95e797965..0a1796ec37 100644
--- a/Source/Meadow.Foundation.Core/Communications/I2cPeripheral.cs
+++ b/Source/Meadow.Foundation.Core/Communications/I2cCommunications.cs
@@ -1,30 +1,41 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
namespace Meadow.Hardware
{
///
- /// Defines a contract for a peripheral that communicates via the IIC/I2C
- /// protocol.
+ /// Helper class for I2C communications, handles registers, endian, etc.
///
- public class I2cPeripheral : II2cPeripheral
+ public class I2cCommunications : II2cCommunications
{
+ ///
+ /// The I2C address
+ ///
public byte Address { get; protected set; }
+
+ ///
+ /// The I2C bus
+ ///
public II2cBus Bus { get; protected set; }
///
- /// Internal write buffer. Used in methods in which the buffers aren't
+ /// Internal write buffer - used in methods in which the buffers aren't
/// passed in.
///
protected Memory WriteBuffer { get; }
///
- /// Internal read buffer. Used in methods in which the buffers aren't
+ /// Internal read buffer - used in methods in which the buffers aren't
/// passed in.
///
protected Memory ReadBuffer { get; }
- public I2cPeripheral(II2cBus bus, byte peripheralAddress, int readBufferSize = 8, int writeBufferSize = 8)
+ ///
+ /// Initializes a new instance of the I2cCommunications class
+ ///
+ /// The II2cBus used for communication with the peripheral
+ /// The address of the peripheral on the I2C bus
+ /// The size of the buffer used for reading data from the peripheral. Defaults to 8 bytes
+ /// The size of the buffer used for writing data to the peripheral. Defaults to 8 bytes
+ public I2cCommunications(II2cBus bus, byte peripheralAddress, int readBufferSize = 8, int writeBufferSize = 8)
{
Bus = bus;
Address = peripheralAddress;
@@ -42,7 +53,7 @@ public I2cPeripheral(II2cBus bus, byte peripheralAddress, int readBufferSize = 8
///
public void Read(Span readBuffer)
{
- Bus.Read(this.Address, readBuffer);
+ Bus.Read(Address, readBuffer);
}
///
@@ -50,20 +61,20 @@ public void Read(Span readBuffer)
///
///
///
- public void ReadRegister(byte address, Span readBuffer)
+ public virtual void ReadRegister(byte address, Span readBuffer)
{
WriteBuffer.Span[0] = address;
- Bus.Exchange(this.Address, WriteBuffer.Span[0..1], readBuffer);
+ Bus.Exchange(Address, WriteBuffer.Span[0..1], readBuffer);
}
///
/// Read a register from the peripheral.
///
/// Address of the register to read.
- public byte ReadRegister(byte address)
+ public virtual byte ReadRegister(byte address)
{
WriteBuffer.Span[0] = address;
- Bus.Exchange(this.Address, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
+ Bus.Exchange(Address, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
return ReadBuffer.Span[0];
}
@@ -73,13 +84,16 @@ public byte ReadRegister(byte address)
/// Register address of the low byte (the high byte will follow).
/// Order of the bytes in the register (little endian is the default).
/// Value read from the register.
- public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
{
WriteBuffer.Span[0] = address;
- Bus.Exchange(this.Address, WriteBuffer[0..1].Span, ReadBuffer[0..2].Span);
- if (order == ByteOrder.LittleEndian) {
+ Bus.Exchange(Address, WriteBuffer[0..1].Span, ReadBuffer[0..2].Span);
+ if (order == ByteOrder.LittleEndian)
+ {
return (ushort)(ReadBuffer.Span[0] | (ReadBuffer.Span[1] << 8));
- } else {
+ }
+ else
+ {
return (ushort)(ReadBuffer.Span[0] << 8 | ReadBuffer.Span[1]);
}
}
@@ -88,33 +102,28 @@ public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.Lit
/// Write a single byte to the peripheral.
///
/// Value to be written (8-bits).
- public void Write(byte value)
+ public virtual void Write(byte value)
{
- // stuff the value into the write buffer
WriteBuffer.Span[0] = value;
- this.Bus.Write(this.Address, WriteBuffer.Span[0..1]);
+ Bus.Write(Address, WriteBuffer.Span[0..1]);
}
///
/// Write an array of bytes to the peripheral.
///
/// Values to be written.
- public void Write(Span data)
- {
- this.Bus.Write(this.Address, data);
- }
+ public virtual void Write(Span data) => Bus.Write(Address, data);
///
/// Write data a register in the peripheral.
///
/// Address of the register to write to.
/// Data to write into the register.
- public void WriteRegister(byte address, byte value)
+ public virtual void WriteRegister(byte address, byte value)
{
- // stuff the address and value into the write buffer
WriteBuffer.Span[0] = address;
WriteBuffer.Span[1] = value;
- this.Bus.Write(this.Address, WriteBuffer.Span[0..2]);
+ Bus.Write(Address, WriteBuffer.Span[0..2]);
}
///
@@ -123,11 +132,9 @@ public void WriteRegister(byte address, byte value)
/// Address to write the first byte to.
/// Value to be written (16-bits).
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrder.LittleEndian)
{
- // split the 16 bit ushort into two bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -137,11 +144,9 @@ public void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrde
/// Address to write the first byte to.
/// Value to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.LittleEndian)
{
- // split the 32 bit uint into four bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -151,11 +156,9 @@ public void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.
/// Address to write the first byte to.
/// Value to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder.LittleEndian)
{
- // split the 64 bit ulong into 8 bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -165,42 +168,50 @@ public void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder
/// Address of the register to write to.
/// A buffer of byte values to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, Span writeBuffer, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, Span writeBuffer, ByteOrder order = ByteOrder.LittleEndian)
{
- if (WriteBuffer.Length < writeBuffer.Length + 1) {
+ if (WriteBuffer.Length < writeBuffer.Length + 1)
+ {
throw new ArgumentException("Data to write is too large for the write buffer. " +
"Must be less than WriteBuffer.Length + 1 (to allow for address). " +
"Instantiate this class with a larger WriteBuffer, or send a smaller" +
"amount of data to fix.");
}
- // stuff the register address into the write buffer
+ // add the register address to the start of the write buffer
WriteBuffer.Span[0] = address;
- // stuff the bytes into the write buffer (starting at `1` index,
- // because `0` is the register address.
- switch (order) {
+ switch (order)
+ {
case ByteOrder.LittleEndian:
- for (int i = 0; i < writeBuffer.Length; i++) {
+ for (int i = 0; i < writeBuffer.Length; i++)
+ {
WriteBuffer.Span[i + 1] = writeBuffer[i];
}
break;
case ByteOrder.BigEndian:
- for (int i = 0; i < writeBuffer.Length; i++) {
- // stuff them backwards
+ for (int i = 0; i < writeBuffer.Length; i++)
+ {
WriteBuffer.Span[i + 1] = writeBuffer[writeBuffer.Length - (i + 1)];
}
break;
}
- // write it
- this.Bus.Write(this.Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
+ Bus.Write(Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
}
- public void Exchange(Span writeBuffer, Span readBuffer, DuplexType duplex = DuplexType.Half)
+ ///
+ /// Exchanges data with an I2C device through a specified write and read buffer
+ ///
+ /// A span of bytes that represents the data to be written to the device
+ /// A span of bytes where the data read from the device will be stored
+ /// An optional parameter that specifies the duplex type of the communication.
+ /// It defaults to half-duplex.
+ /// Thrown when duplex is set to full-duplex, as I2C only supports half-duplex communication
+ public virtual void Exchange(Span writeBuffer, Span readBuffer, DuplexType duplex = DuplexType.Half)
{
if (duplex == DuplexType.Full) { throw new ArgumentException("I2C doesn't support full-duplex communications. Only half-duplex is available because it only has a single data line."); }
- Bus.Exchange(this.Address, writeBuffer, readBuffer);
+ Bus.Exchange(Address, writeBuffer, readBuffer);
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Communications/SpiPeripheral.cs b/Source/Meadow.Foundation.Core/Communications/SpiCommunications.cs
similarity index 70%
rename from Source/Meadow.Foundation.Core/Communications/SpiPeripheral.cs
rename to Source/Meadow.Foundation.Core/Communications/SpiCommunications.cs
index faf07fc748..f943895430 100644
--- a/Source/Meadow.Foundation.Core/Communications/SpiPeripheral.cs
+++ b/Source/Meadow.Foundation.Core/Communications/SpiCommunications.cs
@@ -1,12 +1,13 @@
-using System;
+using Meadow.Units;
+using System;
namespace Meadow.Hardware
{
///
- /// Represents an SPI peripheral object
+ /// Helper class for SPI communications, handles registers, endian, etc.
/// This encapsulates and synchronizes the SPI bus and chip select ports
///
- public class SpiPeripheral : ISpiPeripheral
+ public class SpiCommunications : ISpiCommunications
{
///
/// The SPI chip select port
@@ -16,13 +17,23 @@ public class SpiPeripheral : ISpiPeripheral
///
/// The chip select mode (active high or active low)
///
- ChipSelectMode chipSelectMode;
+ readonly ChipSelectMode chipSelectMode;
///
/// the ISpiBus object
///
public ISpiBus Bus { get; }
+ ///
+ /// SPI bus speed
+ ///
+ public Frequency BusSpeed { get; set; }
+
+ ///
+ /// SPI bus mode
+ ///
+ public SpiClockConfiguration.Mode BusMode { get; set; }
+
///
/// Internal write buffer. Used in methods in which the buffers aren't
/// passed in.
@@ -35,22 +46,28 @@ public class SpiPeripheral : ISpiPeripheral
protected Memory ReadBuffer { get; }
///
- /// Creates a new SpiPeripheral instance
+ /// Creates a new SpiCommunications instance
///
/// The spi bus connected to the peripheral
/// The chip select port
+ /// The SPI bus speed
+ /// The SPI bus mode (0-3)
/// The size of the read buffer in bytes
/// The size of the write buffer in bytes
/// The chip select mode, active high or active low
- public SpiPeripheral(
+ public SpiCommunications(
ISpiBus bus,
IDigitalOutputPort? chipSelect,
+ Frequency busSpeed,
+ SpiClockConfiguration.Mode busMode = SpiClockConfiguration.Mode.Mode0,
int readBufferSize = 8, int writeBufferSize = 8,
ChipSelectMode csMode = ChipSelectMode.ActiveLow)
{
- this.Bus = bus;
- this.ChipSelect = chipSelect;
- this.chipSelectMode = csMode;
+ Bus = bus;
+ BusMode = busMode;
+ BusSpeed = busSpeed;
+ ChipSelect = chipSelect;
+ chipSelectMode = csMode;
WriteBuffer = new byte[writeBufferSize];
ReadBuffer = new byte[readBufferSize];
}
@@ -63,9 +80,11 @@ public SpiPeripheral(
/// The number of bytes to be read is determined by the length of the
/// `readBuffer`.
///
- public void Read(Span readBuffer)
+ public virtual void Read(Span readBuffer)
{
- Bus.Read(this.ChipSelect, readBuffer, this.chipSelectMode);
+ AutoSetBusSpeedAndMode();
+
+ Bus.Read(ChipSelect, readBuffer, chipSelectMode);
}
///
@@ -73,10 +92,12 @@ public void Read(Span readBuffer)
///
/// The register address
/// The buffer to hold the data
- public void ReadRegister(byte address, Span readBuffer)
+ public virtual void ReadRegister(byte address, Span readBuffer)
{
+ AutoSetBusSpeedAndMode();
+
WriteBuffer.Span[0] = address;
- Bus.Exchange(this.ChipSelect, WriteBuffer.Span[0..readBuffer.Length], readBuffer, this.chipSelectMode);
+ Bus.Exchange(ChipSelect, WriteBuffer.Span[0..readBuffer.Length], readBuffer, chipSelectMode);
}
///
@@ -84,10 +105,12 @@ public void ReadRegister(byte address, Span readBuffer)
///
/// Address to read
/// The byte read
- public byte ReadRegister(byte address)
+ public virtual byte ReadRegister(byte address)
{
+ AutoSetBusSpeedAndMode();
+
WriteBuffer.Span[0] = address;
- Bus.Exchange(this.ChipSelect, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1], this.chipSelectMode);
+ Bus.Exchange(ChipSelect, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1], chipSelectMode);
return ReadBuffer.Span[0];
}
@@ -97,7 +120,7 @@ public byte ReadRegister(byte address)
/// Address of the read
/// Endianness of the value read
/// The value read
- public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
{
ReadRegister(address, ReadBuffer[0..2].Span);
if (order == ByteOrder.LittleEndian)
@@ -116,17 +139,21 @@ public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.Lit
/// Value to write
public void Write(byte value)
{
+ AutoSetBusSpeedAndMode();
+
WriteBuffer.Span[0] = value;
- Bus.Write(ChipSelect, WriteBuffer.Span[0..1], this.chipSelectMode);
+ Bus.Write(ChipSelect, WriteBuffer.Span[0..1], chipSelectMode);
}
///
/// Write a span of bytes to the peripheral.
///
/// Data to be written.
- public void Write(Span data)
+ public virtual void Write(Span data)
{
- Bus.Write(this.ChipSelect, data, this.chipSelectMode);
+ AutoSetBusSpeedAndMode();
+
+ Bus.Write(ChipSelect, data, chipSelectMode);
}
///
@@ -134,12 +161,13 @@ public void Write(Span data)
///
/// The target write register address
/// Value to write
- public void WriteRegister(byte address, byte value)
+ public virtual void WriteRegister(byte address, byte value)
{
- // stuff the address and value into the write buffer
+ AutoSetBusSpeedAndMode();
+
WriteBuffer.Span[0] = address;
WriteBuffer.Span[1] = value;
- Bus.Write(ChipSelect, WriteBuffer.Span[0..2], this.chipSelectMode);
+ Bus.Write(ChipSelect, WriteBuffer.Span[0..2], chipSelectMode);
}
///
@@ -148,11 +176,10 @@ public void WriteRegister(byte address, byte value)
/// The target write register address
/// Value to write
/// Endianness of the value to be written
- public void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrder.LittleEndian)
{
// split the 16 bit ushort into two bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -162,11 +189,9 @@ public void WriteRegister(byte address, ushort value, ByteOrder order = ByteOrde
/// Address to write the first byte to.
/// Value to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.LittleEndian)
{
- // split the 32 bit ushort into four bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -176,11 +201,9 @@ public void WriteRegister(byte address, uint value, ByteOrder order = ByteOrder.
/// Address to write the first byte to.
/// Value to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder.LittleEndian)
{
- // split the 64 bit ushort into eight bytes
var bytes = BitConverter.GetBytes(value);
- // call the helper method
WriteRegister(address, bytes, order);
}
@@ -190,7 +213,7 @@ public void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder
/// Address of the register to write to.
/// A buffer of byte values to be written.
/// Indicate if the data should be written as big or little endian.
- public void WriteRegister(byte address, Span writeBuffer, ByteOrder order = ByteOrder.LittleEndian)
+ public virtual void WriteRegister(byte address, Span writeBuffer, ByteOrder order = ByteOrder.LittleEndian)
{
if (WriteBuffer.Length < writeBuffer.Length + 1)
{
@@ -200,11 +223,10 @@ public void WriteRegister(byte address, Span writeBuffer, ByteOrder order
"amount of data to fix.");
}
- // stuff the register address into the write buffer
+ AutoSetBusSpeedAndMode();
+
WriteBuffer.Span[0] = address;
- // stuff the bytes into the write buffer (starting at `1` index,
- // because `0` is the register address.
switch (order)
{
case ByteOrder.LittleEndian:
@@ -216,13 +238,24 @@ public void WriteRegister(byte address, Span writeBuffer, ByteOrder order
case ByteOrder.BigEndian:
for (int i = 0; i < writeBuffer.Length; i++)
{
- // stuff them backwards
WriteBuffer.Span[i + 1] = writeBuffer[writeBuffer.Length - (i + 1)];
}
break;
}
- // write it
- this.Bus.Write(this.ChipSelect, WriteBuffer.Span[0..(writeBuffer.Length + 1)], this.chipSelectMode);
+ Bus.Write(ChipSelect, WriteBuffer.Span[0..(writeBuffer.Length + 1)], chipSelectMode);
+ }
+
+ private void AutoSetBusSpeedAndMode()
+ {
+ if (Bus.Configuration.SpiMode != BusMode)
+ {
+ Bus.Configuration.SetBusMode(BusMode);
+ }
+
+ if (Bus.Configuration.Speed != BusSpeed)
+ {
+ Bus.Configuration.Speed = BusSpeed;
+ }
}
///
@@ -231,36 +264,25 @@ public void WriteRegister(byte address, Span writeBuffer, ByteOrder order
/// The buffer holding the data to write
/// The buffer to receieve data
/// The duplex mode - half or full
- public void Exchange(Span writeBuffer, Span readBuffer, DuplexType duplex = DuplexType.Half)
+ public virtual void Exchange(Span writeBuffer, Span readBuffer, DuplexType duplex = DuplexType.Half)
{
+ AutoSetBusSpeedAndMode();
+
if (duplex == DuplexType.Half)
{
- // Todo: we should move this functionality deeper into the stack
- // and have nuttx write the write buffer, then continue clocking out
- // 0x00's until it's hit writeBuffer.Length + readBuffer.Lenght
- // and ignore the input until it hits writeBuffer.Length, and then
- // start writing directly into the readBuffer starting at 0.
- // that will prevent all the allocations and copying we're doing
- // here.
-
- // clock in and clock out data means that the buffers have to be as
- // long as both tx and rx together
int length = writeBuffer.Length + readBuffer.Length;
Span txBuffer = stackalloc byte[length];
Span rxBuffer = stackalloc byte[length];
- // copy the write into tx
writeBuffer.CopyTo(txBuffer);
- // write/read the data
- Bus.Exchange(ChipSelect, txBuffer, rxBuffer, this.chipSelectMode);
+ Bus.Exchange(ChipSelect, txBuffer, rxBuffer, chipSelectMode);
- // move the rx data into the read buffer, starting it at zero
rxBuffer[writeBuffer.Length..length].CopyTo(readBuffer);
}
else
{
- Bus.Exchange(ChipSelect, writeBuffer, readBuffer, this.chipSelectMode);
+ Bus.Exchange(ChipSelect, writeBuffer, readBuffer, chipSelectMode);
}
}
}
diff --git a/Source/Meadow.Foundation.Core/Leds/Led.Animations.cs b/Source/Meadow.Foundation.Core/Leds/Led.Animations.cs
new file mode 100644
index 0000000000..4383f184a9
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/Led.Animations.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ ///
+ /// Utility functions to provide blinking for Led
+ ///
+ public partial class Led
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask = null;
+ private CancellationTokenSource? cancellationTokenSource = null;
+
+
+ ///
+ /// Stops the current LED animation
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off on an interval of 1 second (500ms on, 500ms off)
+ ///
+ public Task StartBlink()
+ {
+ return StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500));
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off with the especified durations
+ ///
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ public async Task StartBlink(TimeSpan onDuration, TimeSpan offDuration)
+ {
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ IsOn = true;
+ Thread.Sleep(onDuration);
+
+ IsOn = false;
+ Thread.Sleep(offDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/Led.cs b/Source/Meadow.Foundation.Core/Leds/Led.cs
index 5da6a0d833..89a8c161c9 100644
--- a/Source/Meadow.Foundation.Core/Leds/Led.cs
+++ b/Source/Meadow.Foundation.Core/Leds/Led.cs
@@ -1,29 +1,19 @@
using Meadow.Hardware;
using Meadow.Peripherals.Leds;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
{
///
/// Represents a simple LED
///
- public class Led : ILed
+ public partial class Led : ILed, IDisposable
{
- private Task? animationTask;
- private CancellationTokenSource? cancellationTokenSource;
+ readonly bool createdPort = false;
///
- /// Gets the port that is driving the LED
- ///
- /// The port
- protected IDigitalOutputPort Port { get; set; }
-
- ///
- /// Gets or sets a value indicating whether this is on.
+ /// Turns on LED with current color or turns it off
///
- /// true if is on; otherwise, false.
public bool IsOn
{
get => isOn;
@@ -36,89 +26,58 @@ public bool IsOn
bool isOn;
///
- /// Creates a LED through a pin directly from the Digital IO of the board
+ /// Gets the port that is driving the LED
///
- ///
- public Led(IPin pin) :
- this(pin.CreateDigitalOutputPort(false))
- { }
+ protected IDigitalOutputPort Port { get; set; }
///
- /// Creates a LED through a DigitalOutPutPort from an IO Expander
+ /// Is the object disposed
///
- ///
- public Led(IDigitalOutputPort port)
- {
- Port = port;
- }
+ public bool IsDisposed { get; private set; }
///
- /// Stops the LED when its blinking and/or turns it off.
+ /// Create instance of Led
///
- public void Stop()
+ /// The Output Pin
+ public Led(IPin pin) :
+ this(pin.CreateDigitalOutputPort(false))
{
- cancellationTokenSource?.Cancel();
- IsOn = false;
+ createdPort = true;
}
///
- /// Blink animation that turns the LED on (500ms) and off (500ms)
+ /// Create instance of Led
///
- public void StartBlink()
+ /// The Output Port
+ public Led(IDigitalOutputPort port)
{
- var onDuration = TimeSpan.FromMilliseconds(500);
- var offDuration = TimeSpan.FromMilliseconds(500);
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ Port = port;
}
///
- /// Blink animation that turns the LED on and off based on the OnDuration and offDuration values in ms
+ /// Dispose of the object
///
- ///
- ///
- public void StartBlink(TimeSpan onDuration, TimeSpan offDuration)
+ public void Dispose()
{
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
}
///
- /// Set LED to blink
+ /// Dispose of the object
///
- /// on duration in ms
- /// off duration in ms
- /// cancellation token used to cancel blink
- ///
- protected async Task StartBlinkAsync(TimeSpan onDuration, TimeSpan offDuration, CancellationToken cancellationToken)
+ /// Is disposing
+ protected virtual void Dispose(bool disposing)
{
- while (true)
+ if (!IsDisposed)
{
- if (cancellationToken.IsCancellationRequested)
+ if (disposing && createdPort)
{
- break;
+ Port.Dispose();
}
- Port.State = true;
- await Task.Delay(onDuration);
- Port.State = false;
- await Task.Delay(offDuration);
+ IsDisposed = true;
}
-
- Port.State = IsOn;
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/LedBarGraph.Animations.cs b/Source/Meadow.Foundation.Core/Leds/LedBarGraph.Animations.cs
new file mode 100644
index 0000000000..12c8c3e57f
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/LedBarGraph.Animations.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ public partial class LedBarGraph
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask;
+ private CancellationTokenSource? cancellationTokenSource;
+
+ ///
+ /// Stops the LED bar graph when its blinking
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Stops the blinking animation on an individual LED
+ ///
+ public Task StopAnimation(int index)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return leds[index].StopAnimation();
+ }
+
+ ///
+ /// Blink animation that turns the LED bar graph on (500ms) and off (500ms)
+ ///
+ public Task StartBlink()
+ {
+ return StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500));
+ }
+
+ ///
+ /// Blink animation that turns the LED bar graph on and off based on the OnDuration and offDuration values
+ ///
+ /// The duration the LED bar graph stays on
+ /// The duration the LED bar graph stays off
+ public async Task StartBlink(TimeSpan onDuration, TimeSpan offDuration)
+ {
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ foreach (var led in leds)
+ {
+ led.IsOn = true;
+ }
+ Thread.Sleep(onDuration);
+
+ foreach (var led in leds)
+ {
+ led.IsOn = false;
+ }
+ Thread.Sleep(offDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Starts a blink animation on an individual LED on (500ms) and off (500ms)
+ ///
+ /// Index of the LED
+ public Task StartBlink(int index)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return leds[index].StartBlink();
+ }
+
+ ///
+ /// Starts a blink animation on an individual LED
+ ///
+ /// Index of the LED
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ public Task StartBlink(int index, TimeSpan onDuration, TimeSpan offDuration)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return leds[index].StartBlink(onDuration, offDuration);
+ }
+
+ ///
+ /// Returns the index of the last LED turned on
+ ///
+ public int GetTopLedForPercentage()
+ {
+ return (int)Math.Max(0, Percentage * Count - 0.5);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/LedBarGraph.cs b/Source/Meadow.Foundation.Core/Leds/LedBarGraph.cs
index 674c353d69..c30c507ccb 100644
--- a/Source/Meadow.Foundation.Core/Leds/LedBarGraph.cs
+++ b/Source/Meadow.Foundation.Core/Leds/LedBarGraph.cs
@@ -1,6 +1,5 @@
using Meadow.Hardware;
using System;
-using System.Threading;
using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
@@ -8,11 +7,8 @@ namespace Meadow.Foundation.Leds
///
/// Represents an LED bar graph composed on multiple LEDs
///
- public class LedBarGraph
+ public partial class LedBarGraph
{
- private Task? animationTask;
- private CancellationTokenSource? cancellationTokenSource;
-
///
/// Array to hold LED objects for bar
///
@@ -26,17 +22,12 @@ public class LedBarGraph
///
/// A value between 0 and 1 that controls the number of LEDs that are activated
///
- public float Percentage
- {
- get => percentage;
- set => SetPercentage(percentage = value);
- }
- float percentage;
+ public float Percentage { get; protected set; }
///
/// Create an LedBarGraph instance from an array of IPins
///
- ///
+ /// The Digital Output Pins
public LedBarGraph(IPin[] pins)
{
leds = new Led[pins.Length];
@@ -50,7 +41,7 @@ public LedBarGraph(IPin[] pins)
///
/// Create an LedBarGraph instance from an array of IDigitalOutputPort
///
- ///
+ /// The Digital Output Ports
public LedBarGraph(IDigitalOutputPort[] ports)
{
leds = new Led[ports.Length];
@@ -64,16 +55,16 @@ public LedBarGraph(IDigitalOutputPort[] ports)
///
/// Set the LED state
///
- /// index of the LED
- ///
- public void SetLed(int index, bool isOn)
+ /// Index of the LED
+ /// True for on, False for off
+ public async Task SetLed(int index, bool isOn)
{
if (index >= Count)
{
throw new ArgumentOutOfRangeException();
}
- leds[index].Stop();
+ await leds[index].StopAnimation();
leds[index].IsOn = isOn;
}
@@ -81,162 +72,22 @@ public void SetLed(int index, bool isOn)
/// Set the percentage of LEDs that are on starting from index 0
///
/// Percentage (Range from 0 - 1)
- protected void SetPercentage(float percentage)
+ public async Task SetPercentage(float percentage)
{
if (percentage < 0 || percentage > 1)
{
throw new ArgumentOutOfRangeException();
}
+ Percentage = percentage;
+
var value = percentage * Count;
value += 0.5f;
for (int i = 1; i <= Count; i++)
{
- if (i <= value)
- {
- SetLed(i - 1, true);
- }
- else
- {
- SetLed(i - 1, false);
- }
- }
- }
-
- ///
- /// Returns the index of the last LED turned on
- ///
- ///
- public int GetTopLedForPercentage()
- {
- return (int)Math.Max(0, percentage * Count - 0.5);
- }
-
- ///
- /// Starts a blink animation on an individual LED on (500ms) and off (500ms)
- ///
- ///
- public void StartBlink(int index)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
+ await SetLed(i - 1, i <= value);
}
-
- leds[index].StartBlink();
- }
-
- ///
- /// Starts a blink animation on an individual LED
- ///
- ///
- ///
- ///
- public void StartBlink(int index, TimeSpan onDuration, TimeSpan offDuration)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- leds[index].StartBlink(onDuration, offDuration);
- }
-
- ///
- /// Blink animation that turns the LED bar graph on (500ms) and off (500ms)
- ///
- public void StartBlink()
- {
- var onDuration = TimeSpan.FromMilliseconds(500);
- var offDuration = TimeSpan.FromMilliseconds(500);
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Blink animation that turns the LED bar graph on and off based on the OnDuration and offDuration values in ms
- ///
- ///
- ///
- public void StartBlink(TimeSpan onDuration, TimeSpan offDuration)
- {
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Set LED to blink
- ///
- /// on duration in ms
- /// off duration in ms
- /// cancellation token used to cancel blink
- ///
- protected async Task StartBlinkAsync(TimeSpan onDuration, TimeSpan offDuration, CancellationToken cancellationToken)
- {
- while (true)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- foreach (var led in leds)
- {
- led.IsOn = true;
- }
- await Task.Delay(onDuration);
-
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- foreach (var led in leds)
- {
- led.IsOn = false;
- }
- await Task.Delay(offDuration);
- }
- }
-
- ///
- /// Stops the LED bar graph when its blinking and/or turns it off.
- ///
- public void Stop()
- {
- cancellationTokenSource?.Cancel();
-
- foreach (var led in leds)
- {
- led.Stop();
- }
- }
-
- ///
- /// Stops the blinking animation on an individual LED and/or turns it off
- ///
- public void Stop(int index)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- leds[index].Stop();
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/PwmLed.Animations.cs b/Source/Meadow.Foundation.Core/Leds/PwmLed.Animations.cs
new file mode 100644
index 0000000000..f44e9912fc
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/PwmLed.Animations.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ public partial class PwmLed
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask = null;
+ private CancellationTokenSource? cancellationTokenSource = null;
+
+ ///
+ /// Stops any running animations.
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Start a Blink animation which sets the brightness of the LED alternating between a low and high brightness setting.
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartBlink(float highBrightness = 1f, float lowBrightness = 0f)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ await StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500));
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
+ ///
+ /// The duration the LED stays in high brightness
+ /// The duration the LED stays in low brightness
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartBlink(
+ TimeSpan highBrightnessDuration,
+ TimeSpan lowBrightnessDuration,
+ float highBrightness = 1f,
+ float lowBrightness = 0f)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ SetBrightness(highBrightness);
+ Thread.Sleep(highBrightnessDuration);
+
+ SetBrightness(lowBrightness);
+ Thread.Sleep(lowBrightnessDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting.
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ await StartPulse(TimeSpan.FromMilliseconds(600), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ ///
+ /// The pulse animation duration
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartPulse(
+ TimeSpan pulseDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0.15F)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ float brightness = lowBrightness;
+ bool ascending = true;
+ var 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 (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ if (brightness <= lowBrightness)
+ {
+ ascending = true;
+ }
+ else if (brightness >= highBrightness)
+ {
+ ascending = false;
+ }
+
+ brightness += delta * (ascending ? 1 : -1);
+
+ if (brightness < lowBrightness)
+ {
+ brightness = lowBrightness;
+ }
+ else if (brightness > highBrightness)
+ {
+ brightness = highBrightness;
+ }
+
+ SetBrightness(brightness);
+
+ Thread.Sleep(intervalTime);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Validates LED brightness to ensure they're within the range 0 (off) - 1 (full brighness)
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ protected void ValidateBrightness(float highBrightness, float lowBrightness)
+ {
+ if (highBrightness > 1 || highBrightness <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
+ }
+ if (lowBrightness >= 1 || lowBrightness < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
+ }
+ if (lowBrightness >= highBrightness)
+ {
+ throw new Exception("offBrightness must be less than onBrightness");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/PwmLed.cs b/Source/Meadow.Foundation.Core/Leds/PwmLed.cs
index 2395a3e988..5487ec2594 100644
--- a/Source/Meadow.Foundation.Core/Leds/PwmLed.cs
+++ b/Source/Meadow.Foundation.Core/Leds/PwmLed.cs
@@ -2,8 +2,6 @@
using Meadow.Peripherals.Leds;
using Meadow.Units;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
{
@@ -11,47 +9,24 @@ namespace Meadow.Foundation.Leds
/// Represents an LED whose voltage is limited by the duty-cycle of a PWM
/// signal.
///
- public class PwmLed : IPwmLed, IDisposable
+ public partial class PwmLed : IPwmLed, IDisposable
{
- Task? animationTask;
- CancellationTokenSource? cancellationTokenSource;
readonly bool createdPwm = false;
float maximumPwmDuty = 1;
- bool inverted;
///
- /// Is the object disposed
+ /// Maximum forward voltage (3.3 Volts)
///
- public bool IsDisposed { get; private set; }
+ public Voltage MAX_FORWARD_VOLTAGE => new Voltage(3.3);
///
- /// Gets the brightness of the LED, controlled by a PWM signal, and limited by the
- /// calculated maximum voltage. Valid values are from 0 to 1, inclusive.
+ /// Minimum forward voltage (0 Volts)
///
- public float Brightness
- {
- get => _brightness;
- set
- {
- if (value < 0 || value > 1)
- {
- throw new ArgumentOutOfRangeException("Brightness must be between 0 and 1, inclusive.");
- }
-
- _brightness = value;
- Port.DutyCycle = maximumPwmDuty * Brightness;
-
- if (!Port.State)
- {
- Port.Start();
- }
- }
- }
- float _brightness = 0;
+ public Voltage MIN_FORWARD_VOLTAGE => new Voltage(0);
///
- /// Gets or Sets the state of the LED
+ /// Turns on LED with current color or turns it off
///
public bool IsOn
{
@@ -74,6 +49,16 @@ public bool IsOn
///
public Voltage ForwardVoltage { get; protected set; }
+ ///
+ /// The brightness value assigned to the LED
+ ///
+ public float Brightness { get; protected set; } = 1f;
+
+ ///
+ /// Is the object disposed
+ ///
+ public bool IsDisposed { get; private set; }
+
///
/// Initializes a new instance PwmLed class
///
@@ -86,12 +71,10 @@ public bool IsOn
public PwmLed(
IPin pin,
Voltage forwardVoltage,
- CircuitTerminationType terminationType = CircuitTerminationType.CommonGround)
+ CircuitTerminationType terminationType = CircuitTerminationType.CommonGround) :
+ this(pin.CreatePwmPort(new Frequency(100, Frequency.UnitType.Hertz)), forwardVoltage, terminationType)
{
- Port = pin.CreatePwmPort(new Frequency(100, Frequency.UnitType.Hertz));
- createdPwm = true; // signal that we created it, so we should dispose of it
- Port.DutyCycle = 0;
- Initialize(forwardVoltage, terminationType);
+ createdPwm = true;
}
///
@@ -107,60 +90,35 @@ public PwmLed(
Voltage forwardVoltage,
CircuitTerminationType terminationType = CircuitTerminationType.CommonGround)
{
- Port = pwmPort;
- Initialize(forwardVoltage, terminationType);
- }
+ ValidateForwardVoltages(forwardVoltage);
- private void Initialize(
- Voltage forwardVoltage,
- CircuitTerminationType terminationType = CircuitTerminationType.CommonGround)
- {
- if (forwardVoltage < new Voltage(0) || forwardVoltage > new Voltage(3.3))
- {
- throw new ArgumentOutOfRangeException(nameof(forwardVoltage), "error, forward voltage must be between 0, and 3.3");
- }
+ Port = pwmPort;
ForwardVoltage = forwardVoltage;
- inverted = terminationType == CircuitTerminationType.High;
-
maximumPwmDuty = Helpers.CalculateMaximumDutyCycle(forwardVoltage);
+ IsOn = false;
- Port.Inverted = inverted;
+ Port.Inverted = terminationType == CircuitTerminationType.High;
Port.Start();
}
///
- /// Dispose of the object
+ /// Validates forward voltages to ensure they're within the range MIN_FORWARD_VOLTAGE to MAX_FORWARD_VOLTAGE
///
- /// Is disposing
- protected virtual void Dispose(bool disposing)
+ /// The forward voltage for the LED
+ protected void ValidateForwardVoltages(Voltage forwardVoltage)
{
- if (!IsDisposed)
+ if (forwardVoltage < MIN_FORWARD_VOLTAGE || forwardVoltage > MAX_FORWARD_VOLTAGE)
{
- if (disposing && createdPwm)
- {
- Port.Dispose();
- }
-
- IsDisposed = true;
+ throw new ArgumentOutOfRangeException(nameof(forwardVoltage), "error, forward voltage must be between 0, and 3.3");
}
}
- ///
- /// Dispose of the object
- ///
- public void Dispose()
- {
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
-
///
/// Sets the LED to a specific brightness.
///
/// Valid values are from 0 to 1, inclusive
- [Obsolete("Use Brightness property instead")]
public void SetBrightness(float brightness)
{
if (brightness < 0 || brightness > 1)
@@ -168,7 +126,7 @@ public void SetBrightness(float brightness)
throw new ArgumentOutOfRangeException(nameof(brightness), "brightness must be between 0 and 1, inclusive.");
}
- _brightness = brightness;
+ Brightness = brightness;
Port.DutyCycle = maximumPwmDuty * Brightness;
@@ -179,218 +137,29 @@ public void SetBrightness(float brightness)
}
///
- /// Start a Blink animation which sets the brightness of the LED alternating between a low and high brightness setting.
- ///
- ///
- ///
- ///
- ///
- public void StartBlink(float highBrightness = 1f, float lowBrightness = 0f)
- {
- var onDuration = TimeSpan.FromMilliseconds(500);
- var offDuration = TimeSpan.FromMilliseconds(500);
-
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("offBrightness must be less than onBrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(onDuration, offDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public void StartBlink(TimeSpan onDuration, TimeSpan offDuration, float highBrightness = 1f, float lowBrightness = 0f)
- {
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("offBrightness must be less than onBrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync((TimeSpan)onDuration, (TimeSpan)offDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start blinking the LED
- ///
- /// on duration in ms
- /// off duration in ms
- /// maximum brightness
- /// minimum brightness
- /// token for cancellation
- protected async Task StartBlinkAsync(TimeSpan onDuration, TimeSpan offDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
- {
- while (true)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- Brightness = highBrightness;
- await Task.Delay(onDuration);
- Brightness = lowBrightness;
- await Task.Delay(offDuration);
- }
-
- Port.DutyCycle = IsOn ? maximumPwmDuty : 0;
- }
-
- ///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting.
- ///
- ///
- ///
- public void StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
- {
- var pulseDuration = TimeSpan.FromMilliseconds(600);
-
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "highBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("lowBrightness must be less than highbrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ /// Dispose of the object
///
- ///
- ///
- ///
- public void StartPulse(TimeSpan pulseDuration, float highBrightness = 1, float lowBrightness = 0.15F)
+ public void Dispose()
{
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "highBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("lowBrightness must be less than highbrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
}
///
- /// Start pulsing the led
+ /// Dispose of the object
///
- /// duration in ms
- /// maximum brightness
- /// minimum brightness
- /// token used to cancel pulse
- protected async Task StartPulseAsync(TimeSpan pulseDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
+ /// Is disposing
+ protected virtual void Dispose(bool disposing)
{
- 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)
+ if (!IsDisposed)
{
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- if (brightness <= lowBrightness)
- {
- ascending = true;
- }
- else if (brightness >= highBrightness)
- {
- ascending = false;
- }
-
- brightness += delta * (ascending ? 1 : -1);
-
- if (brightness < 0)
- {
- brightness = 0;
- }
- else if (brightness > 1)
+ if (disposing && createdPwm)
{
- brightness = 1;
+ Port.Dispose();
}
- Brightness = brightness;
-
- await Task.Delay(intervalTime);
+ IsDisposed = true;
}
}
-
- ///
- /// Stops any running animations.
- ///
- public void Stop()
- {
- cancellationTokenSource?.Cancel();
- IsOn = false;
- }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.Animations.cs b/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.Animations.cs
new file mode 100644
index 0000000000..1fbd86cc9f
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.Animations.cs
@@ -0,0 +1,266 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ public partial class PwmLedBarGraph
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask;
+ private CancellationTokenSource? cancellationTokenSource;
+
+ ///
+ /// Stops the LED bar graph when its blinking
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Stops the blinking animation on an individual LED
+ ///
+ /// Index of the LED
+ public Task StopAnimation(int index)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return pwmLeds[index].StopAnimation();
+ }
+
+ ///
+ /// Starts a blink animation on an individual LED
+ ///
+ /// Index of the LED
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartBlink(
+ int index,
+ float highBrightness = 1,
+ float lowBrightness = 0)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return pwmLeds[index].StartBlink(highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Starts a blink animation on an individual LED
+ ///
+ /// Index of the LED
+ /// The duration the LED stays in high brightness
+ /// The duration the LED stays in low brightness
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartBlink(
+ int index,
+ TimeSpan highBrightnessDuration,
+ TimeSpan lowBrightnessDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return pwmLeds[index].StartBlink(highBrightnessDuration, lowBrightnessDuration, highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting.
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartBlink(float highBrightness = 1, float lowBrightness = 0)
+ {
+ return StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
+ ///
+ /// On duration.
+ /// Off duration.
+ /// High brigtness.
+ /// Low brightness.
+ public async Task StartBlink(
+ TimeSpan highBrightnessDuration,
+ TimeSpan lowBrightnessDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0)
+ {
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ foreach (var led in pwmLeds)
+ {
+ led.SetBrightness(highBrightness);
+ }
+ Thread.Sleep(highBrightnessDuration);
+
+ foreach (var led in pwmLeds)
+ {
+ led.SetBrightness(lowBrightness);
+ }
+ Thread.Sleep(lowBrightnessDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Starts a pulse animation on an individual LED
+ ///
+ /// Index of the LED
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartPulse(int index, float highBrightness = 1, float lowBrightness = 0.15F)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return pwmLeds[index].StartPulse(highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Starts a pulse animation on an individual LED with the specified pulse cycle
+ ///
+ /// Index of the LED
+ /// The pulse animation duration
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartPulse(int index, TimeSpan pulseDuration, float highBrightness = 1, float lowBrightness = 0.15F)
+ {
+ if (index < 0 || index >= Count)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return pwmLeds[index].StartPulse(pulseDuration, highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting.
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
+ {
+ return StartPulse(TimeSpan.FromMilliseconds(600), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ ///
+ /// The pulse animation duration
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartPulse(
+ TimeSpan pulseDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0.15F)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ float brightness = lowBrightness;
+ bool ascending = true;
+ var 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 (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ if (brightness <= lowBrightness)
+ {
+ ascending = true;
+ }
+ else if (brightness >= highBrightness)
+ {
+ ascending = false;
+ }
+
+ brightness += delta * (ascending ? 1 : -1);
+
+ if (brightness < lowBrightness)
+ {
+ brightness = lowBrightness;
+ }
+ else if (brightness > highBrightness)
+ {
+ brightness = highBrightness;
+ }
+
+ SetBrightness(brightness);
+
+ Thread.Sleep(intervalTime);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Validates LED brightness to ensure they're within the range 0 (off) - 1 (full brighness)
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ protected void ValidateBrightness(float highBrightness, float lowBrightness)
+ {
+ if (highBrightness > 1 || highBrightness <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
+ }
+ if (lowBrightness >= 1 || lowBrightness < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
+ }
+ if (lowBrightness >= highBrightness)
+ {
+ throw new Exception("offBrightness must be less than onBrightness");
+ }
+ }
+
+ ///
+ /// Returns the index of the last LED turned on
+ ///
+ public int GetTopLedForPercentage()
+ {
+ return (int)Math.Max(0, Percentage * Count - 1);
+ }
+ }
+}
diff --git a/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.cs b/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.cs
index b2c1176792..bb2bcd9f77 100644
--- a/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.cs
+++ b/Source/Meadow.Foundation.Core/Leds/PwmLedBarGraph.cs
@@ -1,7 +1,6 @@
using Meadow.Hardware;
using Meadow.Units;
using System;
-using System.Threading;
using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
@@ -9,11 +8,8 @@ namespace Meadow.Foundation.Leds
///
/// Represents an LED bar graph composed on multiple PWM LEDs
///
- public class PwmLedBarGraph
+ public partial class PwmLedBarGraph
{
- private Task? animationTask;
- private CancellationTokenSource? cancellationTokenSource;
-
///
/// Array to hold pwm leds for bar graph
///
@@ -27,12 +23,7 @@ public class PwmLedBarGraph
///
/// A value between 0 and 1 that controls the number of LEDs that are activated
///
- public float Percentage
- {
- get => percentage;
- set => SetPercentage(percentage = value);
- }
- float percentage;
+ public float Percentage { get; protected set; }
///
/// Create an LedBarGraph instance for single color LED bar graphs
@@ -94,363 +85,79 @@ public PwmLedBarGraph(IPwmPort[] ports, Voltage[] forwardVoltage)
}
}
- ///
- /// Set the percentage of LEDs that are on starting from index 0
- ///
- /// Percentage (Range from 0 - 1)
- protected void SetPercentage(float percentage)
- {
- if (percentage < 0 || percentage > 1)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- var value = percentage * Count;
-
- for (int i = 1; i <= Count; i++)
- {
- if (i <= value)
- {
- SetLed(i - 1, true);
- }
- else if (i <= value + 1)
- {
- SetLedBrightness(i - 1, value + 1 - i);
- }
- else
- {
- SetLed(i - 1, false);
- }
- }
- }
-
- ///
- /// Returns the index of the last LED turned on
- ///
- ///
- public int GetTopLedForPercentage()
- {
- return (int)Math.Max(0, percentage * Count - 1);
- }
-
///
/// Set the LED state
///
- /// index of the LED
- ///
- public void SetLed(int index, bool isOn)
+ /// Index of the LED
+ /// True for on, False for off
+ public async Task SetLed(int index, bool isOn)
{
if (index < 0 || index >= Count)
{
throw new ArgumentOutOfRangeException();
}
- pwmLeds[index].Stop();
+ await pwmLeds[index].StopAnimation();
pwmLeds[index].IsOn = isOn;
}
- ///
- /// Set the brightness to the LED bar graph using PWM
- ///
- ///
- public void SetLedBrightness(double brightness)
- {
- foreach (var led in pwmLeds)
- {
- led.Stop();
- led.IsOn = false;
- led.Brightness = (float)brightness;
- }
- }
-
///
/// Set the brightness of an individual LED when using PWM
///
- ///
- ///
- public void SetLedBrightness(int index, float brightness)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- pwmLeds[index].Stop();
- pwmLeds[index].IsOn = false;
- pwmLeds[index].Brightness = brightness;
- }
-
- ///
- /// Starts a blink animation on an individual LED
- ///
- ///
- ///
- ///
- public void StartBlink(int index, float highBrightness = 1, float lowBrightness = 0)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- pwmLeds[index].StartBlink(highBrightness, lowBrightness);
- }
-
- ///
- /// Starts a blink animation on an individual LED
- ///
- ///
- ///
- ///
- ///
- ///
- public void StartBlink(int index, TimeSpan highBrightnessDuration, TimeSpan lowBrightnessDuration, float highBrightness = 1, float lowBrightness = 0)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- pwmLeds[index].StartBlink(highBrightnessDuration, lowBrightnessDuration, highBrightness, lowBrightness);
- }
-
- ///
- /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting.
- ///
- /// High brigtness.
- /// Low brightness.
- public void StartBlink(float highBrightness = 1, float lowBrightness = 0)
- {
- var highBrightnessDuration = TimeSpan.FromMilliseconds(500);
- var lowBrightnessDuration = TimeSpan.FromMilliseconds(500);
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(highBrightnessDuration, lowBrightnessDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
- ///
- /// On duration.
- /// Off duration.
- /// High brigtness.
- /// Low brightness.
- public void StartBlink(TimeSpan highBrightnessDuration, TimeSpan lowBrightnessDuration, float highBrightness = 1, float lowBrightness = 0)
- {
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(highBrightnessDuration, lowBrightnessDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Set LED to blink
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- protected async Task StartBlinkAsync(TimeSpan onDuration, TimeSpan offDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
- {
- while (true)
- {
- 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);
- }
- }
-
- ///
- /// Starts a pulse animation on an individual LED
- ///
- ///
- ///
- ///
- public void StartPulse(int index, float highBrightness = 1, float lowBrightness = 0.15F)
+ /// Index of the LED
+ /// Valid values are from 0 to 1, inclusive
+ public async Task SetLedBrightness(int index, float brightness)
{
if (index < 0 || index >= Count)
{
throw new ArgumentOutOfRangeException();
}
- pwmLeds[index].StartPulse(highBrightness, lowBrightness);
+ await pwmLeds[index].StopAnimation();
+ pwmLeds[index].SetBrightness(brightness);
}
///
- /// Starts a pulse animation on an individual LED with the specified pulse cycle
+ /// Set the percentage of LEDs that are on starting from index 0
///
- ///
- ///
- ///
- ///
- public void StartPulse(int index, TimeSpan pulseDuration, float highBrightness = 1, float lowBrightness = 0.15F)
+ /// Percentage (Range from 0 - 1)
+ public async Task SetPercentage(float percentage)
{
- if (index < 0 || index >= Count)
+ if (percentage < 0 || percentage > 1)
{
throw new ArgumentOutOfRangeException();
}
- pwmLeds[index].StartPulse(pulseDuration, highBrightness, lowBrightness);
- }
-
- ///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting.
- ///
- ///
- ///
- public void StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
- {
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "highBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("lowBrightness must be less than highbrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(TimeSpan.FromSeconds(1), highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
- ///
- ///
- ///
- ///
- public void StartPulse(TimeSpan pulseDuration, float highBrightness = 1, float lowBrightness = 0.15F)
- {
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "highBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("lowBrightness must be less than highbrightness");
- }
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
- ///
- ///
- ///
- ///
- ///
- ///
- 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;
+ var value = percentage * Count;
- while (true)
+ for (int i = 1; i <= Count; i++)
{
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- if (brightness <= lowBrightness)
+ if (i <= value)
{
- ascending = true;
+ await SetLed(i - 1, true);
}
- else if (brightness >= highBrightness)
+ else if (i <= value + 1)
{
- ascending = false;
+ await SetLedBrightness(i - 1, value + 1 - i);
}
-
- brightness += delta * (ascending ? 1 : -1);
-
- foreach (var led in pwmLeds)
+ else
{
- led.Brightness = Math.Clamp(brightness, 0, 1);
+ await SetLed(i - 1, false);
}
-
- await Task.Delay(intervalTime);
}
}
///
- /// Stops any running animations.
+ /// Set the brightness to the LED bar graph using PWM
///
- public void Stop()
+ /// Valid values are from 0 to 1, inclusive
+ public async Task SetBrightness(float brightness)
{
- cancellationTokenSource?.Cancel();
-
foreach (var led in pwmLeds)
{
- led.Stop();
+ await led.StopAnimation();
+ led.SetBrightness(brightness);
}
}
-
- ///
- /// Stops any animation on an individual LED and/or turns it off
- ///
- public void Stop(int index)
- {
- if (index < 0 || index >= Count)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- pwmLeds[index].Stop();
- }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/RgbLed.Animations.cs b/Source/Meadow.Foundation.Core/Leds/RgbLed.Animations.cs
new file mode 100644
index 0000000000..14bc482610
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/RgbLed.Animations.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ ///
+ /// Utility functions to provide blinking and pulsing for RgbLed
+ ///
+ public partial class RgbLed
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask = null;
+ private CancellationTokenSource? cancellationTokenSource = null;
+
+ ///
+ /// Stops the current LED animation
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off on an interval of 1 second (500ms on, 500ms off)
+ ///
+ public Task StartBlink()
+ {
+ return StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500));
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off on an interval of 1 second (500ms on, 500ms off)
+ ///
+ /// The LED color
+ public Task StartBlink(RgbLedColors color)
+ {
+ return StartBlink(color, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500));
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off with the especified durations and color
+ ///
+ /// The LED color
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ public async Task StartBlink(
+ RgbLedColors color,
+ TimeSpan onDuration,
+ TimeSpan offDuration)
+ {
+ await StopAnimation();
+
+ SetColor(color);
+
+ await StartBlink(onDuration, offDuration);
+ }
+
+ ///
+ /// Start the Blink animation which sets turns the LED on and off with the especified durations and current color
+ ///
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ public async Task StartBlink(TimeSpan onDuration, TimeSpan offDuration)
+ {
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ IsOn = true;
+ Thread.Sleep(onDuration);
+
+ IsOn = false;
+ Thread.Sleep(offDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+ }
+}
diff --git a/Source/Meadow.Foundation.Core/Leds/RgbLed.cs b/Source/Meadow.Foundation.Core/Leds/RgbLed.cs
index a173b2e6d1..16aaf32ab3 100644
--- a/Source/Meadow.Foundation.Core/Leds/RgbLed.cs
+++ b/Source/Meadow.Foundation.Core/Leds/RgbLed.cs
@@ -1,8 +1,5 @@
using Meadow.Hardware;
using Meadow.Peripherals.Leds;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
{
@@ -11,31 +8,28 @@ namespace Meadow.Foundation.Leds
///
public partial class RgbLed : IRgbLed
{
- private Task? animationTask;
- private CancellationTokenSource? cancellationTokenSource;
-
///
- /// Get the color the LED has been set to.
+ /// The current LED color
///
public RgbLedColors Color { get; protected set; } = RgbLedColors.White;
///
- /// Get the red LED port
+ /// The red LED port
///
protected IDigitalOutputPort RedPort { get; set; }
///
- /// Get the green LED port
+ /// The green LED port
///
protected IDigitalOutputPort GreenPort { get; set; }
///
- /// Get the blue LED port
+ ///The blue LED port
///
protected IDigitalOutputPort BluePort { get; set; }
///
- /// Is the LED using a common cathode
+ /// The common type (common annode or common cathode)
///
public CommonType Common { get; protected set; }
@@ -45,16 +39,12 @@ public partial class RgbLed : IRgbLed
public bool IsOn
{
get => isOn;
- set
- {
- SetColor(value ? Color : RgbLedColors.Black);
- isOn = value;
- }
+ set => UpdateLed(isOn = value);
}
bool isOn;
///
- /// Initializes a new instance of the class.
+ /// Create instance of RgbLed
///
/// Red Pin
/// Green Pin
@@ -73,7 +63,7 @@ public RgbLed(
{ }
///
- /// Initializes a new instance of the class.
+ /// Create instance of RgbLed
///
/// Red Port
/// Green Port
@@ -91,127 +81,71 @@ public RgbLed(
Common = commonType;
}
- ///
- /// Stops any running animations.
- ///
- public void Stop()
- {
- cancellationTokenSource?.Cancel();
- IsOn = false;
- }
-
///
/// Sets the current color of the LED.
///
- ///
+ /// The color value
public void SetColor(RgbLedColors color)
{
Color = color;
- bool onState = (Common == CommonType.CommonCathode);
-
- switch (color)
- {
- case RgbLedColors.Red:
- RedPort.State = onState;
- GreenPort.State = !onState;
- BluePort.State = !onState;
- break;
- case RgbLedColors.Green:
- RedPort.State = !onState;
- GreenPort.State = onState;
- BluePort.State = !onState;
- break;
- case RgbLedColors.Blue:
- RedPort.State = !onState;
- GreenPort.State = !onState;
- BluePort.State = onState;
- break;
- case RgbLedColors.Yellow:
- RedPort.State = onState;
- GreenPort.State = onState;
- BluePort.State = !onState;
- break;
- case RgbLedColors.Magenta:
- RedPort.State = onState;
- GreenPort.State = !onState;
- BluePort.State = onState;
- break;
- case RgbLedColors.Cyan:
- RedPort.State = !onState;
- GreenPort.State = onState;
- BluePort.State = onState;
- break;
- case RgbLedColors.White:
- RedPort.State = onState;
- GreenPort.State = onState;
- BluePort.State = onState;
- break;
- case RgbLedColors.Black:
- RedPort.State = !onState;
- GreenPort.State = !onState;
- BluePort.State = !onState;
- break;
- }
- }
-
- ///
- /// Starts the blink animation LED turning it on (500) and off (500)
- ///
- ///
- public void StartBlink(RgbLedColors color)
- {
- var onDuration = TimeSpan.FromMilliseconds(500);
- var offDuration = TimeSpan.FromMilliseconds(500);
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(color, onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ IsOn = true;
}
///
- /// Starts the blink animation with the specified on and off duration.
+ /// Turns on LED with current color or LED off
///
- ///
- ///
- ///
- public void StartBlink(RgbLedColors color, TimeSpan onDuration, TimeSpan offDuration)
+ /// True for on, False for off
+ protected void UpdateLed(bool isOn)
{
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(color, onDuration, offDuration, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
+ bool onState = (Common == CommonType.CommonCathode);
- ///
- /// Turn the LED on and off (blink)
- ///
- ///
- ///
- ///
- ///
- protected async Task StartBlinkAsync(RgbLedColors color, TimeSpan onDuration, TimeSpan offDuration, CancellationToken cancellationToken)
- {
- while (true)
+ if (isOn)
{
- if (cancellationToken.IsCancellationRequested)
+ switch (Color)
{
- break;
+ case RgbLedColors.Red:
+ RedPort.State = onState;
+ GreenPort.State = !onState;
+ BluePort.State = !onState;
+ break;
+ case RgbLedColors.Green:
+ RedPort.State = !onState;
+ GreenPort.State = onState;
+ BluePort.State = !onState;
+ break;
+ case RgbLedColors.Blue:
+ RedPort.State = !onState;
+ GreenPort.State = !onState;
+ BluePort.State = onState;
+ break;
+ case RgbLedColors.Yellow:
+ RedPort.State = onState;
+ GreenPort.State = onState;
+ BluePort.State = !onState;
+ break;
+ case RgbLedColors.Magenta:
+ RedPort.State = onState;
+ GreenPort.State = !onState;
+ BluePort.State = onState;
+ break;
+ case RgbLedColors.Cyan:
+ RedPort.State = !onState;
+ GreenPort.State = onState;
+ BluePort.State = onState;
+ break;
+ case RgbLedColors.White:
+ RedPort.State = onState;
+ GreenPort.State = onState;
+ BluePort.State = onState;
+ break;
}
-
- SetColor(color);
- await Task.Delay(onDuration);
- SetColor(RgbLedColors.Black);
- await Task.Delay(offDuration);
+ }
+ else
+ {
+ RedPort.State = !onState;
+ GreenPort.State = !onState;
+ BluePort.State = !onState;
}
}
}
diff --git a/Source/Meadow.Foundation.Core/Leds/RgbLedColors.cs b/Source/Meadow.Foundation.Core/Leds/RgbLedColors.cs
new file mode 100644
index 0000000000..fa731d899f
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/RgbLedColors.cs
@@ -0,0 +1,41 @@
+namespace Meadow.Foundation.Leds
+{
+ ///
+ /// Colors for RGB Led
+ ///
+ public enum RgbLedColors
+ {
+ ///
+ /// Red (red LED only)
+ ///
+ Red,
+ ///
+ /// Green (green LED only)
+ ///
+ Green,
+ ///
+ /// Blue (blue LED only)
+ ///
+ Blue,
+ ///
+ /// Yellow (red and green LEDs)
+ ///
+ Yellow,
+ ///
+ /// Magenta (blue and red LEDs)
+ ///
+ Magenta,
+ ///
+ /// Cyan (blue and green LEDs)
+ ///
+ Cyan,
+ ///
+ /// White (red, green and blue LEDs)
+ ///
+ White,
+ ///
+ /// Count of colors
+ ///
+ count,
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.Animations.cs b/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.Animations.cs
new file mode 100644
index 0000000000..f45cc7cd22
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.Animations.cs
@@ -0,0 +1,248 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Leds
+{
+ ///
+ /// Utility functions to provide blinking and pulsing for RgbPwmLed
+ ///
+ public partial class RgbPwmLed
+ {
+ private object syncRoot = new object();
+
+ private Task? animationTask = null;
+ private CancellationTokenSource? cancellationTokenSource = null;
+
+ ///
+ /// Stops the current LED animation
+ ///
+ public async Task StopAnimation()
+ {
+ if (animationTask != null)
+ {
+ cancellationTokenSource?.Cancel();
+ await animationTask;
+ animationTask = null;
+ cancellationTokenSource = null;
+ }
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness
+ /// On an interval of 1 second (500ms on, 500ms off)
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartBlink(float highBrightness = 1f, float lowBrightness = 0f)
+ {
+ return StartBlink(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness
+ /// On an interval of 1 second (500ms on, 500ms off)
+ ///
+ /// The LED color
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartBlink(
+ Color color,
+ float highBrightness = 1f,
+ float lowBrightness = 0f)
+ {
+ return StartBlink(color, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
+ ///
+ /// The LED color
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+
+ public async Task StartBlink(
+ Color color,
+ TimeSpan onDuration,
+ TimeSpan offDuration,
+ float highBrightness = 1f,
+ float lowBrightness = 0f)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ SetColor(color);
+
+ await StartBlink(onDuration, offDuration, highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
+ ///
+ /// The duration the LED stays on
+ /// The duration the LED stays off
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+
+ public async Task StartBlink(
+ TimeSpan onDuration,
+ TimeSpan offDuration,
+ float highBrightness = 1f,
+ float lowBrightness = 0f)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ while (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ SetBrightness(highBrightness);
+ Thread.Sleep(onDuration);
+
+ SetBrightness(lowBrightness);
+ Thread.Sleep(offDuration);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting
+ /// with a cycle time of 600ms
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartPulse(float highBrightness = 1, float lowBrightness = 0.15F)
+ {
+ return StartPulse(TimeSpan.FromMilliseconds(600), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting
+ /// with a cycle time of 600ms
+ ///
+ /// The LED color
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public Task StartPulse(
+ Color color,
+ float highBrightness = 1,
+ float lowBrightness = 0.15F)
+ {
+ return StartPulse(color, TimeSpan.FromMilliseconds(600), highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ ///
+ /// The LED color
+ /// The pulse animation duration
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartPulse(
+ Color color,
+ TimeSpan pulseDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0.15F)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ SetColor(color);
+
+ await StartPulse(pulseDuration, highBrightness, lowBrightness);
+ }
+
+ ///
+ /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ ///
+ /// The pulse animation duration
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ public async Task StartPulse(
+ TimeSpan pulseDuration,
+ float highBrightness = 1,
+ float lowBrightness = 0.15F)
+ {
+ ValidateBrightness(highBrightness, lowBrightness);
+
+ await StopAnimation();
+
+ lock (syncRoot)
+ {
+ cancellationTokenSource = new CancellationTokenSource();
+
+ animationTask = new Task(() =>
+ {
+ float brightness = lowBrightness;
+ bool ascending = true;
+ var 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 (cancellationTokenSource.Token.IsCancellationRequested == false)
+ {
+ if (brightness <= lowBrightness)
+ {
+ ascending = true;
+ }
+ else if (brightness >= highBrightness)
+ {
+ ascending = false;
+ }
+
+ brightness += delta * (ascending ? 1 : -1);
+
+ if (brightness < lowBrightness)
+ {
+ brightness = lowBrightness;
+ }
+ else if (brightness > highBrightness)
+ {
+ brightness = highBrightness;
+ }
+
+ SetBrightness(brightness);
+
+ Thread.Sleep(intervalTime);
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
+
+ animationTask.Start();
+ }
+ }
+
+ ///
+ /// Validates LED brightness to ensure they're within the range 0 (off) - 1 (full brighness)
+ ///
+ /// The maximum brightness of the animation
+ /// The minimum brightness of the animation
+ protected void ValidateBrightness(float highBrightness, float lowBrightness)
+ {
+ if (highBrightness > 1 || highBrightness <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
+ }
+ if (lowBrightness >= 1 || lowBrightness < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
+ }
+ if (lowBrightness >= highBrightness)
+ {
+ throw new Exception("offBrightness must be less than onBrightness");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.cs b/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.cs
index 122ddd87a4..31dbf78b77 100644
--- a/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.cs
+++ b/Source/Meadow.Foundation.Core/Leds/RgbPwmLed.cs
@@ -2,25 +2,18 @@
using Meadow.Peripherals.Leds;
using Meadow.Units;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace Meadow.Foundation.Leds
{
///
- /// Represents a Pulse-Width-Modulation (PWM) controlled RGB LED. Controlling an RGB LED with
- /// PWM allows for more colors to be expressed than if it were simply controlled with normal
- /// digital outputs which provide only binary control at each pin. As such, a PWM controlled
- /// RGB LED can express millions of colors, as opposed to the 8 colors that can be expressed
- /// via binary digital output.
+ /// Represents a Pulse-Width-Modulation (PWM) controlled RGB LED
///
- public class RgbPwmLed
+ public partial class RgbPwmLed
{
- private Task? animationTask = null;
- private CancellationTokenSource? cancellationTokenSource = null;
-
static readonly Frequency DefaultFrequency = new Frequency(200, Frequency.UnitType.Hertz);
+
readonly float DEFAULT_DUTY_CYCLE = 0f;
+
readonly double maxRedDutyCycle = 1;
readonly double maxGreenDutyCycle = 1;
readonly double maxBlueDutyCycle = 1;
@@ -50,66 +43,66 @@ public bool IsOn
bool isOn;
///
- /// The color the LED has been set to.
+ /// The current LED color
///
public Color Color { get; protected set; } = Color.White;
///
- /// The brightness value assigned to the LED relative to Color
+ /// The brightness value assigned to the LED
///
public float Brightness { get; protected set; } = 1f;
///
- /// Get the red LED port
+ /// The red LED port
///
protected IPwmPort RedPwm { get; set; }
///
- /// Get the blue LED port
+ /// The blue LED port
///
protected IPwmPort BluePwm { get; set; }
///
- /// Get the green LED port
+ /// The green LED port
///
protected IPwmPort GreenPwm { get; set; }
///
- /// Gets the common type
+ /// The common type (common annode or common cathode)
///
public CommonType Common { get; protected set; }
///
- /// Get the red LED forward voltage
+ /// The red LED forward voltage
///
public Voltage RedForwardVoltage { get; protected set; }
///
- /// Get the green LED forward voltage
+ /// The green LED forward voltage
///
public Voltage GreenForwardVoltage { get; protected set; }
///
- /// Get the blue LED forward voltage
+ /// The blue LED forward voltage
///
public Voltage BlueForwardVoltage { get; protected set; }
///
- /// Create instance of RgbPwmLed
+ /// Create instance of RgbPwmLed
///
- ///
- ///
- ///
- ///
+ /// The PWM port for the red LED
+ /// The PWM port for the green LED
+ /// The PWM port for the blue LED
+ /// Common annode or common cathode
public RgbPwmLed(
- IPwmPort redPwm,
- IPwmPort greenPwm,
- IPwmPort bluePwm,
+ IPwmPort redPwmPort,
+ IPwmPort greenPwmPort,
+ IPwmPort bluePwmPort,
CommonType commonType = CommonType.CommonCathode)
{
- RedPwm = redPwm;
- GreenPwm = greenPwm;
- BluePwm = bluePwm;
+ RedPwm = redPwmPort;
+ GreenPwm = greenPwmPort;
+ BluePwm = bluePwmPort;
RedForwardVoltage = TypicalForwardVoltage.Red;
GreenForwardVoltage = TypicalForwardVoltage.Green;
@@ -117,21 +110,20 @@ public RgbPwmLed(
Common = commonType;
- // calculate and set maximum PWM duty cycles
maxRedDutyCycle = Helpers.CalculateMaximumDutyCycle(RedForwardVoltage);
maxGreenDutyCycle = Helpers.CalculateMaximumDutyCycle(GreenForwardVoltage);
maxBlueDutyCycle = Helpers.CalculateMaximumDutyCycle(BlueForwardVoltage);
- ResetPwms();
+ ResetPwmPorts();
}
///
- /// Create instance of RgbPwmLed
+ /// Create instance of RgbPwmLed
///
- ///
- ///
- ///
- ///
+ /// The PWM pin for the red LED
+ /// The PWM pin for the green LED
+ /// The PWM pin for the blue LED
+ /// Common annode or common cathode
public RgbPwmLed(
IPin redPwmPin,
IPin greenPwmPin,
@@ -145,16 +137,15 @@ public RgbPwmLed(
{ }
///
- /// Instantiates a RgbPwmLed object with the especified IO device, connected
- /// to three digital pins for red, green and blue channels, respectively
+ /// Create instance of RgbPwmLed
///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// The PWM pin for the red LED
+ /// The PWM pin for the green LED
+ /// The PWM pin for the blue LED
+ /// The forward voltage for the red LED
+ /// The forward voltage for the green LED
+ /// The forward voltage for the blue LED
+ /// Common annode or common cathode
public RgbPwmLed(
IPin redPwmPin,
IPin greenPwmPin,
@@ -174,317 +165,117 @@ public RgbPwmLed(
{ }
///
- ///
- /// Implementation notes: Architecturally, it would be much cleaner to construct this class
- /// as three PwmLeds. Then each one's implementation would be self-contained. However, that
- /// would require three additional threads during ON; one contained by each PwmLed. For this
- /// reason, I'm basically duplicating the functionality for all three in here.
+ /// Create instance of RgbPwmLed
///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// The PWM port for the red LED
+ /// The PWM port for the green LED
+ /// The PWM port for the blue LED
+ /// The forward voltage for the red LED
+ /// The forward voltage for the green LED
+ /// The forward voltage for the blue LED
+ /// Common annode or common cathode
public RgbPwmLed(
- IPwmPort redPwm,
- IPwmPort greenPwm,
- IPwmPort bluePwm,
+ IPwmPort redPwmPort,
+ IPwmPort greenPwmPort,
+ IPwmPort bluePwmPort,
Voltage redLedForwardVoltage,
Voltage greenLedForwardVoltage,
Voltage blueLedForwardVoltage,
CommonType commonType = CommonType.CommonCathode)
{
- // validate and persist forward voltages
- if (redLedForwardVoltage < MIN_FORWARD_VOLTAGE || redLedForwardVoltage > MAX_FORWARD_VOLTAGE)
- {
- throw new ArgumentOutOfRangeException(nameof(redLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
- }
- RedForwardVoltage = redLedForwardVoltage;
+ ValidateForwardVoltages(redLedForwardVoltage, greenLedForwardVoltage, blueLedForwardVoltage);
- if (greenLedForwardVoltage < MIN_FORWARD_VOLTAGE || greenLedForwardVoltage > MAX_FORWARD_VOLTAGE)
- {
- throw new ArgumentOutOfRangeException(nameof(greenLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
- }
+ RedForwardVoltage = redLedForwardVoltage;
GreenForwardVoltage = greenLedForwardVoltage;
-
- if (blueLedForwardVoltage < MIN_FORWARD_VOLTAGE || blueLedForwardVoltage > MAX_FORWARD_VOLTAGE)
- {
- throw new ArgumentOutOfRangeException(nameof(blueLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
- }
BlueForwardVoltage = blueLedForwardVoltage;
Common = commonType;
- RedPwm = redPwm;
- GreenPwm = greenPwm;
- BluePwm = bluePwm;
+ RedPwm = redPwmPort;
+ GreenPwm = greenPwmPort;
+ BluePwm = bluePwmPort;
- // calculate and set maximum PWM duty cycles
maxRedDutyCycle = Helpers.CalculateMaximumDutyCycle(RedForwardVoltage);
maxGreenDutyCycle = Helpers.CalculateMaximumDutyCycle(GreenForwardVoltage);
maxBlueDutyCycle = Helpers.CalculateMaximumDutyCycle(BlueForwardVoltage);
- ResetPwms();
- }
-
- ///
- /// Resets all PWM ports
- ///
- protected void ResetPwms()
- {
- RedPwm.Frequency = GreenPwm.Frequency = BluePwm.Frequency = DefaultFrequency;
- RedPwm.DutyCycle = GreenPwm.DutyCycle = BluePwm.DutyCycle = DEFAULT_DUTY_CYCLE;
- // invert the PWM signal if it common anode
- RedPwm.Inverted = GreenPwm.Inverted = BluePwm.Inverted
- = (Common == CommonType.CommonAnode);
-
- RedPwm.Start(); GreenPwm.Start(); BluePwm.Start();
+ ResetPwmPorts();
}
///
- /// Sets the current color of the LED.
+ /// Validates forward voltages to ensure they're within the range MIN_FORWARD_VOLTAGE to MAX_FORWARD_VOLTAGE
///
- ///
- ///
- public void SetColor(Color color, float brightness = 1)
+ /// The forward voltage for the red LED
+ /// The forward voltage for the green LED
+ /// The forward voltage for the blue LED
+ protected void ValidateForwardVoltages(Voltage redLedForwardVoltage,
+ Voltage greenLedForwardVoltage,
+ Voltage blueLedForwardVoltage)
{
- if (color == Color && brightness == Brightness)
+ if (redLedForwardVoltage < MIN_FORWARD_VOLTAGE || redLedForwardVoltage > MAX_FORWARD_VOLTAGE)
{
- return;
+ throw new ArgumentOutOfRangeException(nameof(redLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
}
- Color = color;
- Brightness = brightness;
-
- RedPwm.DutyCycle = (float)(Color.R / 255.0 * maxRedDutyCycle * brightness);
- GreenPwm.DutyCycle = (float)(Color.G / 255.0 * maxGreenDutyCycle * brightness);
- BluePwm.DutyCycle = (float)(Color.B / 255.0 * maxBlueDutyCycle * brightness);
- }
-
- ///
- /// Stops any running animations.
- ///
- public void Stop()
- {
- cancellationTokenSource?.Cancel();
- IsOn = false;
- }
-
- ///
- /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting.
- ///
- ///
- ///
- ///
- public void StartBlink(Color color, float highBrightness = 1f, float lowBrightness = 0f)
- {
- var onDuration = TimeSpan.FromMilliseconds(500);
- var offDuration = TimeSpan.FromMilliseconds(500);
-
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
+ if (greenLedForwardVoltage < MIN_FORWARD_VOLTAGE || greenLedForwardVoltage > MAX_FORWARD_VOLTAGE)
{
- throw new Exception("offBrightness must be less than onBrightness");
+ throw new ArgumentOutOfRangeException(nameof(greenLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
}
- Color = color;
-
- Stop();
-
- animationTask = new Task(async () =>
+ if (blueLedForwardVoltage < MIN_FORWARD_VOLTAGE || blueLedForwardVoltage > MAX_FORWARD_VOLTAGE)
{
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(color, (TimeSpan)onDuration, (TimeSpan)offDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ throw new ArgumentOutOfRangeException(nameof(blueLedForwardVoltage), "error, forward voltage must be between 0, and 3.3");
+ }
}
///
- /// Start the Blink animation which sets the brightness of the LED alternating between a low and high brightness setting, using the durations provided.
+ /// Resets all PWM ports
///
- ///
- ///
- ///
- ///
- ///
- public void StartBlink(Color color, TimeSpan onDuration, TimeSpan offDuration, float highBrightness = 1f, float lowBrightness = 0f)
+ protected void ResetPwmPorts()
{
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("offBrightness must be less than onBrightness");
- }
-
- Color = color;
-
- Stop();
+ RedPwm.Frequency = GreenPwm.Frequency = BluePwm.Frequency = DefaultFrequency;
+ RedPwm.DutyCycle = GreenPwm.DutyCycle = BluePwm.DutyCycle = DEFAULT_DUTY_CYCLE;
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartBlinkAsync(color, onDuration, offDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
+ // invert the PWM signal if it common anode
+ RedPwm.Inverted = GreenPwm.Inverted = BluePwm.Inverted = Common == CommonType.CommonAnode;
- ///
- /// Start blinking led
- ///
- /// color to blink
- /// on duration in ms
- /// off duration in ms
- /// maximum brightness
- /// minimum brightness
- /// token to cancel blink
- protected async Task StartBlinkAsync(Color color, TimeSpan onDuration, TimeSpan offDuration, float highBrightness, float lowBrightness, CancellationToken cancellationToken)
- {
- while (true)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- SetColor(color, highBrightness);
- await Task.Delay(onDuration);
- SetColor(color, lowBrightness);
- await Task.Delay(offDuration);
- }
+ RedPwm.Start();
+ GreenPwm.Start();
+ BluePwm.Start();
}
///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting.
+ /// Set the led brightness
///
- ///
- ///
- ///
- public void StartPulse(Color color, float highBrightness = 1, float lowBrightness = 0.15F)
+ /// Valid values are from 0 to 1, inclusive
+ public void SetBrightness(float brightness)
{
- var pulseDuration = TimeSpan.FromMilliseconds(600);
-
- if (highBrightness > 1 || highBrightness <= 0)
+ if (brightness < 0 || brightness > 1)
{
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
- {
- throw new Exception("offBrightness must be less than onBrightness");
+ throw new ArgumentOutOfRangeException(nameof(brightness), "error, brightness must be between 0, and 1");
}
- Color = color;
-
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(color, pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
+ SetColor(Color, brightness);
}
///
- /// Start the Pulse animation which gradually alternates the brightness of the LED between a low and high brightness setting, using the durations provided.
+ /// Sets the current color of the LED
///
- ///
- ///
- ///
- ///
- public void StartPulse(Color color, TimeSpan pulseDuration, float highBrightness = 1, float lowBrightness = 0.15F)
+ /// The LED color
+ /// Valid values are from 0 to 1, inclusive
+ public void SetColor(Color color, float brightness = 1)
{
- if (highBrightness > 1 || highBrightness <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(highBrightness), "onBrightness must be > 0 and <= 1");
- }
- if (lowBrightness >= 1 || lowBrightness < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lowBrightness), "lowBrightness must be >= 0 and < 1");
- }
- if (lowBrightness >= highBrightness)
+ if (color == Color && brightness == Brightness)
{
- throw new Exception("offBrightness must be less than onBrightness");
+ return;
}
Color = color;
+ Brightness = brightness;
- Stop();
-
- animationTask = new Task(async () =>
- {
- cancellationTokenSource = new CancellationTokenSource();
- await StartPulseAsync(color, pulseDuration, highBrightness, lowBrightness, cancellationTokenSource.Token);
- });
- animationTask.Start();
- }
-
- ///
- /// Start led pulsing
- ///
- /// color to pulse
- /// pulse duration in ms
- /// maximum brightness
- /// minimum brightness
- /// token to cancel pulse
- protected async Task StartPulseAsync(Color color, 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)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- if (brightness <= lowBrightness)
- {
- ascending = true;
- }
- else if (brightness >= highBrightness)
- {
- ascending = false;
- }
-
- brightness += delta * (ascending ? 1 : -1);
-
- if (brightness < 0)
- {
- brightness = 0;
- }
- else
- if (brightness > 1)
- {
- brightness = 1;
- }
-
- SetColor(color, brightness);
-
- await Task.Delay(intervalTime);
- }
+ RedPwm.DutyCycle = (float)(Color.R / 255.0 * maxRedDutyCycle * brightness);
+ GreenPwm.DutyCycle = (float)(Color.G / 255.0 * maxGreenDutyCycle * brightness);
+ BluePwm.DutyCycle = (float)(Color.B / 255.0 * maxBlueDutyCycle * brightness);
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/PollingSensorBase.cs b/Source/Meadow.Foundation.Core/PollingSensorBase.cs
index 318e4331ef..9847dc131a 100644
--- a/Source/Meadow.Foundation.Core/PollingSensorBase.cs
+++ b/Source/Meadow.Foundation.Core/PollingSensorBase.cs
@@ -26,14 +26,14 @@ public abstract class PollingSensorBase
/// The default is 5 seconds.
public override void StartUpdating(TimeSpan? updateInterval = null)
{
- lock (samplingLock)
+ lock (samplingLock)
{
if (IsSampling) { return; }
IsSampling = true;
// if an update interval has been passed in, override the default
- if(updateInterval is { } ui) { base.UpdateInterval = ui; }
+ if (updateInterval is { } ui) { base.UpdateInterval = ui; }
base.SamplingTokenSource = new CancellationTokenSource();
CancellationToken ct = SamplingTokenSource.Token;
@@ -41,11 +41,11 @@ public override void StartUpdating(TimeSpan? updateInterval = null)
UNIT oldConditions;
ChangeResult result;
- Task.Run(async () =>
+ var t = new Task(async () =>
{
- while (true)
+ while (true)
{
- if (ct.IsCancellationRequested)
+ if (ct.IsCancellationRequested)
{
observers.ForEach(x => x.OnCompleted());
IsSampling = false;
@@ -61,7 +61,8 @@ public override void StartUpdating(TimeSpan? updateInterval = null)
await Task.Delay(UpdateInterval);
}
- }, SamplingTokenSource.Token);
+ }, SamplingTokenSource.Token, TaskCreationOptions.LongRunning);
+ t.Start();
}
}
@@ -70,7 +71,7 @@ public override void StartUpdating(TimeSpan? updateInterval = null)
///
public override void StopUpdating()
{
- lock (samplingLock)
+ lock (samplingLock)
{
if (!IsSampling) { return; }
diff --git a/Source/Meadow.Foundation.Core/SamplingSensorBase.cs b/Source/Meadow.Foundation.Core/SamplingSensorBase.cs
index 747216a2c1..2d083e2f09 100644
--- a/Source/Meadow.Foundation.Core/SamplingSensorBase.cs
+++ b/Source/Meadow.Foundation.Core/SamplingSensorBase.cs
@@ -67,10 +67,9 @@ protected virtual void RaiseEventsAndNotify(IChangeResult changeResult)
/// Convenience method to get the current sensor readings. For frequent reads, use
/// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
///
- public virtual async Task Read()
+ public virtual Task Read()
{
- Conditions = await ReadSensor();
- return Conditions;
+ return ReadSensor();
}
///
diff --git a/Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs b/Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs
index 8495ba060f..9d4177cc0f 100644
--- a/Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs
+++ b/Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs
@@ -39,7 +39,7 @@ public TimeSpan DebounceDuration
///
/// The button state polling interval for PushButton instances that are created
- /// from a port that doesn't have an tnterrupt mode of EdgeBoth - otherwise ignored
+ /// from a port that doesn't have an interrupt mode of EdgeBoth - otherwise ignored
///
public TimeSpan ButtonPollingInterval { get; set; } = TimeSpan.FromMilliseconds(100);
@@ -141,7 +141,7 @@ public PushButton(IDigitalInputPort inputPort)
bool currentState = DigitalIn.State;
- _ = Task.Run(async () =>
+ var t = new Task(async () =>
{
while (!ctsPolling.Token.IsCancellationRequested)
{
@@ -152,7 +152,8 @@ public PushButton(IDigitalInputPort inputPort)
await Task.Delay(ButtonPollingInterval);
}
- });
+ }, ctsPolling.Token, TaskCreationOptions.LongRunning);
+ t.Start();
}
}
diff --git a/Source/Meadow.Foundation.Core/Sensors/Hid/DigitalJoystick.cs b/Source/Meadow.Foundation.Core/Sensors/Hid/DigitalJoystick.cs
new file mode 100644
index 0000000000..b0e49a2250
--- /dev/null
+++ b/Source/Meadow.Foundation.Core/Sensors/Hid/DigitalJoystick.cs
@@ -0,0 +1,145 @@
+using Meadow.Foundation.Sensors.Buttons;
+using Meadow.Hardware;
+using Meadow.Peripherals.Sensors.Hid;
+using System;
+
+namespace Meadow.Foundation.Sensors.Hid
+{
+ ///
+ /// Represents a 4 switch digital joystick / directional pad (D-pad)
+ ///
+ public class DigitalJoystick : IDigitalJoystick
+ {
+ ///
+ /// Get the current digital joystick position
+ ///
+ public DigitalJoystickPosition? Position { get; protected set; } = DigitalJoystickPosition.Center;
+
+ ///
+ /// Raised when the digital joystick position changes
+ ///
+ public event EventHandler> Updated = delegate { };
+
+ ///
+ /// The PushButton class for the up digital joystick switch
+ ///
+ public PushButton ButtonUp { get; protected set; }
+ ///
+ /// The PushButton class for the down digital joystick switch
+ ///
+ public PushButton ButtonDown { get; protected set; }
+ ///
+ /// The PushButton class for the left digital joystick switch
+ ///
+ public PushButton ButtonLeft { get; protected set; }
+ ///
+ /// The PushButton class for the right digital joystick switch
+ ///
+ public PushButton ButtonRight { get; protected set; }
+
+ ///
+ /// Create a new DigitalJoystick object
+ ///
+ /// The pin connected to the up switch
+ /// The pin connected to the down switch
+ /// The pin connected to the left switch
+ /// The pin connected to the right switch
+ /// The resistor mode for all pins
+ public DigitalJoystick(IPin pinUp, IPin pinDown, IPin pinLeft, IPin pinRight, ResistorMode resistorMode)
+ : this(pinUp.CreateDigitalInputPort(InterruptMode.EdgeBoth, resistorMode),
+ pinDown.CreateDigitalInputPort(InterruptMode.EdgeBoth, resistorMode),
+ pinLeft.CreateDigitalInputPort(InterruptMode.EdgeBoth, resistorMode),
+ pinRight.CreateDigitalInputPort(InterruptMode.EdgeBoth, resistorMode))
+ { }
+
+ ///
+ /// Create a new DigitalJoystick object
+ ///
+ /// The digital port for the up switch
+ /// The digital port for the down switch
+ /// The digital port for the left switch
+ /// The digital port for the right switch
+ public DigitalJoystick(IDigitalInputPort portUp,
+ IDigitalInputPort portDown,
+ IDigitalInputPort portLeft,
+ IDigitalInputPort portRight)
+ {
+ ButtonUp = new PushButton(portUp);
+ ButtonDown = new PushButton(portDown);
+ ButtonLeft = new PushButton(portLeft);
+ ButtonRight = new PushButton(portRight);
+
+ ButtonUp.PressStarted += PressStarted;
+ ButtonDown.PressStarted += PressStarted;
+ ButtonLeft.PressStarted += PressStarted;
+ ButtonRight.PressStarted += PressStarted;
+
+ ButtonUp.PressEnded += PressEnded;
+ ButtonDown.PressEnded += PressEnded;
+ ButtonLeft.PressEnded += PressEnded;
+ ButtonUp.PressEnded += PressEnded;
+ }
+
+ private void PressEnded(object sender, EventArgs e)
+ => Update();
+
+ private void PressStarted(object sender, EventArgs e)
+ => Update();
+
+ void Update()
+ {
+ var isLeftPressed = ButtonLeft.State;
+ var isRightPressed = ButtonRight.State;
+ var isUpPressed = ButtonUp.State;
+ var isDownPressed = ButtonDown.State;
+
+ var newPosition = GetDigitalPosition(isLeftPressed, isRightPressed, isUpPressed, isDownPressed);
+
+ if (newPosition != Position)
+ {
+ Updated?.Invoke(this, new ChangeResult(newPosition, Position));
+ Position = newPosition;
+ }
+ }
+
+ DigitalJoystickPosition GetDigitalPosition(bool isLeftPressed, bool isRightPressed, bool isUpPressed, bool isDownPressed)
+ {
+ if (isRightPressed)
+ { //Right
+ if (isUpPressed)
+ {
+ return DigitalJoystickPosition.UpRight;
+ }
+ if (isDownPressed)
+ {
+ return DigitalJoystickPosition.DownRight;
+ }
+ return DigitalJoystickPosition.Right;
+ }
+ else if (isLeftPressed)
+ { //Left
+ if (isUpPressed)
+ {
+ return DigitalJoystickPosition.UpLeft;
+ }
+ if (isDownPressed)
+ {
+ return DigitalJoystickPosition.DownLeft;
+ }
+ return DigitalJoystickPosition.Left;
+ }
+ else if (isUpPressed)
+ { //Up
+ return DigitalJoystickPosition.Up;
+ }
+ else if (isDownPressed)
+ { //Down
+ return DigitalJoystickPosition.Down;
+ }
+ else
+ { //Center
+ return DigitalJoystickPosition.Center;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Core/Sensors/Rotary/RotaryEncoder.cs b/Source/Meadow.Foundation.Core/Sensors/Rotary/RotaryEncoder.cs
index 3382e35a90..160e0fa15b 100644
--- a/Source/Meadow.Foundation.Core/Sensors/Rotary/RotaryEncoder.cs
+++ b/Source/Meadow.Foundation.Core/Sensors/Rotary/RotaryEncoder.cs
@@ -58,13 +58,14 @@ public class RotaryEncoder : IRotaryEncoder
0, 1, -1, 0 };
///
- /// Instantiate a new RotaryEncoder on the specified pins.
+ /// Instantiate a new RotaryEncoder on the specified pins
///
- ///
- ///
- public RotaryEncoder(IPin aPhasePin, IPin bPhasePin) :
- this(aPhasePin.CreateDigitalInputPort(InterruptMode.EdgeBoth, ResistorMode.InternalPullDown, TimeSpan.Zero, TimeSpan.FromMilliseconds(0.1)),
- bPhasePin.CreateDigitalInputPort(InterruptMode.EdgeBoth, ResistorMode.InternalPullDown, TimeSpan.Zero, TimeSpan.FromMilliseconds(0.1)))
+ /// Pin A
+ /// Pin B
+ /// Do the encode pins use a common ground (true) or common positive (false)
+ public RotaryEncoder(IPin aPhasePin, IPin bPhasePin, bool isCommonGround = false) :
+ this(aPhasePin.CreateDigitalInputPort(InterruptMode.EdgeBoth, isCommonGround ? ResistorMode.InternalPullUp : ResistorMode.InternalPullDown, TimeSpan.Zero, TimeSpan.FromMilliseconds(0.1)),
+ bPhasePin.CreateDigitalInputPort(InterruptMode.EdgeBoth, isCommonGround ? ResistorMode.InternalPullUp : ResistorMode.InternalPullDown, TimeSpan.Zero, TimeSpan.FromMilliseconds(0.1)))
{ }
///
diff --git a/Source/Meadow.Foundation.Core/Sensors/Temperature/AnalogTemperature.cs b/Source/Meadow.Foundation.Core/Sensors/Temperature/AnalogTemperature.cs
index 78b64af733..1a257b27bb 100644
--- a/Source/Meadow.Foundation.Core/Sensors/Temperature/AnalogTemperature.cs
+++ b/Source/Meadow.Foundation.Core/Sensors/Temperature/AnalogTemperature.cs
@@ -203,7 +203,7 @@ public AnalogTemperature(IAnalogInputPort analogInputPort,
/// Convenience method to get the current temperature. For frequent reads, use
/// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
///
- /// A float value that's ann average value of all the samples taken.
+ /// The temperature averages of the given sample count
protected override async Task ReadSensor()
{
var voltage = await AnalogInputPort.Read();
@@ -260,7 +260,7 @@ protected override void RaiseEventsAndNotify(IChangeResult ch
/// Converts voltage to Temperature
///
///
- /// temperature at a Temperature struct
+ /// Temperature
protected Units.Temperature VoltageToTemperature(Voltage voltage)
{
return new Units.Temperature(SensorCalibration.SampleReading +
diff --git a/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs b/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
index 62ce37ea3f..68447f2146 100644
--- a/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
+++ b/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
@@ -11,6 +11,12 @@ namespace Meadow.Foundation.Audio
///
public class PiezoSpeaker : IToneGenerator
{
+ ///
+ /// The volume from 0-1
+ /// Defined by the PWM port duty cycle from 0 to 0.5
+ ///
+ public float Volume { get; protected set; } = 1.0f;
+
///
/// Gets the port that is driving the Piezo Speaker
///
@@ -72,7 +78,7 @@ public async Task PlayTone(Frequency frequency, TimeSpan duration)
isPlaying = true;
Port.Frequency = frequency;
- Port.DutyCycle = 0.5f;
+ Port.DutyCycle = Volume / 2f;
if (duration.TotalMilliseconds > 0)
{
@@ -91,5 +97,19 @@ public void StopTone()
{
Port.DutyCycle = 0f;
}
+
+ ///
+ /// Set the playback volume
+ ///
+ /// The volume from 0 (off) to 1 (max volume)
+ public void SetVolume(float volume)
+ {
+ Volume = Math.Clamp(volume, 0, 1);
+
+ if(isPlaying)
+ {
+ Port.DutyCycle = Volume / 2f;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj
new file mode 100644
index 0000000000..148d246885
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj
@@ -0,0 +1,22 @@
+
+
+ true
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ MicroAudio
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Audio.MicroAudio
+ icon.png
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow,Meadow.Foundation,Audio,Songs,Tone,Tones,Music,Sound,Effects
+ 0.1.0
+ true
+ Lightweight single-voice sound effect and music player designed for embedded applications
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs
new file mode 100644
index 0000000000..4d1ed96946
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs
@@ -0,0 +1,325 @@
+using Meadow.Peripherals.Speakers;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing game sounds using an IToneGenerator
+ ///
+ public class GameSounds
+ {
+ private readonly IToneGenerator toneGenerator;
+ private readonly int defaultDuration = 100;
+ private readonly int defaultPause = 50;
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// The object to use for audio playback
+ public GameSounds(IToneGenerator toneGenerator)
+ {
+ this.toneGenerator = toneGenerator;
+ }
+
+ ///
+ /// Plays the specified sound effect
+ ///
+ /// The sound effect to play
+ public Task PlayEffect(GameSoundEffect effect)
+ {
+ return effect switch
+ {
+ GameSoundEffect.Activation => PlayActivation(),
+ GameSoundEffect.Blip => PlayBlip(),
+ GameSoundEffect.BossBattle => PlayBossBattle(),
+ GameSoundEffect.ButtonPress => PlayButtonPress(),
+ GameSoundEffect.Coin => PlayCoin(),
+ GameSoundEffect.Collectible => PlayCollectible(),
+ GameSoundEffect.Countdown => PlayCountdown(),
+ GameSoundEffect.EnemyDeath => PlayEnemyDeath(),
+ GameSoundEffect.Explosion => PlayExplosion(),
+ GameSoundEffect.Footstep => PlayFootstep(),
+ GameSoundEffect.GameOver => PlayGameOver(),
+ GameSoundEffect.Health => PlayHealth(),
+ GameSoundEffect.Hit => PlayHit(),
+ GameSoundEffect.Jump => PlayJump(),
+ GameSoundEffect.Laser => PlayLaser(),
+ GameSoundEffect.LevelComplete => PlayLevelComplete(),
+ GameSoundEffect.MenuNavigate => PlayMenuNavigate(),
+ GameSoundEffect.PowerDown => PlayPowerDown(),
+ GameSoundEffect.PowerUp => PlayPowerUp(),
+ GameSoundEffect.SecretFound => PlaySecretFound(),
+ GameSoundEffect.Teleport => PlayTeleport(),
+ GameSoundEffect.Victory => PlayVictory(),
+ GameSoundEffect.Warning => PlayWarning(),
+ GameSoundEffect.WeaponSwitch => PlayWeaponSwitch(),
+ _ => throw new ArgumentException("Invalid game sound effect specified.", nameof(effect)),
+ };
+ }
+
+
+ ///
+ /// Plays a simple blip sound effect
+ ///
+ private async Task PlayBlip()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a power-up or item pick-up sound effect
+ ///
+ private async Task PlayPowerUp()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a coin or currency collection sound effect
+ ///
+ private async Task PlayCoin()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a jump or hop sound effect
+ ///
+ private async Task PlayJump()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a hit or damage sound effect
+ ///
+ private async Task PlayHit()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a laser or projectile firing sound effect
+ ///
+ private async Task PlayLaser()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays an explosion or destruction sound effect
+ ///
+ private async Task PlayExplosion()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(110), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(55), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a game over or failure sound effect
+ ///
+ private async Task PlayGameOver()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(110), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(55), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a victory or success sound effect
+ ///
+ private async Task PlayVictory()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(1175), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a countdown or timer sound effect
+ ///
+ private async Task PlayCountdown()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(698.46), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(587.33), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a power-down sound effect
+ ///
+ private async Task PlayPowerDown()
+ {
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(349.23), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a button press sound effect
+ ///
+ private async Task PlayButtonPress()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a menu navigation sound effect
+ ///
+ private async Task PlayMenuNavigate()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a collectible item sound effect
+ ///
+ private async Task PlayCollectible()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a boss battle theme.
+ ///
+ private async Task PlayBossBattle()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(554.37), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a secret found sound effect
+ ///
+ private async Task PlaySecretFound()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(1174.66), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(1396.91), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a level complete sound effect
+ ///
+ private async Task PlayLevelComplete()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(1396.91), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(2217.46), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a weapon switch sound effect
+ ///
+ private async Task PlayWeaponSwitch()
+ {
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(349.23), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a warning or alarm sound effect
+ ///
+ private async Task PlayWarning()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a teleport or warp sound effect
+ ///
+ private async Task PlayTeleport()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a health pickup or healing sound effect
+ ///
+ private async Task PlayHealth()
+ {
+ await toneGenerator.PlayTone(new Frequency(622.25), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(698.46), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays a footstep or movement sound effect
+ ///
+ private async Task PlayFootstep()
+ {
+ await toneGenerator.PlayTone(new Frequency(196), TimeSpan.FromMilliseconds(defaultDuration >> 3));
+ }
+
+ ///
+ /// Plays an item activation or use sound effect
+ ///
+ private async Task PlayActivation()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+
+ ///
+ /// Plays an enemy death or defeat sound effect
+ ///
+ private async Task PlayEnemyDeath()
+ {
+ await toneGenerator.PlayTone(new Frequency(1568), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(1244.51), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(1046.5), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration >> 1));
+ }
+
+ ///
+ /// Plays a splash sound effect
+ ///
+ public async Task PlaySplash()
+ {
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration >> 2));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs
new file mode 100644
index 0000000000..822cc76334
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs
@@ -0,0 +1,294 @@
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Represents a musical note
+ ///
+ public enum Pitch : int
+ {
+ ///
+ /// The C note
+ ///
+ C = 0,
+ ///
+ /// The C sharp note
+ ///
+ CSharp = 1,
+ ///
+ /// The enharmonic equivalent of C sharp
+ ///
+ DFlat = 1,
+ ///
+ /// The D note
+ ///
+ D = 2,
+ ///
+ /// The D sharp note
+ ///
+ DSharp = 3,
+ ///
+ /// The enharmonic equivalent of D sharp
+ ///
+ EFlat = 3,
+ ///
+ /// The E note
+ ///
+ E = 4,
+ ///
+ /// The F note
+ ///
+ F = 5,
+ ///
+ /// The F sharp note
+ ///
+ FSharp = 6,
+ ///
+ /// The enharmonic equivalent of F sharp
+ ///
+ GFlat = 6,
+ ///
+ /// The G note
+ ///
+ G = 7,
+ ///
+ /// The G sharp note
+ ///
+ GSharp = 8,
+ ///
+ /// The enharmonic equivalent of G sharp
+ ///
+ AFlat = 8,
+ ///
+ /// The A note
+ ///
+ A = 9,
+ ///
+ /// The A sharp note
+ ///
+ ASharp = 10,
+ ///
+ /// The enharmonic equivalent of A sharp
+ ///
+ BFlat = 10,
+ ///
+ /// The B note
+ ///
+ B = 11,
+ ///
+ /// Represents a rest note
+ ///
+ Rest
+ }
+
+ ///
+ /// Represents the duration of a musical note
+ ///
+ public enum NoteDuration
+ {
+ ///
+ /// A whole note
+ ///
+ Whole = 4000,
+ ///
+ /// A half note
+ ///
+ Half = 2000,
+ ///
+ /// A quarter note
+ ///
+ Quarter = 1000,
+ ///
+ /// An eighth note
+ ///
+ Eighth = 500,
+ ///
+ /// A sixteenth note
+ ///
+ Sixteenth = 250,
+ ///
+ /// A thirty-second note
+ ///
+ ThirtySecond = 125,
+ ///
+ /// A whole note triplet
+ ///
+ WholeTriplet = 6000,
+ ///
+ /// A dotted half note
+ ///
+ DottedHalf = 3000
+ }
+
+ ///
+ /// Represents the different sound effects that can be played by the class
+ ///
+ public enum SystemSoundEffect
+ {
+ ///
+ /// An alarm or emergency sound effect
+ ///
+ Alarm,
+ ///
+ /// An alert or notification sound effect
+ ///
+ Alert,
+ ///
+ /// A simple beep sound effect
+ ///
+ Beep,
+ ///
+ /// A buzzing or vibrating sound effect
+ ///
+ Buzz,
+ ///
+ /// A chime or bell sound effect
+ ///
+ Chime,
+ ///
+ /// A short click sound effect
+ ///
+ Click,
+ ///
+ /// A failure or error sound effect
+ ///
+ Failure,
+ ///
+ /// A fanfare or celebratory sound effect
+ ///
+ Fanfare,
+ ///
+ /// A notification sound effect
+ ///
+ Notification,
+ ///
+ /// A popping sound effect
+ ///
+ Pop,
+ ///
+ /// A power-up sound effect
+ ///
+ PowerUp,
+ ///
+ /// A power-down sound effect
+ ///
+ PowerDown,
+ ///
+ /// A success or positive feedback sound effect
+ ///
+ Success,
+ ///
+ /// A short tick or click sound effect
+ ///
+ Tick,
+ ///
+ /// A warning or caution sound effect
+ ///
+ Warning,
+ }
+
+ ///
+ /// Represents the different sound effects that can be played by the class
+ ///
+ public enum GameSoundEffect
+ {
+ ///
+ /// A sound effect indicating the activation or use of an item or power-up
+ ///
+ Activation,
+ ///
+ /// A simple blip sound effect
+ ///
+ Blip,
+ ///
+ /// A sound effect indicating a boss battle or end challenge
+ ///
+ BossBattle,
+ ///
+ /// A button press or selection sound effect
+ ///
+ ButtonPress,
+ ///
+ /// A coin or currency collection sound effect
+ ///
+ Coin,
+ ///
+ /// A sound effect indicating the collection of an item or bonus
+ ///
+ Collectible,
+ ///
+ /// A countdown or timer sound effect
+ ///
+ Countdown,
+ ///
+ /// A sound effect indicating the death or defeat of an enemy
+ ///
+ EnemyDeath,
+ ///
+ /// An explosion or destruction sound effect
+ ///
+ Explosion,
+ ///
+ /// A sound effect indicating a footstep or movement
+ ///
+ Footstep,
+ ///
+ /// A game over or failure sound effect
+ ///
+ GameOver,
+ ///
+ /// A sound effect indicating a health pickup or healing
+ ///
+ Health,
+ ///
+ /// A hit or damage sound effect
+ ///
+ Hit,
+ ///
+ /// A jump or hop sound effect
+ ///
+ Jump,
+ ///
+ /// A laser or projectile firing sound effect
+ ///
+ Laser,
+ ///
+ /// A sound effect indicating the completion of a level or challenge
+ ///
+ LevelComplete,
+ ///
+ /// A menu navigation or selection sound effect
+ ///
+ MenuNavigate,
+ ///
+ /// A power-up or item pick-up sound effect
+ ///
+ PowerUp,
+ ///
+ /// A power-down or failure sound effect
+ ///
+ PowerDown,
+ ///
+ /// A sound effect indicating the discovery of a secret or hidden item
+ ///
+ SecretFound,
+ ///
+ /// A sound effect indicating a spash in water
+ ///
+ Splash,
+ ///
+ /// A sound effect indicating a teleport or warp
+ ///
+ Teleport,
+ ///
+ /// A victory or success sound effect
+ ///
+ Victory,
+ ///
+ /// A warning or alarm sound effect
+ ///
+ Warning,
+ ///
+ /// A sound effect indicating a weapon or tool switch
+ ///
+ WeaponSwitch,
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs
new file mode 100644
index 0000000000..8cf83490b5
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs
@@ -0,0 +1,74 @@
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Provide high level audio functions
+ ///
+ public partial class MicroAudio
+ {
+ readonly IToneGenerator speaker;
+
+ SystemSounds systemSounds;
+ GameSounds gameSounds;
+
+ ///
+ /// Create a new MicroAudio instance from a IToneGenerator driver instance
+ ///
+ /// An IToneGenerator object
+ public MicroAudio(IToneGenerator speaker)
+ {
+ this.speaker = speaker;
+ }
+
+ ///
+ /// Set the playback volume
+ ///
+ /// The volume from 0-1
+ public void SetVolume(float volume)
+ {
+ speaker?.SetVolume(volume);
+ }
+
+ ///
+ /// Plays the specified system sound effect
+ ///
+ /// The sound effect to play
+ /// The number of times to play the sound effect
+ public async Task PlaySystemSound(SystemSoundEffect effect, int numberOfLoops = 1)
+ {
+ systemSounds ??= new SystemSounds(speaker);
+
+ for(int i = 0; i < numberOfLoops; i++)
+ {
+ await systemSounds.PlayEffect(effect);
+ }
+ }
+
+ ///
+ /// Plays the specified game sound effect
+ ///
+ /// The sound effect to play
+ /// /// The number of times to play the sound effect
+ public async Task PlayGameSound(GameSoundEffect effect, int numberOfLoops = 1)
+ {
+ gameSounds ??= new GameSounds(speaker);
+
+ for (int i = 0; i < numberOfLoops; i++)
+ {
+ await gameSounds.PlayEffect(effect);
+ }
+ }
+
+ ///
+ /// Play the specified song
+ ///
+ /// The song object
+ public Task PlaySong(Song song)
+ {
+ return song.Play(speaker);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs
new file mode 100644
index 0000000000..93b3ca8436
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs
@@ -0,0 +1,34 @@
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Represents a musical note, with a specific pitch, octave, and duration
+ ///
+ public class Note
+ {
+ ///
+ /// The pitch of the note
+ ///
+ public Pitch Pitch { get; }
+ ///
+ /// The octave of the note
+ ///
+ public int Octave { get; }
+ ///
+ /// The duration of the note
+ ///
+ public NoteDuration Duration { get; }
+
+ ///
+ /// Creates a new instance of the Note class, with the specified pitch, octave, and duration
+ ///
+ /// The pitch of the note
+ /// The octave of the note
+ /// The duration of the note
+ public Note(Pitch pitch, int octave, NoteDuration duration)
+ {
+ Pitch = pitch;
+ Octave = octave;
+ Duration = duration;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs
new file mode 100644
index 0000000000..24a2a7040e
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs
@@ -0,0 +1,35 @@
+using Meadow.Units;
+using System;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A utility class for converting musical notes to their corresponding frequencies in hertz
+ ///
+ public class NotesToFrequency
+ {
+ ///
+ /// The frequency of the A4 note, in hertz
+ ///
+ public static Frequency A4Frequency { get; set; } = new Frequency(440.0, Frequency.UnitType.Hertz);
+
+ private static double SemitoneRatio { get; } = 1.059463094359;
+
+ ///
+ /// Converts the specified musical note to its frequency in hertz
+ ///
+ /// The musical note to convert
+ /// The frequency of the note in hertz
+ public static Frequency ConvertToFrequency(Note note)
+ {
+ int semitonesFromA4 = CalculateSemitonesFromA4(note.Pitch, note.Octave);
+ return A4Frequency * Math.Pow(SemitoneRatio, semitonesFromA4);
+ }
+
+ private static int CalculateSemitonesFromA4(Pitch pitch, int octave)
+ {
+ int semitonesFromC0 = (int)pitch + (octave - 1) * 12;
+ return semitonesFromC0 - 9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs
new file mode 100644
index 0000000000..d1e5abdcb1
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs
@@ -0,0 +1,58 @@
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing a sequence of musical notes
+ ///
+ public class Song
+ {
+ ///
+ /// The collection of notes in order for the song
+ ///
+ public readonly List Notes = new List();
+
+ ///
+ /// Creates a new instance of the Song class
+ ///
+ public Song()
+ {
+ }
+
+ ///
+ /// Adds a musical note to the sequence of notes to be played
+ ///
+ /// The musical note to add
+ public void AddNote(Note note)
+ {
+ Notes.Add(note);
+ }
+
+ ///
+ /// Plays the sequence of musical notes, with the specified tempo
+ ///
+ /// The IToneGenerator object to play the song
+ /// The tempo of the music, in beats per minute
+ /// A Task representing the asynchronous playback operation
+ public async Task Play(IToneGenerator speaker, int tempo = 120)
+ {
+ foreach (var note in Notes)
+ {
+ int duration = (int)(60.0 / tempo * (int)note.Duration);
+
+ if (note.Pitch == Pitch.Rest)
+ {
+ await Task.Delay(TimeSpan.FromMilliseconds(duration));
+ }
+ else
+ {
+ var frequency = NotesToFrequency.ConvertToFrequency(note);
+ await speaker.PlayTone(frequency, TimeSpan.FromMilliseconds(duration));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs
new file mode 100644
index 0000000000..cc4736b9a9
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs
@@ -0,0 +1,198 @@
+using Meadow.Peripherals.Speakers;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing system sounds using an IToneGenerator
+ ///
+ public class SystemSounds
+ {
+ private readonly int defaultDuration;
+ private readonly int defaultPause;
+ private readonly IToneGenerator toneGenerator;
+
+ ///
+ /// Creates a new instance of the SystemSounds class, using the specified IToneGenerator for audio output
+ ///
+ /// The IToneGenerator to use for audio output
+ /// The default duration of system sounds, in milliseconds (optional; defaults to 100)
+ /// The default pause between system sounds, in milliseconds (optional; defaults to 50)
+
+ public SystemSounds(IToneGenerator toneGenerator, int defaultDuration = 100, int defaultPause = 50)
+ {
+ this.toneGenerator = toneGenerator;
+ this.defaultDuration = defaultDuration;
+ this.defaultPause = defaultPause;
+ }
+
+ ///
+ /// Plays the specified sound effect
+ ///
+ /// The sound effect to play
+ public Task PlayEffect(SystemSoundEffect effect)
+ {
+ return effect switch
+ {
+ SystemSoundEffect.Alert => PlayAlert(),
+ SystemSoundEffect.Alarm => PlayAlarm(),
+ SystemSoundEffect.Beep => PlayBeep(),
+ SystemSoundEffect.Buzz => PlayBuzz(),
+ SystemSoundEffect.Chime => PlayChime(),
+ SystemSoundEffect.Click => PlayClick(),
+ SystemSoundEffect.Failure => PlayFailure(),
+ SystemSoundEffect.Fanfare => PlayFanfare(),
+ SystemSoundEffect.Notification => PlayNotification(),
+ SystemSoundEffect.Pop => PlayPop(),
+ SystemSoundEffect.PowerDown => PlayPowerDown(),
+ SystemSoundEffect.PowerUp => PlayPowerUp(),
+ SystemSoundEffect.Success => PlaySuccess(),
+ SystemSoundEffect.Tick => PlayTick(),
+ SystemSoundEffect.Warning => PlayWarning(),
+ _ => throw new ArgumentException($"Unknown effect: {effect}"),
+ };
+ }
+
+
+ private async Task PlayBeep()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlaySuccess()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1500), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayFailure()
+ {
+ await toneGenerator.PlayTone(new Frequency(1500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayWarning()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayAlarm()
+ {
+ for (int i = 0; i < 5; i++)
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ }
+ }
+
+ private async Task PlayTick()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ private async Task PlayChime()
+ {
+ await toneGenerator.PlayTone(new Frequency(262), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(330), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(392), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a buzzing or vibrating sound effect
+ ///
+ private async Task PlayBuzz()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a fanfare or celebratory sound effect
+ ///
+ private async Task PlayFanfare()
+ {
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays an alert or notification sound effect
+ ///
+ private async Task PlayAlert()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1175), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1319), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1397), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+
+ ///
+ /// Plays a short click sound effect
+ ///
+ private async Task PlayClick()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+
+ ///
+ /// Plays a popping sound effect
+ ///
+ private async Task PlayPop()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a power-up sound effect
+ ///
+ private async Task PlayPowerUp()
+ {
+ await toneGenerator.PlayTone(new Frequency(200), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a power-down sound effect
+ ///
+ private async Task PlayPowerDown()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(200), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a notification sound effect
+ ///
+ private async Task PlayNotification()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(698), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(698), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj
new file mode 100644
index 0000000000..0f5262f559
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs
new file mode 100644
index 0000000000..98acd8337f
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs
@@ -0,0 +1,24 @@
+using Meadow.Foundation.Audio;
+
+namespace Audio.MicroAudio_Sample
+{
+ namespace SongPlayer
+ {
+ internal class CScale : Song
+ {
+ public CScale()
+ {
+ AddNotes();
+ }
+
+ void AddNotes()
+ {
+ for (int i = 0; i < 12; i++)
+ {
+ AddNote(new Note((Pitch)(i), 3, NoteDuration.Quarter));
+ }
+ AddNote(new Note(Pitch.C, 4, NoteDuration.Quarter));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..edd889e0a0
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs
@@ -0,0 +1,86 @@
+using Audio.MicroAudio_Sample.SongPlayer;
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Audio;
+using Meadow.Gateways.Bluetooth;
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Threading.Tasks;
+
+namespace MicroAudio_Sample
+{
+ public class MeadowApp : App
+ {
+ private MicroAudio audio;
+
+ IToneGenerator speaker;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initialize...");
+
+ speaker = new PiezoSpeaker(Device.Pins.D11);
+
+ audio = new MicroAudio(speaker);
+
+ return Task.CompletedTask;
+ }
+
+ public override async Task Run()
+ {
+ Resolver.Log.Info("Play happy birthday");
+ await HappyBirthDay(speaker);
+
+ await Task.Delay(1000);
+
+ Resolver.Log.Info("Play C scale");
+ var scale = new CScale();
+ await audio.PlaySong(scale);
+
+ await Task.Delay(1000);
+
+ Resolver.Log.Info("Sound effects test");
+ await SoundEffectsTest();
+
+ Resolver.Log.Info("Game effects test");
+ await GameEffectsTest();
+ }
+
+ Task HappyBirthDay(IToneGenerator speaker)
+ {
+ var happyBirthday = new Song();
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Quarter));
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Quarter));
+ happyBirthday.AddNote(new Note(Pitch.D, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.F, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.E, 3, NoteDuration.Whole));
+
+ return happyBirthday.Play(speaker, 160);
+ }
+
+ async Task GameEffectsTest()
+ {
+ foreach (GameSoundEffect effect in Enum.GetValues(typeof(GameSoundEffect)))
+ {
+ Resolver.Log.Info($"Playing {effect} game effect...");
+ await audio.PlayGameSound(effect);
+ await Task.Delay(1000);
+ }
+
+ Resolver.Log.Info("Sound effects demo complete.");
+ }
+
+ async Task SoundEffectsTest()
+ {
+ foreach (SystemSoundEffect effect in Enum.GetValues(typeof(SystemSoundEffect)))
+ {
+ Resolver.Log.Info($"Playing {effect} sound effect...");
+ await audio.PlaySystemSound(effect);
+ await Task.Delay(1000);
+ }
+
+ Resolver.Log.Info("Sound effects demo complete.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/meadow.config.yaml
similarity index 100%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/meadow.config.yaml
rename to Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/meadow.config.yaml
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.AdafruitIO/Driver/DataLoggers.AdafruitIO.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.AdafruitIO/Driver/DataLoggers.AdafruitIO.csproj
index bc01078230..5ffef7852f 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.AdafruitIO/Driver/DataLoggers.AdafruitIO.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.AdafruitIO/Driver/DataLoggers.AdafruitIO.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.SensorReading/Driver/DataLoggers.SensorReading.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.SensorReading/Driver/DataLoggers.SensorReading.csproj
index 9a3ee85e03..da1bd10972 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.SensorReading/Driver/DataLoggers.SensorReading.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.SensorReading/Driver/DataLoggers.SensorReading.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.ThingSpeak/Driver/DataLoggers.ThingSpeak.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.ThingSpeak/Driver/DataLoggers.ThingSpeak.csproj
index 133a4482a1..8889a0373a 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.ThingSpeak/Driver/DataLoggers.ThingSpeak.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/DataLoggers.ThingSpeak/Driver/DataLoggers.ThingSpeak.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/InputBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/InputBase.cs
index 4cb2e94954..5a4ada89fe 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/InputBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/InputBase.cs
@@ -1,6 +1,6 @@
using Meadow.Peripherals.Displays;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Represents a base input menu item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/MenuItemBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/MenuItemBase.cs
index 05cde8d488..c17014afc9 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/MenuItemBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/MenuItemBase.cs
@@ -1,47 +1,47 @@
-using Newtonsoft.Json;
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+using System.Text.Json.Serialization;
+
+namespace Meadow.Foundation.Displays.UI
{
///
/// Represents a text display menu item
///
- [JsonObject(MemberSerialization.OptIn)]
public class MenuItem
{
///
/// Sub items in the menu
///
- [JsonProperty("sub")]
+ [JsonPropertyName("sub")]
public MenuItem[] SubItems { get; set; }
///
/// The text on the menu item
///
- [JsonProperty("text")]
+ [JsonPropertyName("text")]
public string Text { get; set; }
///
/// The optional command when the item is selected
///
- [JsonProperty("command")]
+ [JsonPropertyName("command")]
public string Command { get; set; }
///
/// The menu item type
///
- [JsonProperty("type")]
+ [JsonPropertyName("type")]
public string Type { get; set; }
///
/// The menu item id
///
- [JsonProperty("id")]
+ [JsonPropertyName("id")]
public string Id { get; set; }
///
/// The menu item value
///
- [JsonProperty("value")]
+ [JsonPropertyName("value")]
public object Value { get; set; }
///
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/NumericBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/NumericBase.cs
index eb4f7d9e4c..89783e4f56 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/NumericBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/NumericBase.cs
@@ -1,6 +1,6 @@
using System;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Represents a base Numeric input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/TimeBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/TimeBase.cs
index 01821d2adc..e4bef47bcd 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/TimeBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/BaseClasses/TimeBase.cs
@@ -1,6 +1,6 @@
using System;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// A base time input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Displays.TextDisplayMenu.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Displays.TextDisplayMenu.csproj
index 29f59b96a2..81a0d23d1d 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Displays.TextDisplayMenu.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Displays.TextDisplayMenu.csproj
@@ -17,7 +17,7 @@
-
-
+
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/EventHandlers.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/EventHandlers.cs
index 20771b0253..fa18d81b7c 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/EventHandlers.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/EventHandlers.cs
@@ -1,6 +1,6 @@
using System;
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
/// Text display MenuSelectedEventArgs
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Age.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Age.cs
index 525f4bc881..001012b279 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Age.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Age.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Age input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Boolean.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Boolean.cs
index 826525bb94..730bab234c 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Boolean.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Boolean.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu bool input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Date.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Date.cs
index 1981b6cc4a..32d98e106e 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Date.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Date.cs
@@ -1,6 +1,6 @@
using System;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu Date input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputHelpers.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputHelpers.cs
index ab86bff46c..7bd5af04f3 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputHelpers.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputHelpers.cs
@@ -1,6 +1,6 @@
using System.Text;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
internal static class InputHelpers
{
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputType.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputType.cs
new file mode 100644
index 0000000000..4636b20e33
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/InputType.cs
@@ -0,0 +1,12 @@
+internal enum InputType
+{
+ Age,
+ Boolean,
+ Date,
+ Numerical,
+ Onff,
+ Temperature,
+ Time,
+ TimeDetailed,
+ TimeShort,
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/ListBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/ListBase.cs
index 6450129b2e..37815f37c2 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/ListBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/ListBase.cs
@@ -1,6 +1,6 @@
using System;
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu base List input type
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Numerical.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Numerical.cs
index e9e0d9efa8..39705b30d0 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Numerical.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Numerical.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu Numerical input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/OnOff.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/OnOff.cs
index 1a452ae297..70497f3b0a 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/OnOff.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/OnOff.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu on/off input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Temperature.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Temperature.cs
index 8f7ebf391e..a502d390bc 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Temperature.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Temperature.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu Temperature input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Time.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Time.cs
index a14d28c84b..a4cf9df1a6 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Time.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/Time.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu Time input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeDetailed.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeDetailed.cs
index 8095a8efa5..b60ffbc2f9 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeDetailed.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeDetailed.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu TimeDetailed input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeShort.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeShort.cs
index 59e8542e94..072659b182 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeShort.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/InputTypes/TimeShort.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu.InputTypes
+namespace Meadow.Foundation.Displays.UI.InputTypes
{
///
/// Text display menu TimeShort input item
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IMenuInputItem.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IMenuInputItem.cs
index 4ee6e7011c..b51aad175a 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IMenuInputItem.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IMenuInputItem.cs
@@ -1,9 +1,9 @@
using Meadow.Peripherals.Displays;
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
- /// Text display Menu Input abstraction
+ /// Text display TextDisplayMenu Input abstraction
///
public interface IMenuInputItem : IPage
{
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IPage.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IPage.cs
index 309fc88684..79e35a9ac2 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IPage.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/Interfaces/IPage.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
/// Text display menu page abstraction
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/MenuPage.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/MenuPage.cs
index 3ed3cc339f..42511a5271 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/MenuPage.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/MenuPage.cs
@@ -1,7 +1,6 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
/// Text display MenuPage class
@@ -13,8 +12,9 @@ public class MenuPage : IPage
///
public int ScrollPosition
{
- get => scrollPosition;
- set {
+ get => scrollPosition;
+ set
+ {
if (value > MenuItems.Count - 1 || value < 0)
{
Resolver.Log.Warn("Attempting to set a scroll position outside of item range: " + value.ToString());
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextCharacters.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextCharacters.cs
index d6bfbb2461..99753c6bfe 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextCharacters.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextCharacters.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
/// TextCharacters class for custom characters on LCD character displays
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextDisplayMenu.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextDisplayMenu.cs
index f0157ee8fd..69ec074875 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextDisplayMenu.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Driver/TextDisplayMenu.cs
@@ -1,17 +1,16 @@
-using System;
+using Meadow.Foundation.Displays.UI.InputTypes;
+using Meadow.Peripherals.Displays;
+using System;
using System.Collections;
using System.Collections.Generic;
-using System.IO;
-using Meadow.Foundation.Displays.TextDisplayMenu.InputTypes;
-using Meadow.Peripherals.Displays;
-using Newtonsoft.Json;
+using System.Text.Json;
-namespace Meadow.Foundation.Displays.TextDisplayMenu
+namespace Meadow.Foundation.Displays.UI
{
///
- /// TextDisplayMenu Menu class
+ /// TextDisplayMenu TextDisplayMenu class
///
- public class Menu
+ public class TextDisplayMenu
{
const string INPUT_TYPES_NAMESPACE = "Meadow.Foundation.Displays.TextDisplayMenu.InputTypes.";
ITextDisplay display;
@@ -46,12 +45,12 @@ public class Menu
public bool IsEnabled { get; protected set; } = false;
///
- /// Create a new Menu object
+ /// Create a new TextDisplayMenu object
///
/// The display to render the menu
/// Json to define the menu structure
/// True to show Back item on root menu
- public Menu(ITextDisplay display, byte[] menuJson, bool showBackOnRoot = false)
+ public TextDisplayMenu(ITextDisplay display, byte[] menuJson, bool showBackOnRoot = false)
{
this.showBackOnRoot = showBackOnRoot;
var items = ParseMenuData(menuJson);
@@ -59,12 +58,12 @@ public Menu(ITextDisplay display, byte[] menuJson, bool showBackOnRoot = false)
}
///
- /// Create a new Menu object
+ /// Create a new TextDisplayMenu object
///
/// The display to render the menu
- /// Menu items array
+ /// TextDisplayMenu items array
/// True to show Back item on root menu
- public Menu(ITextDisplay display, MenuItem[] menuItems, bool showBackOnRoot = false)
+ public TextDisplayMenu(ITextDisplay display, MenuItem[] menuItems, bool showBackOnRoot = false)
{
Init(display, CreateMenuPage(menuItems, showBackOnRoot));
}
@@ -73,7 +72,7 @@ MenuItem[] ParseMenuData(byte[] menuJson)
{
var menuString = System.Text.Encoding.Default.GetString(menuJson);
- return JsonConvert.DeserializeObject
protected void ShowCurrentPage()
{
- if (!IsEnabled) {
+ if (!IsEnabled)
+ {
Resolver.Log.Warn("Render not enabled");
return;
}
@@ -186,7 +186,7 @@ protected void ShowCurrentPage()
/// The item text
protected string GetItemText(MenuItem item, bool isSelected)
{
- if(item == null)
+ if (item == null)
{
Resolver.Log.Warn("GetItemText: item is null");
return "no item";
@@ -216,7 +216,7 @@ protected string GetItemText(MenuItem item, bool isSelected)
string padding = string.Empty;
if (paddingLength > 0) { padding = new string(' ', paddingLength); }
- itemText += padding + (isSelected?"*":">");
+ itemText += padding + (isSelected ? "*" : ">");
}
return itemText;
@@ -228,7 +228,7 @@ protected string GetItemText(MenuItem item, bool isSelected)
protected void UpdateCurrentMenuPage()
{
currentMenuPage = rootMenuPage;
- }
+ }
///
/// Next input - navigates down/forward in the list of items
@@ -236,9 +236,9 @@ protected void UpdateCurrentMenuPage()
/// True if successful, false in menu is disabled
public bool Next()
{
- if(IsEnabled == false) { return false; }
+ if (IsEnabled == false) { return false; }
- if(currentInputItem != null)
+ if (currentInputItem != null)
{
currentInputItem.Next();
}
@@ -327,7 +327,7 @@ public bool Select()
Exited(this, new EventArgs());
return true;
}
-
+
// if currently on a subpage and user selects back, pop back to parent page.
if (currentMenuPage.ScrollPosition == 0 && pageStack.Count > 0)
{
@@ -359,19 +359,10 @@ public bool Select()
else if (menuItem.Type != string.Empty)
{
pageStack.Push(currentMenuPage);
-
- isEditMode = true;
- // create the new input type
- var type = Type.GetType(INPUT_TYPES_NAMESPACE + menuItem.Type);
-
- if (type == null)
- {
- throw new ArgumentException(menuItem.Type + " was not found");
- }
+ isEditMode = true;
- var constructor = type.GetConstructor(new Type[] { });
- currentInputItem = constructor.Invoke(new object[] { }) as IMenuInputItem;
+ currentInputItem = GetMenuInputItemFromName(menuItem.Type);
// setup callback
currentInputItem.ValueChanged += delegate (object sender, ValueChangedEventArgs e)
@@ -400,6 +391,30 @@ public bool Select()
}
}
+ enum DaysOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
+
+ IMenuInputItem GetMenuInputItemFromName(string name)
+ {
+ if (Enum.TryParse(name, out InputType inputType) == false)
+ {
+ throw new ArgumentException(name + " was not found");
+ }
+
+ return inputType switch
+ {
+ InputType.Age => new Age(),
+ InputType.Boolean => new InputTypes.Boolean(),
+ InputType.Date => new Date(),
+ InputType.Numerical => new Numerical(),
+ InputType.Onff => new OnOff(),
+ InputType.Temperature => new Temperature(),
+ InputType.Time => new Time(),
+ InputType.TimeDetailed => new TimeDetailed(),
+ InputType.TimeShort => new TimeShort(),
+ _ => null,
+ };
+ }
+
///
/// Refresh / redraw the menu
///
@@ -441,7 +456,7 @@ private void UpdateMenuItemValue(string id, object value)
MenuItem node = null;
foreach (var menuItem in rootMenuPage.MenuItems)
{
- node = FindNodeById(menuItem as MenuItem, id);
+ node = FindNodeById(menuItem, id);
if (node != null) { break; }
}
@@ -465,7 +480,7 @@ private MenuItem FindNodeById(MenuItem menuItem, string id)
{
foreach (var subMenuItem in menuItem.SubItems)
{
- var node = FindNodeById(subMenuItem as MenuItem, id);
+ var node = FindNodeById(subMenuItem, id);
if (node != null) return node;
}
}
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/MeadowApp.cs
index 20eaf9e04c..1d5316d543 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/MeadowApp.cs
@@ -1,42 +1,38 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Displays;
-using Meadow.Foundation.Displays.TextDisplayMenu;
+using Meadow.Foundation.Displays.UI;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Sensors.Buttons;
-using Meadow.Hardware;
-using Meadow.Peripherals.Displays;
using Meadow.Peripherals.Sensors.Buttons;
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
-namespace MeadowApp
+namespace TextDisplayMenu_GameMenu_Sample
{
public class MeadowApp : App
{
- Menu menu;
+ TextDisplayMenu menu;
- MicroGraphics graphics;
- Ssd1309 ssd1309;
+ MicroGraphics microGraphics;
IButton up = null;
IButton down = null;
IButton left = null;
IButton right = null;
+ bool playGame = false;
+
public override Task Initialize()
{
Resolver.Log.Info("Initialize...");
- Resolver.Log.Info("Create Display with SPI...");
-
- var config = new SpiClockConfiguration(Ssd1309.DefaultSpiBusSpeed, Ssd1309.DefaultSpiClockMode);
-
- var bus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var bus = Device.CreateSpiBus();
- ssd1309 = new Ssd1309
+ // SSD1309 with SPI
+ var ssd1309 = new Ssd1309
(
spiBus: bus,
chipSelectPin: Device.Pins.D02,
@@ -44,49 +40,67 @@ public override Task Initialize()
resetPin: Device.Pins.D00
);
- Resolver.Log.Info("Create MicroGraphics...");
+ // SSD1309 with I2C
+ //var ssd1309 = new Ssd1309
+ //(
+ // Device.CreateI2cBus()
+ //);
- graphics = new MicroGraphics(ssd1309)
+ microGraphics = new MicroGraphics(ssd1309)
{
CurrentFont = new Font8x12(),
};
- graphics.Clear();
- graphics.DrawText(0, 0, "Loading Menu");
- graphics.Show();
+ microGraphics.Clear();
+ microGraphics.DrawText(0, 0, "Loading Menu");
+ microGraphics.Show();
- CreateMenu(graphics);
+ Resolver.Log.Info("Load menu data...");
+
+ var menuData = LoadResource("menu.json");
+
+ Resolver.Log.Info("Create menu...");
+
+ menu = new TextDisplayMenu(microGraphics, menuData, false);
+
+ menu.Selected += Menu_Selected;
Resolver.Log.Info("Create buttons...");
- up = new PushButton(Device.Pins.D09, ResistorMode.InternalPullDown);
+ up = new PushButton(Device.Pins.D09);
up.Clicked += Up_Clicked;
- left = new PushButton(Device.Pins.D11, ResistorMode.InternalPullDown);
+ left = new PushButton(Device.Pins.D11);
left.Clicked += Left_Clicked;
- right = new PushButton(Device.Pins.D10, ResistorMode.InternalPullDown);
+ right = new PushButton(Device.Pins.D10);
right.Clicked += Right_Clicked;
- down = new PushButton(Device.Pins.D12, ResistorMode.InternalPullDown);
+ down = new PushButton(Device.Pins.D12);
down.Clicked += Down_Clicked;
+ Resolver.Log.Info("Enable menu...");
+
menu.Enable();
return Task.CompletedTask;
}
- private void Down_Clicked(object sender, EventArgs e)
+ private void Up_Clicked(object sender, EventArgs e)
{
- if (menu.IsEnabled) { menu.Next(); }
+ Resolver.Log.Info("Up_Clicked");
+ if (menu.IsEnabled)
+ {
+ menu.Previous();
+ }
}
- private void Right_Clicked(object sender, EventArgs e)
+ private void Down_Clicked(object sender, EventArgs e)
{
- Resolver.Log.Info("Right_Clicked");
+ Resolver.Log.Info("Down_Clicked");
if (menu.IsEnabled)
{
- menu.Select();
+ menu.Next();
}
}
@@ -99,15 +113,24 @@ private void Left_Clicked(object sender, EventArgs e)
}
}
- private void Up_Clicked(object sender, EventArgs e)
+ private void Right_Clicked(object sender, EventArgs e)
{
+ Resolver.Log.Info("Right_Clicked");
if (menu.IsEnabled)
{
- menu.Previous();
+ menu.Select();
}
}
- bool playGame = false;
+ private void Menu_Selected(object sender, MenuSelectedEventArgs e)
+ {
+ Resolver.Log.Info($"******** Selected: {e.Command}");
+
+ DisableMenu();
+
+ _ = StartGame(e.Command);
+ }
+
async Task StartGame(string command)
{
Resolver.Log.Info($"******** {command}");
@@ -121,13 +144,13 @@ await Task.Run(() =>
{
while (count < 150 && playGame == true)
{
- graphics.Clear();
- graphics.DrawText(0, 0, $"{command}:");
- graphics.DrawText(0, 20, $"{count++}");
- graphics.DrawPixel(x += xD, y += yD);
- if (x == graphics.Width || x == 0) { xD *= -1; };
- if (y == graphics.Height || y == 0) { yD *= -1; };
- graphics.Show();
+ microGraphics.Clear();
+ microGraphics.DrawText(0, 0, $"{command}:");
+ microGraphics.DrawText(0, 20, $"{count++}");
+ microGraphics.DrawPixel(x += xD, y += yD);
+ if (x == microGraphics.Width || x == 0) { xD *= -1; };
+ if (y == microGraphics.Height || y == 0) { yD *= -1; };
+ microGraphics.Show();
}
}).ConfigureAwait(false);
@@ -146,34 +169,10 @@ void DisableMenu()
menu?.Disable();
}
- void CreateMenu(ITextDisplay display)
- {
- Resolver.Log.Info("Load menu data...");
-
- var menuData = LoadResource("menu.json");
-
- Resolver.Log.Info($"Data length: {menuData.Length}...");
-
- Resolver.Log.Info("Create menu...");
-
- menu = new Menu(display, menuData, false);
-
- menu.Selected += Menu_Selected;
- }
-
- private void Menu_Selected(object sender, MenuSelectedEventArgs e)
- {
- Resolver.Log.Info($"******** Selected: {e.Command}");
-
- DisableMenu();
-
- _ = StartGame(e.Command);
- }
-
byte[] LoadResource(string filename)
{
var assembly = Assembly.GetExecutingAssembly();
- var resourceName = $"Graphics.TextDisplayMenu_GameMenu_Sample.{filename}";
+ var resourceName = $"TextDisplayMenu_GameMenu_Sample.{filename}";
using Stream stream = assembly.GetManifestResourceStream(resourceName);
using var ms = new MemoryStream();
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/TextDisplayMenu_GameMenu_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/TextDisplayMenu_GameMenu_Sample.csproj
index b53abd752b..be9dfbc67b 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/TextDisplayMenu_GameMenu_Sample.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_GameMenu_Sample/TextDisplayMenu_GameMenu_Sample.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/MeadowApp.cs
index a2c6a5ac53..94538faf45 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/MeadowApp.cs
@@ -1,23 +1,19 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Displays;
-using Meadow.Foundation.Displays.TextDisplayMenu;
+using Meadow.Foundation.Displays.UI;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Sensors.Buttons;
-using Meadow.Hardware;
-using Meadow.Peripherals.Displays;
using Meadow.Peripherals.Sensors.Buttons;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
-namespace MeadowApp
+namespace TextDisplayMenu_Sample
{
public class MeadowApp : App
{
- Menu menu;
-
- Ssd1309 ssd1309;
+ TextDisplayMenu menu;
IButton next = null;
IButton previous = null;
@@ -27,28 +23,29 @@ public override Task Initialize()
{
Resolver.Log.Info("Initialize...");
- var config = new SpiClockConfiguration(Ssd1309.DefaultSpiBusSpeed, Ssd1309.DefaultSpiClockMode);
-
- var bus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
-
- ssd1309 = new Ssd1309
+ // SSD1309 with SPI
+ var ssd1309 = new Ssd1309
(
- spiBus: bus,
+ spiBus: Device.CreateSpiBus(),
chipSelectPin: Device.Pins.D02,
dcPin: Device.Pins.D01,
resetPin: Device.Pins.D00
);
- Resolver.Log.Info("Create MicroGraphics...");
+ // SSD1309 with I2C
+ //var ssd1309 = new Ssd1309
+ //(
+ // Device.CreateI2cBus()
+ //);
- var gl = new MicroGraphics(ssd1309)
+ var microGraphics = new MicroGraphics(ssd1309)
{
CurrentFont = new Font8x12(),
};
- gl.Clear();
- gl.DrawText(0, 0, "Loading Menu");
- gl.Show();
+ microGraphics.Clear();
+ microGraphics.DrawText(0, 0, "Loading Menu");
+ microGraphics.Show();
Resolver.Log.Info("Load menu data...");
@@ -60,7 +57,7 @@ public override Task Initialize()
Resolver.Log.Info("Create menu...");
- menu = new Menu(ssd1309 as ITextDisplay, menuData, false);
+ menu = new TextDisplayMenu(microGraphics, menuData, false);
next = new PushButton(Device.Pins.D10);
next.Clicked += (s, e) => { menu.Next(); };
@@ -81,16 +78,12 @@ public override Task Initialize()
byte[] LoadResource(string filename)
{
var assembly = Assembly.GetExecutingAssembly();
- var resourceName = $"Graphics.TextDisplayMenu_Sample.{filename}";
+ var resourceName = $"TextDisplayMenu_Sample.{filename}";
- using (Stream stream = assembly.GetManifestResourceStream(resourceName))
- {
- using (var ms = new MemoryStream())
- {
- stream.CopyTo(ms);
- return ms.ToArray();
- }
- }
+ using Stream stream = assembly.GetManifestResourceStream(resourceName);
+ using var ms = new MemoryStream();
+ stream.CopyTo(ms);
+ return ms.ToArray();
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/TextDisplayMenu_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/TextDisplayMenu_Sample.csproj
index b53abd752b..be9dfbc67b 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/TextDisplayMenu_Sample.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Displays.TextDisplayMenu/Samples/TextDisplayMenu_Sample/TextDisplayMenu_Sample.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bpp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bpp.cs
index 03b77721da..f33fd11f87 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bpp.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bpp.cs
@@ -19,8 +19,8 @@ public class Buffer1bpp : PixelBufferBase
/// width of buffer in pixels
/// height of buffer in pixels
/// data to copy into buffer
- public Buffer1bpp(int width, int height, byte[] buffer) :
- base(width, height, buffer)
+ public Buffer1bpp(int width, int height, byte[] buffer) :
+ base(width, height, buffer)
{ }
///
@@ -28,8 +28,8 @@ public Buffer1bpp(int width, int height, byte[] buffer) :
///
/// width of buffer in pixels
/// height of buffer in pixels
- public Buffer1bpp(int width, int height) :
- base(width, height)
+ public Buffer1bpp(int width, int height) :
+ base(width, height)
{ }
///
@@ -49,7 +49,8 @@ public Buffer1bpp(int width, int height, int pageSize)
Width = width;
Height = height;
- int bufferSize = width * height / 8;
+ int bufferSize = (height * width >> 3);
+
bufferSize += bufferSize % pageSize;
Buffer = new byte[bufferSize];
@@ -63,7 +64,7 @@ public Buffer1bpp(int width, int height, int pageSize)
/// true if pixel is set / enabled
public virtual bool GetPixelIsEnabled(int x, int y)
{
- var index = (y >> 8) * Width + x;
+ var index = (y >> 3) * Width + x;
return (Buffer[index] & (1 << y % 8)) != 0;
}
@@ -87,16 +88,11 @@ public override Color GetPixel(int x, int y)
/// is pixel enabled (on)
public virtual void SetPixel(int x, int y, bool enabled)
{
- var index = (y >> 3) * Width + x; //divide by 8
+ var index = (y >> 3) * Width + x;
- if (enabled)
- {
- Buffer[index] = (byte)(Buffer[index] | (byte)(1 << (y % 8)));
- }
- else
- {
- Buffer[index] = (byte)(Buffer[index] & ~(byte)(1 << (y % 8)));
- }
+ var bitMask = (byte)(1 << (y % 8));
+
+ Buffer[index] = enabled ? (byte)(Buffer[index] | bitMask) : (byte)(Buffer[index] & ~bitMask);
}
///
@@ -137,12 +133,12 @@ public override void Fill(int x, int y, int width, int height, Color color)
}
var isColored = color.Color1bpp;
-
+
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{ //byte aligned and at least 8 rows to go
- if((j + y) % 8 == 0 && j + y + 8 <= height)
+ if ((j + y) % 8 == 0 && j + y + 8 <= height)
{
//set an entire byte - fast
Buffer[((j + y) >> 3) * Width + x + i] = (byte)((isColored) ? 0xFF : 0);
@@ -183,7 +179,7 @@ public void Clear(bool enabled)
/// y position of pixel
public override void InvertPixel(int x, int y)
{
- var index = (y / 8 * Width) + x;
+ var index = (y >> 3) * Width + x;
Buffer[index] = Buffer[index] ^= (byte)(1 << y % 8);
}
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bppV.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bppV.cs
index 38f5e94cb4..9a3928d51b 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bppV.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/Buffer1bppV.cs
@@ -44,9 +44,9 @@ public Buffer1bppV(int width, int height, int pageSize)
Width = width;
Height = height;
- width = width % 8 > 0 ? width + 8 - (width % 8) : width;
+ width = (width + 7) & ~7;
- int bufferSize = width * height / 8;
+ int bufferSize = (width * height) >> 3;
bufferSize += bufferSize % pageSize;
Buffer = new byte[bufferSize];
@@ -60,7 +60,7 @@ public Buffer1bppV(int width, int height, int pageSize)
/// true if pixel is set / enabled
public override bool GetPixelIsEnabled(int x, int y)
{
- return (Buffer[(x + y * Width) / 8] & (0x80 >> (x % 8))) != 0;
+ return (Buffer[(x + y * Width) >> 3] & (0x80 >> (x % 8))) != 0;
}
///
@@ -71,14 +71,10 @@ public override bool GetPixelIsEnabled(int x, int y)
/// is pixel enabled (on)
public override void SetPixel(int x, int y, bool enabled)
{
- if (enabled)
- { //0x80 = 128 = 0b_10000000
- Buffer[(x + y * Width) / 8] |= (byte)(0x80 >> (x % 8));
- }
- else
- {
- Buffer[(x + y * Width) / 8] &= (byte)~(0x80 >> (x % 8));
- }
+ int index = (x + y * Width) >> 3;
+ byte bitMask = (byte)(0x80 >> (x % 8));
+
+ Buffer[index] = enabled ? (byte)(Buffer[index] | bitMask) : (byte)(Buffer[index] & ~bitMask);
}
///
@@ -103,7 +99,7 @@ public override void Fill(int x, int y, int width, int height, Color color)
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
- {
+ {
//ToDo - optimize for full byte copies
SetPixel(x + i, y + j, isColored);
}
@@ -117,7 +113,7 @@ public override void Fill(int x, int y, int width, int height, Color color)
/// y position of pixel
public override void InvertPixel(int x, int y)
{
- Buffer[(x + y * Width) / 8] ^= (byte)~(0x80 >> (x % 8));
+ Buffer[(x + y * Width) >> 3] ^= (byte)~(0x80 >> (x % 8));
}
///
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/PixelBufferBase.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/PixelBufferBase.cs
index dda36c13f3..ee22d868d3 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/PixelBufferBase.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Buffers/PixelBufferBase.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
namespace Meadow.Foundation.Graphics.Buffers
{
@@ -51,7 +52,7 @@ public int BitDepth
///
/// Number of bytes in buffer
///
- public int ByteCount => (Width * Height * BitDepth) / 8;
+ public int ByteCount => (Width * Height * BitDepth) >> 3;
///
/// The buffer that holds the pixel data
@@ -87,7 +88,7 @@ public PixelBufferBase(int width, int height, byte[] buffer)
{
Width = width;
Height = height;
- if(buffer.Length != ByteCount)
+ if (buffer.Length != ByteCount)
{
throw new ArgumentException($"Provided buffer length ({buffer.Length}) does not match this buffer's ByteCount ({ByteCount}).");
}
@@ -101,7 +102,7 @@ public PixelBufferBase(int width, int height, byte[] buffer)
/// If true, will recreates the buffer if it already exists
public void InitializeBuffer(bool replaceIfExists = false)
{
- if(Buffer == null || replaceIfExists)
+ if (Buffer == null || replaceIfExists)
{
Buffer = new byte[ByteCount];
}
@@ -120,7 +121,7 @@ public virtual void Clear()
///
/// Fill color
public abstract void Fill(Color color);
-
+
///
/// Fill a region of the pixel buffer with a color
///
@@ -182,7 +183,7 @@ protected void WriteBufferSlow(int originX, int originY, IPixelBuffer buffer)
{
for (var x = 0; x < buffer.Width; x++)
{
- for(var y = 0; y < buffer.Height; y++)
+ for (var y = 0; y < buffer.Height; y++)
{
SetPixel(originX + x, originY + y, buffer.GetPixel(x, y));
}
@@ -195,94 +196,87 @@ protected void WriteBufferSlow(int originX, int originY, IPixelBuffer buffer)
/// Buffer type
/// Rotation
/// The new buffer
- public T RotateAndConvert(RotationType rotation)
+ public T RotateAndConvert(RotationType rotation)
where T : PixelBufferBase, new()
{
T newBuffer;
+ int[] rowLookup;
+ int[] colLookup;
switch (rotation)
{
case RotationType._90Degrees:
- newBuffer = new T
- {
- Width = Height,
- Height = Width
- };
- newBuffer.InitializeBuffer();
-
- for (int i = 0; i < Width; i++)
- {
- for (int j = 0; j < Height; j++)
- {
- newBuffer.SetPixel(Height - j - 1, i, GetPixel(i, j));
- }
- }
+ newBuffer = new T { Width = Height, Height = Width };
+ rowLookup = Enumerable.Range(0, Height).Reverse().ToArray();
+ colLookup = Enumerable.Range(0, Width).ToArray();
break;
case RotationType._270Degrees:
- newBuffer = new T
- {
- Width = Height,
- Height = Width
- };
- newBuffer.InitializeBuffer();
-
- for (int i = 0; i < Width; i++)
- {
- for (int j = 0; j < Height; j++)
- {
- newBuffer.SetPixel(j, Width - i - 1, GetPixel(i, j));
- }
- }
+ newBuffer = new T { Width = Height, Height = Width };
+ rowLookup = Enumerable.Range(0, Height).ToArray();
+ colLookup = Enumerable.Range(0, Width).Reverse().ToArray();
break;
case RotationType._180Degrees:
- newBuffer = new T
- {
- Width = Width,
- Height = Height
- };
- newBuffer.InitializeBuffer();
-
- for (int i = 0; i < Width; i++)
- {
- for (int j = 0; j < Height; j++)
- {
- newBuffer.SetPixel(Width - i - 1, Height - j - 1, GetPixel(i, j));
- }
- }
+ newBuffer = new T { Width = Width, Height = Height };
+ rowLookup = Enumerable.Range(0, Width).Reverse().ToArray();
+ colLookup = Enumerable.Range(0, Height).Reverse().ToArray();
break;
case RotationType.Default:
default:
- newBuffer = new T
- {
- Width = Height,
- Height = Width
- };
- newBuffer.InitializeBuffer();
-
- for (int i = 0; i < Width; i++)
- {
- for (int j = 0; j < Height; j++)
- {
- newBuffer.SetPixel(i, j, GetPixel(i, j));
- }
- }
- break;
+ return Clone();
+ }
+
+ newBuffer.InitializeBuffer();
+
+ for (int i = 0; i < Width; i++)
+ {
+ for (int j = 0; j < Height; j++)
+ {
+ newBuffer.SetPixel(rowLookup[j], colLookup[i], GetPixel(i, j));
+ }
}
return newBuffer;
}
+ ///
+ /// Create a new buffer scaled up from the existing buffer
+ ///
+ /// Buffer type
+ /// Integer scale ratio
+ /// The new buffer
+
+ public T ScaleUp(int scaleFactor)
+ where T : PixelBufferBase, new()
+ {
+ T newBuffer = new T
+ {
+ Width = Width * scaleFactor,
+ Height = Height * scaleFactor,
+ };
+ newBuffer.InitializeBuffer(true);
+ newBuffer.Clear();
+
+ for (int i = 0; i < Width; i++)
+ {
+ for (int j = 0; j < Height; j++)
+ {
+ newBuffer.Fill(i * scaleFactor, j * scaleFactor, scaleFactor, scaleFactor, GetPixel(i, j));
+ }
+ }
+ return newBuffer;
+ }
+
///
/// Create a new pixel buffer and
/// copy/convert pixel data from existing buffer
///
/// The buffer type to convert to
/// A pixel buffer derrived from PixelBufferBase
- public T ConvertPixelBuffer()
+ public T ConvertPixelBuffer()
where T : PixelBufferBase, new()
{
- if(GetType() == typeof(T))
- {
+ if (GetType() == typeof(T))
+ {
return Clone();
}
@@ -303,7 +297,7 @@ public T ConvertPixelBuffer()
return newBuffer;
}
-
+
///
/// Make a copy of the buffer object
/// Intentionally private
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Graphics.MicroGraphics.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Graphics.MicroGraphics.csproj
index 6bf01b4d0d..f82424dd8a 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Graphics.MicroGraphics.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Graphics.MicroGraphics.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Image.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Image.cs
index d8364a3877..1e98d9ae88 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Image.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/Image.cs
@@ -118,7 +118,7 @@ private void LoadBitmap(Stream source)
source.Seek(-4, SeekOrigin.Current);
source.Read(dib, 0, dib.Length);
- var width = BitConverter.ToInt32(dib, 18 - 14 );
+ var width = BitConverter.ToInt32(dib, 18 - 14);
var height = BitConverter.ToInt32(dib, 22 - 14);
var invertedRows = false;
if (height < 0)
@@ -150,9 +150,9 @@ private void LoadBitmap(Stream source)
throw new NotSupportedException("Unsupported bitmap compression");
}
- var bytesPerRow = (int)(width * (BitsPerPixel / 8f));
+ var bytesPerRow = width * (BitsPerPixel >> 3);
// BMP row length is evenly divisible by 4
- var mod = (bytesPerRow % 4);
+ var mod = bytesPerRow % 4;
var rowPad = mod == 0 ? 0 : 4 - mod;
var pixelBufferSize = height * bytesPerRow;
var pixelData = new byte[pixelBufferSize];
@@ -222,7 +222,7 @@ private void ConvertRGBBufferToBGRBuffer(byte[] buffer)
{
byte temp;
- for (int i = 0; i < buffer.Length; i+=3)
+ for (int i = 0; i < buffer.Length; i += 3)
{
// pull red
temp = buffer[i];
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
index 03aa4388be..3e96bd173f 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
@@ -19,10 +19,11 @@ public partial class MicroGraphics
///
/// PixelBuffer draw target
///
- protected IPixelBuffer pixelBuffer;
+ protected IPixelBuffer PixelBuffer => (display != null) ? display.PixelBuffer : _memoryBuffer;
+ private readonly IPixelBuffer _memoryBuffer;
///
- /// Ingore pixels that are outside of the pixel buffer coordinate space
+ /// ignore pixels that are outside of the pixel buffer coordinate space
///
public bool IgnoreOutOfBoundsPixels = true;
@@ -33,12 +34,7 @@ public IFont CurrentFont
{
get
{
- // lazy load
- if (currentFont == null)
- {
- currentFont = new Font6x8();
- }
-
+ currentFont ??= new Font6x8();
return currentFont;
}
set
@@ -55,7 +51,7 @@ public IFont CurrentFont
///
/// Current color mode
///
- public ColorMode ColorMode => pixelBuffer.ColorMode;
+ public ColorMode ColorMode => PixelBuffer.ColorMode;
///
/// Current rotation used for drawing pixels to the display
@@ -87,14 +83,34 @@ public RotationType Rotation
public Color PenColor { get; set; } = Color.White;
///
- /// Return the height of the display after accounting for the rotation.
+ /// Return the height of the display after accounting for the rotation
///
- public int Height => Rotation == RotationType.Default || Rotation == RotationType._180Degrees ? pixelBuffer.Height : pixelBuffer.Width;
+ public int Height
+ {
+ get
+ {
+ if (display is IRotatableDisplay)
+ {
+ return display.Height;
+ }
+ return Rotation == RotationType.Default || Rotation == RotationType._180Degrees ? PixelBuffer.Height : PixelBuffer.Width;
+ }
+ }
///
- /// Return the width of the display after accounting for the rotation.
+ /// Return the width of the display after accounting for the rotation
///
- public int Width => Rotation == RotationType.Default || Rotation == RotationType._180Degrees ? pixelBuffer.Width : pixelBuffer.Height;
+ public int Width
+ {
+ get
+ {
+ if (display is IRotatableDisplay)
+ {
+ return display.Width;
+ }
+ return Rotation == RotationType.Default || Rotation == RotationType._180Degrees ? PixelBuffer.Width : PixelBuffer.Height;
+ }
+ }
///
/// Text display configuration for use with text display menu
@@ -123,8 +139,6 @@ public RotationType Rotation
public MicroGraphics(IGraphicsDisplay display)
{
this.display = display;
-
- this.pixelBuffer = display.PixelBuffer;
}
///
@@ -134,7 +148,7 @@ public MicroGraphics(IGraphicsDisplay display)
/// Initialize the offscreen buffer if true
public MicroGraphics(PixelBufferBase pixelBuffer, bool initializeBuffer)
{
- this.pixelBuffer = pixelBuffer;
+ _memoryBuffer = pixelBuffer;
if (initializeBuffer)
{
@@ -155,7 +169,14 @@ public virtual void DrawPixel(int x, int y, Color color)
return;
}
- pixelBuffer.SetPixel(GetXForRotation(x, y), GetYForRotation(x, y), color);
+ if (display is IRotatableDisplay)
+ {
+ PixelBuffer.SetPixel(x, y, color);
+ }
+ else
+ {
+ PixelBuffer.SetPixel(GetXForRotation(x, y), GetYForRotation(x, y), color);
+ }
}
///
@@ -190,7 +211,7 @@ public virtual void DrawPixel(int index)
return;
}
- pixelBuffer.SetPixel(index % pixelBuffer.Width, index / pixelBuffer.Width, PenColor);
+ PixelBuffer.SetPixel(index % PixelBuffer.Width, index / PixelBuffer.Width, PenColor);
}
///
@@ -205,7 +226,7 @@ public void InvertPixel(int x, int y)
return;
}
- pixelBuffer.InvertPixel(GetXForRotation(x, y), GetYForRotation(x, y));
+ PixelBuffer.InvertPixel(GetXForRotation(x, y), GetYForRotation(x, y));
}
///
@@ -516,29 +537,12 @@ public void DrawArc(int centerX, int centerY, int radius, Angle startAngle, Angl
int offset = centerBetweenPixels ? 1 : 0;
- if (startAngle > endAngle)
- {
- endAngle += new Angle(360);
- }
+ double startAngleRadians = startAngle.Radians;
+ double endAngleRadians = endAngle.Radians;
- bool IsCoordinateOnArc(int x, int y)
+ if (startAngleRadians > endAngleRadians)
{
- var angle = Math.Atan2(y, x);
- if (angle < 0) { angle += 2 * Math.PI; }
-
- if (angle >= startAngle.Radians &&
- angle <= endAngle.Radians)
- {
- return true;
- }
-
- if (angle >= (startAngle.Radians - 2 * Math.PI) &&
- angle <= (endAngle.Radians - 2 * Math.PI))
- {
- return true;
- }
-
- return false;
+ (endAngleRadians, startAngleRadians) = (startAngleRadians, endAngleRadians);
}
void DrawArcPoint(int x, int y, Color color)
@@ -555,17 +559,23 @@ void DrawArcPoint(int x, int y, Color color)
while (x <= y)
{
- if (IsCoordinateOnArc(y, -x)) DrawArcPoint(centerX + y - offset, centerY - x, color); //1
- if (IsCoordinateOnArc(x, -y)) DrawArcPoint(centerX + x - offset, centerY - y, color); //2
-
- if (IsCoordinateOnArc(-x, -y)) DrawArcPoint(centerX - x, centerY - y, color); //3
- if (IsCoordinateOnArc(-y, -x)) DrawArcPoint(centerX - y, centerY - x, color); //4
-
- if (IsCoordinateOnArc(-y, x)) DrawArcPoint(centerX - y, centerY + x - offset, color); //5
- if (IsCoordinateOnArc(-x, y)) DrawArcPoint(centerX - x, centerY + y - offset, color); //6
-
- if (IsCoordinateOnArc(x, y)) DrawArcPoint(centerX + x - offset, centerY + y - offset, color); //7
- if (IsCoordinateOnArc(y, x)) DrawArcPoint(centerX + y - offset, centerY + x - offset, color); //8
+ double angle1 = Math.Atan2(y, -x);
+ double angle2 = Math.Atan2(x, -y);
+ double angle3 = Math.Atan2(-x, -y);
+ double angle4 = Math.Atan2(-y, -x);
+ double angle5 = Math.Atan2(-y, x);
+ double angle6 = Math.Atan2(-x, y);
+ double angle7 = Math.Atan2(x, y);
+ double angle8 = Math.Atan2(y, x);
+
+ if (angle1 >= startAngleRadians && angle1 <= endAngleRadians) { DrawArcPoint(centerX + y - offset, centerY - x, color); }
+ if (angle2 >= startAngleRadians && angle2 <= endAngleRadians) { DrawArcPoint(centerX + x - offset, centerY - y, color); }
+ if (angle3 >= startAngleRadians && angle3 <= endAngleRadians) { DrawArcPoint(centerX - x, centerY - y, color); }
+ if (angle4 >= startAngleRadians && angle4 <= endAngleRadians) { DrawArcPoint(centerX - y, centerY - x, color); }
+ if (angle5 >= startAngleRadians && angle5 <= endAngleRadians) { DrawArcPoint(centerX - y, centerY + x - offset, color); }
+ if (angle6 >= startAngleRadians && angle6 <= endAngleRadians) { DrawArcPoint(centerX - x, centerY + y - offset, color); }
+ if (angle7 >= startAngleRadians && angle7 <= endAngleRadians) { DrawArcPoint(centerX + x - offset, centerY + y - offset, color); }
+ if (angle8 >= startAngleRadians && angle8 <= endAngleRadians) { DrawArcPoint(centerX + y - offset, centerY + x - offset, color); }
if (d < 0)
{
@@ -1241,12 +1251,7 @@ public void DrawText(int x, int y, string text, Color color,
VerticalAlignment alignmentV = VerticalAlignment.Top,
IFont? font = null)
{
- var fontToDraw = font != null ? font : CurrentFont;
-
- if (fontToDraw == null)
- {
- throw new Exception("CurrentFont must be set before calling DrawText.");
- }
+ var fontToDraw = (font ?? CurrentFont) ?? throw new Exception("CurrentFont must be set before calling DrawText.");
byte[] bitMap = GetBytesForTextBitmap(text, fontToDraw);
@@ -1323,9 +1328,9 @@ public void DrawBuffer(int x, int y, IPixelBuffer buffer)
}
//fast and happy path
- if (Rotation == RotationType.Default && isInBounds)
+ if (display is IRotatableDisplay || Rotation == RotationType.Default && isInBounds)
{
- pixelBuffer.WriteBuffer(x, y, buffer);
+ PixelBuffer.WriteBuffer(x, y, buffer);
}
else //loop over every pixel
{
@@ -1333,7 +1338,7 @@ public void DrawBuffer(int x, int y, IPixelBuffer buffer)
{
for (int j = yStartIndex; j < heightToDraw; j++)
{
- pixelBuffer.SetPixel(GetXForRotation(x + i, y + j),
+ PixelBuffer.SetPixel(GetXForRotation(x + i, y + j),
GetYForRotation(x + i, y + j),
buffer.GetPixel(i, j));
}
@@ -1627,11 +1632,11 @@ public virtual void Clear(bool updateDisplay = false)
{
if (display.DisabledColor == Color.Black)
{
- pixelBuffer.Clear();
+ PixelBuffer.Clear();
}
else
{
- pixelBuffer.Fill(display.DisabledColor);
+ PixelBuffer.Fill(display.DisabledColor);
}
if (updateDisplay)
@@ -1650,7 +1655,7 @@ public virtual void Clear(bool updateDisplay = false)
/// Update the display immediately when true
public virtual void Clear(int originX, int originY, int width, int height, bool updateDisplay = false)
{
- pixelBuffer.Fill(originX, originY, width, height, display.DisabledColor);
+ PixelBuffer.Fill(originX, originY, width, height, display.DisabledColor);
if (updateDisplay)
{
@@ -1743,10 +1748,12 @@ protected void DrawBitmap(int x, int y, int width, int height, byte[] bitmap, Sc
///
public int GetXForRotation(int x, int y)
{
+ if (display is IRotatableDisplay) { return x; }
+
return Rotation switch
{
- RotationType._90Degrees => pixelBuffer.Width - y - 1,
- RotationType._180Degrees => pixelBuffer.Width - x - 1,
+ RotationType._90Degrees => PixelBuffer.Width - y - 1,
+ RotationType._180Degrees => PixelBuffer.Width - x - 1,
RotationType._270Degrees => y,
_ => x,
};
@@ -1760,11 +1767,13 @@ public int GetXForRotation(int x, int y)
///
public int GetYForRotation(int x, int y)
{
+ if (display is IRotatableDisplay) { return y; }
+
return Rotation switch
{
RotationType._90Degrees => x,
- RotationType._180Degrees => pixelBuffer.Height - y - 1,
- RotationType._270Degrees => pixelBuffer.Height - x - 1,
+ RotationType._180Degrees => PixelBuffer.Height - y - 1,
+ RotationType._270Degrees => PixelBuffer.Height - x - 1,
_ => y,
};
}
@@ -1796,19 +1805,25 @@ void Fill(int x, int y, int width, int height, Color color)
if (y + height >= Height) height = Height - y;
}
+ if (display is IRotatableDisplay)
+ {
+ PixelBuffer.Fill(x, y, width, height, color);
+ return;
+ }
+
switch (Rotation)
{
case RotationType.Default:
- pixelBuffer.Fill(x, y, width, height, color);
+ PixelBuffer.Fill(x, y, width, height, color);
break;
case RotationType._90Degrees:
- pixelBuffer.Fill(GetXForRotation(x, y) - height + 1, GetYForRotation(x, y), height, width, color);
+ PixelBuffer.Fill(GetXForRotation(x, y) - height + 1, GetYForRotation(x, y), height, width, color);
break;
case RotationType._180Degrees:
- pixelBuffer.Fill(GetXForRotation(x, y) - width + 1, GetYForRotation(x, y) - height + 1, width, height, color);
+ PixelBuffer.Fill(GetXForRotation(x, y) - width + 1, GetYForRotation(x, y) - height + 1, width, height, color);
break;
case RotationType._270Degrees:
- pixelBuffer.Fill(GetXForRotation(x, y), GetYForRotation(x, y) - width + 1, height, width, color);
+ PixelBuffer.Fill(GetXForRotation(x, y), GetYForRotation(x, y) - width + 1, height, width, color);
break;
}
}
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Samples/ImageLoadSample/ImageLoad_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Samples/ImageLoadSample/ImageLoad_Sample.csproj
index 2b966ed4a5..133629e6ad 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Samples/ImageLoadSample/ImageLoad_Sample.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Samples/ImageLoadSample/ImageLoad_Sample.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Driver/Sensors.Location.Gnss.NmeaProcessor.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Driver/Sensors.Location.Gnss.NmeaProcessor.csproj
index 69c68b9d9e..cc66492434 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Driver/Sensors.Location.Gnss.NmeaProcessor.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Driver/Sensors.Location.Gnss.NmeaProcessor.csproj
@@ -20,6 +20,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Samples/NmeaProcessor_Sample/NmeaProcessor_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Samples/NmeaProcessor_Sample/NmeaProcessor_Sample.csproj
index 90d9b56fc1..b09c180581 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Samples/NmeaProcessor_Sample/NmeaProcessor_Sample.csproj
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Sensors.Location.Gnss.NmeaProcessor/Samples/NmeaProcessor_Sample/NmeaProcessor_Sample.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Driver/Audio.Mp3.Yx5300.csproj b/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Driver/Audio.Mp3.Yx5300.csproj
index 22a753d535..97c48c99db 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Driver/Audio.Mp3.Yx5300.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Driver/Audio.Mp3.Yx5300.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Samples/Yx5300_Sample/Yx5300_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Samples/Yx5300_Sample/Yx5300_Sample.csproj
index fabfbad8b5..d0b166c4eb 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Samples/Yx5300_Sample/Yx5300_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Mp3.Yx5300/Samples/Yx5300_Sample/Yx5300_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Audio.Radio.Tea5767.csproj b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Audio.Radio.Tea5767.csproj
index 7449e4cf31..06de32f482 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Audio.Radio.Tea5767.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Audio.Radio.Tea5767.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.Enums.cs b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.Enums.cs
index 8e5481dc86..6367d6f020 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.Enums.cs
@@ -3,9 +3,9 @@
public partial class Tea5767
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// I2C address 0
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.cs b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.cs
index d21d9d3445..066da694e5 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.cs
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Driver/Tea5767.cs
@@ -1,20 +1,20 @@
-using System;
-using System.Threading;
using Meadow.Hardware;
using Meadow.Units;
+using System;
+using System.Threading;
namespace Meadow.Foundation.Audio.Radio
{
///
/// Represents a TEA5767 radio
///
- public partial class Tea5767
+ public partial class Tea5767 : II2cPeripheral
{
///
- /// TEA5767 radio.
+ /// I2C Communication bus used to communicate with the peripheral
///
- private readonly II2cPeripheral i2cPeripheral;
+ protected readonly II2cCommunications i2cComms;
byte hiInjection;
readonly Memory writeBuffer = new byte[5];
@@ -25,14 +25,19 @@ public partial class Tea5767
///
public bool IsMuted { get; set; }
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new TEA5767 object using the default parameters
///
/// I2Cbus connected to the radio
/// Address of the bus on the I2C display.
- public Tea5767(II2cBus i2cBus, byte address = (byte)Address.Default)
+ public Tea5767(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
InitTEA5767();
}
@@ -111,7 +116,7 @@ void SetFrequency(double frequency)
void TransmitData()
{
- i2cPeripheral.Exchange(writeBuffer.Span, readBuffer.Span);
+ i2cComms.Exchange(writeBuffer.Span, readBuffer.Span);
Thread.Sleep(100);
}
@@ -155,7 +160,7 @@ public void SelectFrequency(Frequency frequency)
void ReadStatus()
{
- i2cPeripheral.Read(readBuffer.Span);
+ i2cComms.Read(readBuffer.Span);
Thread.Sleep(100);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Samples/Tea5767_Sample/Tea5767_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Samples/Tea5767_Sample/Tea5767_Sample.csproj
index 93b8663c86..0a4bf80da1 100644
--- a/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Samples/Tea5767_Sample/Tea5767_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Audio.Radio.Tea5767/Samples/Tea5767_Sample/Tea5767_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Ch1115.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Ch1115.cs
index 9c2ded5a69..3384dba39a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Ch1115.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Ch1115.cs
@@ -1,15 +1,16 @@
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
using Meadow.Hardware;
+using Meadow.Units;
using System;
using System.Threading;
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the Ch1115 family of displays.
+ /// Provide an interface to the Ch1115 family of displays
///
- public partial class Ch1115 : IGraphicsDisplay
+ public partial class Ch1115 : IGraphicsDisplay, ISpiPeripheral
{
///
/// The display color mode - 1 bit per pixel monochrome
@@ -37,18 +38,46 @@ public partial class Ch1115 : IGraphicsDisplay
public IPixelBuffer PixelBuffer => imageBuffer;
///
- /// SPI peripheral object
+ /// The default SPI bus speed for the device
///
- ISpiPeripheral spiPerihperal;
+ public Frequency DefaultSpiBusSpeed => new Frequency(375, Frequency.UnitType.Kilohertz);
- IDigitalOutputPort dataCommandPort;
- IDigitalOutputPort resetPort;
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
+ ///
+ protected readonly ISpiCommunications spiComms;
+
+ readonly IDigitalOutputPort dataCommandPort;
+ readonly IDigitalOutputPort resetPort;
const bool Data = true;
const bool Command = false;
- Buffer1bpp imageBuffer;
- byte[] pageBuffer;
+ readonly Buffer1bpp imageBuffer;
+ readonly byte[] pageBuffer;
///
/// Create a new Ch1115 object
@@ -84,7 +113,7 @@ public Ch1115(ISpiBus spiBus,
this.dataCommandPort = dataCommandPort;
this.resetPort = resetPort;
- spiPerihperal = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
imageBuffer = new Buffer1bpp(width, height);
pageBuffer = new byte[PageSize];
@@ -194,7 +223,7 @@ public void SetContrast(byte contrast)
private void SendCommand(byte command)
{
dataCommandPort.State = Command;
- spiPerihperal.Write(command);
+ spiComms.Write(command);
}
///
@@ -208,7 +237,7 @@ private void SendCommands(byte[] commands)
Array.Copy(commands, 0, data, 1, commands.Length);
dataCommandPort.State = Command;
- spiPerihperal.Write(commands);
+ spiComms.Write(commands);
}
const int StartColumnOffset = 0;
@@ -228,7 +257,7 @@ public void Show()
dataCommandPort.State = Data;
Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ spiComms.Write(pageBuffer);
}
}
@@ -259,7 +288,7 @@ public void Show(int left, int top, int right, int bottom)
dataCommandPort.State = Data;
Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ spiComms.Write(pageBuffer);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Displays.Ch1115.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Displays.Ch1115.csproj
index e9d6113de8..dadb73d968 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Displays.Ch1115.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Driver/Displays.Ch1115.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/Ch1115_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/Ch1115_Sample.csproj
index 9e5b64a30b..ff2e0c050a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/Ch1115_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/Ch1115_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/MeadowApp.cs
index 90862010c0..2d2d448c9e 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ch1115/Samples/Ch1115_Sample/MeadowApp.cs
@@ -6,7 +6,7 @@
namespace Displays.Ch1115_Sample
{
- public class MeadowApp : App
+ public class MeadowApp : App
{
//
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Gtk/Driver/Displays.Gtk.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Gtk/Driver/Displays.Gtk.csproj
index 0454cf7697..256638b403 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Gtk/Driver/Displays.Gtk.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Gtk/Driver/Displays.Gtk.csproj
@@ -25,6 +25,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/Displays.Lcd.CharacterDisplay.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/Displays.Lcd.CharacterDisplay.csproj
index 2ac132c89b..9bb9f0551f 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/Displays.Lcd.CharacterDisplay.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/Displays.Lcd.CharacterDisplay.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/GroveCharacterDisplay.cs b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/GroveCharacterDisplay.cs
index ab904ea8a6..bcccf0c94b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/GroveCharacterDisplay.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/GroveCharacterDisplay.cs
@@ -1,5 +1,5 @@
-using System.Threading;
-using Meadow.Hardware;
+using Meadow.Hardware;
+using System.Threading;
namespace Meadow.Foundation.Displays.Lcd
{
@@ -66,7 +66,7 @@ protected override void Initialize()
protected override void Command(byte value)
{
var data = new byte[] { 0x80, value };
- i2cPeripheral.Write(data);
+ i2cComms.Write(data);
}
///
@@ -77,7 +77,7 @@ protected override void Command(byte value)
protected override void Send(byte value, byte mode)
{
var data = new byte[] { 0x40, value };
- i2cPeripheral.Write(data);
+ i2cComms.Write(data);
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.Enums.cs
index 6fe29f48d5..6b44b83894 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.Enums.cs
@@ -3,7 +3,7 @@
public partial class I2cCharacterDisplay
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.cs b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.cs
index 30d5941143..54f5b3cae9 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Driver/I2cCharacterDisplay.cs
@@ -7,18 +7,23 @@ namespace Meadow.Foundation.Displays.Lcd
///
/// Represents a character display using I2C
///
- public partial class I2cCharacterDisplay : ICharacterDisplay
+ public partial class I2cCharacterDisplay : ICharacterDisplay, II2cPeripheral
{
///
- /// The I2C peripheral used to communicate with the display
+ /// The default I2C address for the peripheral
///
- protected readonly II2cPeripheral i2cPeripheral;
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
///
/// Display control value
///
protected byte displayControl;
-
+
///
/// Display mode value
///
@@ -77,7 +82,7 @@ protected enum I2CCommands
///
LCD_SETDDRAMADDR = 0x80,
}
-
+
// flags for display entry mode
internal static byte LCD_ENTRYRIGHT = 0x00;
internal static byte LCD_ENTRYLEFT = 0x02;
@@ -123,7 +128,7 @@ protected enum I2CCommands
/// Number of character columns
public I2cCharacterDisplay(II2cBus i2cBus, byte address = (byte)Addresses.Default, byte rows = 4, byte columns = 20)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
DisplayConfig = new TextDisplayConfig() { Width = columns, Height = rows };
backlightValue = LCD_BACKLIGHT;
@@ -138,7 +143,7 @@ protected virtual void Initialize()
{
var displayFunction = (byte)(LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS);
- if(DisplayConfig.Height > 1)
+ if (DisplayConfig.Height > 1)
{
displayFunction |= LCD_2LINE;
}
@@ -181,7 +186,7 @@ protected virtual void Initialize()
void Home()
{
Command((byte)I2CCommands.LCD_RETURNHOME); // set cursor position to zero
- Thread.Sleep(2);
+ Thread.Sleep(2);
}
///
@@ -201,7 +206,7 @@ void Write4Bits(byte value)
void ExpanderWrite(byte value)
{
- i2cPeripheral.Write((byte)(value | backlightValue));
+ i2cComms.Write((byte)(value | backlightValue));
}
///
@@ -262,7 +267,7 @@ public void SetCursorPosition(byte column, byte line)
if (line > DisplayConfig.Height)
{
- line = (byte)(DisplayConfig.Height - 1);
+ line = (byte)(DisplayConfig.Height - 1);
}
Command((byte)((byte)I2CCommands.LCD_SETDDRAMADDR | (column + rowOffsets[line])));
@@ -422,7 +427,7 @@ public void SaveCustomCharacter(byte[] characterMap, byte address)
Command((byte)((byte)I2CCommands.LCD_SETCGRAMADDR | (address << 3)));
for (int i = 0; i < 8; i++)
{
- i2cPeripheral.WriteRegister(Rs, characterMap[i]);
+ i2cComms.WriteRegister(Rs, characterMap[i]);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Samples/CharacterDisplay_Sample/CharacterDisplay_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Samples/CharacterDisplay_Sample/CharacterDisplay_Sample.csproj
index 3027db4da9..a3072ddbd8 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Samples/CharacterDisplay_Sample/CharacterDisplay_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Lcd.CharacterDisplay/Samples/CharacterDisplay_Sample/CharacterDisplay_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/Displays.Led.FourDigitSevenSegment.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/Displays.Led.FourDigitSevenSegment.csproj
index ba3559ad4a..067f6011f4 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/Displays.Led.FourDigitSevenSegment.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/Displays.Led.FourDigitSevenSegment.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/FourDigitSevenSegment.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/FourDigitSevenSegment.cs
index 0a8807da19..7df8edc0ae 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/FourDigitSevenSegment.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Driver/FourDigitSevenSegment.cs
@@ -12,8 +12,7 @@ public class FourDigitSevenSegment
CancellationTokenSource cts = null;
readonly IDigitalOutputPort[] digits;
-
- SevenSegment[] sevenSegments;
+ readonly SevenSegment[] sevenSegments;
///
/// Creates a SevenSegment connected to the especified IPins to a IODevice
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Samples/FourDigitSevenSegment_Sample/FourDigitSevenSegment_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Samples/FourDigitSevenSegment_Sample/FourDigitSevenSegment_Sample.csproj
index 5ba5b90891..ca22616d61 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Samples/FourDigitSevenSegment_Sample/FourDigitSevenSegment_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourDigitSevenSegment/Samples/FourDigitSevenSegment_Sample/FourDigitSevenSegment_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/Displays.Led.FourteenSegment.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/Displays.Led.FourteenSegment.csproj
new file mode 100644
index 0000000000..d2d8f36533
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/Displays.Led.FourteenSegment.csproj
@@ -0,0 +1,22 @@
+
+
+ true
+ icon.png
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ FourteenSegment
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Displays.Led.FourteenSegment
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow.Foundation,FourteenSegment,Fourteen,14,Segment,Display,LED
+ 0.1.0
+ true
+ Digital Fourteen (14) segment display
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Ascii.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Ascii.cs
new file mode 100644
index 0000000000..b03711bcd4
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Ascii.cs
@@ -0,0 +1,104 @@
+namespace Meadow.Foundation.Displays.Led
+{
+ public partial class FourteenSegment
+ {
+ static ushort[] fourteenSegmentASCII = {
+ 0b000000000000000, /* (space) */
+ 0b100000000000110, /* ! */
+ 0b000001000000010, /* " */
+ 0b001001011001110, /* # */
+ 0b001001011101101, /* $ */
+ 0b011111111100100, /* % */
+ 0b010001101011001, /* & */
+ 0b000001000000000, /* ' */
+ 0b010010000000000, /* ( */
+ 0b000100100000000, /* ) */
+ 0b011111111000000, /* * */
+ 0b001001011000000, /* + */
+ 0b000100000000000, /* , */
+ 0b000000011000000, /* - */
+ 0b100000000000000, /* . */
+ 0b000110000000000, /* / */
+ 0b000110000111111, /* 0 */
+ 0b000010000000110, /* 1 */
+ 0b000000011011011, /* 2 */
+ 0b000000010001111, /* 3 */
+ 0b000000011100110, /* 4 */
+ 0b010000001101001, /* 5 */
+ 0b000000011111101, /* 6 */
+ 0b000000000000111, /* 7 */
+ 0b000000011111111, /* 8 */
+ 0b000000011101111, /* 9 */
+ 0b001001000000000, /* : */
+ 0b000101000000000, /* ; */
+ 0b010010001000000, /* < */
+ 0b000000011001000, /* = */
+ 0b000100110000000, /* > */
+ 0b101000010000011, /* ? */
+ 0b000001010111011, /* @ */
+ 0b000000011110111, /* A */
+ 0b001001010001111, /* B */
+ 0b000000000111001, /* C */
+ 0b001001000001111, /* D */
+ 0b000000001111001, /* E */
+ 0b000000001110001, /* F */
+ 0b000000010111101, /* G */
+ 0b000000011110110, /* H */
+ 0b001001000001001, /* I */
+ 0b000000000011110, /* J */
+ 0b010010001110000, /* K */
+ 0b000000000111000, /* L */
+ 0b000010100110110, /* M */
+ 0b010000100110110, /* N */
+ 0b000000000111111, /* O */
+ 0b000000011110011, /* P */
+ 0b010000000111111, /* Q */
+ 0b010000011110011, /* R */
+ 0b000000011101101, /* S */
+ 0b001001000000001, /* T */
+ 0b000000000111110, /* U */
+ 0b000110000110000, /* V */
+ 0b010100000110110, /* W */
+ 0b010110100000000, /* X */
+ 0b000000011101110, /* Y */
+ 0b000110000001001, /* Z */
+ 0b000000000111001, /* [ */
+ 0b010000100000000, /* \ */
+ 0b000000000001111, /* ] */
+ 0b010100000000000, /* ^ */
+ 0b000000000001000, /* _ */
+ 0b000000100000000, /* ` */
+ 0b001000001011000, /* a */
+ 0b010000001111000, /* b */
+ 0b000000011011000, /* c */
+ 0b000100010001110, /* d */
+ 0b000100001011000, /* e */
+ 0b001010011000000, /* f */
+ 0b000010010001110, /* g */
+ 0b001000001110000, /* h */
+ 0b001000000000000, /* i */
+ 0b000101000010000, /* j */
+ 0b011011000000000, /* k */
+ 0b000000000110000, /* l */
+ 0b001000011010100, /* m */
+ 0b001000001010000, /* n */
+ 0b000000011011100, /* o */
+ 0b000000101110000, /* p */
+ 0b000010010000110, /* q */
+ 0b000000001010000, /* r */
+ 0b010000010001000, /* s */
+ 0b000000001111000, /* t */
+ 0b000000000011100, /* u */
+ 0b000100000010000, /* v */
+ 0b010100000010100, /* w */
+ 0b010110100000000, /* x */
+ 0b000001010001110, /* y */
+ 0b000100001001000, /* z */
+ 0b000100101001001, /* { */
+ 0b001001000000000, /* | */
+ 0b010010010001001, /* } */
+ 0b000110011000000, /* ~ */
+ 0b000000000000000, /* (del) */
+ };
+ }
+}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Enums.cs
new file mode 100644
index 0000000000..b592aeb17e
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.Enums.cs
@@ -0,0 +1,72 @@
+namespace Meadow.Foundation.Displays.Led
+{
+ public partial class FourteenSegment
+ {
+ ///
+ /// The led segments
+ ///
+ public enum Segment : byte
+ {
+ ///
+ /// Segment A
+ ///
+ A,
+ ///
+ /// Segment B
+ ///
+ B,
+ ///
+ /// Segment C
+ ///
+ C,
+ ///
+ /// Segment D
+ ///
+ D,
+ ///
+ /// Segment E
+ ///
+ E,
+ ///
+ /// Segment F
+ ///
+ F,
+ ///
+ /// Segment G
+ ///
+ G,
+ ///
+ /// Segment G2
+ ///
+ G2,
+ ///
+ /// Segment H
+ ///
+ H,
+ ///
+ /// Segment J
+ ///
+ J,
+ ///
+ /// Segment K
+ ///
+ K,
+ ///
+ /// Segment L
+ ///
+ L,
+ ///
+ /// Segment M
+ ///
+ M,
+ ///
+ /// Segment N
+ ///
+ N,
+ ///
+ /// Segment decimal
+ ///
+ Decimal,
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.cs
new file mode 100644
index 0000000000..79ba8c1a7f
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Driver/FourteenSegment.cs
@@ -0,0 +1,169 @@
+using Meadow.Hardware;
+
+namespace Meadow.Foundation.Displays.Led
+{
+ ///
+ /// Fourteen Segment Display
+ ///
+ public partial class FourteenSegment
+ {
+ private readonly IDigitalOutputPort portA;
+ private readonly IDigitalOutputPort portB;
+ private readonly IDigitalOutputPort portC;
+ private readonly IDigitalOutputPort portD;
+ private readonly IDigitalOutputPort portE;
+ private readonly IDigitalOutputPort portF;
+ private readonly IDigitalOutputPort portG;
+ private readonly IDigitalOutputPort portG2;
+ private readonly IDigitalOutputPort portH;
+ private readonly IDigitalOutputPort portJ;
+ private readonly IDigitalOutputPort portK;
+ private readonly IDigitalOutputPort portL;
+ private readonly IDigitalOutputPort portM;
+ private readonly IDigitalOutputPort portN;
+ private readonly IDigitalOutputPort portDecimal;
+
+ private readonly bool isCommonCathode;
+
+ ///
+ /// Creates a FourteenSegment connected to the especified IPins to a IODevice
+ ///
+ /// Pin A
+ /// Pin B
+ /// Pin C
+ /// Pin D
+ /// Pin E
+ /// Pin F
+ /// Pin G
+ /// Pin G2
+ /// Pin H
+ /// Pin J
+ /// Pin K
+ /// Pin L
+ /// Pin M
+ /// Pin N
+ /// Pin decimal
+ /// Is the display using common cathod (true) or common annode (false)
+ public FourteenSegment(
+ IPin pinA, IPin pinB, IPin pinC, IPin pinD, IPin pinE, IPin pinF, IPin pinG,
+ IPin pinG2, IPin pinH, IPin pinJ, IPin pinK, IPin pinL, IPin pinM, IPin pinN,
+ IPin pinDecimal,
+ bool isCommonCathode) :
+ this(pinA.CreateDigitalOutputPort(),
+ pinB.CreateDigitalOutputPort(),
+ pinC.CreateDigitalOutputPort(),
+ pinD.CreateDigitalOutputPort(),
+ pinE.CreateDigitalOutputPort(),
+ pinF.CreateDigitalOutputPort(),
+ pinG.CreateDigitalOutputPort(),
+ pinG2.CreateDigitalOutputPort(),
+ pinH.CreateDigitalOutputPort(),
+ pinJ.CreateDigitalOutputPort(),
+ pinK.CreateDigitalOutputPort(),
+ pinL.CreateDigitalOutputPort(),
+ pinM.CreateDigitalOutputPort(),
+ pinN.CreateDigitalOutputPort(),
+ pinDecimal.CreateDigitalOutputPort(),
+ isCommonCathode)
+ { }
+
+ ///
+ /// Creates a FourteenSegment connected to the especified IDigitalOutputPorts
+ ///
+ /// Digital input port for pin A
+ /// Digital input port for pin B
+ /// Digital input port for pin C
+ /// Digital input port for pin D
+ /// Digital input port for pin E
+ /// Digital input port for pin F
+ /// Digital input port for pin G
+ /// Digital input port for pin G2
+ /// Digital input port for pin H
+ /// Digital input port for pin J
+ /// Digital input port for pin K
+ /// Digital input port for pin L
+ /// Digital input port for pin M
+ /// Digital input port for pin N
+ /// Digital input port for decimal pin
+ /// Is the display using common cathod (true) or common annode (false)
+ public FourteenSegment(
+ IDigitalOutputPort portA, IDigitalOutputPort portB, IDigitalOutputPort portC, IDigitalOutputPort portD,
+ IDigitalOutputPort portE, IDigitalOutputPort portF, IDigitalOutputPort portG, IDigitalOutputPort portG2,
+ IDigitalOutputPort portH, IDigitalOutputPort portJ, IDigitalOutputPort portK, IDigitalOutputPort portL,
+ IDigitalOutputPort portM, IDigitalOutputPort portN,
+ IDigitalOutputPort portDecimal,
+ bool isCommonCathode)
+ {
+ this.portA = portA;
+ this.portB = portB;
+ this.portC = portC;
+ this.portD = portD;
+ this.portE = portE;
+ this.portF = portF;
+ this.portG = portG;
+ this.portG2 = portG2;
+ this.portH = portH;
+ this.portJ = portJ;
+ this.portK = portK;
+ this.portL = portL;
+ this.portM = portM;
+ this.portN = portN;
+ this.portDecimal = portDecimal;
+
+ this.isCommonCathode = isCommonCathode;
+ }
+
+ ///
+ /// Displays the specified ascii character (from 32 to 126)
+ /// Unsupported ascii values will be blank
+ ///
+ public void SetDisplay(char asciiCharacter, bool? showDecimal = null)
+ {
+ if (asciiCharacter < 32 || asciiCharacter > 126)
+ {
+ asciiCharacter = ' ';
+ }
+
+ var data = fourteenSegmentASCII[asciiCharacter - 32];
+
+ portA.State = (data & 1 << 0) != 0;
+ portB.State = (data & 1 << 1) != 0;
+ portC.State = (data & 1 << 2) != 0;
+ portD.State = (data & 1 << 3) != 0;
+ portE.State = (data & 1 << 4) != 0;
+ portF.State = (data & 1 << 5) != 0;
+ portG.State = (data & 1 << 6) != 0;
+ portG2.State = (data & 1 << 7) != 0;
+ portH.State = (data & 1 << 8) != 0;
+ portJ.State = (data & 1 << 9) != 0;
+ portK.State = (data & 1 << 10) != 0;
+ portL.State = (data & 1 << 11) != 0;
+ portM.State = (data & 1 << 12) != 0;
+ portN.State = (data & 1 << 13) != 0;
+ portDecimal.State = (data & 1 << 14) != 0;
+
+ if (showDecimal != null)
+ {
+ portDecimal.State = isCommonCathode ? showDecimal.Value : !showDecimal.Value;
+ }
+ }
+
+ ///
+ /// Is a specific led segment enabled for an ascii character
+ ///
+ /// The led segment
+ /// The ascii character
+ ///
+ public static bool IsEnabled(Segment segment, char asciiCharacter)
+ {
+ if (asciiCharacter < 32 || asciiCharacter > 126)
+ {
+ return false;
+ }
+
+ var data = fourteenSegmentASCII[asciiCharacter - 32];
+
+ return (data & 1 << (int)segment) != 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/FourteenSegment_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/FourteenSegment_Sample.csproj
new file mode 100644
index 0000000000..587271b4e7
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/FourteenSegment_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..0cc3a93fee
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/MeadowApp.cs
@@ -0,0 +1,50 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Displays.Led;
+using System.Threading.Tasks;
+
+namespace Displays.Led.FourteenSegment_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ FourteenSegment fourteenSegment;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initializing...");
+
+ fourteenSegment = new FourteenSegment
+ (
+ portA: Device.CreateDigitalOutputPort(Device.Pins.D00),
+ portB: Device.CreateDigitalOutputPort(Device.Pins.D01),
+ portC: Device.CreateDigitalOutputPort(Device.Pins.D02),
+ portD: Device.CreateDigitalOutputPort(Device.Pins.D03),
+ portE: Device.CreateDigitalOutputPort(Device.Pins.D04),
+ portF: Device.CreateDigitalOutputPort(Device.Pins.D05),
+ portG: Device.CreateDigitalOutputPort(Device.Pins.D06),
+ portG2: Device.CreateDigitalOutputPort(Device.Pins.D07),
+ portH: Device.CreateDigitalOutputPort(Device.Pins.D08),
+ portJ: Device.CreateDigitalOutputPort(Device.Pins.D09),
+ portK: Device.CreateDigitalOutputPort(Device.Pins.D10),
+ portL: Device.CreateDigitalOutputPort(Device.Pins.D11),
+ portM: Device.CreateDigitalOutputPort(Device.Pins.D12),
+ portN: Device.CreateDigitalOutputPort(Device.Pins.D13),
+ portDecimal: Device.CreateDigitalOutputPort(Device.Pins.D14),
+ isCommonCathode: false
+ );
+
+ return base.Initialize();
+ }
+
+ public override Task Run()
+ {
+ fourteenSegment.SetDisplay(asciiCharacter: 'A', showDecimal: true);
+
+ return base.Run();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.FourteenSegment/Samples/FourteenSegment_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Driver/Displays.Led.SevenSegment.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Driver/Displays.Led.SevenSegment.csproj
index cfac952597..f0ecda2e5c 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Driver/Displays.Led.SevenSegment.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Driver/Displays.Led.SevenSegment.csproj
@@ -10,13 +10,13 @@
http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
Meadow.Foundation.Displays.Led.SevenSegment
https://github.com/WildernessLabs/Meadow.Foundation
- Meadow.Foundation, SevenSegment, Display
+ Meadow.Foundation,SevenSegment,Seven,7,Segment,Display,LED
0.9.52
true
- Ditigal Seven segment displays
+ Digital Seven (7) segment display
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Samples/SevenSegment_Sample/SevenSegment_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Samples/SevenSegment_Sample/SevenSegment_Sample.csproj
index 8ddd30aaae..17d6c70395 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Samples/SevenSegment_Sample/SevenSegment_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SevenSegment/Samples/SevenSegment_Sample/SevenSegment_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Displays.Sh1106.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/Displays.Led.SixteenSegment.csproj
similarity index 65%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Displays.Sh1106.csproj
rename to Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/Displays.Led.SixteenSegment.csproj
index ace950b3bf..c28d4525d0 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Displays.Sh1106.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/Displays.Led.SixteenSegment.csproj
@@ -5,18 +5,18 @@
Wilderness Labs, Inc
netstandard2.1
Library
- Sh1106
+ SixteenSegment
Wilderness Labs, Inc
http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
- Meadow.Foundation.Displays.Sh1106
+ Meadow.Foundation.Displays.Led.SixteenSegment
https://github.com/WildernessLabs/Meadow.Foundation
- Meadow, Meadow.Foundation, Displays, LCD, Sh1106
+ Meadow.Foundation,SixteenSegment,Sixteen,14,Segment,Display,LED
0.1.0
true
- Sh1106 SPI monochrome OLED display
+ Digital Sixteen (16) segment display
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Ascii.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Ascii.cs
new file mode 100644
index 0000000000..eaa611fc04
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Ascii.cs
@@ -0,0 +1,104 @@
+namespace Meadow.Foundation.Displays.Led
+{
+ public partial class SixteenSegment
+ {
+ static uint[] sixteenSegmentASCII = {
+ 0b00000000000000000, /* (space) */
+ 0b10000000000001100, /* ! */
+ 0b00000001000000100, /* " */
+ 0b01010101000111100, /* # */
+ 0b01010101010111011, /* $ */
+ 0b01110111010011001, /* % */
+ 0b01001001101110001, /* & */
+ 0b00000001000000000, /* ' */
+ 0b00001010000000000, /* ( */
+ 0b00100000100000000, /* ) */
+ 0b01111111100000000, /* * */
+ 0b01010101000000000, /* + */
+ 0b00100000000000000, /* , */
+ 0b01000100000000000, /* - */
+ 0b10000000000000000, /* . */
+ 0b00100010000000000, /* / */
+ 0b00100010011111111, /* 0 */
+ 0b00000010000001100, /* 1 */
+ 0b01000100001110111, /* 2 */
+ 0b00000100000111111, /* 3 */
+ 0b01000100010001100, /* 4 */
+ 0b01001000010110011, /* 5 */
+ 0b01000100011111011, /* 6 */
+ 0b00000000000001111, /* 7 */
+ 0b01000100011111111, /* 8 */
+ 0b01000100010111111, /* 9 */
+ 0b00010001000000000, /* : */
+ 0b00100001000000000, /* ; */
+ 0b01001010000000000, /* < */
+ 0b01000100000110000, /* = */
+ 0b00100100100000000, /* > */
+ 0b10010100000000111, /* ? */
+ 0b00000101011110111, /* @ */
+ 0b01000100011001111, /* A */
+ 0b00010101000111111, /* B */
+ 0b00000000011110011, /* C */
+ 0b00010001000111111, /* D */
+ 0b01000000011110011, /* E */
+ 0b01000000011000011, /* F */
+ 0b00000100011111011, /* G */
+ 0b01000100011001100, /* H */
+ 0b00010001000110011, /* I */
+ 0b00000000001111100, /* J */
+ 0b01001010011000000, /* K */
+ 0b00000000011110000, /* L */
+ 0b00000010111001100, /* M */
+ 0b00001000111001100, /* N */
+ 0b00000000011111111, /* O */
+ 0b01000100011000111, /* P */
+ 0b00001000011111111, /* Q */
+ 0b01001100011000111, /* R */
+ 0b01000100010111011, /* S */
+ 0b00010001000000011, /* T */
+ 0b00000000011111100, /* U */
+ 0b00100010011000000, /* V */
+ 0b00101000011001100, /* W */
+ 0b00101010100000000, /* X */
+ 0b01000100010111100, /* Y */
+ 0b00100010000110011, /* Z */
+ 0b00010001000010010, /* [ */
+ 0b00001000100000000, /* \ */
+ 0b00010001000100001, /* ] */
+ 0b00101000000000000, /* ^ */
+ 0b00000000000110000, /* _ */
+ 0b00000000100000000, /* ` */
+ 0b01010000001110000, /* a */
+ 0b01010000011100000, /* b */
+ 0b01000000001100000, /* c */
+ 0b00010100000011100, /* d */
+ 0b01100000001100000, /* e */
+ 0b01010101000000010, /* f */
+ 0b01010001010100001, /* g */
+ 0b01010000011000000, /* h */
+ 0b00010000000000000, /* i */
+ 0b00010001001100000, /* j */
+ 0b00011011000000000, /* k */
+ 0b00000000011000000, /* l */
+ 0b01010100001001000, /* m */
+ 0b01010000001000000, /* n */
+ 0b01010000001100000, /* o */
+ 0b01000001011000001, /* p */
+ 0b01010001010000001, /* q */
+ 0b01000000001000000, /* r */
+ 0b01010000010100001, /* s */
+ 0b01000000011100000, /* t */
+ 0b00010000001100000, /* u */
+ 0b00100000001000000, /* v */
+ 0b00101000001001000, /* w */
+ 0b00101010100000000, /* x */
+ 0b00000101000011100, /* y */
+ 0b01100000000100000, /* z */
+ 0b01010001000010010, /* { */
+ 0b00010001000000000, /* | */
+ 0b00010101000100001, /* } */
+ 0b01100110000000000, /* ~ */
+ 0b00000000000000000, /* (del) */
+ };
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Enums.cs
new file mode 100644
index 0000000000..7a5e11a350
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.Enums.cs
@@ -0,0 +1,84 @@
+namespace Meadow.Foundation.Displays.Led
+{
+ public partial class SixteenSegment
+ {
+ ///
+ /// The led segments
+ ///
+ public enum Segment : byte
+ {
+ ///
+ /// Segment A
+ ///
+ A,
+ ///
+ /// Segment B
+ ///
+ B,
+ ///
+ /// Segment C
+ ///
+ C,
+ ///
+ /// Segment D
+ ///
+ D,
+ ///
+ /// Segment E
+ ///
+ E,
+ ///
+ /// Segment F
+ ///
+ F,
+ ///
+ /// Segment G
+ ///
+ G,
+ ///
+ /// Segment H
+ ///
+ H,
+ ///
+ /// Segment K
+ ///
+ K,
+ ///
+ /// Segment L
+ ///
+ L,
+ ///
+ /// Segment M
+ ///
+ M,
+ ///
+ /// Segment N
+ ///
+ N,
+ ///
+ /// Segment P
+ ///
+ P,
+ ///
+ /// Segment R
+ ///
+ R,
+ ///
+ /// Segment S
+ ///
+ S,
+ ///
+ /// Segment T
+ ///
+ T,
+ ///
+ /// Segment U
+ ///
+ U,
+ ///
+ /// Segment decimal
+ ///
+ Decimal,
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.cs
new file mode 100644
index 0000000000..1e36a4cf8e
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Driver/SixteenSegment.cs
@@ -0,0 +1,183 @@
+using Meadow.Hardware;
+
+namespace Meadow.Foundation.Displays.Led
+{
+ ///
+ /// Sixteen Segment Display
+ ///
+ public partial class SixteenSegment
+ {
+ private readonly IDigitalOutputPort portA;
+ private readonly IDigitalOutputPort portB;
+ private readonly IDigitalOutputPort portC;
+ private readonly IDigitalOutputPort portD;
+ private readonly IDigitalOutputPort portE;
+ private readonly IDigitalOutputPort portF;
+ private readonly IDigitalOutputPort portG;
+ private readonly IDigitalOutputPort portH;
+ private readonly IDigitalOutputPort portK;
+ private readonly IDigitalOutputPort portM;
+ private readonly IDigitalOutputPort portN;
+ private readonly IDigitalOutputPort portP;
+ private readonly IDigitalOutputPort portR;
+ private readonly IDigitalOutputPort portS;
+ private readonly IDigitalOutputPort portT;
+ private readonly IDigitalOutputPort portU;
+ private readonly IDigitalOutputPort portDecimal;
+
+ private readonly bool isCommonCathode;
+
+ ///
+ /// Creates a SixteenSegment connected to the especified IPins to a IODevice
+ ///
+ /// Pin A
+ /// Pin B
+ /// Pin C
+ /// Pin D
+ /// Pin E
+ /// Pin F
+ /// Pin G
+ /// Pin H
+ /// Pin K
+ /// Pin M
+ /// Pin N
+ /// Pin P
+ /// Pin R
+ /// Pin S
+ /// Pin T
+ /// Pin U
+ /// Pin decimal
+ /// Is the display using common cathod (true) or common annode (false)
+ public SixteenSegment(
+ IPin pinA, IPin pinB, IPin pinC, IPin pinD,
+ IPin pinE, IPin pinF, IPin pinG, IPin pinH,
+ IPin pinK, IPin pinM, IPin pinN, IPin pinP,
+ IPin pinR, IPin pinS, IPin pinT, IPin pinU,
+ IPin pinDecimal,
+ bool isCommonCathode) :
+ this(pinA.CreateDigitalOutputPort(),
+ pinB.CreateDigitalOutputPort(),
+ pinC.CreateDigitalOutputPort(),
+ pinD.CreateDigitalOutputPort(),
+ pinE.CreateDigitalOutputPort(),
+ pinF.CreateDigitalOutputPort(),
+ pinG.CreateDigitalOutputPort(),
+ pinH.CreateDigitalOutputPort(),
+ pinK.CreateDigitalOutputPort(),
+ pinM.CreateDigitalOutputPort(),
+ pinN.CreateDigitalOutputPort(),
+ pinP.CreateDigitalOutputPort(),
+ pinR.CreateDigitalOutputPort(),
+ pinS.CreateDigitalOutputPort(),
+ pinT.CreateDigitalOutputPort(),
+ pinU.CreateDigitalOutputPort(),
+ pinDecimal.CreateDigitalOutputPort(),
+ isCommonCathode)
+ { }
+
+ ///
+ /// Creates a SixteenSegment connected to the especified IDigitalOutputPorts
+ ///
+ /// Digital input port for pin A
+ /// Digital input port for pin B
+ /// Digital input port for pin C
+ /// Digital input port for pin D
+ /// Digital input port for pin E
+ /// Digital input port for pin F
+ /// Digital input port for pin G
+ /// Digital input port for pin H
+ /// Digital input port for pin K
+ /// Digital input port for pin M
+ /// Digital input port for pin N
+ /// Digital input port for pin P
+ /// Digital input port for pin R
+ /// Digital input port for pin S
+ /// Digital input port for pin T
+ /// Digital input port for pin U
+ /// Digital input port for decimal pin
+ /// Is the display using common cathod (true) or common annode (false)
+ public SixteenSegment(
+ IDigitalOutputPort portA, IDigitalOutputPort portB, IDigitalOutputPort portC, IDigitalOutputPort portD,
+ IDigitalOutputPort portE, IDigitalOutputPort portF, IDigitalOutputPort portG, IDigitalOutputPort portH,
+ IDigitalOutputPort portK, IDigitalOutputPort portM, IDigitalOutputPort portN, IDigitalOutputPort portP,
+ IDigitalOutputPort portR, IDigitalOutputPort portS, IDigitalOutputPort portT, IDigitalOutputPort portU,
+ IDigitalOutputPort portDecimal,
+ bool isCommonCathode)
+ {
+ this.portA = portA;
+ this.portB = portB;
+ this.portC = portC;
+ this.portD = portD;
+ this.portE = portE;
+ this.portF = portF;
+ this.portG = portG;
+ this.portH = portH;
+ this.portK = portK;
+ this.portM = portM;
+ this.portN = portN;
+ this.portP = portP;
+ this.portR = portR;
+ this.portS = portS;
+ this.portT = portT;
+ this.portU = portU;
+ this.portDecimal = portDecimal;
+
+ this.isCommonCathode = isCommonCathode;
+ }
+
+ ///
+ /// Displays the specified ascii character (from 32 to 126)
+ /// Unsupported ascii values will be blank
+ ///
+ public void SetDisplay(char asciiCharacter, bool? showDecimal = null)
+ {
+ if (asciiCharacter < 32 || asciiCharacter > 126)
+ {
+ asciiCharacter = ' ';
+ }
+
+ var data = sixteenSegmentASCII[asciiCharacter - 32];
+
+ portA.State = (data & 1 << 0) != 0;
+ portB.State = (data & 1 << 1) != 0;
+ portC.State = (data & 1 << 2) != 0;
+ portD.State = (data & 1 << 3) != 0;
+ portE.State = (data & 1 << 4) != 0;
+ portF.State = (data & 1 << 5) != 0;
+ portG.State = (data & 1 << 6) != 0;
+ portH.State = (data & 1 << 7) != 0;
+ portK.State = (data & 1 << 8) != 0;
+ portM.State = (data & 1 << 9) != 0;
+ portN.State = (data & 1 << 10) != 0;
+ portP.State = (data & 1 << 11) != 0;
+ portR.State = (data & 1 << 12) != 0;
+ portS.State = (data & 1 << 13) != 0;
+ portT.State = (data & 1 << 14) != 0;
+ portU.State = (data & 1 << 15) != 0;
+ portDecimal.State = (data & 1 << 16) != 0;
+
+ if (showDecimal != null)
+ {
+ portDecimal.State = isCommonCathode ? showDecimal.Value : !showDecimal.Value;
+ }
+ }
+
+ ///
+ /// Is a specific led segment enabled for an ascii character
+ ///
+ /// The led segment
+ /// The ascii character
+ ///
+ public static bool IsEnabled(Segment segment, char asciiCharacter)
+ {
+ if (asciiCharacter < 32 || asciiCharacter > 126)
+ {
+ return false;
+ }
+
+ var data = sixteenSegmentASCII[asciiCharacter - 32];
+
+ return (data & 1 << (int)segment) != 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..e921f28c6c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/MeadowApp.cs
@@ -0,0 +1,52 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Displays.Led;
+using System.Threading.Tasks;
+
+namespace Displays.Led.SixteenSegment_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ SixteenSegment sixteenSegment;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initializing...");
+
+ sixteenSegment = new SixteenSegment
+ (
+ portA: Device.CreateDigitalOutputPort(Device.Pins.D00),
+ portB: Device.CreateDigitalOutputPort(Device.Pins.D01),
+ portC: Device.CreateDigitalOutputPort(Device.Pins.D02),
+ portD: Device.CreateDigitalOutputPort(Device.Pins.D03),
+ portE: Device.CreateDigitalOutputPort(Device.Pins.D04),
+ portF: Device.CreateDigitalOutputPort(Device.Pins.D05),
+ portG: Device.CreateDigitalOutputPort(Device.Pins.D06),
+ portH: Device.CreateDigitalOutputPort(Device.Pins.D07),
+ portK: Device.CreateDigitalOutputPort(Device.Pins.D08),
+ portM: Device.CreateDigitalOutputPort(Device.Pins.D09),
+ portN: Device.CreateDigitalOutputPort(Device.Pins.D10),
+ portP: Device.CreateDigitalOutputPort(Device.Pins.D11),
+ portR: Device.CreateDigitalOutputPort(Device.Pins.D12),
+ portS: Device.CreateDigitalOutputPort(Device.Pins.D13),
+ portT: Device.CreateDigitalOutputPort(Device.Pins.D14),
+ portU: Device.CreateDigitalOutputPort(Device.Pins.D15),
+ portDecimal: Device.CreateDigitalOutputPort(Device.Pins.A00),
+ isCommonCathode: false
+ );
+
+ return base.Initialize();
+ }
+
+ public override Task Run()
+ {
+ sixteenSegment.SetDisplay(asciiCharacter: 'Z', showDecimal: true);
+
+ return base.Run();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/SixteenSegment_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/SixteenSegment_Sample.csproj
new file mode 100644
index 0000000000..f0550a6169
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/SixteenSegment_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Led.SixteenSegment/Samples/SixteenSegment_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Displays.Max7219.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Displays.Max7219.csproj
index dc491de832..f6c44ef382 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Displays.Max7219.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Displays.Max7219.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.Display.cs b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.Display.cs
index 3291bf7689..f76b4d9f22 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.Display.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.Display.cs
@@ -1,6 +1,5 @@
-using System;
+using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
-using Meadow.Foundation.Graphics;
namespace Meadow.Foundation.Displays
{
@@ -90,7 +89,7 @@ public void DrawPixel(int x, int y, bool enabled)
{
var index = x % 8;
- var display = y / 8 + (x / 8) * DigitRows;
+ var display = (y >> 3) + (x >> 3) * DigitRows;
if (display > DeviceCount)
{
@@ -116,7 +115,7 @@ public void InvertPixel(int x, int y)
{
var index = x % 8;
- var display = y / 8 + (x / 8) * DigitRows;
+ var display = (y >> 3) + (x >> 3) * DigitRows;
if (display > DeviceCount)
{
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.PixelBuffer.cs b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.PixelBuffer.cs
index 899b9874a4..90b7adc69c 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.PixelBuffer.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.PixelBuffer.cs
@@ -12,7 +12,7 @@ public partial class Max7219 : IPixelBuffer
///
/// The total bytes used for the display buffer
///
- public int ByteCount => Width * Height / 8;
+ public int ByteCount => Width * Height >> 3;
///
/// The backing buffer for the pixel buffer (not implemented)
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.cs b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.cs
index 285aa1a316..30c7219e88 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Driver/Max7219.cs
@@ -8,13 +8,8 @@ namespace Meadow.Foundation.Displays
///
/// Max7219 LED matrix driver
///
- public partial class Max7219
+ public partial class Max7219 : ISpiPeripheral
{
- ///
- /// MAX7219 Spi Clock Frequency
- ///
- public static Frequency DefaultSpiBusSpeed = new Frequency(6000, Frequency.UnitType.Kilohertz);
-
///
/// Number of digits per Module
///
@@ -40,7 +35,38 @@ public partial class Max7219
///
public int Length => DigitRows * DigitColumns;
- private readonly ISpiPeripheral max7219;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(10000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
+ ///
+ protected ISpiCommunications spiComms;
///
/// internal buffer used to write to registers for all devices.
@@ -60,7 +86,7 @@ public partial class Max7219
/// SPI bus
/// Chip select port
/// Number of cascaded devices
- /// Display mode of max7219
+ /// Display mode
public Max7219(ISpiBus spiBus, IDigitalOutputPort chipselectPort, int deviceCount = 1, Max7219Mode maxMode = Max7219Mode.Display)
: this(spiBus, chipselectPort, deviceCount, 1, maxMode)
{
@@ -73,10 +99,10 @@ public Max7219(ISpiBus spiBus, IDigitalOutputPort chipselectPort, int deviceCoun
/// Chip select port
/// Number of devices cascaded vertically
/// Number of devices cascaded horizontally
- /// Display mode of max7219
+ /// Display mode
public Max7219(ISpiBus spiBus, IDigitalOutputPort chipselectPort, int deviceRows, int deviceColumns, Max7219Mode maxMode = Max7219Mode.Display)
{
- max7219 = new SpiPeripheral(spiBus, chipselectPort);
+ spiComms = new SpiCommunications(spiBus, chipselectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
DigitRows = deviceRows;
DigitColumns = deviceColumns * DigitsPerDevice;
@@ -95,7 +121,7 @@ public Max7219(ISpiBus spiBus, IDigitalOutputPort chipselectPort, int deviceRows
/// Chip select pin
/// Number of devices cascaded vertically
/// Number of devices cascaded horizontally
- /// Display mode of max7219
+ /// Display mode
public Max7219(ISpiBus spiBus, IPin chipSelectPin, int deviceRows = 1, int deviceColumns = 1, Max7219Mode maxMode = Max7219Mode.Display)
: this(spiBus, chipSelectPin.CreateDigitalOutputPort(), deviceRows, deviceColumns, maxMode)
{ }
@@ -106,7 +132,7 @@ public Max7219(ISpiBus spiBus, IPin chipSelectPin, int deviceRows = 1, int devic
/// SPI bus
/// Chip select pin
/// Number of cascaded devices
- /// Display mode of max7219
+ /// Display mode
public Max7219(ISpiBus spiBus, IPin chipSelectPin, int deviceCount = 1, Max7219Mode maxMode = Max7219Mode.Display)
: this(spiBus, chipSelectPin.CreateDigitalOutputPort(), deviceCount, 1, maxMode)
{ }
@@ -191,7 +217,7 @@ public void TestDisplay(TimeSpan time)
}
///
- /// Set the display mode of the max7219
+ /// Set the display mode of the Max7219
///
/// the mode
public void SetMode(Max7219Mode maxMode)
@@ -211,7 +237,7 @@ internal void SetRegister(Register register, byte data)
writeBuffer[i++] = (byte)register;
writeBuffer[i++] = data;
}
- max7219.Write(writeBuffer);
+ spiComms.Write(writeBuffer);
}
///
@@ -224,7 +250,7 @@ internal void SetRegister(int deviceId, Register register, byte data)
writeBuffer[deviceId * 2] = (byte)register;
writeBuffer[deviceId * 2 + 1] = data;
- max7219.Write(writeBuffer);
+ spiComms.Write(writeBuffer);
}
///
@@ -317,7 +343,7 @@ public void WriteBuffer(byte[,] buffer)
writeBuffer[i++] = (byte)((int)Register.Digit0 + digit);
writeBuffer[i++] = buffer[deviceId, digit];
}
- max7219.Write(writeBuffer);
+ spiComms.Write(writeBuffer);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/Max7219_8x8x4_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/Max7219_8x8x4_Sample.csproj
index 5c2a5c8793..f6e6d249d4 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/Max7219_8x8x4_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/Max7219_8x8x4_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/MeadowApp.cs
index 71739c282a..82c0e9545f 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4_Sample/MeadowApp.cs
@@ -17,7 +17,7 @@ public override Task Initialize()
Resolver.Log.Info("Init...");
display = new Max7219(
- Device.CreateSpiBus(Max7219.DefaultSpiBusSpeed),
+ Device.CreateSpiBus(),
Device.Pins.D00, deviceCount: 4,
maxMode: Max7219.Max7219Mode.Display);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/Max7219_8x8x4x2_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/Max7219_8x8x4x2_Sample.csproj
index 5c2a5c8793..f6e6d249d4 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/Max7219_8x8x4x2_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/Max7219_8x8x4x2_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/MeadowApp.cs
index 40a1d160c0..275986285e 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_8x8x4x2_Sample/MeadowApp.cs
@@ -38,7 +38,7 @@ public override Task Initialize()
Resolver.Log.Info("Init...");
- var spiBus = Device.CreateSpiBus(Max7219.DefaultSpiBusSpeed);
+ var spiBus = Device.CreateSpiBus();
display = new Max7219(spiBus, Device.Pins.D01, 4, 2, Max7219.Max7219Mode.Display);
@@ -53,8 +53,8 @@ public override Task Initialize()
void Show3dCube()
{
- int originY = (int)display.Width / 2;
- int originX = (int)display.Height / 2;
+ int originY = display.Width / 2;
+ int originX = display.Height / 2;
int angle = 0;
while (true)
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_Sample/Max7219_7Segment_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_Sample/Max7219_7Segment_Sample.csproj
index 9643fea42c..8407db89ab 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_Sample/Max7219_7Segment_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Max7219/Samples/Max7219_Sample/Max7219_7Segment_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Datasheet/ArduCAM_Mini_2MP_Camera_Shield_Hardware_Application_Note.pdf b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Datasheet/ArduCAM_Mini_2MP_Camera_Shield_Hardware_Application_Note.pdf
deleted file mode 100644
index 0d82c0c6e9..0000000000
Binary files a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Datasheet/ArduCAM_Mini_2MP_Camera_Shield_Hardware_Application_Note.pdf and /dev/null differ
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Displays.Pcd8544.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Displays.Pcd8544.csproj
index 002e791655..7d48ec626e 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Displays.Pcd8544.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Displays.Pcd8544.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Pcd8544.cs b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Pcd8544.cs
index a476ab1bfb..154a509ad9 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Pcd8544.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Driver/Pcd8544.cs
@@ -1,21 +1,16 @@
-using Meadow.Hardware;
+using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
-using System;
-using Meadow.Foundation.Graphics;
+using Meadow.Hardware;
using Meadow.Units;
+using System;
namespace Meadow.Foundation.Displays
{
///
/// Represents a Pcd8544 monochrome display
///
- public class Pcd8544 : IGraphicsDisplay
+ public class Pcd8544 : IGraphicsDisplay, ISpiPeripheral
{
- ///
- /// Default SPI bus speed
- ///
- public static Frequency DEFAULT_SPEED = new Frequency(4000, Frequency.UnitType.Kilohertz);
-
///
/// Display color mode
///
@@ -46,9 +41,41 @@ public class Pcd8544 : IGraphicsDisplay
///
public bool IsDisplayInverted { get; private set; } = false;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(4000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
readonly IDigitalOutputPort dataCommandPort;
readonly IDigitalOutputPort resetPort;
- readonly ISpiPeripheral spiPeripheral;
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
+ ///
+ protected ISpiCommunications spiComms;
///
/// Buffer to hold display data
@@ -67,7 +94,7 @@ public class Pcd8544 : IGraphicsDisplay
/// Chip select pin
/// Data command pin
/// Reset pin
- public Pcd8544(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin):
+ public Pcd8544(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin) :
this(spiBus, chipSelectPin?.CreateDigitalOutputPort(), dcPin.CreateDigitalOutputPort(true),
resetPin.CreateDigitalOutputPort(true))
{
@@ -80,18 +107,20 @@ public Pcd8544(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin):
/// Chip select output port
/// Data command output port
/// Reset output port
- public Pcd8544(ISpiBus spiBus,
+ public Pcd8544(ISpiBus spiBus,
IDigitalOutputPort chipSelectPort,
IDigitalOutputPort dataCommandPort,
IDigitalOutputPort resetPort)
{
+ imageBuffer = new Buffer1bpp(Width, Height);
+
dataCommandPort.State = true;
resetPort.State = true;
this.dataCommandPort = dataCommandPort;
this.resetPort = resetPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
Initialize();
}
@@ -111,7 +140,7 @@ private void Initialize()
commandBuffer.Span[5] = 0x20;
commandBuffer.Span[6] = 0x0C;
- spiPeripheral.Write(commandBuffer.Span[0..6]);
+ spiComms.Write(commandBuffer.Span[0..6]);
dataCommandPort.State = true;
@@ -173,7 +202,7 @@ public void DrawPixel(int x, int y, Color color)
///
public void Show()
{
- spiPeripheral.Write(imageBuffer.Buffer);
+ spiComms.Write(imageBuffer.Buffer);
}
///
@@ -199,7 +228,7 @@ public void InvertDisplay(bool inverse)
dataCommandPort.State = false;
commandBuffer.Span[0] = inverse ? (byte)0x0D : (byte)0x0C;
- spiPeripheral.Write(commandBuffer.Span[0]);
+ spiComms.Write(commandBuffer.Span[0]);
dataCommandPort.State = true;
}
@@ -212,7 +241,7 @@ public void Fill(Color fillColor, bool updateDisplay = false)
{
imageBuffer.Clear(fillColor.Color1bpp);
- if(updateDisplay) { Show(); }
+ if (updateDisplay) { Show(); }
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/MeadowApp.cs
index 45fb8973bd..884af1a519 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using System;
using System.Threading.Tasks;
namespace Displays.Pcd8854_Sample
@@ -17,11 +16,9 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- var config = new Meadow.Hardware.SpiClockConfiguration(Pcd8544.DEFAULT_SPEED, Meadow.Hardware.SpiClockConfiguration.Mode.Mode0);
-
var display = new Pcd8544
(
- spiBus: Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config),
+ spiBus: Device.CreateSpiBus(),
chipSelectPin: Device.Pins.D01,
dcPin: Device.Pins.D00,
resetPin: Device.Pins.D02
@@ -52,7 +49,7 @@ void CounterDemo(MicroGraphics graphics)
graphics.CurrentFont = new Font12x20();
- while(true)
+ while (true)
{
graphics.Clear();
graphics.DrawText(0, 0, $"Count:");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/Pcd8544_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/Pcd8544_Sample.csproj
index a43e1bcd88..bd40575663 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/Pcd8544_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Pcd8544/Samples/Pcd8544_Sample/Pcd8544_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Datasheet/SH1106-SINOWEALTH.pdf b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Datasheet/SH1106-SINOWEALTH.pdf
similarity index 100%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Datasheet/SH1106-SINOWEALTH.pdf
rename to Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Datasheet/SH1106-SINOWEALTH.pdf
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Datasheet/SH1107.pdf b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Datasheet/SH1107.pdf
new file mode 100644
index 0000000000..9c472f309c
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Datasheet/SH1107.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Displays.Sh110x.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Displays.Sh110x.csproj
new file mode 100644
index 0000000000..721a5726e4
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Displays.Sh110x.csproj
@@ -0,0 +1,22 @@
+
+
+ true
+ icon.png
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ Sh110x
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Displays.Sh1106
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow,Meadow.Foundation,Displays,LCD,Sh1106,SH1107,oled,monochrome
+ 0.1.0
+ true
+ S1106 and SH1107 SPI and I2C monochrome OLED displays
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1106.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1106.cs
new file mode 100644
index 0000000000..0a4d33f390
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1106.cs
@@ -0,0 +1,92 @@
+using Meadow.Hardware;
+using System.Threading;
+
+namespace Meadow.Foundation.Displays
+{
+ ///
+ /// Represents the Sh1106 family of displays
+ ///
+ public class Sh1106 : Sh110x
+ {
+ ///
+ /// Create a new Sh1106 object
+ ///
+ /// I2C bus connected to display
+ /// I2C address
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1106(II2cBus i2cBus, byte address, int width, int height)
+ : base(i2cBus, address, width, height)
+ { }
+
+ ///
+ /// Create a new Sh1106 object
+ ///
+ /// SPI bus connected to display
+ /// Chip select pin
+ /// Data command pin
+ /// Reset pin
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1106(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin, int width = 128, int height = 64)
+ : base(spiBus, chipSelectPin, dcPin, resetPin, width, height)
+ { }
+
+ ///
+ /// Create a new Sh1106 display object
+ ///
+ /// SPI bus connected to display
+ /// Chip select output port
+ /// Data command output port
+ /// Reset output port
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1106(ISpiBus spiBus,
+ IDigitalOutputPort chipSelectPort,
+ IDigitalOutputPort dataCommandPort,
+ IDigitalOutputPort resetPort,
+ int width = 128, int height = 64)
+ : base(spiBus, chipSelectPort, dataCommandPort, resetPort, width, height)
+ { }
+
+ ///
+ /// Initialize the Sh1106
+ ///
+ protected override void Initialize()
+ {
+ Reset();
+
+ SendCommand(DisplayCommand.DisplayOff);
+ SendCommand(DisplayCommand.SetDisplayClockDiv);
+ SendCommand(0x80);
+
+ SendCommand(DisplayCommand.MultiplexModeSet);
+ SendCommand(DisplayCommand.MultiplexDataSet);
+
+ SendCommand(DisplayCommand.SetDisplayOffset);
+ SendCommand((byte)0);
+
+ SendCommand(DisplayCommand.DisplayStartLine);
+
+ SendCommand(DisplayCommand.SegInvNormal);
+ SendCommand(0xC0);
+
+ SendCommand(DisplayCommand.SetComPins);
+ SendCommand(0x12);
+
+ SendCommand(DisplayCommand.SetContrast);
+ SendCommand(0x0F);
+
+ SendCommand(0x30);
+ SendCommand(DisplayCommand.DisplayOnResume);
+
+ SendCommand(DisplayCommand.SetDisplayClockDiv);
+ SendCommand(0xF0);
+
+ SendCommand(DisplayCommand.DisplayVideoNormal);
+
+ Thread.Sleep(100);
+ SendCommand(DisplayCommand.DisplayOn);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1107.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1107.cs
new file mode 100644
index 0000000000..f81537e592
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Drivers/Sh1107.cs
@@ -0,0 +1,105 @@
+using Meadow.Hardware;
+using System.Threading;
+
+namespace Meadow.Foundation.Displays
+{
+ ///
+ /// Represents the Sh1107 family of displays
+ ///
+ public class Sh1107 : Sh110x
+ {
+ ///
+ /// Create a new Sh1107 object
+ ///
+ /// I2C bus connected to display
+ /// I2C address
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1107(II2cBus i2cBus, byte address, int width = 128, int height = 128)
+ : base(i2cBus, address, width, height)
+ { }
+
+ ///
+ /// Create a new Sh1107 object
+ ///
+ /// SPI bus connected to display
+ /// Chip select pin
+ /// Data command pin
+ /// Reset pin
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1107(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin, int width = 128, int height = 128)
+ : base(spiBus, chipSelectPin, dcPin, resetPin, width, height)
+ { }
+
+ ///
+ /// Create a new Sh1107 display object
+ ///
+ /// SPI bus connected to display
+ /// Chip select output port
+ /// Data command output port
+ /// Reset output port
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh1107(ISpiBus spiBus,
+ IDigitalOutputPort chipSelectPort,
+ IDigitalOutputPort dataCommandPort,
+ IDigitalOutputPort resetPort,
+ int width = 128, int height = 128)
+ : base(spiBus, chipSelectPort, dataCommandPort, resetPort, width, height)
+ { }
+
+ ///
+ /// Initialize the Sh1107
+ ///
+ protected override void Initialize()
+ {
+ SendCommand(DisplayCommand.DisplayOff);
+ SendCommand(DisplayCommand.SetDisplayClockDiv);
+ SendCommand(0x51);
+
+ SendCommand(DisplayCommand.SetContrast);
+ SendCommand(0x4F);
+
+ SendCommand(DisplayCommand.DCDC);
+ SendCommand(0x8A);
+
+ SendCommand(DisplayCommand.SetSegmentRemap);
+ SendCommand(DisplayCommand.ComScanInc);
+
+ SendCommand(DisplayCommand.DisplayStartLine);
+ SendCommand((byte)0);
+
+ SendCommand(DisplayCommand.SegInvNormal);
+ SendCommand(0xC0);
+
+ SendCommand(DisplayCommand.SetPrecharge);
+ SendCommand(0x22);
+
+ SendCommand(DisplayCommand.SetVComDetect);
+ SendCommand(0x35);
+
+ SendCommand(DisplayCommand.DisplayOnResume);
+ SendCommand(DisplayCommand.DisplayVideoNormal);
+
+ if (Width == 128 && Height == 128)
+ {
+ SendCommand(DisplayCommand.SetDisplayOffset);
+ SendCommand((byte)0x00);
+ SendCommand(DisplayCommand.MultiplexModeSet);
+ SendCommand(0x07F);
+ }
+ else
+ {
+ SendCommand(DisplayCommand.SetDisplayOffset);
+ SendCommand(0x60);
+ SendCommand(DisplayCommand.MultiplexModeSet);
+ SendCommand(DisplayCommand.MultiplexDataSet);
+ }
+
+ Thread.Sleep(100);
+
+ SendCommand(DisplayCommand.DisplayOn);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.Enums.cs
similarity index 61%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.Enums.cs
rename to Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.Enums.cs
index 09599643ec..343c145196 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.Enums.cs
@@ -1,9 +1,6 @@
namespace Meadow.Foundation.Displays
{
- ///
- /// Provide an interface to the Sh1106 family of displays
- ///
- public partial class Sh1106
+ public partial class Sh110x
{
///
/// Allow the programmer to set the scroll direction
@@ -28,17 +25,17 @@ public enum ScrollDirection
LeftAndVertical
}
- enum DisplayCommand : byte
+ internal enum DisplayCommand : byte
{
+ DCDC = 0xAD,
DisplayOff = 0xAE,
DisplayOn = 0xAF,
DisplayOnResume = 0xA4,
DisplayStartLine = 0x40,
- PageAddress = 0xB0,
+ SetPageAddress = 0xB0,
ColumnAddressHigh = 0x10,
ColumnAddressLow = 0x02,
- SetPageAddress = 0xB0,
- ColumnAddress = 0x21,
+
DisplayVideoNormal = 0xA6,
DisplayVideoReverse = 0xA7,
AllPixelsOn = 0xA5,
@@ -47,6 +44,8 @@ enum DisplayCommand : byte
SetDisplayOffset = 0xD3,
OutputFollowsRam = 0xA4,
MemoryMode = 0x20,
+ ColumnAddress = 0x21,
+ PageAddress = 0x22,
MultiplexModeSet = 0xA8,
MultiplexDataSet = 0x3F,
@@ -54,7 +53,7 @@ enum DisplayCommand : byte
SetChargePump = 0x8D,
SetPrecharge = 0xD9,
SetComPins = 0xDA,
- SetComDetect = 0xDB,
+ SetVComDetect = 0xDB,
ComScanInc = 0xC0,
ComScanDec = 0xC8,
@@ -63,5 +62,40 @@ enum DisplayCommand : byte
SetSegmentRemap = 0xA1,
}
+
+ ///
+ /// Valid I2C addresses for the display
+ ///
+ public enum Addresses : byte
+ {
+ ///
+ /// Bus address 0x3C
+ /// Commonly used with 128x32 displays
+ ///
+ Address_0x3C = 0x3C,
+ ///
+ /// Bus address 0x3D
+ ///
+ Address_0x3D = 0x3D,
+ ///
+ /// Default bus address
+ ///
+ Default = Address_0x3D
+ }
+
+ ///
+ /// The display connection type
+ ///
+ public enum ConnectionType
+ {
+ ///
+ /// SPI
+ ///
+ SPI,
+ ///
+ /// I2C
+ ///
+ I2C,
+ }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.cs
similarity index 60%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.cs
rename to Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.cs
index cf57b60bd3..71269a3b40 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Driver/Sh1106.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Driver/Sh110x.cs
@@ -1,15 +1,16 @@
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
using Meadow.Hardware;
+using Meadow.Units;
using System;
using System.Threading;
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the Sh1106 family of displays
+ /// Provide an interface to the Sh110x family of displays
///
- public partial class Sh1106 : IGraphicsDisplay
+ public abstract partial class Sh110x : IGraphicsDisplay, ISpiPeripheral, II2cPeripheral
{
///
/// The display color mode - 1 bit per pixel monochrome
@@ -24,12 +25,50 @@ public partial class Sh1106 : IGraphicsDisplay
///
/// The display width in pixels
///
- public int Width => 128;
+ public int Width { get; protected set; } = 128;
///
/// The display height in pixels
///
- public int Height => 64;
+ public int Height { get; protected set; } = 64;
+
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(4000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// The connection type (I2C or SPI)
+ ///
+ protected ConnectionType connectionType;
///
/// The buffer the holds the pixel data for the display
@@ -37,55 +76,113 @@ public partial class Sh1106 : IGraphicsDisplay
public IPixelBuffer PixelBuffer => imageBuffer;
///
- /// SPI peripheral object
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
///
- ISpiPeripheral spiPerihperal;
+ protected ISpiCommunications spiComms;
+
+ readonly IDigitalOutputPort dataCommandPort;
+ readonly IDigitalOutputPort resetPort;
- IDigitalOutputPort dataCommandPort;
- IDigitalOutputPort resetPort;
+ const int StartColumnOffset = 0;
+ readonly int PAGE_SIZE;
const bool Data = true;
const bool Command = false;
- Buffer1bpp imageBuffer;
- byte[] pageBuffer;
+ readonly Buffer1bpp imageBuffer;
+ readonly byte[] pageBuffer;
+
+ ///
+ /// Display command buffer
+ ///
+ protected Memory commandBuffer;
+
+ ///
+ /// Create a new Sh110x object
+ ///
+ /// I2C bus connected to display
+ /// I2C address
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh110x(II2cBus i2cBus, byte address, int width, int height)
+ {
+ i2cComms = new I2cCommunications(i2cBus, address);
+
+ Width = width;
+ Height = height;
+
+ connectionType = ConnectionType.I2C;
+ commandBuffer = new byte[2];
+
+ imageBuffer = new Buffer1bpp(Width, Height);
+ PAGE_SIZE = Width;
+ pageBuffer = new byte[PAGE_SIZE + 1];
+
+ Initialize();
+ }
///
- /// Create a new Sh1106 object
+ /// Create a new Sh110x object
///
/// SPI bus connected to display
/// Chip select pin
/// Data command pin
/// Reset pin
- public Sh1106(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin) :
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh110x(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin, int width, int height) :
this(spiBus, chipSelectPin?.CreateDigitalOutputPort(), dcPin.CreateDigitalOutputPort(),
- resetPin.CreateDigitalOutputPort())
+ resetPin.CreateDigitalOutputPort(), width, height)
{
}
///
- /// Create a new Sh1106 display object
+ /// Create a new Sh110x display object
///
/// SPI bus connected to display
/// Chip select output port
/// Data command output port
/// Reset output port
- public Sh1106(ISpiBus spiBus,
+ /// Display width in pixels
+ /// Display height in pixels
+ public Sh110x(ISpiBus spiBus,
IDigitalOutputPort chipSelectPort,
IDigitalOutputPort dataCommandPort,
- IDigitalOutputPort resetPort)
+ IDigitalOutputPort resetPort,
+ int width, int height)
{
+ connectionType = ConnectionType.SPI;
+
this.dataCommandPort = dataCommandPort;
this.resetPort = resetPort;
- spiPerihperal = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
+
+ Width = width;
+ Height = height;
imageBuffer = new Buffer1bpp(Width, Height);
- pageBuffer = new byte[PageSize];
+ pageBuffer = new byte[Width];
Initialize();
}
+ ///
+ /// This varies between manufactures
+ /// If the display is misaligned, try 0 and 0x40
+ ///
+ ///
+ public void SetDisplayOffset(byte offset)
+ {
+ SendCommand(DisplayCommand.SetDisplayOffset);
+ SendCommand(offset);
+ }
+
///
/// Invert the entire display (true) or return to normal mode (false)
///
@@ -110,12 +207,10 @@ public void PowerSaveMode()
SendCommand(DisplayCommand.AllPixelsOn);
}
- void SendCommand(DisplayCommand command)
- {
- SendCommand((byte)command);
- }
-
- void Reset()
+ ///
+ /// Reset for SPI displays
+ ///
+ protected void Reset()
{
resetPort.State = true;
Thread.Sleep(10);
@@ -125,40 +220,10 @@ void Reset()
Thread.Sleep(100);
}
- private void Initialize()
- {
- Reset();
-
- SendCommand(DisplayCommand.DisplayOff);
- SendCommand(DisplayCommand.SetDisplayClockDiv);
- //128x64 init commands
- SendCommand(0x80);
-
- SendCommand(DisplayCommand.MultiplexModeSet);
- SendCommand(DisplayCommand.MultiplexDataSet);
-
- SendCommand(DisplayCommand.SetDisplayOffset);
- SendCommand((byte)0);
-
- SendCommand(DisplayCommand.DisplayStartLine);
-
- SendCommand(DisplayCommand.SegInvNormal);
- SendCommand(0xC0);
-
- SendCommand(DisplayCommand.SetComPins);
- SendCommand(0x12);
-
- SendCommand(DisplayCommand.SetContrast);
- SendCommand(0x0F);
-
- SendCommand(0x30);
- SendCommand(0xA4);
-
- SendCommand(DisplayCommand.SetDisplayClockDiv);
- SendCommand(0xF0);
-
- SendCommand(DisplayCommand.DisplayOn);
- }
+ ///
+ /// Initialize the display
+ ///
+ protected abstract void Initialize();
///
/// Set the display contrast
@@ -174,46 +239,86 @@ public void SetContrast(byte contrast)
/// Send a command to the display
///
/// Command byte to send to the display
- private void SendCommand(byte command)
+ internal void SendCommand(byte command)
+ {
+ if (connectionType == ConnectionType.SPI)
+ {
+ dataCommandPort.State = Command;
+ spiComms.Write(command);
+ }
+ else
+ {
+ commandBuffer.Span[0] = 0x00;
+ commandBuffer.Span[1] = command;
+ i2cComms.Write(commandBuffer.Span);
+ }
+ }
+
+ ///
+ /// Send a command to the display
+ ///
+ /// Command byte to send to the display
+ internal void SendCommand(DisplayCommand command)
{
- dataCommandPort.State = Command;
- spiPerihperal.Write(command);
+ SendCommand((byte)command);
}
///
/// Send a sequence of commands to the display
///
/// List of commands to send
- private void SendCommands(byte[] commands)
+ internal void SendCommands(byte[] commands)
{
- var data = new byte[commands.Length + 1];
- data[0] = 0x00;
- Array.Copy(commands, 0, data, 1, commands.Length);
-
- dataCommandPort.State = Command;
- spiPerihperal.Write(commands);
+ if (connectionType == ConnectionType.SPI)
+ {
+ dataCommandPort.State = Command;
+ spiComms.Write(commands);
+ }
+ else
+ {
+ Span data = new byte[commands.Length + 1];
+ data[0] = 0x00;
+ commands.CopyTo(data.Slice(1, commands.Length));
+ i2cComms.Write(data);
+ }
}
- const int StartColumnOffset = 0;
- const int PageSize = 128;
-
///
/// Send the internal pixel buffer to display
///
public void Show()
{
- for (int page = 0; page < 8; page++)
+ if (connectionType == ConnectionType.SPI)
{
- SendCommand(DisplayCommand.ColumnAddressLow);
- SendCommand(DisplayCommand.ColumnAddressHigh);
- SendCommand((byte)((byte)DisplayCommand.PageAddress | page));
+ int count = (Height + 7) / 8;//+7 to round up
+ for (int page = 0; page < count; page++)
+ {
+ {
+ SendCommand(DisplayCommand.ColumnAddressLow);
+ SendCommand(DisplayCommand.ColumnAddressHigh);
+ SendCommand((byte)((byte)DisplayCommand.SetPageAddress | page));
- dataCommandPort.State = Data;
+ dataCommandPort.State = Data;
- Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PAGE_SIZE);
+ spiComms.Write(pageBuffer);
+ }
+ }
+ }
+ else //I2C
+ {
+ pageBuffer[0] = 0x40;
+ int count = (Height + 7) / 8;//+7 to round up
+ for (int page = 0; page < count; page++)
+ {
+ SendCommand((byte)0);
+ SendCommand((byte)((byte)DisplayCommand.SetPageAddress | page));
+ SendCommand(0x10 >> 4);
+ SendCommand((byte)(0x10 & 0xF));
- dataCommandPort.State = Command;
+ Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 1, PAGE_SIZE);
+ i2cComms.Write(pageBuffer);
+ }
}
}
@@ -237,14 +342,14 @@ public void Show(int left, int top, int right, int bottom)
continue;
}
- SendCommand((byte)((int)DisplayCommand.PageAddress | page));
+ SendCommand((byte)((int)DisplayCommand.SetPageAddress | page));
SendCommand((DisplayCommand.ColumnAddressLow) | (StartColumnOffset & 0x0F));
SendCommand((int)DisplayCommand.ColumnAddressHigh | 0);
dataCommandPort.State = Data;
- Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PAGE_SIZE);
+ spiComms.Write(pageBuffer);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/MeadowApp.cs
similarity index 96%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/MeadowApp.cs
rename to Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/MeadowApp.cs
index 7ad862910f..9e0de1b3c8 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/MeadowApp.cs
@@ -6,7 +6,7 @@
namespace Displays.Sh1106_Sample
{
- public class MeadowApp : App
+ public class MeadowApp : App
{
//
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/Sh1106_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/Sh1106_Sample.csproj
similarity index 77%
rename from Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/Sh1106_Sample.csproj
rename to Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/Sh1106_Sample.csproj
index 71e4a4cd37..6f8db894fd 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Sh1106/Samples/Sh1106_Sample/Sh1106_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/Sh1106_Sample.csproj
@@ -9,8 +9,8 @@
App
-
-
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1106_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..ae107cdbc0
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/MeadowApp.cs
@@ -0,0 +1,51 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Displays;
+using Meadow.Foundation.Graphics;
+using System.Threading.Tasks;
+using static Meadow.Foundation.Displays.Sh110x;
+
+namespace Displays.Sh1107_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ MicroGraphics graphics;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initializing...");
+
+ var sh1107 = new Sh1107
+ (
+ i2cBus: Device.CreateI2cBus(),
+ address: (byte)Addresses.Address_0x3C,
+ width: 128,
+ height: 128
+ );
+
+ graphics = new MicroGraphics(sh1107)
+ {
+ CurrentFont = new Font12x16(),
+ Rotation = RotationType._180Degrees
+ };
+
+ return base.Initialize();
+ }
+
+ public override Task Run()
+ {
+ graphics.Clear();
+ graphics.DrawRectangle(0, 0, graphics.Width, graphics.Height, false);
+ graphics.DrawTriangle(10, 10, 50, 50, 10, 50, false);
+ graphics.DrawRectangle(20, 15, 40, 20, true);
+ graphics.DrawText(5, 5, "SH1107");
+ graphics.Show();
+
+ return base.Run();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/Sh1107_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/Sh1107_Sample.csproj
new file mode 100644
index 0000000000..6f8db894fd
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/Sh1107_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Sh110x/Samples/Sh1107_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Displays.Ssd130x.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Displays.Ssd130x.csproj
index bd1b3a4ad8..63456de2f7 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Displays.Ssd130x.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Displays.Ssd130x.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1306.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1306.cs
index cccb671c36..7e2646d664 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1306.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1306.cs
@@ -4,7 +4,7 @@
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the SSD1306 family of OLED displays
+ /// Represents the SSD1306 family of OLED displays
///
public partial class Ssd1306 : Ssd130xBase
{
@@ -17,7 +17,7 @@ public partial class Ssd1306 : Ssd130xBase
/// Reset pin
/// Type of SSD1306 display (default = 128x64 pixel display)
public Ssd1306(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin,
- DisplayType displayType = DisplayType.OLED128x64):
+ DisplayType displayType = DisplayType.OLED128x64) :
this(spiBus, chipSelectPin?.CreateDigitalOutputPort(false), dcPin.CreateDigitalOutputPort(true),
resetPin.CreateDigitalOutputPort(false), displayType)
{ }
@@ -40,7 +40,7 @@ public Ssd1306(ISpiBus spiBus,
this.chipSelectPort = chipSelectPort;
this.resetPort = resetPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
connectionType = ConnectionType.SPI;
@@ -59,7 +59,7 @@ public Ssd1306(II2cBus i2cBus,
{
this.displayType = displayType;
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
connectionType = ConnectionType.I2C;
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1309.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1309.cs
index 7bb8a9dc88..05e69772c8 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1309.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Drivers/Ssd1309.cs
@@ -1,23 +1,12 @@
using Meadow.Hardware;
-using Meadow.Units;
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the SSD1309 family of OLED displays
+ /// Represents the SSD1309 family of OLED displays
///
public class Ssd1309 : Ssd1306
{
- ///
- /// The default SPI clock mode
- ///
- public static SpiClockConfiguration.Mode DefaultSpiClockMode = SpiClockConfiguration.Mode.Mode0;
-
- ///
- /// Default SPI frequency
- ///
- public static Frequency DefaultSpiBusSpeed = new Frequency(12000, Frequency.UnitType.Kilohertz);
-
///
/// Create a new Ssd1309 object
///
@@ -47,7 +36,7 @@ public Ssd1309(ISpiBus spiBus, IDigitalOutputPort chipSelectPort, IDigitalOutput
///
/// I2cBus connected to display
/// Address of the bus on the I2C display.
- public Ssd1309(II2cBus i2cBus, byte address = (byte)Addresses.Default) :
+ public Ssd1309(II2cBus i2cBus, byte address = (byte)Addresses.Default) :
base(i2cBus, address, DisplayType.OLED128x64)
{
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/SSd130xBase.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/SSd130xBase.Enums.cs
index 9e26717a08..61e5002b9b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/SSd130xBase.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/SSd130xBase.Enums.cs
@@ -1,12 +1,9 @@
namespace Meadow.Foundation.Displays
{
- ///
- /// Provide an interface to the SSD1306 family of OLED displays
- ///
public abstract partial class Ssd130xBase
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the display
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Ssd130xBase.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Ssd130xBase.cs
index 0496e5b64b..9e5fa6078d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Ssd130xBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Driver/Ssd130xBase.cs
@@ -1,14 +1,15 @@
-using System;
-using Meadow.Hardware;
+using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
-using Meadow.Foundation.Graphics;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the SSD130x family of OLED displays
+ /// Represents the SSD130x family of OLED displays
///
- public abstract partial class Ssd130xBase : IGraphicsDisplay
+ public abstract partial class Ssd130xBase : IGraphicsDisplay, ISpiPeripheral, II2cPeripheral
{
///
/// The display color mode
@@ -36,9 +37,42 @@ public abstract partial class Ssd130xBase : IGraphicsDisplay
public IPixelBuffer PixelBuffer => imageBuffer;
///
- /// SSD1306 SPI display
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(8000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
///
- protected ISpiPeripheral spiPeripheral;
+ protected ISpiCommunications spiComms;
///
/// The data command port
@@ -76,9 +110,9 @@ public abstract partial class Ssd130xBase : IGraphicsDisplay
protected const int PAGE_SIZE = 16;
///
- /// SSD1306 I2C display
+ /// I2C Communication bus used to communicate with the peripheral
///
- protected II2cPeripheral i2cPeripheral;
+ protected II2cCommunications i2cComms;
///
/// Buffer holding the pixels in the display
@@ -175,13 +209,13 @@ private void SendCommand(byte command)
if (connectionType == ConnectionType.SPI)
{
dataCommandPort.State = Command;
- spiPeripheral.Write(command);
+ spiComms.Write(command);
}
else
{
commandBuffer.Span[0] = 0x00;
commandBuffer.Span[1] = command;
- i2cPeripheral.Write(commandBuffer.Span);
+ i2cComms.Write(commandBuffer.Span);
}
}
@@ -194,7 +228,7 @@ protected void SendCommands(Span commands)
if (connectionType == ConnectionType.SPI)
{
dataCommandPort.State = Command;
- spiPeripheral.Write(commands);
+ spiComms.Write(commands);
}
else
{ //a little heavy but this is only used a couple of times
@@ -202,7 +236,7 @@ protected void SendCommands(Span commands)
Span data = new byte[commands.Length + 1];
data[0] = 0x00;
commands.CopyTo(data.Slice(1, commands.Length));
- i2cPeripheral.Write(data);
+ i2cComms.Write(data);
}
}
@@ -216,7 +250,7 @@ public void Show()
if (connectionType == ConnectionType.SPI)
{
dataCommandPort.State = Data;
- spiPeripheral.Bus.Exchange(chipSelectPort, imageBuffer.Buffer, readBuffer);
+ spiComms.Bus.Exchange(chipSelectPort, imageBuffer.Buffer, readBuffer);
}
else// I2C
{ // Send the buffer page by page
@@ -228,7 +262,7 @@ public void Show()
if (imageBuffer.ByteCount - index < PAGE_SIZE) { break; }
Array.Copy(imageBuffer.Buffer, index, pageBuffer, 1, PAGE_SIZE);
- i2cPeripheral.Write(pageBuffer);
+ i2cComms.Write(pageBuffer);
}
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1039_3DCube_Sample/Ssd1039_3DCube_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1039_3DCube_Sample/Ssd1039_3DCube_Sample.csproj
index de6076c2e0..146b540624 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1039_3DCube_Sample/Ssd1039_3DCube_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1039_3DCube_Sample/Ssd1039_3DCube_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1306_Sample/Ssd1306_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1306_Sample/Ssd1306_Sample.csproj
index de6076c2e0..146b540624 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1306_Sample/Ssd1306_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1306_Sample/Ssd1306_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Game_Sample/Ssd1309_Game_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Game_Sample/Ssd1309_Game_Sample.csproj
index de6076c2e0..146b540624 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Game_Sample/Ssd1309_Game_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Game_Sample/Ssd1309_Game_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Sample/Ssd1309_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Sample/Ssd1309_Sample.csproj
index de6076c2e0..146b540624 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Sample/Ssd1309_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd130x/Samples/Ssd1309_Sample/Ssd1309_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Displays.Ssd1327.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Displays.Ssd1327.csproj
index 847ba0fd76..9322e47efc 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Displays.Ssd1327.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Displays.Ssd1327.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Ssd1327.cs b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Ssd1327.cs
index 0f52a9a15a..8749a93282 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Ssd1327.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Driver/Ssd1327.cs
@@ -1,15 +1,16 @@
-using System;
-using System.Threading;
-using Meadow.Hardware;
+using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
-using Meadow.Foundation.Graphics;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
+using System.Threading;
namespace Meadow.Foundation.Displays
{
///
/// Provides an interface to the Ssd1327 greyscale OLED display
///
- public partial class Ssd1327 : IGraphicsDisplay
+ public partial class Ssd1327 : IGraphicsDisplay, ISpiPeripheral
{
///
/// The display color mode (4 bit per pixel grayscale)
@@ -36,10 +37,41 @@ public partial class Ssd1327 : IGraphicsDisplay
///
public IPixelBuffer PixelBuffer => imageBuffer;
- readonly ISpiPeripheral spiPeripheral;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(10000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
+ ///
+ protected ISpiCommunications spiComms;
+
readonly IDigitalOutputPort dataCommandPort;
readonly IDigitalOutputPort resetPort;
- readonly IDigitalOutputPort chipSelectPort;
readonly BufferGray4 imageBuffer;
@@ -54,16 +86,8 @@ public partial class Ssd1327 : IGraphicsDisplay
/// Data command pin
/// Reset pin
public Ssd1327(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin)
+ : this(spiBus, chipSelectPin?.CreateDigitalOutputPort(false), dcPin?.CreateDigitalOutputPort(false), resetPin?.CreateDigitalOutputPort(true))
{
- imageBuffer = new BufferGray4(Width, Height);
-
- dataCommandPort = dcPin.CreateDigitalOutputPort(false);
- if (resetPin != null) { resetPort = resetPin.CreateDigitalOutputPort(true); }
- if (chipSelectPin != null) { chipSelectPort = chipSelectPin.CreateDigitalOutputPort(false); }
-
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
-
- Initialize();
}
///
@@ -78,11 +102,12 @@ public Ssd1327(ISpiBus spiBus,
IDigitalOutputPort dataCommandPort,
IDigitalOutputPort resetPort)
{
+ imageBuffer = new BufferGray4(Width, Height);
+
this.dataCommandPort = dataCommandPort;
- this.chipSelectPort = chipSelectPort;
this.resetPort = resetPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
Initialize();
}
@@ -106,7 +131,7 @@ protected void Initialize()
dataCommandPort.State = CommandState;
- spiPeripheral.Write(init128x128);
+ spiComms.Write(init128x128);
Thread.Sleep(100); // 100ms delay recommended
SendCommand(Command.DISPLAYON); // 0xaf
@@ -121,7 +146,7 @@ public void Clear(bool updateDisplay = false)
{
Array.Clear(imageBuffer.Buffer, 0, imageBuffer.ByteCount);
- if(updateDisplay == true)
+ if (updateDisplay == true)
{
Show();
}
@@ -193,14 +218,14 @@ public void Show()
dataCommandPort.State = DataState;
- spiPeripheral.Write(imageBuffer.Buffer);
+ spiComms.Write(imageBuffer.Buffer);
}
void SetAddressWindow(byte x0, byte y0, byte x1, byte y1)
{
SendCommand(Command.SETCOLUMN); //Set Column Address
SendCommand(x0); //Beginning. Note that you must divide the column by 2, since 1 byte in memory is 2 pixels
- SendCommand((byte)(x1/2)); //End
+ SendCommand((byte)(x1 / 2)); //End
SendCommand(Command.SETROW); //Set Row Address
SendCommand(y0); //Beginning
@@ -215,24 +240,7 @@ void SendCommand(Command command)
void SendCommand(byte command)
{
dataCommandPort.State = CommandState;
- spiPeripheral.Write(command);
- }
-
- void SendData(int data)
- {
- SendData((byte)data);
- }
-
- void SendData(byte data)
- {
- dataCommandPort.State = DataState;
- spiPeripheral.Write(data);
- }
-
- void SendData(byte[] data)
- {
- dataCommandPort.State = DataState;
- spiPeripheral.Write(data);
+ spiComms.Write(command);
}
///
@@ -281,7 +289,7 @@ public void WriteBuffer(int x, int y, IPixelBuffer displayBuffer)
0x00, // 0xA1, 0x00
(byte)Command.SETDISPLAYOFFSET,
0x00, // 0xA2, 0x00
- (byte)Command.DISPLAYALLOFF,
+ (byte)Command.DISPLAYALLOFF,
(byte)Command.SETMULTIPLEX,
0x7F, // 0xA8, 0x7F (1/64)
(byte)Command.PHASELEN,
@@ -305,7 +313,7 @@ public void WriteBuffer(int x, int y, IPixelBuffer displayBuffer)
0x62, // 0xD5, 0x62
(byte)Command.CMDLOCK,
0x12, // 0xFD, 0x12
- (byte)Command.NORMALDISPLAY,
+ (byte)Command.NORMALDISPLAY,
(byte)Command.DISPLAYON
};
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Samples/Ssd1327_Sample/Ssd1327_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Samples/Ssd1327_Sample/Ssd1327_Sample.csproj
index 9862eaaa14..6dd495359b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Samples/Ssd1327_Sample/Ssd1327_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Ssd1327/Samples/Ssd1327_Sample/Ssd1327_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/Displays.St7565.csproj b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/Displays.St7565.csproj
index ab767b3cb9..caf3aef140 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/Displays.St7565.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/Displays.St7565.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/St7565.cs b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/St7565.cs
index b622c7c418..59314c9e72 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/St7565.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Driver/St7565.cs
@@ -1,15 +1,16 @@
-using System;
-using System.Threading;
-using Meadow.Hardware;
-using Meadow.Foundation.Graphics;
+using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
+using System.Threading;
namespace Meadow.Foundation.Displays
{
///
- /// Provide an interface to the ST7565 family of displays.
+ /// Provide an interface to the ST7565 family of displays
///
- public partial class St7565 : IGraphicsDisplay
+ public partial class St7565 : IGraphicsDisplay, ISpiPeripheral
{
///
/// The display color mode - 1 bit per pixel monochrome
@@ -37,18 +38,46 @@ public partial class St7565 : IGraphicsDisplay
public IPixelBuffer PixelBuffer => imageBuffer;
///
- /// SPI peripheral object
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(12000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
///
- ISpiPeripheral spiPerihperal;
+ protected ISpiCommunications spiComms;
- IDigitalOutputPort dataCommandPort;
- IDigitalOutputPort resetPort;
+ readonly IDigitalOutputPort dataCommandPort;
+ readonly IDigitalOutputPort resetPort;
const bool Data = true;
const bool Command = false;
- Buffer1bpp imageBuffer;
- byte[] pageBuffer;
+ readonly Buffer1bpp imageBuffer;
+ readonly byte[] pageBuffer;
///
/// Create a new ST7565 object
@@ -84,7 +113,7 @@ public St7565(ISpiBus spiBus,
this.dataCommandPort = dataCommandPort;
this.resetPort = resetPort;
- spiPerihperal = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
imageBuffer = new Buffer1bpp(width, height);
pageBuffer = new byte[PageSize];
@@ -162,7 +191,7 @@ public void SetContrast(byte contrast)
private void SendCommand(byte command)
{
dataCommandPort.State = Command;
- spiPerihperal.Write(command);
+ spiComms.Write(command);
}
///
@@ -176,7 +205,7 @@ private void SendCommands(byte[] commands)
Array.Copy(commands, 0, data, 1, commands.Length);
dataCommandPort.State = Command;
- spiPerihperal.Write(commands);
+ spiComms.Write(commands);
}
const int StartColumnOffset = 0;
@@ -197,7 +226,7 @@ public void Show()
dataCommandPort.State = Data;
Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ spiComms.Write(pageBuffer);
}
}
@@ -216,7 +245,7 @@ public void Show(int left, int top, int right, int bottom)
//so interate over all 8 pages and check if they're in range
for (int page = 0; page < 8; page++)
{
- if(top > pageHeight*page || bottom < (page + 1) * pageHeight)
+ if (top > pageHeight * page || bottom < (page + 1) * pageHeight)
{
continue;
}
@@ -229,7 +258,7 @@ public void Show(int left, int top, int right, int bottom)
dataCommandPort.State = Data;
Array.Copy(imageBuffer.Buffer, Width * page, pageBuffer, 0, PageSize);
- spiPerihperal.Write(pageBuffer);
+ spiComms.Write(pageBuffer);
}
}
@@ -321,7 +350,7 @@ public void StartScrolling(ScrollDirection direction, byte startPage, byte endPa
scrollDirection = 0x29;
}
- commands = new byte[] { 0xa3, 0x00, (byte) Height, scrollDirection, 0x00, startPage, 0x00, endPage, 0x01, 0x2f };
+ commands = new byte[] { 0xa3, 0x00, (byte)Height, scrollDirection, 0x00, startPage, 0x00, endPage, 0x01, 0x2f };
}
SendCommands(commands);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Samples/St7565_Sample/St7565_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Samples/St7565_Sample/St7565_Sample.csproj
index f64310cb2a..be8439be9d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.St7565/Samples/St7565_Sample/St7565_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.St7565/Samples/St7565_Sample/St7565_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Displays.TftSpi.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Displays.TftSpi.csproj
index 52a64f3308..3737d90268 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Displays.TftSpi.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Displays.TftSpi.csproj
@@ -19,7 +19,7 @@
-
-
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Gc9a01.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Gc9a01.cs
index ca9f1a4178..e54a788052 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Gc9a01.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Gc9a01.cs
@@ -11,7 +11,7 @@ public class Gc9a01 : TftSpiBase, IRotatableDisplay
///
/// The display default color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format16bppRgb565;
+ public override ColorMode DefaultColorMode => ColorMode.Format16bppRgb565;
///
/// The color modes supported by the display
@@ -286,32 +286,6 @@ protected override void Initialize()
DelayMs(20);
}
- ///
- /// Set address window to update
- ///
- /// Start x position in pixels
- /// End x position in pixels
- /// Start y position in pixels
- /// End y position in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the rotation of the display
///
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Hx8357d.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Hx8357d.cs
index 167998b5c3..a3bcf53de4 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Hx8357d.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Hx8357d.cs
@@ -11,7 +11,7 @@ public class Hx8357d : TftSpiBase, IRotatableDisplay
///
/// The display default color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format16bppRgb565;
+ public override ColorMode DefaultColorMode => ColorMode.Format16bppRgb565;
///
/// The color modes supported by the display
@@ -167,32 +167,6 @@ protected override void Initialize()
DelayMs(50);
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
@@ -201,7 +175,7 @@ public void SetRotation(RotationType rotation)
{
SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)(Register.MADCTL_MX | Register.MADCTL_MY | Register.MADCTL_RGB));
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9163.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9163.cs
index 02d713a9a1..4395f73cd1 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9163.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9163.cs
@@ -11,7 +11,7 @@ public class Ili9163 : TftSpiBase
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -186,36 +186,7 @@ protected override void Initialize()
Write(0x29); // Set display on
DelayMs(10);
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
-
- dataCommandPort.State = (Data);
- }
-
- ///
- /// Set the address window to update the display
- ///
- /// X0
- /// Y0
- /// X1
- /// Y1
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = (Data);
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- dataCommandPort.State = (Command);
- Write((byte)LcdCommand.RAMWR); // write to RAM */
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9341.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9341.cs
index 1dd8403bdf..101b5fe7fc 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9341.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9341.cs
@@ -7,17 +7,17 @@ namespace Meadow.Foundation.Displays
///
/// Represents a Ili9341 TFT color display
///
- public class Ili9341 : TftSpiBase
+ public class Ili9341 : TftSpiBase, IRotatableDisplay
{
///
- /// The default SPI bus frequency
+ /// SPI bus speed
///
- public static Frequency DefaultSpiBusSpeed = new Frequency(24000, Frequency.UnitType.Kilohertz);
+ public override Frequency DefaultSpiBusSpeed => new Frequency(24000, Frequency.UnitType.Kilohertz);
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -75,22 +75,22 @@ protected override void Initialize()
}
else
{
- DelayMs(150); //Not sure if this is needed but can't hurt
+ DelayMs(120); //Not sure if this is needed but can't hurt
}
SendCommand(0xEF, new byte[] { 0x03, 0x80, 0x02 });
SendCommand(0xCF, new byte[] { 0x00, 0xC1, 0x30 });
SendCommand(0xED, new byte[] { 0x64, 0x03, 0x12, 0x81 });
- SendCommand(0xe8, new byte[] { 0x85, 0x00, 0x78 });
+ SendCommand(0xE8, new byte[] { 0x85, 0x00, 0x78 });
SendCommand(0xCB, new byte[] { 0x39, 0x2C, 0x00, 0x34, 0x02 });
SendCommand(0xF7, new byte[] { 0x20 });
SendCommand(0xEA, new byte[] { 0x00, 0x00 });
SendCommand(ILI9341_PWCTR1, new byte[] { 0x23 });
SendCommand(ILI9341_PWCTR2, new byte[] { 0x10 });
- SendCommand(ILI9341_VMCTR1, new byte[] { 0x3e, 0x28 });
+ SendCommand(ILI9341_VMCTR1, new byte[] { 0x3E, 0x28 });
SendCommand(ILI9341_VMCTR2, new byte[] { 0x86 });
- SendCommand((byte)Register.MADCTL, new byte[] { (byte)(Register.MADCTL_MX | Register.MADCTL_BGR) }); //13
+ SendCommand((byte)Register.MADCTL, new byte[] { (byte)(Register.MADCTL_MX | Register.MADCTL_BGR) });
if (ColorMode == ColorMode.Format16bppRgb565)
{
@@ -110,36 +110,7 @@ protected override void Initialize()
DelayMs(120);
SendCommand(Register.DISPON);
- SetAddressWindow(0, 0, Width - 1, Height - 1);
-
- dataCommandPort.State = (Data);
- }
-
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- dataCommandPort.State = Command;
- Write((byte)LcdCommand.RAMWR); // write to RAM */
}
void SendCommand(byte command, byte[] data)
@@ -154,6 +125,33 @@ void SendCommand(byte command, byte[] data)
}
}
+ ///
+ /// Set the display rotation
+ ///
+ /// The rotation value
+ public void SetRotation(RotationType rotation)
+ {
+ SendCommand(Register.MADCTL);
+
+ switch (Rotation = rotation)
+ {
+ case RotationType.Normal:
+ SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_BGR);
+ break;
+ case RotationType._90Degrees:
+ SendData((byte)Register.MADCTL_MV | (byte)Register.MADCTL_BGR);
+ break;
+ case RotationType._180Degrees:
+ SendData((byte)Register.MADCTL_MY | (byte)Register.MADCTL_BGR);
+ break;
+ case RotationType._270Degrees:
+ SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_MY | (byte)Register.MADCTL_MV | (byte)Register.MADCTL_BGR);
+ break;
+ }
+
+ UpdateBuffer();
+ }
+
static byte ILI9341_GAMMASET = 0x26;
static byte ILI9341_DFUNCTR = 0xB6;
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9481.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9481.cs
index cd508f8365..abeb45c418 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9481.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9481.cs
@@ -11,7 +11,7 @@ public class Ili9481 : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -134,32 +134,6 @@ protected override void Initialize()
DelayMs(25);
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
@@ -168,7 +142,7 @@ public void SetRotation(RotationType rotation)
{
SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)(Register.MADCTL_SS | Register.MADCTL_BGR));
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9486.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9486.cs
index 0c5e0c70b2..c52665a6e0 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9486.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9486.cs
@@ -11,7 +11,7 @@ public class Ili9486 : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -123,32 +123,6 @@ protected override void Initialize()
DelayMs(150);
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
@@ -157,7 +131,7 @@ public void SetRotation(RotationType rotation)
{
SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_BGR);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9488.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9488.cs
index bc611976d7..7312d674df 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9488.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ili9488.cs
@@ -11,14 +11,13 @@ public class Ili9488 : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format24bppRgb888;
+ public override ColorMode DefaultColorMode => ColorMode.Format24bppRgb888;
///
/// The color modes supported by the display
///
public override ColorMode SupportedColorModes => ColorMode.Format24bppRgb888;
-
///
/// Create a new Ili9488 display object
///
@@ -114,10 +113,10 @@ protected override void Initialize()
SendData(0x12);
SendData(0x80);
- SendCommand((byte)Register.MADCTL); // Memory Access Control
- SendData(0x48); // MX, BGR
+ SendCommand(Register.MADCTL);
+ SendData(0x48);
- SendCommand((byte)Register.COLOR_MODE); // Pixel Interface Format
+ SendCommand(Register.COLOR_MODE);
SendData(0x66); //24bpp
SendCommand(0xB0); // Interface Mode Control
@@ -153,41 +152,15 @@ protected override void Initialize()
DelayMs(25);
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
/// The rotation value
public void SetRotation(RotationType rotation)
{
- SendCommand((byte)Register.MADCTL);
+ SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_BGR);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Rm68140.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Rm68140.cs
index 4d6bdc85d7..9193a5d2b9 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Rm68140.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Rm68140.cs
@@ -11,7 +11,7 @@ public class Rm68140 : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -103,10 +103,10 @@ protected override void Initialize()
SendData(0x0C);
SendData(0x00);
- SendCommand((byte)Register.MADCTL);
+ SendCommand(Register.MADCTL);
SendData(0x0A);
- SendCommand((byte)Register.COLOR_MODE);
+ SendCommand(Register.COLOR_MODE);
if (ColorMode == ColorMode.Format16bppRgb565)
SendData(0x55); //16 bit RGB565
else
@@ -129,41 +129,15 @@ protected override void Initialize()
DelayMs(25);
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
/// The rotation value
public void SetRotation(RotationType rotation)
{
- SendCommand((byte)Register.MADCTL);
+ SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_BGR);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/S6D02A1.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/S6D02A1.cs
index 198b06dff2..219ca463ca 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/S6D02A1.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/S6D02A1.cs
@@ -11,7 +11,7 @@ public class S6D02A1 : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -108,7 +108,7 @@ protected override void Initialize()
SendCommand(0x36, new byte[] { 0xC8 }); // Memory access data control
SendCommand(0x35, new byte[] { 0x00 }); // Tearing effect line on
- SendCommand((byte)Register.COLOR_MODE);
+ SendCommand(Register.COLOR_MODE);
if (ColorMode == ColorMode.Format16bppRgb565)
SendData(0x05); //16 bit RGB565
else
@@ -118,36 +118,7 @@ protected override void Initialize()
SendCommand(0x29, null); // Display on
SendCommand(0x2c, null); // Memory write
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
-
- dataCommandPort.State = (Data);
- }
-
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = (Data);
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = (Data);
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- dataCommandPort.State = (Command);
- Write((byte)LcdCommand.RAMWR); // write to RAM */
+ dataCommandPort.State = Data;
}
///
@@ -156,9 +127,9 @@ protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
/// The rotation value
public void SetRotation(RotationType rotation)
{
- SendCommand((byte)Register.MADCTL);
+ SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_MY | (byte)Register.MADCTL_BGR);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1331.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1331.cs
index 5222db3355..c4f7e20db6 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1331.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1331.cs
@@ -12,7 +12,7 @@ public class Ssd1331 : TftSpiBase
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format16bppRgb565;
+ public override ColorMode DefaultColorMode => ColorMode.Format16bppRgb565;
///
/// The color modes supported by the display
@@ -120,13 +120,11 @@ protected override void Initialize()
SendCommand(CMD_DISPLAYON); //--turn on oled panel
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
-
dataCommandPort.State = Data;
}
///
- /// Set addrees window for display updates
+ /// Set address window for display updates
///
/// X start in pixels
/// Y start in pixels
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1351.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1351.cs
index 26b79f7e6a..3db1c56e2c 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1351.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/Ssd1351.cs
@@ -1,6 +1,5 @@
using Meadow.Foundation.Graphics;
using Meadow.Hardware;
-using Meadow.Units;
namespace Meadow.Foundation.Displays
{
@@ -9,15 +8,10 @@ namespace Meadow.Foundation.Displays
///
public class Ssd1351 : TftSpiBase
{
- ///
- /// The default SPI bus frequency
- ///
- public static Frequency DefaultSpiBusSpeed = new Frequency(12000, Frequency.UnitType.Kilohertz);
-
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format16bppRgb565;
+ public override ColorMode DefaultColorMode => ColorMode.Format16bppRgb565;
///
/// The color modes supported by the display
@@ -133,8 +127,6 @@ protected override void Initialize()
SendCommand(CMD_DISPLAYON);
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
-
dataCommandPort.State = Data;
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7735.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7735.cs
index d3279aa2ad..f72f21109d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7735.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7735.cs
@@ -1,6 +1,5 @@
using Meadow.Foundation.Graphics;
using Meadow.Hardware;
-using Meadow.Units;
namespace Meadow.Foundation.Displays
{
@@ -9,15 +8,10 @@ namespace Meadow.Foundation.Displays
///
public class St7735 : TftSpiBase
{
- ///
- /// The default SPI bus frequency
- ///
- public static Frequency DefaultSpiBusSpeed = new Frequency(12000, Frequency.UnitType.Kilohertz);
-
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -153,7 +147,6 @@ protected override void Initialize()
if (displayType == DisplayType.ST7735B)
{
Init7735B();
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
return;
}
@@ -177,8 +170,6 @@ protected override void Initialize()
SendCommand(Register.INVOFF);
}
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
-
dataCommandPort.State = Data;
}
@@ -389,21 +380,7 @@ protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
x1 += xOffset;
y1 += yOffset;
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
+ base.SetAddressWindow(x0, y0, x1, y1);
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7789.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7789.cs
index 9a48a3d42c..938e4a2d41 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7789.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7789.cs
@@ -9,21 +9,26 @@ namespace Meadow.Foundation.Displays
///
public class St7789 : TftSpiBase, IRotatableDisplay
{
- ///
- /// The default SPI bus frequency
- ///
- public static Frequency DefaultSpiBusSpeed = new Frequency(48000, Frequency.UnitType.Kilohertz);
-
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format16bppRgb565;
+ public override ColorMode DefaultColorMode => ColorMode.Format16bppRgb565;
///
/// The color modes supported by the display
///
public override ColorMode SupportedColorModes => ColorMode.Format16bppRgb565 | ColorMode.Format12bppRgb444;
+ ///
+ /// SPI bus speed
+ ///
+ public override Frequency DefaultSpiBusSpeed => new Frequency(48000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public override SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode3;
+
private byte rowStart, rowStart2;
private byte columnStart, columnStart2;
@@ -128,9 +133,7 @@ protected override void Initialize()
SendCommand(Register.NORON); //normal display
DelayMs(10);
SendCommand(Register.DISPON); //display on
- DelayMs(500);
-
- SetAddressWindow(0, 0, (Width - 1), (Height - 1));
+ DelayMs(120);
dataCommandPort.State = Data;
}
@@ -150,21 +153,7 @@ protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
x1 += xOffset;
y1 += yOffset;
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
+ base.SetAddressWindow(x0, y0, x1, y1);
}
///
@@ -175,7 +164,7 @@ public void SetRotation(RotationType rotation)
{
SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_MY | (byte)Register.MADCTL_RGB);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7796s.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7796s.cs
index 684d7c1d20..e68ef5398c 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7796s.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/Drivers/St7796s.cs
@@ -11,7 +11,7 @@ public class St7796s : TftSpiBase, IRotatableDisplay
///
/// The default display color mode
///
- public override ColorMode DefautColorMode => ColorMode.Format12bppRgb444;
+ public override ColorMode DefaultColorMode => ColorMode.Format12bppRgb444;
///
/// The color modes supported by the display
@@ -158,41 +158,15 @@ protected override void Initialize()
SendCommand(0x29); //Display on
}
- ///
- /// Set addrees window for display updates
- ///
- /// X start in pixels
- /// Y start in pixels
- /// X end in pixels
- /// Y end in pixels
- protected override void SetAddressWindow(int x0, int y0, int x1, int y1)
- {
- SendCommand(LcdCommand.CASET); // column addr set
- dataCommandPort.State = Data;
- Write((byte)(x0 >> 8));
- Write((byte)(x0 & 0xff)); // XSTART
- Write((byte)(x1 >> 8));
- Write((byte)(x1 & 0xff)); // XEND
-
- SendCommand(LcdCommand.RASET); // row addr set
- dataCommandPort.State = Data;
- Write((byte)(y0 >> 8));
- Write((byte)(y0 & 0xff)); // YSTART
- Write((byte)(y1 >> 8));
- Write((byte)(y1 & 0xff)); // YEND
-
- SendCommand(LcdCommand.RAMWR); // write to RAM
- }
-
///
/// Set the display rotation
///
/// The rotation value
public void SetRotation(RotationType rotation)
{
- SendCommand((byte)Register.MADCTL);
+ SendCommand(Register.MADCTL);
- switch (rotation)
+ switch (Rotation = rotation)
{
case RotationType.Normal:
SendData((byte)Register.MADCTL_MX | (byte)Register.MADCTL_BGR);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.Enums.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.Enums.cs
index 482f583d25..900c15314a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.Enums.cs
@@ -11,11 +11,11 @@ public abstract partial class TftSpiBase
protected enum LcdCommand : byte
{
///
- /// CASET
+ /// Column address set
///
CASET = 0x2A,
///
- /// RASET
+ /// Row address set
///
RASET = 0x2B,
///
@@ -70,7 +70,7 @@ protected enum Register : byte
///
DISPON = 0x29,
///
- /// MADCTL
+ /// Memory access control
///
MADCTL = 0x36,
///
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.cs
index b76f1efebe..df89f9dc9d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Driver/TftSpiBase.cs
@@ -1,13 +1,19 @@
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
using Meadow.Hardware;
+using Meadow.Units;
using System;
using System.Threading;
namespace Meadow.Foundation.Displays
{
- public abstract partial class TftSpiBase : IGraphicsDisplay
+ public abstract partial class TftSpiBase : IGraphicsDisplay, ISpiPeripheral
{
+ ///
+ /// Temporary buffer that can be used to batch set address window buffer commands
+ ///
+ protected byte[] SetAddressBuffer { get; } = new byte[4];
+
//these displays typically support 16 & 18 bit, some also include 8, 9, 12 and/or 24 bit color
///
@@ -23,12 +29,12 @@ public abstract partial class TftSpiBase : IGraphicsDisplay
///
/// The current rotation of the display
///
- public RotationType Rotation { get; set; } = RotationType.Normal;
+ public RotationType Rotation { get; protected set; } = RotationType.Normal;
///
/// The display default color mode
///
- public abstract ColorMode DefautColorMode { get; }
+ public abstract ColorMode DefaultColorMode { get; }
///
/// Width of display in pixels
@@ -45,6 +51,34 @@ public abstract partial class TftSpiBase : IGraphicsDisplay
///
public IPixelBuffer PixelBuffer => imageBuffer;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public virtual Frequency DefaultSpiBusSpeed => new Frequency(12000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiDisplay.BusSpeed;
+ set => spiDisplay.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public virtual SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiDisplay.BusMode;
+ set => spiDisplay.BusMode = value;
+ }
+
///
/// The data command port
///
@@ -63,7 +97,7 @@ public abstract partial class TftSpiBase : IGraphicsDisplay
///
/// The spi peripheral for the display
///
- protected ISpiPeripheral spiDisplay;
+ protected ISpiCommunications spiDisplay;
///
/// The offscreen image buffer
@@ -100,6 +134,30 @@ public abstract partial class TftSpiBase : IGraphicsDisplay
///
protected int nativeWidth;
+ ///
+ /// Previous x0 value passed to SetAddressWindow
+ /// Used for optimization to avoid unnecessary SPI commands
+ ///
+ protected int setAddressLastX0 = -1;
+
+ ///
+ /// Previous x1 value passed to SetAddressWindow
+ /// Used for optimization to avoid unnecessary SPI commands
+ ///
+ protected int setAddressLastX1 = -1;
+
+ ///
+ /// Previous y0 value passed to SetAddressWindow
+ /// Used for optimization to avoid unnecessary SPI commands
+ ///
+ protected int setAddressLastY0 = -1;
+
+ ///
+ /// Previous y1 value passed to SetAddressWindow
+ /// Used for optimization to avoid unnecessary SPI commands
+ ///
+ protected int setAddressLastY1 = -1;
+
///
/// Represents an abstract TftSpiBase object
///
@@ -116,7 +174,7 @@ public TftSpiBase(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin,
spiBus,
chipSelectPin?.CreateDigitalOutputPort(),
dcPin.CreateDigitalOutputPort(),
- resetPin.CreateDigitalOutputPort(),
+ resetPin?.CreateDigitalOutputPort(),
width, height, colorMode
)
{
@@ -143,7 +201,7 @@ public TftSpiBase(ISpiBus spiBus,
this.chipSelectPort = chipSelectPort;
this.resetPort = resetPort;
- spiDisplay = new SpiPeripheral(spiBus, chipSelectPort);
+ spiDisplay = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
CreateBuffer(colorMode, nativeWidth = width, nativeHeight = height);
}
@@ -156,42 +214,32 @@ public TftSpiBase(ISpiBus spiBus,
public virtual bool IsColorTypeSupported(ColorMode colorType)
{
return (SupportedColorModes | colorType) != 0;
- /*
- if (SupportedColors)
-
-
- if (mode == ColorType.Format12bppRgb444 ||
- mode == ColorType.Format16bppRgb565)
- {
- return true;
- }
- return false;*/
}
///
/// Create an offscreen buffer for the display
///
- /// The color mode
+ /// The color mode
/// The width in pixels
/// The height in pixels
/// Throws an exception if the color mode isn't supported
- protected void CreateBuffer(ColorMode colorType, int width, int height)
+ protected void CreateBuffer(ColorMode colorMode, int width, int height)
{
- if (IsColorTypeSupported(colorType) == false)
+ if (IsColorTypeSupported(colorMode) == false)
{
- throw new ArgumentException($"color mode {colorType} not supported");
+ throw new ArgumentException($"color mode {colorMode} not supported");
}
- if (colorType == ColorMode.Format24bppRgb888)
+ if (colorMode == ColorMode.Format24bppRgb888)
{
imageBuffer = new BufferRgb888(width, height);
}
- else if (colorType == ColorMode.Format16bppRgb565)
+ else if (colorMode == ColorMode.Format16bppRgb565)
{
imageBuffer = new BufferRgb565(width, height);
}
- else //Rgb444
+ else
{
imageBuffer = new BufferRgb444(width, height);
}
@@ -199,13 +247,40 @@ protected void CreateBuffer(ColorMode colorType, int width, int height)
}
///
- /// Set addrees window for display updates
+ /// Set address window for display updates
///
/// X start in pixels
/// Y start in pixels
/// X end in pixels
/// Y end in pixels
- protected abstract void SetAddressWindow(int x0, int y0, int x1, int y1);
+ protected virtual void SetAddressWindow(int x0, int y0, int x1, int y1)
+ {
+ if (x0 != setAddressLastX0 || x1 != setAddressLastX1 || y0 != setAddressLastY0 || y1 != setAddressLastY1)
+ {
+ setAddressLastX0 = x0;
+ setAddressLastX1 = x1;
+ setAddressLastY0 = y0;
+ setAddressLastY1 = y1;
+
+ SendCommand(LcdCommand.CASET); // column addr set
+ dataCommandPort.State = Data;
+ SetAddressBuffer[0] = (byte)(x0 >> 8);
+ SetAddressBuffer[1] = (byte)(x0 & 0xff); // XSTART
+ SetAddressBuffer[2] = (byte)(x1 >> 8);
+ SetAddressBuffer[3] = (byte)(x1 & 0xff); // XEND
+ Write(SetAddressBuffer);
+
+ SendCommand(LcdCommand.RASET); // row addr set
+ dataCommandPort.State = Data;
+ SetAddressBuffer[0] = (byte)(y0 >> 8);
+ SetAddressBuffer[1] = (byte)(y0 & 0xff); // XEND
+ SetAddressBuffer[2] = (byte)(y1 >> 8);
+ SetAddressBuffer[3] = (byte)(y1 & 0xff); // YEND
+ Write(SetAddressBuffer);
+
+ SendCommand(LcdCommand.RAMWR); // write to RAM
+ }
+ }
///
/// Clear the display.
@@ -308,7 +383,7 @@ public void Fill(int x, int y, int width, int height, Color color)
///
public void Show()
{
- SetAddressWindow(0, 0, Width - 1, Height);
+ SetAddressWindow(0, 0, Width - 1, Height - 1);
dataCommandPort.State = Data;
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/Gc9a01_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/Gc9a01_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/Gc9a01_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/Gc9a01_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/MeadowApp.cs
index 205e2ec8a7..7a096b9962 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Gc9a01_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Gc9a01_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/Hx8357b_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/Hx8357b_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/Hx8357b_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/Hx8357b_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/MeadowApp.cs
index 8bb6f15a1c..3d17ae9d19 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357b_Sample/MeadowApp.cs
@@ -3,8 +3,6 @@
using Meadow.Foundation;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System;
using System.Diagnostics;
using System.Threading;
@@ -22,8 +20,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/Hx8357d_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/Hx8357d_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/Hx8357d_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/Hx8357d_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/MeadowApp.cs
index 48d47254e3..612b5a2363 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Hx8357d_Sample/MeadowApp.cs
@@ -3,8 +3,6 @@
using Meadow.Foundation;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System;
using System.Diagnostics;
using System.Threading;
@@ -22,8 +20,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/Ili9163_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/Ili9163_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/Ili9163_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/Ili9163_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/MeadowApp.cs
index c73a6b656d..e8e2ad9252 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9163_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Ili9163_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/Ili9341_Jpg_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/Ili9341_Jpg_Sample.csproj
index 523f0ef410..09e1200534 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/Ili9341_Jpg_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/Ili9341_Jpg_Sample.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/MeadowApp.cs
index a51c01d0a7..b7c9fba4e9 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Jpg_Sample/MeadowApp.cs
@@ -22,7 +22,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- var spiBus = Device.CreateSpiBus(Ili9341.DefaultSpiBusSpeed);
+ var spiBus = Device.CreateSpiBus();
display = new Ili9341
(
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/Ili9341_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/Ili9341_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/Ili9341_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/Ili9341_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/MeadowApp.cs
index 709f57ea91..041e20ee90 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9341_Sample/MeadowApp.cs
@@ -3,8 +3,6 @@
using Meadow.Foundation;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -22,14 +20,11 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
-
Resolver.Log.Info("Create display driver instance");
display = new Ili9341
(
- spiBus: spiBus,
+ spiBus: Device.CreateSpiBus(),
chipSelectPin: Device.Pins.D13,
dcPin: Device.Pins.D14,
resetPin: Device.Pins.D15,
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/Ili9481_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/Ili9481_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/Ili9481_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/Ili9481_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/MeadowApp.cs
index 9c7c0d4029..7dc529438d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9481_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Ili9481_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/Ili9486_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/Ili9486_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/Ili9486_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/Ili9486_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/MeadowApp.cs
index 76747c5923..aa76b0625b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9486_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Ili9486_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/Ili9488_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/Ili9488_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/Ili9488_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/Ili9488_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/MeadowApp.cs
index eb1128b7f1..2c65de9ea8 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ili9488_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Ili9488_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/MeadowApp.cs
index 38d6a4452a..a95d1ecff2 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.Rm68140_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/Rm68140_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/Rm68140_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/Rm68140_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Rm68140_Sample/Rm68140_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/MeadowApp.cs
index 48ef960502..ead06e0241 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/MeadowApp.cs
@@ -2,8 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
-using Meadow.Units;
using System.Threading.Tasks;
namespace Displays.Tft.S6D02A1_Sample
@@ -18,8 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(12000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/S6D02A1_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/S6D02A1_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/S6D02A1_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/S6D02A1_Sample/S6D02A1_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/MeadowApp.cs
index d34a9ce65d..8d221beb2f 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/MeadowApp.cs
@@ -4,8 +4,6 @@
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
-using Meadow.Hardware;
-using Meadow.Units;
using System;
using System.Diagnostics;
using System.Threading;
@@ -39,8 +37,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Frequency(48000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode3);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
display = new St7789(
spiBus: spiBus,
@@ -312,7 +309,7 @@ void LineTest()
for (int i = 1; i < 10; i++)
{
graphics.Stroke = i;
- graphics.DrawHorizontalLine((int)graphics.Width - 5, 20 * i, (int)(10 - graphics.Width), Color.Green);
+ graphics.DrawHorizontalLine(graphics.Width - 5, 20 * i, 10 - graphics.Width, Color.Green);
}
graphics.Show();
Thread.Sleep(1500);
@@ -325,7 +322,7 @@ void LineTest()
for (int i = 1; i < 10; i++)
{
graphics.Stroke = i;
- graphics.DrawVerticalLine(20 * i, 5, (int)(graphics.Height - 10), Color.Orange);
+ graphics.DrawVerticalLine(20 * i, 5, graphics.Height - 10, Color.Orange);
}
graphics.Show();
Thread.Sleep(1500);
@@ -335,7 +332,7 @@ void LineTest()
for (int i = 1; i < 10; i++)
{
graphics.Stroke = i;
- graphics.DrawVerticalLine(20 * i, (int)(graphics.Height - 5), (int)(10 - graphics.Width), Color.Blue);
+ graphics.DrawVerticalLine(20 * i, graphics.Height - 5, 10 - graphics.Width, Color.Blue);
}
graphics.Show();
Thread.Sleep(1500);
@@ -464,7 +461,7 @@ void StrokeTest()
graphics.DrawLine(85, 125, 195, 235, Color.Silver);
graphics.Stroke = 2;
- graphics.DrawRectangle(2, 2, (int)(graphics.Width - 4), (int)(graphics.Height - 4), Color.DimGray, false);
+ graphics.DrawRectangle(2, 2, graphics.Width - 4, graphics.Height - 4, Color.DimGray, false);
graphics.Show();
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/ST7789_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/ST7789_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/ST7789_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/ST7789_Sample/ST7789_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/MeadowApp.cs
index 2138bf6a13..af1dd5a09a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
using System.Threading.Tasks;
namespace Displays.Tft.Ssd1331_Sample
@@ -17,9 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Meadow.Units.Frequency(12000, Meadow.Units.Frequency.UnitType.Kilohertz),
- SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/Ssd1331_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/Ssd1331_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/Ssd1331_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1331_Sample/Ssd1331_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/MeadowApp.cs
index 79052d7c94..c7c33854a6 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/MeadowApp.cs
@@ -16,7 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var spiBus = Device.CreateSpiBus(Ssd1351.DefaultSpiBusSpeed);
+ var spiBus = Device.CreateSpiBus();
var display = new Ssd1351(
spiBus: spiBus,
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/Ssd1351_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/Ssd1351_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/Ssd1351_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/Ssd1351_Sample/Ssd1351_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/MeadowApp.cs
index 7cb5720756..48ba59b2c9 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/MeadowApp.cs
@@ -17,7 +17,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var spiBus = Device.CreateSpiBus(St7735.DefaultSpiBusSpeed);
+ var spiBus = Device.CreateSpiBus();
//note - you may need to adjust the DisplayType for your specific St7735
var display = new St7735(
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/St7735_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/St7735_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/St7735_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7735_Sample/St7735_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/MeadowApp.cs
index 7b79b082e9..c340fbae6f 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
-using Meadow.Hardware;
using System.Threading.Tasks;
namespace Displays.Tft.St7796s_Sample
@@ -17,9 +16,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing ...");
- var config = new SpiClockConfiguration(new Meadow.Units.Frequency(12000, Meadow.Units.Frequency.UnitType.Kilohertz)
- , SpiClockConfiguration.Mode.Mode0);
- var spiBus = Device.CreateSpiBus(Device.Pins.SCK, Device.Pins.MOSI, Device.Pins.MISO, config);
+ var spiBus = Device.CreateSpiBus();
Resolver.Log.Info("Create display driver instance");
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/St7796s_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/St7796s_Sample.csproj
index 48503a4911..e9e1887334 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/St7796s_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.TftSpi/Samples/St7796s_Sample/St7796s_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Driver/Displays.Tm1637.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Driver/Displays.Tm1637.csproj
index 66bdc65397..6e5d48837d 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Driver/Displays.Tm1637.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Driver/Displays.Tm1637.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Samples/Tm1637_Sample/Tm1637_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Samples/Tm1637_Sample/Tm1637_Sample.csproj
index 82789bbe4a..428001c25b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Samples/Tm1637_Sample/Tm1637_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.Tm1637/Samples/Tm1637_Sample/Tm1637_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.WinForms/Driver/Displays.WinForms.csproj b/Source/Meadow.Foundation.Peripherals/Displays.WinForms/Driver/Displays.WinForms.csproj
index 7d589dc922..a641691013 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.WinForms/Driver/Displays.WinForms.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.WinForms/Driver/Displays.WinForms.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Displays.ePaper.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Displays.ePaper.csproj
index 1556a625b5..0ec966ac3b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Displays.ePaper.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Displays.ePaper.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il0373.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il0373.cs
index df1c93aa7b..ca00098204 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il0373.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il0373.cs
@@ -108,14 +108,14 @@ protected void SetPartialWindow(byte[] bufferBlack, byte[] bufferColor, int x, i
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(bufferBlack[i]);
+ spiComms.Write(bufferBlack[i]);
}
}
else
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(0x00);
+ spiComms.Write(0x00);
}
}
DelayMs(2);
@@ -127,14 +127,14 @@ protected void SetPartialWindow(byte[] bufferBlack, byte[] bufferColor, int x, i
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(bufferColor[i]);
+ spiComms.Write(bufferColor[i]);
}
}
else
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(0x00);
+ spiComms.Write(0x00);
}
}
DelayMs(2);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il91874.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il91874.cs
index 95c7da4320..0cf250eb14 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il91874.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Il91874.cs
@@ -277,7 +277,7 @@ void DisplayFrame(byte[] bufferBlack, byte[] bufferRed)
for (int i = 0; i < Width * Height / 8; i++)
{
- spiPeripheral.Write(bufferBlack[i]);
+ spiComms.Write(bufferBlack[i]);
}
}
@@ -289,7 +289,7 @@ void DisplayFrame(byte[] bufferBlack, byte[] bufferRed)
for (int i = 0; i < Width * Height / 8; i++)
{
- spiPeripheral.Write((byte)~bufferRed[i]);
+ spiComms.Write((byte)~bufferRed[i]);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Ssd1681.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Ssd1681.cs
index 1e11f1e5ac..b2047d301c 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Ssd1681.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Ssd1681.cs
@@ -141,7 +141,7 @@ void DisplayFrame(byte[] blackBuffer, byte[] colorBuffer)
for (int i = 0; i < colorBuffer.Length; i++)
{ //invert the color data
- spiPeripheral.Write((byte)~colorBuffer[i]);
+ spiComms.Write((byte)~colorBuffer[i]);
}
DisplayFrame();
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Uc8151c.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Uc8151c.cs
index a20ec37bee..4093a67c85 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Uc8151c.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/Drivers/Uc8151c.cs
@@ -119,14 +119,14 @@ protected void SetPartialWindow(byte[] bufferBlack, byte[] bufferColor, int x, i
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(bufferBlack[i]);
+ spiComms.Write(bufferBlack[i]);
}
}
else
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(0x00);
+ spiComms.Write(0x00);
}
}
DelayMs(2);
@@ -138,14 +138,14 @@ protected void SetPartialWindow(byte[] bufferBlack, byte[] bufferColor, int x, i
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(bufferColor[i]);
+ spiComms.Write(bufferColor[i]);
}
}
else
{
for (int i = 0; i < width / 8 * height; i++)
{
- spiPeripheral.Write(0x00);
+ spiComms.Write(0x00);
}
}
DelayMs(2);
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperMonoBase.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperMonoBase.cs
index 90f475f3fa..0014e77833 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperMonoBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperMonoBase.cs
@@ -92,7 +92,7 @@ public EPaperMonoBase(ISpiBus spiBus,
this.resetPort = resetPort;
this.busyPort = busyPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
imageBuffer = new Buffer1bppV(width, height);
@@ -284,7 +284,7 @@ public virtual void SetFrameMemory(byte[] buffer)
dataCommandPort.State = DataState;
for (int i = 0; i < Width / 8 * Height; i++)
{
- spiPeripheral.Write(buffer[i]);
+ spiComms.Write(buffer[i]);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperTriColorBase.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperTriColorBase.cs
index 2792a84571..5fd512d52b 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperTriColorBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/EPaperTriColorBase.cs
@@ -103,7 +103,7 @@ public EPaperTriColorBase(ISpiBus spiBus,
this.resetPort = resetPort;
this.busyPort = busyPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
this.width = width;
this.height = height;
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/ePaperBase.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/ePaperBase.cs
index b6a1a362dc..f07678cb18 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/ePaperBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Driver/ePaperBase.cs
@@ -1,4 +1,5 @@
using Meadow.Hardware;
+using Meadow.Units;
using System.Threading;
namespace Meadow.Foundation.Displays
@@ -6,8 +7,36 @@ namespace Meadow.Foundation.Displays
///
/// Represents a base ePaper display driver
///
- public abstract class EPaperBase
+ public abstract class EPaperBase : ISpiPeripheral
{
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(375, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
///
/// The command buffer
///
@@ -34,9 +63,9 @@ public abstract class EPaperBase
protected IDigitalInputPort busyPort;
///
- /// The SpiPeripheral object that reprsents the display
+ /// SPI Communication bus used to communicate with the peripheral
///
- protected ISpiPeripheral spiPeripheral;
+ protected ISpiCommunications spiComms;
///
/// Const bool representing the data state
@@ -55,7 +84,7 @@ public abstract class EPaperBase
protected void Write(byte value)
{
commandBuffer[0] = value;
- spiPeripheral.Write(commandBuffer);
+ spiComms.Write(commandBuffer);
}
///
@@ -68,7 +97,7 @@ protected virtual void Reset()
resetPort.State = true;
DelayMs(200);
}
-
+
///
/// Delay for a specified amount of time
///
@@ -114,7 +143,7 @@ protected void SendData(byte data)
protected void SendData(byte[] data)
{
dataCommandPort.State = DataState;
- spiPeripheral.Write(data);
+ spiComms.Write(data);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0373_Sample/IL0373_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0373_Sample/IL0373_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0373_Sample/IL0373_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0373_Sample/IL0373_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0376F_Sample/IL0376F_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0376F_Sample/IL0376F_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0376F_Sample/IL0376F_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0376F_Sample/IL0376F_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0398_Sample/IL0398_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0398_Sample/IL0398_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0398_Sample/IL0398_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL0398_Sample/IL0398_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL3897_Sample/IL3897_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL3897_Sample/IL3897_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL3897_Sample/IL3897_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL3897_Sample/IL3897_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874V03_Sample/IL91874V03_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874V03_Sample/IL91874V03_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874V03_Sample/IL91874V03_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874V03_Sample/IL91874V03_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874_Sample/IL91874_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874_Sample/IL91874_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874_Sample/IL91874_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/IL91874_Sample/IL91874_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1608_Sample/SSD1608_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1608_Sample/SSD1608_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1608_Sample/SSD1608_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1608_Sample/SSD1608_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1680_Sample/SSD1680_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1680_Sample/SSD1680_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1680_Sample/SSD1680_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1680_Sample/SSD1680_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1681_Sample/SSD1681_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1681_Sample/SSD1681_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1681_Sample/SSD1681_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/SSD1681_Sample/SSD1681_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/UC8151C_Sample/UC8151C_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/UC8151C_Sample/UC8151C_Sample.csproj
index c2155c249f..f605c3cd8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/UC8151C_Sample/UC8151C_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaper/Samples/UC8151C_Sample/UC8151C_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Displays.ePaperWaveShare.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Displays.ePaperWaveShare.csproj
index 088ee8c830..6cf5f8cdd4 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Displays.ePaperWaveShare.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Displays.ePaperWaveShare.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Drivers/Epd5in65f.cs b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Drivers/Epd5in65f.cs
index 364336bba4..8447b85c48 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Drivers/Epd5in65f.cs
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Driver/Drivers/Epd5in65f.cs
@@ -1,7 +1,6 @@
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Graphics.Buffers;
using Meadow.Hardware;
-using System;
namespace Meadow.Foundation.Displays
{
@@ -86,7 +85,7 @@ public Epd5in65f(ISpiBus spiBus,
this.resetPort = resetPort;
this.busyPort = busyPort;
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
imageBuffer = new BufferIndexed4(Width, Height);
@@ -151,7 +150,7 @@ public void Clear(bool updateDisplay = false)
{
imageBuffer.Clear();
- if(updateDisplay)
+ if (updateDisplay)
{
Show();
}
@@ -201,7 +200,7 @@ public void Show()
dataCommandPort.State = DataState;
- spiPeripheral.Write(imageBuffer.Buffer);
+ spiComms.Write(imageBuffer.Buffer);
SendCommand(0x04);
WaitForBusyState(true);
@@ -233,7 +232,7 @@ public void Show(int left, int top, int right, int bottom)
{
if (i < bottom && i >= top && j < right / 2 && j >= left / 2)
{
- spiPeripheral.Write(imageBuffer.Buffer[j + ((Width / 2) * i)]);
+ spiComms.Write(imageBuffer.Buffer[j + ((Width / 2) * i)]);
}
else
{ //no-op
@@ -259,7 +258,7 @@ public void Fill(Color fillColor, bool updateDisplay = false)
{
Fill(fillColor);
- if(updateDisplay)
+ if (updateDisplay)
{
Show();
}
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/Epd5in65f_Sample/Epd5in65f_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/Epd5in65f_Sample/Epd5in65f_Sample.csproj
index e3ffab4558..dec8368b51 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/Epd5in65f_Sample/Epd5in65f_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/Epd5in65f_Sample/Epd5in65f_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdColor_Sample/EpdColor_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdColor_Sample/EpdColor_Sample.csproj
index e3ffab4558..dec8368b51 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdColor_Sample/EpdColor_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdColor_Sample/EpdColor_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdMonochrome_Sample/EpdMonochrome_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdMonochrome_Sample/EpdMonochrome_Sample.csproj
index e3ffab4558..dec8368b51 100644
--- a/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdMonochrome_Sample/EpdMonochrome_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Displays.ePaperWaveShare/Samples/EpdMonochrome_Sample/EpdMonochrome_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.Enums.cs
index 112545c7f0..021f84d016 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.Enums.cs
@@ -3,7 +3,7 @@
public abstract partial class Ads1x15Base
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.cs b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.cs
index d7e748ffac..dc420e47b3 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/Ads1x15Base.cs
@@ -1,15 +1,24 @@
-using System.Threading.Tasks;
using Meadow.Hardware;
using Meadow.Units;
+using System.Threading.Tasks;
namespace Meadow.Foundation.ICs.ADC
{
///
/// Encapsulation for ADCs based upon the Ads1x1x family of chips.
///
- public abstract partial class Ads1x15Base : PollingSensorBase
+ public abstract partial class Ads1x15Base : PollingSensorBase, II2cPeripheral
{
- private readonly II2cPeripheral i2cPeripheral;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
+
private ushort config;
// These are config register bit offsets
@@ -38,8 +47,8 @@ protected Ads1x15Base(II2cBus i2cBus,
Addresses address,
MeasureMode mode,
ChannelSetting channel)
- {
- i2cPeripheral = new I2cPeripheral(i2cBus, (byte)address, 3, 3);
+ {
+ i2cComms = new I2cCommunications(i2cBus, (byte)address, 3, 3);
SetConfigRegister(0x8583); // this is the default reset - force it in case it's not been reset
config = GetConfigRegister();
@@ -49,7 +58,7 @@ protected Ads1x15Base(II2cBus i2cBus,
private ushort GetRegister(Register register)
{
- var read = i2cPeripheral.ReadRegisterAsUShort((byte)register, ByteOrder.BigEndian);
+ var read = i2cComms.ReadRegisterAsUShort((byte)register, ByteOrder.BigEndian);
return read;
}
@@ -59,7 +68,7 @@ private void SetRegister(Register register, ushort value)
w[0] = (byte)register;
w[1] = (byte)(value >> 8);
w[2] = (byte)(value & 0xff);
- i2cPeripheral.Write(w);
+ i2cComms.Write(w);
config = value;
}
@@ -137,8 +146,8 @@ public MeasureMode Mode
if (value == Mode) return;
ushort newConfig;
-
- if(value == MeasureMode.OneShot)
+
+ if (value == MeasureMode.OneShot)
{
newConfig = (ushort)(config | (1 << ModeShift));
}
@@ -159,7 +168,7 @@ protected override async Task ReadSensor()
var raw = await ReadRaw();
var scale = 0d;
- switch(Gain)
+ switch (Gain)
{
case FsrGain.TwoThirds:
scale = 6.144d;
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/ICs.ADC.Ads1x15.csproj b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/ICs.ADC.Ads1x15.csproj
index ae6f47a5da..a751b4ee55 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/ICs.ADC.Ads1x15.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Driver/ICs.ADC.Ads1x15.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1015_Sample/Ads1015_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1015_Sample/Ads1015_Sample.csproj
index f1fa173c58..ac5847f4e9 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1015_Sample/Ads1015_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1015_Sample/Ads1015_Sample.csproj
@@ -6,7 +6,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1115_Sample/Ads1115_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1115_Sample/Ads1115_Sample.csproj
index f1fa173c58..ac5847f4e9 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1115_Sample/Ads1115_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.ADC.Ads1x15/Samples/Ads1115_Sample/Ads1115_Sample.csproj
@@ -6,7 +6,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.Enums.cs
index 740aace3e1..25dd0945d6 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.Enums.cs
@@ -3,9 +3,9 @@
public partial class At24Cxx
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x50
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.cs b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.cs
index a95da43334..75cd6881bb 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/At24Cxx.cs
@@ -1,26 +1,31 @@
+using Meadow.Hardware;
using System;
using System.Threading;
-using Meadow.Hardware;
namespace Meadow.Foundation.ICs.EEPROM
{
///
- /// Encapsulation for EEPROMs based upon the AT24Cxx family of chips.
+ /// Encapsulation for EEPROMs based upon the AT24Cxx family of chips
///
- public partial class At24Cxx
+ public partial class At24Cxx : II2cPeripheral
{
///
- /// Communication bus used to communicate with the EEPROM.
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
///
- private II2cPeripheral Peripheral { get; }
+ protected readonly II2cCommunications i2cComms;
///
- /// Number of bytes in a page.
+ /// Number of bytes in a page
///
public ushort PageSize { get; }
///
- /// Number of bytes in the EEPROM module.
+ /// Number of bytes in the EEPROM module
///
public ushort MemorySize { get; }
@@ -35,12 +40,12 @@ public partial class At24Cxx
/// Number of bytes in a page (default = 32 - AT24C32).
/// Total number of bytes in the EEPROM (default = 8192 - AT24C32).
public At24Cxx(II2cBus i2cBus,
- byte address = (byte)Address.Default,
+ byte address = (byte)Addresses.Default,
ushort pageSize = 32,
ushort memorySize = 8192)
{
- var device = new I2cPeripheral(i2cBus, address);
- Peripheral = device;
+ var device = new I2cCommunications(i2cBus, address);
+ i2cComms = device;
PageSize = pageSize;
MemorySize = memorySize;
@@ -77,13 +82,13 @@ public byte[] Read(ushort startAddress, ushort amount)
{
CheckAddress(startAddress, amount);
Span data = WriteBuffer.Span[0..2];
- data[0] = (byte) ((startAddress >> 8) & 0xff);
- data[1] = (byte) (startAddress & 0xff);
+ data[0] = (byte)((startAddress >> 8) & 0xff);
+ data[1] = (byte)(startAddress & 0xff);
var results = new byte[amount];
- Peripheral.Write(data);
- Peripheral.Read(results);
+ i2cComms.Write(data);
+ i2cComms.Read(results);
return results;
}
@@ -95,18 +100,18 @@ public byte[] Read(ushort startAddress, ushort amount)
/// Data to be written to the EEPROM.
public void Write(ushort startAddress, params byte[] data)
{
- CheckAddress(startAddress, (ushort) data.Length);
+ CheckAddress(startAddress, (ushort)data.Length);
//
// TODO: Convert to use page writes where possible.
//
for (ushort index = 0; index < data.Length; index++)
{
- var address = (ushort) (startAddress + index);
+ var address = (ushort)(startAddress + index);
var addressAndData = new byte[3];
- addressAndData[0] = (byte) ((address >> 8) & 0xff);
- addressAndData[1] = (byte) (address & 0xff);
+ addressAndData[0] = (byte)((address >> 8) & 0xff);
+ addressAndData[1] = (byte)(address & 0xff);
addressAndData[2] = data[index];
- Peripheral.Write(addressAndData);
+ i2cComms.Write(addressAndData);
Thread.Sleep(10);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/ICs.EEPROM.At24Cxx.csproj b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/ICs.EEPROM.At24Cxx.csproj
index 3886fb8bb2..cfacc56ee0 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/ICs.EEPROM.At24Cxx.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Driver/ICs.EEPROM.At24Cxx.csproj
@@ -18,6 +18,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Samples/At24Cxx_Sample/At24Cxx_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Samples/At24Cxx_Sample/At24Cxx_Sample.csproj
index f509d1ffef..05c6946fd7 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Samples/At24Cxx_Sample/At24Cxx_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.EEPROM.At24Cxx/Samples/At24Cxx_Sample/At24Cxx_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.Enums.cs
index b0afc11f2b..cd4a0c7131 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.Enums.cs
@@ -131,13 +131,13 @@ public enum DataRate : byte
///
/// 32hz
///
- _32hz,
+ _32hz,
}
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x4C
@@ -188,4 +188,4 @@ public enum LutIndex : byte
Index7,
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.cs b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.cs
index 59361c35db..80d2837a81 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/Emc2101.cs
@@ -10,7 +10,8 @@ namespace Meadow.Foundation.ICs.FanControllers
/// Represents an EMC2101 fan controller and temperature monitor
///
public partial class Emc2101 :
- PollingSensorBase<(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed)>
+ PollingSensorBase<(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed)>,
+ II2cPeripheral
{
///
/// Internal Temperature changed event
@@ -42,6 +43,11 @@ public partial class Emc2101 :
///
public AngularVelocity? FanSpeed => Conditions.FanSpeed;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Get/Set the minimum fan speed for the currently connected fan
///
@@ -49,15 +55,15 @@ public AngularVelocity MinimumFanSpeed
{
get
{
- byte lsb = i2cPeripheral.ReadRegister((byte)Registers.TachLimitLSB);
- byte msb = i2cPeripheral.ReadRegister((byte)Registers.TachLimitMSB);
+ byte lsb = i2cComms.ReadRegister((byte)Registers.TachLimitLSB);
+ byte msb = i2cComms.ReadRegister((byte)Registers.TachLimitMSB);
ushort speed = (ushort)(msb << 8 | lsb);
return new AngularVelocity(FanRpmNumerator / speed, AngularVelocity.UnitType.RevolutionsPerMinute);
}
set
{
ushort raw = (ushort)(value.RevolutionsPerMinute * FanRpmNumerator);
- i2cPeripheral.WriteRegister((byte)Registers.TachLimitLSB, raw);
+ i2cComms.WriteRegister((byte)Registers.TachLimitLSB, raw);
}
}
@@ -68,8 +74,8 @@ public AngularVelocity MinimumFanSpeed
///
public byte PwmFrequencyScaler
{
- get => i2cPeripheral.ReadRegister((byte)Registers.PwmFrequency);
- set => i2cPeripheral.WriteRegister((byte)Registers.PwmFrequency, Math.Min(value, (byte)0x1F));
+ get => i2cComms.ReadRegister((byte)Registers.PwmFrequency);
+ set => i2cComms.WriteRegister((byte)Registers.PwmFrequency, Math.Min(value, (byte)0x1F));
}
///
@@ -78,8 +84,8 @@ public byte PwmFrequencyScaler
///
public byte PwmDivisor
{
- get => i2cPeripheral.ReadRegister((byte)Registers.PwmDivisor);
- set => i2cPeripheral.WriteRegister((byte)Registers.PwmDivisor, value);
+ get => i2cComms.ReadRegister((byte)Registers.PwmDivisor);
+ set => i2cComms.WriteRegister((byte)Registers.PwmDivisor, value);
}
///
@@ -87,8 +93,8 @@ public byte PwmDivisor
///
public float FanPwmDutyCycle
{
- get => i2cPeripheral.ReadRegister((byte)Registers.FanSetting) / (float)MaxFanSpeed;
- set => i2cPeripheral.WriteRegister((byte)Registers.FanSetting, (byte)(Math.Clamp(value, 0, 1) * MaxFanSpeed));
+ get => i2cComms.ReadRegister((byte)Registers.FanSetting) / (float)MaxFanSpeed;
+ set => i2cComms.WriteRegister((byte)Registers.FanSetting, (byte)(Math.Clamp(value, 0, 1) * MaxFanSpeed));
}
///
@@ -98,8 +104,8 @@ public float FanPwmDutyCycle
/// The hysteresis temperature value
public Temperature Hysteresis
{
- get => new Temperature(i2cPeripheral.ReadRegister((byte)Registers.LutHysteresis), Temperature.UnitType.Celsius);
- set => i2cPeripheral.WriteRegister((byte)Registers.LutHysteresis, (byte)value.Celsius);
+ get => new Temperature(i2cComms.ReadRegister((byte)Registers.LutHysteresis), Temperature.UnitType.Celsius);
+ set => i2cComms.WriteRegister((byte)Registers.LutHysteresis, (byte)value.Celsius);
}
///
@@ -107,8 +113,8 @@ public Temperature Hysteresis
///
public DataRate SensorDataRate
{
- get => (DataRate)i2cPeripheral.ReadRegister((byte)Registers.DataRate);
- set => i2cPeripheral.WriteRegister((byte)Registers.DataRate, (byte)value);
+ get => (DataRate)i2cComms.ReadRegister((byte)Registers.DataRate);
+ set => i2cComms.WriteRegister((byte)Registers.DataRate, (byte)value);
}
///
@@ -117,12 +123,12 @@ public DataRate SensorDataRate
/// true if enabled
bool LutEnabled
{
- get => BitHelpers.GetBitValue(i2cPeripheral.ReadRegister((byte)Registers.FanConfiguration), 5);
+ get => BitHelpers.GetBitValue(i2cComms.ReadRegister((byte)Registers.FanConfiguration), 5);
set
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.FanConfiguration);
+ byte config = i2cComms.ReadRegister((byte)Registers.FanConfiguration);
BitHelpers.SetBit(config, 5, value);
- i2cPeripheral.WriteRegister((byte)Registers.FanConfiguration, config);
+ i2cComms.WriteRegister((byte)Registers.FanConfiguration, config);
}
}
@@ -131,28 +137,28 @@ bool LutEnabled
///
public bool DACOutputEnabled
{
- get => BitHelpers.GetBitValue(i2cPeripheral.ReadRegister((byte)Registers.Configuration), 4);
+ get => BitHelpers.GetBitValue(i2cComms.ReadRegister((byte)Registers.Configuration), 4);
set
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.Configuration);
+ byte config = i2cComms.ReadRegister((byte)Registers.Configuration);
config = BitHelpers.SetBit(config, 4, value);
- i2cPeripheral.WriteRegister((byte)Registers.Configuration, config);
+ i2cComms.WriteRegister((byte)Registers.Configuration, config);
}
}
///
- /// Communication bus used to communicate with the Emc2101
+ /// I2C Communication bus used to communicate with the peripheral
///
- readonly II2cPeripheral i2cPeripheral;
+ protected readonly II2cCommunications i2cComms;
///
/// Create a new EMC2101 object
///
/// I2CBus connected to display
/// Address of the EMC2101 (default = 0x4C)
- public Emc2101(II2cBus i2cBus, byte address = (byte)Address.Default)
+ public Emc2101(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
Initialize();
}
@@ -160,7 +166,7 @@ public Emc2101(II2cBus i2cBus, byte address = (byte)Address.Default)
void Initialize()
{
EnableTachInput(true);
-
+
InvertFanSpeed(false);
PwmFrequencyScaler = 0x1F;
ConfigurePwmClock(true, false);
@@ -185,7 +191,7 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Interna
{
ExternalTemperatureUpdated?.Invoke(this, new ChangeResult(tempEx, changeResult.Old?.ExternalTemperature));
}
- if(changeResult.New.FanSpeed is { } fanSpeed)
+ if (changeResult.New.FanSpeed is { } fanSpeed)
{
FanSpeedUpdated?.Invoke(this, new ChangeResult(fanSpeed, changeResult.Old?.FanSpeed));
}
@@ -199,28 +205,25 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Interna
/// The latest sensor reading
protected override Task<(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed)> ReadSensor()
{
- return Task.Run(() =>
- {
- (Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed) conditions;
-
- //internal temperature
- conditions.InternalTemperature = new Temperature(i2cPeripheral.ReadRegister((byte)Registers.InternalTemperature), Temperature.UnitType.Celsius);
-
- //external temperature
- byte lsb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureLSB);
- byte msb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureMSB);
- short raw = (short)(msb << 8 | lsb);
- raw >>= 5;
- conditions.ExternalTemperature = new Temperature(raw * TemperatureBit, Temperature.UnitType.Celsius);
-
- //fan speed
- lsb = i2cPeripheral.ReadRegister((byte)Registers.TachLSB);
- msb = i2cPeripheral.ReadRegister((byte)Registers.TachMSB);
- short speed = (short)(msb << 8 | lsb);
- conditions.FanSpeed = new AngularVelocity(FanRpmNumerator / speed, AngularVelocity.UnitType.RevolutionsPerMinute);
-
- return conditions;
- });
+ (Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed) conditions;
+
+ //internal temperature
+ conditions.InternalTemperature = new Temperature(i2cComms.ReadRegister((byte)Registers.InternalTemperature), Temperature.UnitType.Celsius);
+
+ //external temperature
+ byte lsb = i2cComms.ReadRegister((byte)Registers.ExternalTemperatureLSB);
+ byte msb = i2cComms.ReadRegister((byte)Registers.ExternalTemperatureMSB);
+ short raw = (short)(msb << 8 | lsb);
+ raw >>= 5;
+ conditions.ExternalTemperature = new Temperature(raw * TemperatureBit, Temperature.UnitType.Celsius);
+
+ //fan speed
+ lsb = i2cComms.ReadRegister((byte)Registers.TachLSB);
+ msb = i2cComms.ReadRegister((byte)Registers.TachMSB);
+ short speed = (short)(msb << 8 | lsb);
+ conditions.FanSpeed = new AngularVelocity(FanRpmNumerator / speed, AngularVelocity.UnitType.RevolutionsPerMinute);
+
+ return Task.FromResult(conditions);
}
///
@@ -229,11 +232,11 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Interna
/// true to renable, false to disable
public void EnableTachInput(bool enable)
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.Configuration);
+ byte config = i2cComms.ReadRegister((byte)Registers.Configuration);
config = BitHelpers.SetBit(config, 2, enable);
- i2cPeripheral.WriteRegister((byte)Registers.Configuration, config);
+ i2cComms.WriteRegister((byte)Registers.Configuration, config);
}
///
@@ -242,11 +245,11 @@ public void EnableTachInput(bool enable)
/// true to invert, false for normal
public void InvertFanSpeed(bool invert)
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.FanConfiguration);
+ byte config = i2cComms.ReadRegister((byte)Registers.FanConfiguration);
config = BitHelpers.SetBit(config, 4, invert);
- i2cPeripheral.WriteRegister((byte)Registers.FanConfiguration, config);
+ i2cComms.WriteRegister((byte)Registers.FanConfiguration, config);
}
///
@@ -256,12 +259,12 @@ public void InvertFanSpeed(bool invert)
/// true to override the base clock and use the frequency divisor to set the PWM frequency
public void ConfigurePwmClock(bool clockSelect, bool clockOverride)
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.FanConfiguration);
+ byte config = i2cComms.ReadRegister((byte)Registers.FanConfiguration);
config = BitHelpers.SetBit(config, 3, clockSelect);
config = BitHelpers.SetBit(config, 2, clockOverride);
- i2cPeripheral.WriteRegister((byte)Registers.FanConfiguration, config);
+ i2cComms.WriteRegister((byte)Registers.FanConfiguration, config);
}
///
@@ -271,13 +274,13 @@ public void ConfigurePwmClock(bool clockSelect, bool clockOverride)
/// The time taken to spin up to the drive speed
public void ConfigureFanSpinup(FanSpinupDrive spinupDrive, FanSpinupTime spinupTime)
{
- byte config = i2cPeripheral.ReadRegister((byte)Registers.FanSpinup);
+ byte config = i2cComms.ReadRegister((byte)Registers.FanSpinup);
config = (byte)(config & ~0x1F); //zero out the bits
config |= (byte)spinupDrive;
config |= (byte)spinupTime;
- i2cPeripheral.WriteRegister((byte)Registers.FanSpinup, config);
+ i2cComms.WriteRegister((byte)Registers.FanSpinup, config);
}
///
@@ -286,13 +289,13 @@ public void ConfigureFanSpinup(FanSpinupDrive spinupDrive, FanSpinupTime spinupT
/// The LUT index to set
/// the temperature threshhold
/// the fan PWM duty cycle
- public void SetLookupTable(LutIndex index,
- Temperature temperatureThreshhold,
+ public void SetLookupTable(LutIndex index,
+ Temperature temperatureThreshhold,
float pwmDutyCycle)
{
pwmDutyCycle = Math.Clamp(pwmDutyCycle, 0, 1);
- if(temperatureThreshhold.Celsius > MaxLutTemperature)
+ if (temperatureThreshhold.Celsius > MaxLutTemperature)
{
temperatureThreshhold = new Units.Temperature(MaxLutTemperature, Units.Temperature.UnitType.Celsius);
}
@@ -305,8 +308,8 @@ public void SetLookupTable(LutIndex index,
//Oh C# and bytes/enums ... best to leave as an int and cast when it's used
int address = (byte)Registers.LutStartRegister + (byte)index * 2;
- i2cPeripheral.WriteRegister((byte)address, (byte)temperatureThreshhold.Celsius);
- i2cPeripheral.WriteRegister((byte)(address + 1), (byte)(pwmDutyCycle * MaxFanSpeed));
+ i2cComms.WriteRegister((byte)address, (byte)temperatureThreshhold.Celsius);
+ i2cComms.WriteRegister((byte)(address + 1), (byte)(pwmDutyCycle * MaxFanSpeed));
//restore lut state
LutEnabled = lutState;
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/ICs.FanControllers.Emc2101.csproj b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/ICs.FanControllers.Emc2101.csproj
index 70b43660a7..3f726fd349 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/ICs.FanControllers.Emc2101.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Driver/ICs.FanControllers.Emc2101.csproj
@@ -16,7 +16,7 @@
Emc2101 I2C fan controller and temperature monitor
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Samples/Emc2101_Sample/Emc2101_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Samples/Emc2101_Sample/Emc2101_Sample.csproj
index 15f0d92735..ff25e07fbb 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Samples/Emc2101_Sample/Emc2101_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.FanControllers.Emc2101/Samples/Emc2101_Sample/Emc2101_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Driver/ICs.IOExpanders.AnalogMux.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Driver/ICs.IOExpanders.AnalogMux.csproj
index 4eb132edbd..de8eda5123 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Driver/ICs.IOExpanders.AnalogMux.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Driver/ICs.IOExpanders.AnalogMux.csproj
@@ -18,6 +18,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Samples/Nxp74HC4051_Sample/Nxp74HC4051_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Samples/Nxp74HC4051_Sample/Nxp74HC4051_Sample.csproj
index d45bf7555b..f93e637400 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Samples/Nxp74HC4051_Sample/Nxp74HC4051_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.AnalogMux/Samples/Nxp74HC4051_Sample/Nxp74HC4051_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.Enums.cs
index dfdd1a420c..b42572fdb6 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.Enums.cs
@@ -3,7 +3,7 @@
public partial class As1115
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.cs
index dc4840f326..c6f1687e7a 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/As1115.cs
@@ -11,7 +11,7 @@ namespace Meadow.Foundation.ICs.IOExpanders
///
/// Represents an As1115 led driver and key scanner
///
- public partial class As1115 : IGraphicsDisplay, IDisposable
+ public partial class As1115 : IGraphicsDisplay, II2cPeripheral, IDisposable
{
///
/// Event raised when any key scan button is pressed
@@ -41,9 +41,14 @@ public partial class As1115 : IGraphicsDisplay, IDisposable
KeyScanButtonType lastButtonPressed = KeyScanButtonType.None;
///
- /// As1115 I2C driver
+ /// I2C Communication bus used to communicate with the peripheral
///
- protected II2cPeripheral i2cPeripheral;
+ protected readonly II2cCommunications i2cComms;
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
///
/// The display color mode (1 bit per pixel)
@@ -97,7 +102,7 @@ public partial class As1115 : IGraphicsDisplay, IDisposable
public As1115(II2cBus i2cBus, IPin buttonInterruptPin,
byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
interruptPort = buttonInterruptPin.CreateDigitalInputPort(
InterruptMode.EdgeFalling,
@@ -120,22 +125,22 @@ void Initialize()
KeyScanButtons = new ReadOnlyDictionary(keyDictionary);
- i2cPeripheral.WriteRegister(REG_SHUTDOWN, REG_SHUTDOWN_RUNNING | REG_SHUTDOWN_RESET_FEATUREREG);
+ i2cComms.WriteRegister(REG_SHUTDOWN, REG_SHUTDOWN_RUNNING | REG_SHUTDOWN_RESET_FEATUREREG);
- i2cPeripheral.WriteRegister(REG_SCAN_LIMIT, 0x07);
+ i2cComms.WriteRegister(REG_SCAN_LIMIT, 0x07);
SetDecodeMode(DecodeType.Pixel);
byte[] data = new byte[2];
//read the key scan registers to clear
- i2cPeripheral.ReadRegister(REG_KEYA, data);
+ i2cComms.ReadRegister(REG_KEYA, data);
}
private void InterruptPort_Changed(object sender, DigitalPortResult e)
{
byte[] data = new byte[2];
- i2cPeripheral.ReadRegister(REG_KEYA, data);
+ i2cComms.ReadRegister(REG_KEYA, data);
var keyScanButton = GetButtonFromKeyScanRegister(data[0], data[1]);
@@ -206,7 +211,7 @@ KeyScanButtonType GetButtonFromKeyScanRegister(byte keyA, byte keyB)
/// True for fast blink (period of 1s), False for slow blink (period of 2s)
public void EnableBlink(bool isEnabled, bool fastBlink = true)
{
- var reg = i2cPeripheral.ReadRegister(REG_FEATURE);
+ var reg = i2cComms.ReadRegister(REG_FEATURE);
byte mask = 1 << REG_FEATURE_BLINK;
@@ -229,7 +234,7 @@ public void EnableBlink(bool isEnabled, bool fastBlink = true)
reg &= (byte)~mask;
}
- i2cPeripheral.WriteRegister(REG_FEATURE, reg);
+ i2cComms.WriteRegister(REG_FEATURE, reg);
}
///
@@ -247,7 +252,7 @@ void SetDecodeMode(DecodeType mode)
switch (mode)
{
case DecodeType.Pixel:
- i2cPeripheral.WriteRegister(REG_DECODE_MODE, 0);
+ i2cComms.WriteRegister(REG_DECODE_MODE, 0);
break;
}
}
@@ -329,7 +334,7 @@ public void SetIntensity(byte intensity)
{
intensity = Math.Max(intensity, (byte)15);
- i2cPeripheral.WriteRegister(REG_GLOBAL_INTEN, intensity);
+ i2cComms.WriteRegister(REG_GLOBAL_INTEN, intensity);
}
///
@@ -338,7 +343,7 @@ public void SetIntensity(byte intensity)
/// True to enable, false to disable
public void TestMode(bool testOn)
{
- i2cPeripheral.WriteRegister(REG_DECODE_MODE, (byte)(testOn ? 0x01 : 0x00));
+ i2cComms.WriteRegister(REG_DECODE_MODE, (byte)(testOn ? 0x01 : 0x00));
}
///
@@ -346,14 +351,14 @@ public void TestMode(bool testOn)
///
public void Show()
{
- i2cPeripheral.WriteRegister(REG_DIGIT0, buffer.Buffer[0]);
- i2cPeripheral.WriteRegister(REG_DIGIT1, buffer.Buffer[1]);
- i2cPeripheral.WriteRegister(REG_DIGIT2, buffer.Buffer[2]);
- i2cPeripheral.WriteRegister(REG_DIGIT3, buffer.Buffer[3]);
- i2cPeripheral.WriteRegister(REG_DIGIT4, buffer.Buffer[4]);
- i2cPeripheral.WriteRegister(REG_DIGIT5, buffer.Buffer[5]);
- i2cPeripheral.WriteRegister(REG_DIGIT6, buffer.Buffer[6]);
- i2cPeripheral.WriteRegister(REG_DIGIT7, buffer.Buffer[7]);
+ i2cComms.WriteRegister(REG_DIGIT0, buffer.Buffer[0]);
+ i2cComms.WriteRegister(REG_DIGIT1, buffer.Buffer[1]);
+ i2cComms.WriteRegister(REG_DIGIT2, buffer.Buffer[2]);
+ i2cComms.WriteRegister(REG_DIGIT3, buffer.Buffer[3]);
+ i2cComms.WriteRegister(REG_DIGIT4, buffer.Buffer[4]);
+ i2cComms.WriteRegister(REG_DIGIT5, buffer.Buffer[5]);
+ i2cComms.WriteRegister(REG_DIGIT6, buffer.Buffer[6]);
+ i2cComms.WriteRegister(REG_DIGIT7, buffer.Buffer[7]);
}
///
@@ -464,7 +469,7 @@ protected virtual void Dispose(bool disposing)
}
///
- /// Dispose Peripheral
+ /// Dispose BusComms
///
public void Dispose()
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/ICs.IOExpanders.As1115.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/ICs.IOExpanders.As1115.csproj
index dda8424a4c..5f630ea03a 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/ICs.IOExpanders.As1115.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Driver/ICs.IOExpanders.As1115.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Samples/As1115_Sample/As1115_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Samples/As1115_Sample/As1115_Sample.csproj
index f47ae6a8de..77ed15adc4 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Samples/As1115_Sample/As1115_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.As1115/Samples/As1115_Sample/As1115_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.Enums.cs
index cf544ca5dd..0e792d0c31 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.Enums.cs
@@ -3,7 +3,7 @@
public partial class Ds3502
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
/// Controlled by pulling A0 and A1 high or low
///
public enum Addresses : byte
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.cs
index 4b41e93f78..5e7f635095 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/Ds3502.cs
@@ -1,20 +1,28 @@
-using System;
+using Meadow.Hardware;
+using System;
using System.Threading.Tasks;
-using Meadow.Hardware;
namespace Meadow.Foundation.ICs.IOExpanders
{
///
/// Represents a DS3502 digital potentiometer
///
- public partial class Ds3502
+ public partial class Ds3502 : II2cPeripheral
{
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Default I2C bus speed
///
public static I2cBusSpeed DefaultBusSpeed => I2cBusSpeed.Fast;
- private readonly II2cPeripheral i2cPeripheral;
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
///
/// Create a new Ds3502 object using the default parameters
@@ -23,9 +31,9 @@ public partial class Ds3502
/// I2C bus instance
public Ds3502(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
- i2cPeripheral.WriteRegister((byte)Register.DS3502_MODE, 0x80);
+ i2cComms.WriteRegister((byte)Register.DS3502_MODE, 0x80);
}
///
@@ -34,7 +42,7 @@ public Ds3502(II2cBus i2cBus, byte address = (byte)Addresses.Default)
/// the 7-bit wiper value
public byte GetWiper()
{
- return i2cPeripheral.ReadRegister((byte)Register.DS3502_WIPER);
+ return i2cComms.ReadRegister((byte)Register.DS3502_WIPER);
}
///
@@ -45,7 +53,7 @@ public void SetWiper(byte value)
{
value = Math.Min(value, (byte)127);
- i2cPeripheral.WriteRegister((byte)Register.DS3502_WIPER, value);
+ i2cComms.WriteRegister((byte)Register.DS3502_WIPER, value);
}
///
@@ -55,13 +63,13 @@ public void SetWiper(byte value)
public async Task SetWiperDefault(byte value)
{
value = Math.Min(value, (byte)127);
-
- i2cPeripheral.WriteRegister((byte)Register.DS3502_MODE, 0x00);
- i2cPeripheral.WriteRegister((byte)Register.DS3502_WIPER, value);
+
+ i2cComms.WriteRegister((byte)Register.DS3502_MODE, 0x00);
+ i2cComms.WriteRegister((byte)Register.DS3502_WIPER, value);
await Task.Delay(100).ConfigureAwait(false);
- i2cPeripheral.WriteRegister((byte)Register.DS3502_MODE, 0x80);
+ i2cComms.WriteRegister((byte)Register.DS3502_MODE, 0x80);
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/ICs.IOExpanders.Ds3502.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/ICs.IOExpanders.Ds3502.csproj
index 7657f96667..ea1a94a775 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/ICs.IOExpanders.Ds3502.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Driver/ICs.IOExpanders.Ds3502.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Samples/Ds3502_Sample/Ds3502_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Samples/Ds3502_Sample/Ds3502_Sample.csproj
index bb09c86b89..d646735cf3 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Samples/Ds3502_Sample/Ds3502_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ds3502/Samples/Ds3502_Sample/Ds3502_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.14Character.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.14Character.cs
new file mode 100644
index 0000000000..16494adf7b
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.14Character.cs
@@ -0,0 +1,47 @@
+using Meadow.Foundation.Displays.Led;
+using System;
+
+namespace Meadow.Foundation.ICs.IOExpanders
+{
+ public partial class Ht16k33
+ {
+ ///
+ /// Set a message on a 14-segment display array
+ ///
+ /// The message (up to 4 chracters)
+ public void Set14SegmentMessage(string message)
+ {
+ for (int i = 0; i < Math.Max(message.Length, 4); i++)
+ {
+ Set14SegmentDisplay(message[i], i);
+ }
+ }
+
+ ///
+ /// Set a single 14-segment display to a specific character
+ ///
+ /// The ascii chracter
+ /// The display index (0-3)
+ public void Set14SegmentDisplay(char character, int displayIndex)
+ {
+ if (displayIndex < 0 || displayIndex > 3)
+ {
+ throw new IndexOutOfRangeException("Set14SegmentDisplay index must be 0, 1, 2 or 3");
+ }
+
+ int startIndex = 16 * displayIndex;
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (FourteenSegment.IsEnabled((FourteenSegment.Segment)i, character))
+ {
+ SetLed((byte)(startIndex + i), true);
+ }
+ else
+ {
+ SetLed((byte)(startIndex + i), false);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.Enums.cs
index 1798ad84e4..e97b83d3b6 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.Enums.cs
@@ -5,7 +5,7 @@
public partial class Ht16k33
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.cs
index 5f9a441fee..4527c4c926 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/Ht16k33.cs
@@ -1,17 +1,22 @@
-using System;
-using Meadow.Hardware;
+using Meadow.Hardware;
+using System;
namespace Meadow.Foundation.ICs.IOExpanders
{
///
/// Represents an Ht16k33 128 led driver and 39 key scanner
///
- public partial class Ht16k33
+ public partial class Ht16k33 : II2cPeripheral
{
///
- /// HT16K33 LED driver and key scan
+ /// The default I2C address for the peripheral
///
- private readonly II2cPeripheral i2cPeripheral;
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
///
/// Display buffer for 16x8 LEDs
@@ -26,20 +31,20 @@ public partial class Ht16k33
///
/// Create a new HT16K33 object using the default parameters
///
- /// Address of the bus on the I2C display.
+ /// Address of the bus on the I2C display
/// I2C bus instance
public Ht16k33(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address, 8, 17);
+ i2cComms = new I2cCommunications(i2cBus, address, 8, 17);
Initialize();
}
void Initialize()
{
- i2cPeripheral.Write(0x21);
+ i2cComms.Write(0x21);
- i2cPeripheral.Write(0x81);
+ i2cComms.Write(0x81);
SetBrightness(Brightness.Maximum);
ClearDisplay();
@@ -53,7 +58,7 @@ public void SetIsAwake(bool awake)
{
byte value = (byte)((byte)Register.HT16K33_SS | (byte)(awake ? 1 : 0));
- i2cPeripheral.Write(value);
+ i2cComms.Write(value);
}
///
@@ -64,7 +69,7 @@ public void SetDisplayOn(bool isOn)
{
byte value = (byte)((byte)Register.HT16K33_DSP | (byte)(isOn ? 1 : 0));
- i2cPeripheral.Write(value);
+ i2cComms.Write(value);
}
///
@@ -75,7 +80,7 @@ public void SetBlinkRate(BlinkRate blinkRate)
{
byte value = (byte)((byte)Register.HT16K33_DSP | (byte)blinkRate);
- i2cPeripheral.Write(value);
+ i2cComms.Write(value);
}
///
@@ -86,7 +91,7 @@ public void SetBrightness(Brightness brightness)
{
byte value = (byte)((byte)Register.HT16K33_DIM | (byte)brightness);
- i2cPeripheral.Write(value);
+ i2cComms.Write(value);
}
///
@@ -105,7 +110,7 @@ public void ClearDisplay()
///
public void UpdateDisplay()
{
- i2cPeripheral.WriteRegister(0x0, displayBuffer.Span);
+ i2cComms.WriteRegister(0x0, displayBuffer.Span);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/ICs.IOExpanders.Ht16k33.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/ICs.IOExpanders.Ht16k33.csproj
index c8e2001837..74f67d5868 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/ICs.IOExpanders.Ht16k33.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Driver/ICs.IOExpanders.Ht16k33.csproj
@@ -17,6 +17,7 @@
-
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/Ht16k33_Character_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/Ht16k33_Character_Sample.csproj
new file mode 100644
index 0000000000..64c7e9b299
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/Ht16k33_Character_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..7f05e05f35
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/MeadowApp.cs
@@ -0,0 +1,53 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.ICs.IOExpanders;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ICs.IOExpanders.HT16K33_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ Ht16k33 ht16k33;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initialize...");
+ ht16k33 = new Ht16k33(Device.CreateI2cBus());
+
+ return base.Initialize();
+ }
+
+ public override async Task Run()
+ {
+ ht16k33.Set14SegmentDisplay('F', 0);
+ ht16k33.Set14SegmentDisplay('7', 1);
+ ht16k33.Set14SegmentDisplay('v', 2);
+ ht16k33.Set14SegmentDisplay('2', 3);
+
+ ht16k33.UpdateDisplay();
+ }
+
+ //
+
+ void LoopCharacters()
+ {
+ while (true)
+ {
+ for (int i = 32; i < 127; i++)
+ {
+ ht16k33.Set14SegmentDisplay((char)i, 0);
+ ht16k33.Set14SegmentDisplay((char)i, 1);
+ ht16k33.Set14SegmentDisplay((char)i, 2);
+ ht16k33.Set14SegmentDisplay((char)i, 3);
+
+ ht16k33.UpdateDisplay();
+
+ Thread.Sleep(250);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Character_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/Ht16k33_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/Ht16k33_Sample.csproj
index 98fa1ad197..64c7e9b299 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/Ht16k33_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/Ht16k33_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/MeadowApp.cs
index bfe3940610..b1637c23c3 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Ht16k33/Samples/Ht16k33_Sample/MeadowApp.cs
@@ -1,7 +1,6 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.ICs.IOExpanders;
-using System;
using System.Threading.Tasks;
namespace ICs.IOExpanders.HT16K33_Sample
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/ICs.IOExpanders.Is31fl3731.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/ICs.IOExpanders.Is31fl3731.csproj
index b0e4f86988..a62b6004e4 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/ICs.IOExpanders.Is31fl3731.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/ICs.IOExpanders.Is31fl3731.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.Enums.cs
index 9eb0011ac7..fb7d64b86d 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.Enums.cs
@@ -3,7 +3,7 @@
public partial class Is31fl3731
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.cs
index b4b98c0057..4414a9f443 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Driver/Is31fl3731.cs
@@ -9,26 +9,28 @@ namespace Meadow.Foundation.ICs.IOExpanders
/// The Is31fl3731 is a compact LED driver for 144 single LEDs
///
/// Based on https://github.com/adafruit/Adafruit_IS31FL3731
- public partial class Is31fl3731
+ public partial class Is31fl3731 : II2cPeripheral
{
const byte RegConfig = 0x00;
const byte RegConfigPictureMode = 0x00;
- //const byte RegConfigAutoPlayMode = 0x08;
- //const byte RegConfigAudioPlayMode = 0x18;
- //const byte ConfPictureMode = 0x00;
- //const byte ConfAutoFrameMode = 0x04;
- //const byte ConfAudioMode = 0x08;
const byte DisplayOptionRegister = 0x05;
const byte PictureFrameReg = 0x01;
const byte RegShutdown = 0x0A;
- //const byte RegAudioSync = 0x06;
const byte CommandRegister = 0xFD;
- const byte CommandFunctionReg = 0x0B; //'page nine'
+ const byte CommandFunctionReg = 0x0B;
- readonly II2cPeripheral i2cPeripheral;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
///
/// The current frame
@@ -42,7 +44,7 @@ public partial class Is31fl3731
/// The I2C address
public Is31fl3731(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- i2cPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
Frame = 0;
}
@@ -120,7 +122,7 @@ protected virtual void WriteRegister(byte frame, byte register, byte data)
{
SelectPage(frame);
- i2cPeripheral.WriteRegister(register, data);
+ i2cComms.WriteRegister(register, data);
}
///
@@ -173,7 +175,7 @@ public virtual void Clear(byte frame)
///
public virtual void ClearAllFrames()
{
- for(byte i = 0; i < 7; i++)
+ for (byte i = 0; i < 7; i++)
{
Clear(i);
}
@@ -268,7 +270,7 @@ public virtual void SetBlinkFunctionOnAllLeds(byte frame, bool on)
/// page/frame #
protected virtual void SelectPage(byte page)
{
- i2cPeripheral.WriteRegister(CommandRegister, page);
+ i2cComms.WriteRegister(CommandRegister, page);
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Samples/Is31fl3731_Sample/Is31fl3731_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Samples/Is31fl3731_Sample/Is31fl3731_Sample.csproj
index f95b958a0d..667efbf6b0 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Samples/Is31fl3731_Sample/Is31fl3731_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Is31fl3731/Samples/Is31fl3731_Sample/Is31fl3731_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.PinDefinitions.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.PinDefinitions.cs
index 5812cda889..8d26e13828 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.PinDefinitions.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.PinDefinitions.cs
@@ -11,6 +11,9 @@ public abstract partial class Mcp23x0x
///
public class PinDefinitions : IPinDefinitions
{
+ ///
+ /// The controller for the pins
+ ///
public IPinController Controller { get; set; }
///
@@ -19,7 +22,7 @@ public class PinDefinitions : IPinDefinitions
public IList AllPins { get; } = new List();
///
- /// GP0
+ /// Pin GP0
///
public IPin GP0 => new Pin(
Controller,
@@ -30,7 +33,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP1
+ /// Pin GP1
///
public IPin GP1 => new Pin(
Controller,
@@ -41,7 +44,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP2
+ /// Pin GP2
///
public IPin GP2 => new Pin(
Controller,
@@ -52,7 +55,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP3
+ /// Pin GP3
///
public IPin GP3 => new Pin(
Controller,
@@ -63,7 +66,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP4
+ /// Pin GP4
///
public IPin GP4 => new Pin(
Controller,
@@ -74,7 +77,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP5
+ /// Pin GP5
///
public IPin GP5 => new Pin(
Controller,
@@ -85,7 +88,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP6
+ /// Pin GP6
///
public IPin GP6 => new Pin(
Controller,
@@ -96,7 +99,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GP7
+ /// Pin GP7
///
public IPin GP7 => new Pin(
Controller,
@@ -111,7 +114,7 @@ public class PinDefinitions : IPinDefinitions
///
public PinDefinitions(Mcp23x0x controller)
{
- controller = controller;
+ Controller = controller;
InitAllPins();
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.cs
index be7e0c0ed3..e5c79903e1 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x0x.cs
@@ -49,7 +49,7 @@ protected Mcp23x0x(II2cBus i2cBus, byte address = 32, IDigitalInputPort interrup
/// optional interupt port, needed for input interrupts
/// Optional Meadow output port used to reset the mcp expander
protected Mcp23x0x(ISpiBus spiBus, IDigitalOutputPort chipSelectPort, IDigitalInputPort interruptPort = null, IDigitalOutputPort resetPort = null) :
- base(new SpiMcpDeviceComms(spiBus, chipSelectPort), interruptPort, resetPort) // use the internal constructor that takes an IMcpDeviceComms
+ base(spiBus, chipSelectPort, interruptPort, resetPort)
{
Pins = new PinDefinitions(this)
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x1x.PinDefinitions.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x1x.PinDefinitions.cs
index 8288113e33..95464f6d03 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x1x.PinDefinitions.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Drivers/Extras/Mcp23x1x.PinDefinitions.cs
@@ -11,6 +11,9 @@ public abstract partial class Mcp23x1x
///
public class PinDefinitions : IPinDefinitions
{
+ ///
+ /// The controller for the pins
+ ///
public IPinController Controller { get; set; }
///
@@ -19,7 +22,7 @@ public class PinDefinitions : IPinDefinitions
public IList AllPins { get; } = new List();
///
- /// GPA0
+ /// Pin GPA0
///
public IPin GPA0 => new Pin(
Controller,
@@ -30,7 +33,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA1
+ /// Pin GPA1
///
public IPin GPA1 => new Pin(
Controller,
@@ -41,7 +44,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA2
+ /// Pin GPA2
///
public IPin GPA2 => new Pin(
Controller,
@@ -52,7 +55,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA3
+ /// Pin GPA3
///
public IPin GPA3 => new Pin(
Controller,
@@ -63,7 +66,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA4
+ /// Pin GPA4
///
public IPin GPA4 => new Pin(
Controller,
@@ -74,7 +77,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA5
+ /// Pin GPA5
///
public IPin GPA5 => new Pin(
Controller,
@@ -85,7 +88,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA6
+ /// Pin GPA6
///
public IPin GPA6 => new Pin(
Controller,
@@ -96,7 +99,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPA7
+ /// Pin GPA7
///
public IPin GPA7 => new Pin(
Controller,
@@ -107,7 +110,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB0
+ /// Pin GPB0
///
public IPin GPB0 => new Pin(
Controller,
@@ -118,7 +121,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB1
+ /// Pin GPB1
///
public IPin GPB1 => new Pin(
Controller,
@@ -129,7 +132,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB2
+ /// Pin GPB2
///
public IPin GPB2 => new Pin(
Controller,
@@ -140,7 +143,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB3
+ /// Pin GPB3
///
public IPin GPB3 => new Pin(
Controller,
@@ -151,7 +154,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB4
+ /// Pin GPB4
///
public IPin GPB4 => new Pin(
Controller,
@@ -162,7 +165,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB5
+ /// Pin GPB5
///
public IPin GPB5 => new Pin(
Controller,
@@ -173,7 +176,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB6
+ /// Pin GPB6
///
public IPin GPB6 => new Pin(
Controller,
@@ -184,7 +187,7 @@ public class PinDefinitions : IPinDefinitions
);
///
- /// GPB7
+ /// Pin GPB7
///
public IPin GPB7 => new Pin(
Controller,
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/ICs.IOExpanders.Mcp23xxx.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/ICs.IOExpanders.Mcp23xxx.csproj
index 42ee840691..4e77ce41a1 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/ICs.IOExpanders.Mcp23xxx.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/ICs.IOExpanders.Mcp23xxx.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.Enums.cs
index 972ef67f6a..46ece3624d 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.Enums.cs
@@ -92,7 +92,7 @@ public enum PortBankType : byte
///
///
/// 16-bit controllers are logically separated into two 8-bit ports. 8-bit
- /// controllers only have one "port" of GPIO pins and ingore the bank setting
+ /// controllers only have one "port" of GPIO pins and ignore the bank setting
///
public enum PortBank
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.I2cMcpDeviceComms.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.I2cMcpDeviceComms.cs
deleted file mode 100644
index 8d3715adaf..0000000000
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.I2cMcpDeviceComms.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.ICs.IOExpanders
-{
- public partial class Mcp23xxx
- {
- internal class I2cMcpDeviceComms : I2cPeripheral, IMcpDeviceComms
- {
- public I2cMcpDeviceComms(II2cBus i2cBus, byte peripheralAddress)
- : base(i2cBus, peripheralAddress)
- {
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.IMcpDeviceComms.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.IMcpDeviceComms.cs
deleted file mode 100644
index e40b026ff6..0000000000
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.IMcpDeviceComms.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace Meadow.Foundation.ICs.IOExpanders
-{
- public partial class Mcp23xxx
- {
- internal interface IMcpDeviceComms
- {
- byte ReadRegister(byte address);
- void WriteRegister(byte address, byte value);
-
- void WriteRegister(byte address, Span writeBuffer, ByteOrder order = ByteOrder.LittleEndian);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.SpiMcpDeviceComms.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.SpiMcpDeviceComms.cs
deleted file mode 100644
index 22995c38ef..0000000000
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.SpiMcpDeviceComms.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.ICs.IOExpanders
-{
- public partial class Mcp23xxx
- {
- internal class SpiMcpDeviceComms : SpiPeripheral, IMcpDeviceComms
- {
- public SpiMcpDeviceComms(ISpiBus spiBus, IDigitalOutputPort chipSelectPort)
- : base(spiBus, chipSelectPort)
- {
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.cs
index b4e9d92bf5..3fe3365e07 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Driver/Mcp23xxx.cs
@@ -1,16 +1,16 @@
using Meadow.Hardware;
+using Meadow.Units;
using Meadow.Utilities;
using System;
using System.Collections.Generic;
using System.Threading;
-using static Meadow.Foundation.ICs.IOExpanders.Mcp23xxx;
namespace Meadow.Foundation.ICs.IOExpanders
{
///
/// Provide an interface to connect to a MCP2xxx port expander
///
- abstract partial class Mcp23xxx : IDigitalInputOutputController
+ abstract partial class Mcp23xxx : IDigitalInputOutputController, ISpiPeripheral, II2cPeripheral
{
///
/// Raised when the value of any pin configured for input interrupts changes
@@ -24,14 +24,45 @@ abstract partial class Mcp23xxx : IDigitalInputOutputController
///
public abstract int NumberOfPins { get; }
- private readonly IMcpDeviceComms mcpDevice;
- private readonly IDigitalInputPort interruptPort;
- private readonly IDigitalOutputPort resetPort;
- private readonly IDictionary inputPorts;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(375, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => (mcpDevice as ISpiCommunications).BusSpeed;
+ set => (mcpDevice as ISpiCommunications).BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => (mcpDevice as ISpiCommunications).BusMode;
+ set => (mcpDevice as ISpiCommunications).BusMode = value;
+ }
- // state
- byte ioDirA, ioDirB;
- byte olatA, olatB;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ private readonly IByteCommunications mcpDevice;
+ private IDigitalOutputPort resetPort;
+ private IDictionary inputPorts;
+
+ private byte ioDirA, ioDirB;
+ private byte olatA, olatB;
///
/// object for using lock() to do thread sync
@@ -46,9 +77,11 @@ abstract partial class Mcp23xxx : IDigitalInputOutputController
/// Optional interupt port, needed for input interrupts (pins 1-8)
/// Optional Meadow output port used to reset the mcp expander
protected Mcp23xxx(II2cBus i2cBus, byte address,
- IDigitalInputPort interruptPort = null, IDigitalOutputPort resetPort = null) :
- this(new I2cMcpDeviceComms(i2cBus, address), interruptPort, resetPort) // use the internal constructor that takes an IMcpDeviceComms
- { }
+ IDigitalInputPort interruptPort = null, IDigitalOutputPort resetPort = null)
+ {
+ mcpDevice = new I2cCommunications(i2cBus, address);
+ Initialize(interruptPort, resetPort);
+ }
///
/// Mcpxxx base class contructor
@@ -60,39 +93,74 @@ protected Mcp23xxx(II2cBus i2cBus, byte address,
protected Mcp23xxx(ISpiBus spiBus,
IDigitalOutputPort chipSelectPort,
IDigitalInputPort interruptPort = null,
- IDigitalOutputPort resetPort = null) :
- this(new SpiMcpDeviceComms(spiBus, chipSelectPort), interruptPort, resetPort) // use the internal constructor that takes an IMcpDeviceComms
- { }
+ IDigitalOutputPort resetPort = null)
+ {
+ mcpDevice = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
+ Initialize(interruptPort, resetPort);
+ }
///
- /// Mcp23xxx base class
+ /// Initializes the Mcp23xxx
///
- ///
/// optional interupt port, needed for input interrupts (pins 1-8)
/// Optional Meadow output port used to reset the mcp expander
- internal Mcp23xxx(IMcpDeviceComms device,
- IDigitalInputPort interruptPort = null,
- IDigitalOutputPort resetPort = null)
+ void Initialize(IDigitalInputPort interruptPort = null,
+ IDigitalOutputPort resetPort = null)
{
- if (resetPort != null)
- { //disable and enable the mcp before initializing
- this.resetPort = resetPort;
- ResetMcp();
- }
-
// TODO: more interrupt
// check the interrupt mode and make sure it's correct
// raise an exception if not. also, doc in constructor what we expect from an interrupt port
if (interruptPort != null)
{
- this.interruptPort = interruptPort;
interruptPort.Changed += InterruptPortChanged;
}
+ if (resetPort != null)
+ {
+ this.resetPort = resetPort;
+ ResetMcp();
+ }
+
inputPorts = new Dictionary();
- mcpDevice = device;
- Initialize();
+ mcpDevice.WriteRegister(MapRegister(Registers.IODIR_IODirection, PortBank.A), 0xFF);
+ mcpDevice.WriteRegister(MapRegister(Registers.GPIO, PortBank.A), 0x00);
+ mcpDevice.WriteRegister(MapRegister(Registers.IPOL_InputPolarity, PortBank.A), 0x00);
+ mcpDevice.WriteRegister(MapRegister(Registers.GPINTEN_InterruptOnChange), 0x00);
+
+ if (NumberOfPins == 16)
+ { //write the following registers as well (assume device is interleaving)
+ mcpDevice.WriteRegister(MapRegister(Registers.IODIR_IODirection, PortBank.B), 0xFF);
+ mcpDevice.WriteRegister(MapRegister(Registers.GPIO, PortBank.B), 0x00);
+ mcpDevice.WriteRegister(MapRegister(Registers.IPOL_InputPolarity, PortBank.B), 0x00);
+ mcpDevice.WriteRegister(MapRegister(Registers.GPINTEN_InterruptOnChange, PortBank.B), 0x00);
+ }
+
+ // save our state
+ ioDirA = ioDirB = 0xFF;
+ olatA = olatB = 0x00;
+
+ if (interruptPort != null)
+ {
+ bool intHigh = true;
+
+ if (interruptPort.Resistor == ResistorMode.InternalPullUp ||
+ interruptPort.Resistor == ResistorMode.ExternalPullUp)
+ {
+ intHigh = false;
+ }
+
+ byte iocon = 0x00;
+ iocon = BitHelpers.SetBit(iocon, 0x01, intHigh); //set interrupt pin to active high (true), low (false)
+ iocon = BitHelpers.SetBit(iocon, 0x02, false); //don't set interrupt to open drain (should be the default)
+
+ mcpDevice.WriteRegister(MapRegister(Registers.IOCON_IOConfiguration), iocon);
+
+ if (NumberOfPins == 16)
+ {
+ mcpDevice.WriteRegister(MapRegister(Registers.IOCON_IOConfiguration, PortBank.B), iocon);
+ }
+ }
}
///
@@ -138,51 +206,6 @@ private void InterruptPortChanged(object sender, DigitalPortResult e)
InputChanged?.Invoke(this, new IOExpanderInputChangedEventArgs(interruptFlag, (ushort)(currentStatesB << 8 | currentStates)));
}
- ///
- /// Initializes the Mcp23xxx
- ///
- protected virtual void Initialize()
- {
- mcpDevice.WriteRegister(MapRegister(Registers.IODIR_IODirection, PortBank.A), 0xFF);
- mcpDevice.WriteRegister(MapRegister(Registers.GPIO, PortBank.A), 0x00);
- mcpDevice.WriteRegister(MapRegister(Registers.IPOL_InputPolarity, PortBank.A), 0x00);
- mcpDevice.WriteRegister(MapRegister(Registers.GPINTEN_InterruptOnChange), 0x00);
-
- if (NumberOfPins == 16)
- { //write the following registers as well (assume device is interleaving)
- mcpDevice.WriteRegister(MapRegister(Registers.IODIR_IODirection, PortBank.B), 0xFF);
- mcpDevice.WriteRegister(MapRegister(Registers.GPIO, PortBank.B), 0x00);
- mcpDevice.WriteRegister(MapRegister(Registers.IPOL_InputPolarity, PortBank.B), 0x00);
- mcpDevice.WriteRegister(MapRegister(Registers.GPINTEN_InterruptOnChange, PortBank.B), 0x00);
- }
-
- // save our state
- ioDirA = ioDirB = 0xFF;
- olatA = olatB = 0x00;
-
- if (interruptPort != null)
- {
- bool intHigh = true;
-
- if (interruptPort.Resistor == ResistorMode.InternalPullUp ||
- interruptPort.Resistor == ResistorMode.ExternalPullUp)
- {
- intHigh = false;
- }
-
- byte iocon = 0x00;
- iocon = BitHelpers.SetBit(iocon, 0x01, intHigh); //set interrupt pin to active high (true), low (false)
- iocon = BitHelpers.SetBit(iocon, 0x02, false); //don't set interrupt to open drain (should be the default)
-
- mcpDevice.WriteRegister(MapRegister(Registers.IOCON_IOConfiguration), iocon);
-
- if (NumberOfPins == 16)
- {
- mcpDevice.WriteRegister(MapRegister(Registers.IOCON_IOConfiguration, PortBank.B), iocon);
- }
- }
- }
-
///
/// Checks if a pin exists on the Mcpxxxxx
///
@@ -290,7 +313,7 @@ public IDigitalInputPort CreateDigitalInputPort(
private void SetRegisterBit(byte register, int bit)
{
- if (bit >= 7 || bit < 0) { throw new ArgumentOutOfRangeException(); }
+ if (bit > 7 || bit < 0) { throw new ArgumentOutOfRangeException(); }
var value = mcpDevice.ReadRegister(register);
value |= (byte)(1 << bit);
@@ -299,7 +322,7 @@ private void SetRegisterBit(byte register, int bit)
private void ClearRegisterBit(byte register, int bit)
{
- if (bit >= 7 || bit < 0) { throw new ArgumentOutOfRangeException(); }
+ if (bit > 7 || bit < 0) { throw new ArgumentOutOfRangeException(); }
var value = mcpDevice.ReadRegister(register);
value &= (byte)~(1 << bit);
mcpDevice.WriteRegister(register, value);
@@ -538,7 +561,7 @@ byte MapRegister(byte address, PortBank port = PortBank.A, PortBankType bankStyl
PortBank GetPortBankForPin(IPin pin)
{ //hard coded ... verify in Mcp23x1x.PinDefinitions.cs
- if (pin.Name.StartsWith("GPB"))
+ if ((byte)pin.Key >= 8)
{
return PortBank.B;
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23008_Sample/Mcp23008_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23008_Sample/Mcp23008_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23008_Sample/Mcp23008_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23008_Sample/Mcp23008_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23009_Sample/Mcp23009_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23009_Sample/Mcp23009_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23009_Sample/Mcp23009_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23009_Sample/Mcp23009_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23017_Sample/Mcp23017_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23017_Sample/Mcp23017_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23017_Sample/Mcp23017_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23017_Sample/Mcp23017_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23018_Sample/Mcp23018_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23018_Sample/Mcp23018_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23018_Sample/Mcp23018_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23018_Sample/Mcp23018_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s08_Sample/Mcp23s08_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s08_Sample/Mcp23s08_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s08_Sample/Mcp23s08_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s08_Sample/Mcp23s08_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s09_Sample/Mcp23s09_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s09_Sample/Mcp23s09_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s09_Sample/Mcp23s09_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s09_Sample/Mcp23s09_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s17_Sample/Mcp23s17_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s17_Sample/Mcp23s17_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s17_Sample/Mcp23s17_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s17_Sample/Mcp23s17_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s18_Sample/Mcp23s18_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s18_Sample/Mcp23s18_Sample.csproj
index a2ab40e1d0..7124be98ad 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s18_Sample/Mcp23s18_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23s18_Sample/Mcp23s18_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/Mcp23x08_Input_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/Mcp23x08_Input_Sample.csproj
index 6c41472925..771d3570a2 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/Mcp23x08_Input_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/Mcp23x08_Input_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/MeadowApp.cs
index 844eeafbf5..db00ba212b 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x08_Input_Sample/MeadowApp.cs
@@ -20,7 +20,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
-
+
IDigitalInputPort interruptPort = Device.CreateDigitalInputPort(Device.Pins.D00, InterruptMode.EdgeBoth, ResistorMode.InternalPullDown);
IDigitalOutputPort resetPort = Device.CreateDigitalOutputPort(Device.Pins.D01);
@@ -28,10 +28,10 @@ public override Task Initialize()
return base.Initialize();
}
-
+
public override Task Run()
{
- // TestInterrupts();
+ // TestInterrupts();
return TestDigitalInputPorts(1000);
@@ -40,19 +40,19 @@ public override Task Run()
void TestBulkPinReads(int loopCount)
{
- for (int l = 0; l < loopCount; l++)
+ for (int l = 0; l < loopCount; l++)
{
byte mask = mcp.ReadFromPorts();
var bits = new BitArray(new byte[] { mask });
var bitsString = new StringBuilder();
-
- foreach (var bit in bits)
+
+ foreach (var bit in bits)
{
- bitsString.Append((bool)bit ? "1":"0");
+ bitsString.Append((bool)bit ? "1" : "0");
}
- Resolver.Log.Info($"Port Values, raw:{mask:X}, bits: { bitsString}");
+ Resolver.Log.Info($"Port Values, raw:{mask:X}, bits: {bitsString}");
Thread.Sleep(100);
}
@@ -69,7 +69,7 @@ async Task TestDigitalInputPorts(int loopCount)
var in06 = mcp.CreateDigitalInputPort(mcp.Pins.GP6, InterruptMode.EdgeFalling, ResistorMode.InternalPullUp);
var in07 = mcp.CreateDigitalInputPort(mcp.Pins.GP7, InterruptMode.EdgeFalling, ResistorMode.InternalPullUp);
- var inputPorts = new List()
+ var inputPorts = new List()
{
in00, in01, in02, in03, in04, in05, in06, in07
};
@@ -77,11 +77,11 @@ async Task TestDigitalInputPorts(int loopCount)
string output;
// read all the ports, sleep for 100ms and repeat a few times.
- for (int l = 0; l < loopCount; l++)
+ for (int l = 0; l < loopCount; l++)
{
output = string.Empty;
- foreach (var inputPort in inputPorts)
+ foreach (var inputPort in inputPorts)
{
//Resolver.Log.Info($"InputPort {inputPort.Pin.Name} Read: {inputPort.State}");
output += $"{(inputPort.State ? 1 : 0)}";
@@ -91,7 +91,7 @@ async Task TestDigitalInputPorts(int loopCount)
}
// cleanup
- for (int i = 0; i < inputPorts.Count; i++)
+ for (int i = 0; i < inputPorts.Count; i++)
{
inputPorts[i].Dispose();
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/Mcp23x17_Input_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/Mcp23x17_Input_Sample.csproj
index 6c41472925..771d3570a2 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/Mcp23x17_Input_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/Mcp23x17_Input_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/MeadowApp.cs
index 0946c28f13..4ee0acb267 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Mcp23xxx/Samples/Mcp23x17_Input_Sample/MeadowApp.cs
@@ -39,26 +39,26 @@ public override Task Run()
{
TestInterrupts();
- // return TestDigitalInputPorts(1000);
+ // return TestDigitalInputPorts(1000);
return base.Run();
}
void TestBulkPinReads(int loopCount)
{
- for (int l = 0; l < loopCount; l++)
+ for (int l = 0; l < loopCount; l++)
{
byte mask = mcp.ReadFromPorts();
var bits = new BitArray(new byte[] { mask });
var bitsString = new StringBuilder();
-
- foreach (var bit in bits)
+
+ foreach (var bit in bits)
{
- bitsString.Append((bool)bit ? "1":"0");
+ bitsString.Append((bool)bit ? "1" : "0");
}
- Resolver.Log.Info($"Port Values, raw:{mask:X}, bits: { bitsString}");
+ Resolver.Log.Info($"Port Values, raw:{mask:X}, bits: {bitsString}");
Thread.Sleep(100);
}
@@ -84,20 +84,20 @@ async Task TestDigitalInputPorts(int loopCount)
var in14 = mcp.CreateDigitalInputPort(mcp.Pins.GPB6, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
var in15 = mcp.CreateDigitalInputPort(mcp.Pins.GPB7, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
- var inputPorts = new List()
+ var inputPorts = new List()
{
- in00, in01, in02, in03, in04, in05, in06, in07,
+ in00, in01, in02, in03, in04, in05, in06, in07,
in08, in09, in10, in11, in12, in13, in14, in15,
};
string output;
// read all the ports, sleep for 100ms and repeat a few times.
- for (int l = 0; l < loopCount; l++)
+ for (int l = 0; l < loopCount; l++)
{
output = string.Empty;
- foreach (var inputPort in inputPorts)
+ foreach (var inputPort in inputPorts)
{
//Resolver.Log.Info($"InputPort {inputPort.Pin.Name} Read: {inputPort.State}");
output += $"{(inputPort.State ? 1 : 0)}";
@@ -107,7 +107,7 @@ async Task TestDigitalInputPorts(int loopCount)
}
// cleanup
- for (int i = 0; i < inputPorts.Count; i++)
+ for (int i = 0; i < inputPorts.Count; i++)
{
inputPorts[i].Dispose();
}
@@ -127,7 +127,7 @@ void TestInterrupts()
var inputPort05 = mcp.CreateDigitalInputPort(mcp.Pins.GPA5, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
var inputPort06 = mcp.CreateDigitalInputPort(mcp.Pins.GPA6, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
var inputPort07 = mcp.CreateDigitalInputPort(mcp.Pins.GPA7, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
-
+
var inputPort08 = mcp.CreateDigitalInputPort(mcp.Pins.GPB0, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
var inputPort09 = mcp.CreateDigitalInputPort(mcp.Pins.GPB1, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
var inputPort10 = mcp.CreateDigitalInputPort(mcp.Pins.GPB2, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp, debounceTime);
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/ICs.IOExpanders.Pca9685.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/ICs.IOExpanders.Pca9685.csproj
index b00455f5d5..2b38a713ff 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/ICs.IOExpanders.Pca9685.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/ICs.IOExpanders.Pca9685.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.Enums.cs
index 93911d8870..4d14780ab3 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.Enums.cs
@@ -3,7 +3,7 @@
public partial class Pca9685
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.cs
index 1bdf16ae49..91a1dd51d3 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Driver/Pca9685.cs
@@ -9,12 +9,20 @@ namespace Meadow.Foundation.ICs.IOExpanders
/// Represents PCA9685 IC
///
/// All PWM channels run at the same Frequency
- public partial class Pca9685
+ public partial class Pca9685 : II2cPeripheral
{
- private readonly II2cPeripheral i2cPeripheral;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
+
private readonly Frequency frequency;
- //# Registers/etc.
const byte Mode1 = 0x00;
const byte Mode2 = 0x01;
const byte SubAdr1 = 0x02;
@@ -55,7 +63,7 @@ public Pca9685(II2cBus i2cBus, Frequency frequency, byte address = (byte)Address
{
i2CBus = i2cBus;
this.address = address;
- i2cPeripheral = new I2cPeripheral(i2CBus, address);
+ i2cComms = new I2cCommunications(i2CBus, address);
this.frequency = frequency;
}
@@ -160,7 +168,7 @@ void Write(byte register, byte ledXOnL, byte ledXOnH, byte ledXOffL, byte ledXOf
void Write(byte register, byte value)
{
- i2cPeripheral.WriteRegister(register, value);
+ i2cComms.WriteRegister(register, value);
}
void SetFrequency(Frequency frequency)
@@ -171,7 +179,7 @@ void SetFrequency(Frequency frequency)
prescaleval -= 1.0;
double prescale = Math.Floor(prescaleval + 0.5);
- byte oldmode = i2cPeripheral.ReadRegister(Mode1);
+ byte oldmode = i2cComms.ReadRegister(Mode1);
byte newmode = (byte)((oldmode & 0x7F) | 0x10); // # sleep
Write(Mode1, newmode);// # go to sleep
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/MeadowApp.cs
index 38500ce0f9..99d4de22d0 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.ICs.IOExpanders;
using Meadow.Hardware;
-using System;
using System.Threading.Tasks;
namespace ICs.IOExpanders.Pca9685_Sample
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/Pca9685_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/Pca9685_Sample.csproj
index 40e6a94252..222f95eb3a 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/Pca9685_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.Pca9685/Samples/Pca9685_Sample/Pca9685_Sample.csproj
@@ -10,7 +10,7 @@
ICs.IOExpanders
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/Drivers/Sw18AB.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/Drivers/Sw18AB.cs
index a25be8f709..fe49cf9453 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/Drivers/Sw18AB.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/Drivers/Sw18AB.cs
@@ -14,7 +14,7 @@ public class Sw18AB : SerialWombatBase
/// The I2C bus connected to the wombat
/// The I2C address
/// Meadow logger (optional)
- public Sw18AB(II2cBus i2cBus, Address address = SerialWombatBase.Address.Default, Logger? logger = null)
+ public Sw18AB(II2cBus i2cBus, Addresses address = SerialWombatBase.Addresses.Default, Logger? logger = null)
: base(i2cBus, address, logger)
{ }
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/ICs.IOExpanders.SerialWombat.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/ICs.IOExpanders.SerialWombat.csproj
index 4e3f5589cb..48d8891285 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/ICs.IOExpanders.SerialWombat.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/ICs.IOExpanders.SerialWombat.csproj
@@ -18,8 +18,8 @@
-
-
-
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.Enums.cs
index e47849fa27..451357bbed 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.Enums.cs
@@ -6,9 +6,9 @@
public partial class SerialWombatBase
{
///
- /// Valid addresses for the Chip.
+ /// Valid I2C addresses for the device
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x6a
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.cs
index 5da3fcac57..30e3269545 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Driver/SerialWombatBase.cs
@@ -9,17 +9,23 @@
namespace Meadow.Foundation.ICs.IOExpanders
{
- public abstract partial class SerialWombatBase : IDigitalInputOutputController, IPwmOutputController, IAnalogInputController
+ public abstract partial class SerialWombatBase : IDigitalInputOutputController, IPwmOutputController,
+ IAnalogInputController, II2cPeripheral
{
- private II2cBus _bus; // TODO: add uart support
- private WombatVersion _version = null!;
- private WombatInfo? _info;
- private Guid? _uuid;
+ private readonly II2cBus i2cBus;
+ private WombatVersion version = null!;
+ private WombatInfo? wombatInfo;
+ private Guid? uuid;
///
- /// The I2C address
+ /// The default I2C address for the peripheral
///
- public Address _address { get; }
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// The current I2C address for the peripheral
+ ///
+ public Addresses I2cAddress { get; }
///
/// The sync root object
@@ -34,11 +40,10 @@ public abstract partial class SerialWombatBase : IDigitalInputOutputController,
///
/// Create SerialWombatBase object
///
- protected SerialWombatBase(II2cBus bus, Address address = SerialWombatBase.Address.Default, Logger? logger = null)
+ protected SerialWombatBase(II2cBus bus, Addresses address = Addresses.Default, Logger? logger = null)
{
Pins = new PinDefinitions(this);
- _bus = bus;
- _address = address;
+ i2cBus = bus;
Logger = logger;
}
@@ -52,7 +57,7 @@ protected SerialWombatBase(II2cBus bus, Address address = SerialWombatBase.Addre
///
protected void SendPacket(Span tx, Span rx)
{
- _bus.Exchange((byte)_address, tx, rx);
+ i2cBus.Exchange((byte)I2cAddress, tx, rx);
}
///
@@ -62,12 +67,12 @@ public WombatVersion Version
{
get
{
- if (_version == null) // lazy load
+ if (version == null) // lazy load
{
try
{
var response = SendCommand(Commands.GetVersion);
- _version = new WombatVersion(Encoding.ASCII.GetString(response));
+ version = new WombatVersion(Encoding.ASCII.GetString(response));
}
catch (Exception ex)
{
@@ -75,7 +80,7 @@ public WombatVersion Version
}
}
- return _version ?? new WombatVersion("0");
+ return version ?? new WombatVersion("0");
}
}
@@ -86,13 +91,13 @@ public WombatInfo Info
{
get
{
- if (_info == null) // lazy load
+ if (wombatInfo == null) // lazy load
{
try
{
var id = (ushort)ReadFlash(FlashRegister18.DeviceID);
var rev = (ushort)(ReadFlash(FlashRegister18.DeviceRevision) & 0xf);
- _info = new WombatInfo(id, rev);
+ wombatInfo = new WombatInfo(id, rev);
}
catch (Exception ex)
{
@@ -100,7 +105,7 @@ public WombatInfo Info
}
}
- return _info ?? new WombatInfo(0, 0);
+ return wombatInfo ?? new WombatInfo(0, 0);
}
}
@@ -111,7 +116,7 @@ public Guid Uuid
{
get
{
- if (_uuid == null) // lazy load
+ if (uuid == null) // lazy load
{
var address = FlashRegister18.DeviceUuid;
@@ -126,10 +131,10 @@ public Guid Uuid
bytes[index++] = (byte)(data & 0xff >> 16);
}
- _uuid = new Guid(bytes);
+ uuid = new Guid(bytes);
}
- return _uuid.Value;
+ return uuid.Value;
}
}
@@ -141,7 +146,7 @@ protected byte[] SendCommand(in Span command)
lock (SyncRoot)
{
var rx = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- _bus.Exchange((byte)_address, command, rx);
+ i2cBus.Exchange((byte)I2cAddress, command, rx);
Logger?.Trace($"SW: TX {BitConverter.ToString(command.ToArray())}");
Logger?.Trace($"SW: RX {BitConverter.ToString(rx)}");
@@ -447,7 +452,7 @@ public IPwmPort CreatePwmPort(IPin pin, Frequency frequency, float dutyCycle = 0
{
var channel = pin.SupportedChannels.OfType().FirstOrDefault();
- if (channel == null) throw new NotSupportedException($"Pin {pin.Name} Does not support PWM");
+ if (channel == null) { throw new NotSupportedException($"Pin {pin.Name} Does not support PWM"); }
return new PwmPort(this, pin, channel);
}
@@ -457,7 +462,7 @@ public IPwmPort CreatePwmPort(IPin pin, Frequency frequency, float dutyCycle = 0
///
public IAnalogInputPort CreateAnalogInputPort(IPin pin, int sampleCount = 64)
{
- return CreateAnalogInputPort((IPin)pin, sampleCount, TimeSpan.FromSeconds(1), new Voltage(0));
+ return CreateAnalogInputPort(pin, sampleCount, TimeSpan.FromSeconds(1), new Voltage(0));
}
///
@@ -467,7 +472,7 @@ public IAnalogInputPort CreateAnalogInputPort(IPin pin, int sampleCount, TimeSpa
{
var channel = pin.SupportedChannels.OfType().FirstOrDefault();
- if (channel == null) throw new NotSupportedException($"Pin {pin.Name} Does not support ADC");
+ if (channel == null) { throw new NotSupportedException($"Pin {pin.Name} Does not support ADC"); }
return new AnalogInputPort(this, pin, channel, sampleCount);
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_ADC_Sample/Sw18AB_ADC_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_ADC_Sample/Sw18AB_ADC_Sample.csproj
index 915b63566c..ecac6aa1f4 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_ADC_Sample/Sw18AB_ADC_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_ADC_Sample/Sw18AB_ADC_Sample.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Core_Sample/Sw18AB_Core_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Core_Sample/Sw18AB_Core_Sample.csproj
index ed7da98a43..859e298e47 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Core_Sample/Sw18AB_Core_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Core_Sample/Sw18AB_Core_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_PWM_Sample/Sw18AB_PWM_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_PWM_Sample/Sw18AB_PWM_Sample.csproj
index ed7da98a43..859e298e47 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_PWM_Sample/Sw18AB_PWM_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_PWM_Sample/Sw18AB_PWM_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Sample/Sw18AB_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Sample/Sw18AB_Sample.csproj
index ed7da98a43..859e298e47 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Sample/Sw18AB_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Sample/Sw18AB_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Ultrasonic_Sample/Sw18AB_Ultrasonic_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Ultrasonic_Sample/Sw18AB_Ultrasonic_Sample.csproj
index 915b63566c..ecac6aa1f4 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Ultrasonic_Sample/Sw18AB_Ultrasonic_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.SerialWombat/Samples/Sw18AB_Ultrasonic_Sample/Sw18AB_Ultrasonic_Sample.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/ICs.IOExpanders.Tca9548a.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/ICs.IOExpanders.Tca9548a.csproj
index 6b7b424a49..b4e0ed65f8 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/ICs.IOExpanders.Tca9548a.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/ICs.IOExpanders.Tca9548a.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.Addresses.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.Addresses.cs
index a76df3502e..cb0512005f 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.Addresses.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.Addresses.cs
@@ -3,7 +3,7 @@
public partial class Tca9548a
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.cs
index 91c64f1d0e..446420f620 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Driver/Tca9548A.cs
@@ -10,7 +10,7 @@ namespace Meadow.Foundation.ICs.IOExpanders
///
/// A TCA9548A i2c multiplexer
///
- public partial class Tca9548a : II2cPeripheral
+ public partial class Tca9548a : II2cCommunications
{
internal SemaphoreSlim BusSelectorSemaphore = new SemaphoreSlim(1, 1);
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Samples/Tca9548a_Sample/Tca9548a_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Samples/Tca9548a_Sample/Tca9548a_Sample.csproj
index 544a40a07f..2bd2057f64 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Samples/Tca9548a_Sample/Tca9548a_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.TCA9548A/Samples/Tca9548a_Sample/Tca9548a_Sample.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/ICs.IOExpanders.x74595.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/ICs.IOExpanders.x74595.csproj
index d5bae06a84..1624a49a57 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/ICs.IOExpanders.x74595.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/ICs.IOExpanders.x74595.csproj
@@ -13,10 +13,10 @@
Meadow.Foundation, IOExpanders, x74595
0.1.52
true
- x74595 I2C shift register digital output expander
+ x74595 SPI shift register digital output expander
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.Enums.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.Enums.cs
deleted file mode 100644
index 957a8ac305..0000000000
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.Enums.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Meadow.Foundation.ICs.IOExpanders
-{
- public partial class x74595
- {
-
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.PinDefinitions.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.PinDefinitions.cs
index a9eb18b06f..f074d4e064 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.PinDefinitions.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.PinDefinitions.cs
@@ -11,6 +11,9 @@ public partial class x74595
///
public class PinDefinitions : IPinDefinitions
{
+ ///
+ /// The controller for the pin definitions
+ ///
public IPinController Controller { get; set; }
///
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.cs b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.cs
index 3fd9d39d0f..b7c9f76aca 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Driver/x74595.cs
@@ -1,4 +1,5 @@
using Meadow.Hardware;
+using Meadow.Units;
using Meadow.Utilities;
using System;
using System.Linq;
@@ -6,13 +7,13 @@
namespace Meadow.Foundation.ICs.IOExpanders
{
///
- /// Provide an interface to connect to a 74595 shift register.
+ /// Provide an interface to connect to a 74595 shift register
///
///
/// Control the outputs from a 74595 shift register (or a chain of shift registers)
- /// using a SPI interface.
+ /// using a SPI interface
///
- public partial class x74595 : IDigitalOutputController
+ public partial class x74595 : IDigitalOutputController, ISpiPeripheral
{
///
/// The pin definitions
@@ -20,22 +21,50 @@ public partial class x74595 : IDigitalOutputController
public PinDefinitions Pins { get; }
///
- /// Number of chips required to implement this ShiftRegister.
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(10000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// Number of chips required to implement this ShiftRegister
///
private readonly int numberOfChips;
private byte[] latchData;
///
- /// SPI interface used to communicate with the shift registers.
+ /// SPI Communication bus used to communicate with the peripheral
///
- private readonly ISpiPeripheral spiPeripheral;
+ protected ISpiCommunications spiComms;
///
/// Default constructor.
///
///
- /// This is private to prevent the programmer from calling it explicitly.
+ /// This is private to prevent the programmer from calling it explicitly
///
private x74595()
{
@@ -51,14 +80,13 @@ public x74595(ISpiBus spiBus, IPin pinChipSelect, int pins = 8)
{
Pins = new PinDefinitions(this);
- // if ((pins > 0) && ((pins % 8) == 0))
if (pins == 8)
{
numberOfChips = pins / 8;
latchData = new byte[numberOfChips];
- spiPeripheral = new SpiPeripheral(spiBus, pinChipSelect?.CreateDigitalOutputPort());
+ spiComms = new SpiCommunications(spiBus, pinChipSelect?.CreateDigitalOutputPort(), DefaultSpiBusSpeed, DefaultSpiBusMode);
}
else
{
@@ -95,7 +123,7 @@ public void Clear(bool update = true)
if (update)
{
- spiPeripheral.Write(latchData);
+ spiComms.Write(latchData);
}
}
@@ -115,7 +143,7 @@ public void WriteToPin(IPin pin, bool value)
{
throw new Exception("Pin is out of range");
}
- spiPeripheral.Write(latchData);
+ spiComms.Write(latchData);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Samples/x74595_Sample/x74595_Sample.csproj b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Samples/x74595_Sample/x74595_Sample.csproj
index 6c6988c7c7..7853e8be9c 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Samples/x74595_Sample/x74595_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/ICs.IOExpanders.x74595/Samples/x74595_Sample/x74595_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.Enums.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.Enums.cs
index c1e4ceadd7..f7d595d8d5 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.Enums.cs
@@ -33,4 +33,4 @@ public enum PixelOrder
BGR
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.cs
index aec36a96cb..5a67cf5016 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Apa102.cs
@@ -5,20 +5,42 @@
namespace Meadow.Foundation.Leds
{
///
- /// Represents APA102/Dotstar Led(s).
+ /// Represents APA102/Dotstar Led(s)
///
- /// Based on logic from https://github.com/adafruit/Adafruit_CircuitPython_DotStar/blob/master/adafruit_dotstar.py
- public partial class Apa102 : IApa102
+ public partial class Apa102 : IApa102, ISpiPeripheral
{
///
- /// Default SPI bus speed
+ /// The default SPI bus speed for the device
///
- public static Frequency DefaultSpiBusSpeed = new Frequency(6000, Frequency.UnitType.Kilohertz);
+ public Frequency DefaultSpiBusSpeed => new Frequency(6000, Frequency.UnitType.Kilohertz);
///
- /// SpiPeripheral object
+ /// The SPI bus speed for the device
///
- protected ISpiPeripheral spiPeripheral;
+ public Frequency SpiBusSpeed
+ {
+ get => spiComms.BusSpeed;
+ set => spiComms.BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => spiComms.BusMode;
+ set => spiComms.BusMode = value;
+ }
+
+ ///
+ /// SPI Communication bus used to communicate with the peripheral
+ ///
+ protected ISpiCommunications spiComms;
const short StartHeaderSize = 4;
const byte LedStart = 0b11100000;
@@ -73,7 +95,7 @@ public Apa102(ISpiBus spiBus, IPin chipSelectPin, int numberOfLeds, PixelOrder p
/// SPI chip select port (optional)
public Apa102(ISpiBus spiBus, int numberOfLeds, PixelOrder pixelOrder = PixelOrder.BGR, IDigitalOutputPort chipSelectPort = null)
{
- spiPeripheral = new SpiPeripheral(spiBus, chipSelectPort);
+ spiComms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
this.numberOfLeds = numberOfLeds;
endHeaderSize = this.numberOfLeds / 16;
Brightness = 1.0f;
@@ -206,7 +228,7 @@ public void Clear(bool update = false)
///
public void Show()
{
- spiPeripheral.Write(buffer);
+ spiComms.Write(buffer);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Leds.Apa102.csproj b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Leds.Apa102.csproj
index 2db2652af1..ef20ea02d0 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Leds.Apa102.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/Leds.Apa102.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.Enums.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.Enums.cs
index 331f90738b..d64f842745 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.Enums.cs
@@ -3,7 +3,7 @@
public partial class SparkFunQwiicLEDStick
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.cs
index d454710aa1..a805fe621b 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Driver/SparkFunQwiicLEDStick.cs
@@ -6,7 +6,7 @@ namespace Meadow.Foundation.Leds
///
/// Represents a SparkFunQwiicLEDStick that uses APA102 leds
///
- public partial class SparkFunQwiicLEDStick : I2cPeripheral, IApa102
+ public partial class SparkFunQwiicLEDStick : I2cCommunications, IApa102
{
///
/// Enable or disable autowrite to update the LEDs as they're set
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/Apa102_Display_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/Apa102_Display_Sample.csproj
index 711507f815..f0ec3ac486 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/Apa102_Display_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/Apa102_Display_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/MeadowApp.cs
index fa94a611da..aeb01d8647 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Display_Sample/MeadowApp.cs
@@ -3,8 +3,6 @@
using Meadow.Foundation;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Leds;
-using System;
-using System.Threading;
using System.Threading.Tasks;
namespace Leds.Apa102_Display_Sample
@@ -19,7 +17,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initialize...");
- display = new Apa102(Device.CreateSpiBus(Apa102.DefaultSpiBusSpeed), 32, 8, Apa102.PixelOrder.BGR);
+ display = new Apa102(Device.CreateSpiBus(), 32, 8, Apa102.PixelOrder.BGR);
canvas = new MicroGraphics(display);
Resolver.Log.Info("Hardware intitialized.");
@@ -50,22 +48,28 @@ public override async Task Run()
static class Colors
{
- public static Color AzureBlue {
- get {
+ public static Color AzureBlue
+ {
+ get
+ {
var azureBlue = Color.FromHex("#23abe3");
// make it way less bright
return Color.FromHsba(azureBlue.Hue, azureBlue.Saturation, 0.025);
}
}
- public static Color ChileanFire {
- get {
+ public static Color ChileanFire
+ {
+ get
+ {
var chileanFire = Color.FromHex("#ef7d3b");
// make it way less bright
return Color.FromHsba(chileanFire.Hue, chileanFire.Saturation, 0.025);
}
}
- public static Color PearGreen {
- get {
+ public static Color PearGreen
+ {
+ get
+ {
var PearGreen = Color.FromHex("#c9db31");
// make it way less bright
return Color.FromHsba(PearGreen.Hue, PearGreen.Saturation, 0.025);
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/Apa102_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/Apa102_Sample.csproj
index c1ec7ea573..93a26db4d2 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/Apa102_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/Apa102_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/MeadowApp.cs
index 29f31bcbdf..f98bf474c8 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Apa102/Samples/Apa102_Sample/MeadowApp.cs
@@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation;
using Meadow.Foundation.Leds;
-using System;
using System.Threading;
using System.Threading.Tasks;
@@ -19,7 +18,7 @@ public class MeadowApp : App
public override Task Initialize()
{
Resolver.Log.Info("Initialize...");
- apa102 = new Apa102(Device.CreateSpiBus(Apa102.DefaultSpiBusSpeed), numberOfLeds, Apa102.PixelOrder.BGR);
+ apa102 = new Apa102(Device.CreateSpiBus(), numberOfLeds, Apa102.PixelOrder.BGR);
return base.Initialize();
}
@@ -65,7 +64,7 @@ void SetColor(Color color, float brightness)
{
Resolver.Log.Info($"SetColor(color:{color}");
- for (int i = 0; i < apa102.NumberOfLeds; i++)
+ for (int i = 0; i < apa102.NumberOfLeds; i++)
{
apa102.SetLed(i, color, brightness);
}
@@ -133,13 +132,13 @@ void WalkTheStrip(Color color, int numberOfTraverses)
apa102.SetLed(index, color);
last = index;
- if(forward) { index++; }
+ if (forward) { index++; }
else { index--; }
apa102.Show();
- if(index == apa102.NumberOfLeds - 1) { forward = false; }
- if(index == 0) { forward = true; }
+ if (index == apa102.NumberOfLeds - 1) { forward = false; }
+ if (index == 0) { forward = true; }
Thread.Sleep(50);
}
@@ -157,13 +156,13 @@ void Start()
apa102.SetLed(2, Color.Blue);
apa102.Show();
Thread.Sleep(2000);
-
+
apa102.SetLed(0, Color.Green);
apa102.SetLed(1, Color.Yellow);
apa102.SetLed(2, Color.Pink);
apa102.Show();
Thread.Sleep(5000);
-
+
apa102.Clear(true);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Leds.Pca9633.csproj b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Leds.Pca9633.csproj
index e2b70e8581..f4d6acce70 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Leds.Pca9633.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Leds.Pca9633.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.Enums.cs b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.Enums.cs
index a027732ae4..2a0fb8a64a 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.Enums.cs
@@ -3,7 +3,7 @@
public partial class Pca9633
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.cs b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.cs
index 077537a5ba..e421033edc 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.cs
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Driver/Pca9633.cs
@@ -5,12 +5,17 @@ namespace Meadow.Foundation.Leds
///
/// Represents a Pca9633 led driver
///
- public partial class Pca9633
+ public partial class Pca9633 : II2cPeripheral
{
///
- /// Pca9633 i2c peripheral object
+ /// The default I2C address for the peripheral
///
- readonly II2cPeripheral i2CPeripheral;
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
///
/// Red LED location - used for RGB control
@@ -31,7 +36,7 @@ public partial class Pca9633
public bool IsOn
{
get => isOn;
- set => i2CPeripheral.WriteRegister((byte)Registers.LEDOUT, (byte)(value == true?1:0));
+ set => i2cComms.WriteRegister((byte)Registers.LEDOUT, (byte)(value == true ? 1 : 0));
}
bool isOn = true;
@@ -40,7 +45,7 @@ public bool IsOn
///
/// i2c bus
/// i2c address
- public Pca9633(II2cBus i2cBus, Addresses address)
+ public Pca9633(II2cBus i2cBus, Addresses address = Addresses.Default)
: this(i2cBus, (byte)address)
{
}
@@ -50,9 +55,9 @@ public Pca9633(II2cBus i2cBus, Addresses address)
///
/// i2c bus
/// i2c address
- public Pca9633(II2cBus i2cBus, byte address = (byte)Addresses.Default)
+ public Pca9633(II2cBus i2cBus, byte address)
{
- i2CPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
Initialize();
}
@@ -60,10 +65,10 @@ public Pca9633(II2cBus i2cBus, byte address = (byte)Addresses.Default)
void Initialize()
{
// backlight init
- i2CPeripheral.WriteRegister((byte)Registers.MODE1, 0);
+ i2cComms.WriteRegister((byte)Registers.MODE1, 0);
// set LEDs controllable by both PWM and GRPPWM registers
- i2CPeripheral.WriteRegister(8, 0xFF);
- i2CPeripheral.WriteRegister((byte)Registers.MODE2, 20);
+ i2cComms.WriteRegister(8, 0xFF);
+ i2cComms.WriteRegister((byte)Registers.MODE2, 20);
}
///
@@ -71,19 +76,19 @@ void Initialize()
///
public void Wake()
{
- var value = i2CPeripheral.ReadRegister((byte)Registers.MODE1);
+ var value = i2cComms.ReadRegister((byte)Registers.MODE1);
value = (byte)(value & ~(1 << BIT_SLEEP));
- i2CPeripheral.WriteRegister((byte)Registers.MODE1, value);
+ i2cComms.WriteRegister((byte)Registers.MODE1, value);
}
-
+
///
/// Put device into sleep state
///
public void Sleep()
{
- var value = i2CPeripheral.ReadRegister((byte)Registers.MODE1);
+ var value = i2cComms.ReadRegister((byte)Registers.MODE1);
value = (byte)(value | (1 << BIT_SLEEP));
- i2CPeripheral.WriteRegister((byte)Registers.MODE1, value);
+ i2cComms.WriteRegister((byte)Registers.MODE1, value);
}
///
@@ -107,15 +112,15 @@ public void SetColor(Color color)
{
if (LedRed != LedPosition.Undefined)
{
- i2CPeripheral.WriteRegister((byte)LedRed, (byte)(255 - color.R));
+ i2cComms.WriteRegister((byte)LedRed, (byte)(255 - color.R));
}
if (LedGreen != LedPosition.Undefined)
{
- i2CPeripheral.WriteRegister((byte)LedGreen, (byte)(255 - color.G));
+ i2cComms.WriteRegister((byte)LedGreen, (byte)(255 - color.G));
}
if (LedBlue != LedPosition.Undefined)
{
- i2CPeripheral.WriteRegister((byte)LedBlue, (byte)(255 - color.B));
+ i2cComms.WriteRegister((byte)LedBlue, (byte)(255 - color.B));
}
}
@@ -126,7 +131,7 @@ public void SetColor(Color color)
/// brightness (0-255)
public void SetLedBrightness(LedPosition led, byte brightness)
{
- i2CPeripheral.WriteRegister((byte)led, (byte)(255 - brightness));
+ i2cComms.WriteRegister((byte)led, (byte)(255 - brightness));
}
///
@@ -135,7 +140,7 @@ public void SetLedBrightness(LedPosition led, byte brightness)
/// brightness (0-255)
public void SetGroupBrightess(byte brightness)
{
- i2CPeripheral.WriteRegister((byte)Registers.GRPPWM, (byte)(255 - brightness));
+ i2cComms.WriteRegister((byte)Registers.GRPPWM, (byte)(255 - brightness));
}
///
@@ -145,10 +150,10 @@ public void SetGroupBrightess(byte brightness)
///
public void SetDriveMode(DriveType drive)
{
- var value = i2CPeripheral.ReadRegister((byte)Registers.MODE2);
+ var value = i2cComms.ReadRegister((byte)Registers.MODE2);
value = (byte)(value & ~(1 << BIT_OUTDRV));
value |= (byte)((byte)drive << BIT_OUTDRV);
- i2CPeripheral.WriteRegister((byte)Registers.MODE2, value);
+ i2cComms.WriteRegister((byte)Registers.MODE2, value);
}
///
@@ -165,7 +170,7 @@ public void SetAutoIncrementMode(AutoIncrement mode)
AutoIncrement.IndividualAndGlobalRegisters => 1 << 7 | 1 << 6 | 1 << 5,
_ => 0,
};
- i2CPeripheral.WriteRegister((byte)Registers.MODE1, (byte)value);
+ i2cComms.WriteRegister((byte)Registers.MODE1, (byte)value);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Samples/Pca9633_Sample/Pca9633_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Samples/Pca9633_Sample/Pca9633_Sample.csproj
index a709d767fc..8ff278dd6e 100644
--- a/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Samples/Pca9633_Sample/Pca9633_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Leds.Pca9633/Samples/Pca9633_Sample/Pca9633_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Driver/Motors.ElectronicSpeedController.csproj b/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Driver/Motors.ElectronicSpeedController.csproj
index 846b30dbf2..a2b24edada 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Driver/Motors.ElectronicSpeedController.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Driver/Motors.ElectronicSpeedController.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Samples/ElectronicSpeedController_Sample/ElectronicSpeedController_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Samples/ElectronicSpeedController_Sample/ElectronicSpeedController_Sample.csproj
index 94450ae30e..a2b1a31d42 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Samples/ElectronicSpeedController_Sample/ElectronicSpeedController_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.ElectronicSpeedController/Samples/ElectronicSpeedController_Sample/ElectronicSpeedController_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Driver/Motors.Stepper.A4988.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Driver/Motors.Stepper.A4988.csproj
index 5d021738c9..3129cb4391 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Driver/Motors.Stepper.A4988.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Driver/Motors.Stepper.A4988.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Samples/A4988_Sample/A4988_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Samples/A4988_Sample/A4988_Sample.csproj
index e465643087..af1a3ec6b0 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Samples/A4988_Sample/A4988_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.A4988/Samples/A4988_Sample/A4988_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Driver/Motors.Stepper.Uln2003.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Driver/Motors.Stepper.Uln2003.csproj
index ed89d08425..91edeacd57 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Driver/Motors.Stepper.Uln2003.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Driver/Motors.Stepper.Uln2003.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Samples/Uln2003_Sample/Uln2003_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Samples/Uln2003_Sample/Uln2003_Sample.csproj
index 103d18896b..9642084eb8 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Samples/Uln2003_Sample/Uln2003_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Stepper.Uln2003/Samples/Uln2003_Sample/Uln2003_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Driver/Motors.Tb67h420ftg.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Driver/Motors.Tb67h420ftg.csproj
index 03fbcdec08..64353463a9 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Driver/Motors.Tb67h420ftg.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Driver/Motors.Tb67h420ftg.csproj
@@ -10,19 +10,16 @@
http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
Meadow.Foundation.Motors.Tb67h420ftg
https://github.com/WildernessLabs/Meadow.Foundation
- Meadow, Meadow.Foundation, Motor, HBridge, Tb67h420ftg
+ Meadow,Meadow.Foundation,Motor,HBridge,Tb67h420ftg
0.1.22
true
Tb67h420ftg digital input motor controller
-
- 8.0
-
-
- 8.0
+
+ 10.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Encoder_Sample/Tb67h420ftg_Encoder_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Encoder_Sample/Tb67h420ftg_Encoder_Sample.csproj
index 3cbd61dc1c..8f2dd29c8d 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Encoder_Sample/Tb67h420ftg_Encoder_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Encoder_Sample/Tb67h420ftg_Encoder_Sample.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Sample/Tb67h420ftg_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Sample/Tb67h420ftg_Sample.csproj
index de3746657b..2fe4806d8c 100644
--- a/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Sample/Tb67h420ftg_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Motors.Tb67h420ftg/Samples/Tb67h420ftg_Sample/Tb67h420ftg_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.Enums.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.Enums.cs
index f14a713c14..2a5c0a459c 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.Enums.cs
@@ -3,9 +3,9 @@
public partial class Ds1307
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x68
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.cs
index 01ce3fd1ab..82f2fdbec8 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.cs
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/Ds1307.cs
@@ -7,8 +7,13 @@ namespace Meadow.Foundation.RTCs
///
/// Represents a DS1307 real-time clock
///
- public partial class Ds1307
+ public partial class Ds1307 : II2cPeripheral
{
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
const int OriginYear = 1980;
readonly II2cBus i2cBus;
@@ -31,15 +36,15 @@ public bool IsRunning
get
{ // read 1 byte starting from 0x00
var reg = new byte[1];
- i2cBus.Write((byte)Address.Default, new byte[] { 0 });
- i2cBus.Read((byte)Address.Default, reg);
+ i2cBus.Write((byte)Addresses.Default, new byte[] { 0 });
+ i2cBus.Read((byte)Addresses.Default, reg);
return (reg[0] & (1 << 7)) != 0;
}
set
{ // read the seconds register
var reg = new byte[1];
- i2cBus.Write((byte)Address.Default, new byte[] { 0 });
- i2cBus.Read((byte)Address.Default, reg);
+ i2cBus.Write((byte)Addresses.Default, new byte[] { 0 });
+ i2cBus.Read((byte)Addresses.Default, reg);
var current = (reg[0] & (1 << 7)) != 0;
if ((value && current) || (!value && !current)) return;
@@ -54,7 +59,7 @@ public bool IsRunning
}
// and write it back to register 0x00
- i2cBus.Write((byte)Address.Default, reg);
+ i2cBus.Write((byte)Addresses.Default, reg);
}
}
@@ -65,8 +70,8 @@ public bool IsRunning
public DateTime GetTime()
{
var data = new byte[7];
- i2cBus.Write((byte)Address.Default, new byte[] { 0 });
- i2cBus.Read((byte)Address.Default, data);
+ i2cBus.Write((byte)Addresses.Default, new byte[] { 0 });
+ i2cBus.Read((byte)Addresses.Default, data);
return FromRTCTime(data);
}
@@ -76,11 +81,10 @@ public DateTime GetTime()
/// The new time
public void SetTime(DateTime time)
{
- var data = new List();
- data.Add(0);
+ var data = new List { 0 };
data.AddRange(ToRTCTime(time));
- i2cBus.Write((byte)Address.Default, data.ToArray());
+ i2cBus.Write((byte)Addresses.Default, data.ToArray());
}
///
@@ -90,9 +94,9 @@ public void SetTime(DateTime time)
/// The number of bytes to read
public byte[] ReadRAM(int offset, int count)
{
- var data = new byte[count];
- i2cBus.Write((byte)Address.Default, new byte[] { (byte)(0x08 + offset) });
- i2cBus.Read((byte)Address.Default, data);
+ var data = new byte[count];
+ i2cBus.Write((byte)Addresses.Default, new byte[] { (byte)(0x08 + offset) });
+ i2cBus.Read((byte)Addresses.Default, data);
return data;
}
@@ -104,11 +108,13 @@ public byte[] ReadRAM(int offset, int count)
///
public void WriteRAM(int offset, params byte[] data)
{
- var d = new List();
- d.Add((byte)(0x08 + offset)); // target start register offset
+ var d = new List
+ {
+ (byte)(0x08 + offset) // target start register offset
+ };
d.AddRange(data);
- i2cBus.Write((byte)Address.Default, d.ToArray());
+ i2cBus.Write((byte)Addresses.Default, d.ToArray());
}
///
@@ -118,34 +124,19 @@ public void WriteRAM(int offset, params byte[] data)
/// Throw if invalid frequency is selected
public void SquareWaveOutput(SquareWaveFrequency freq)
{
- byte registerData;
-
- switch (freq)
+ var registerData = freq switch
{
- case SquareWaveFrequency.Wave_1000Hz:
- registerData = (1 << 4);
- break;
- case SquareWaveFrequency.Wave_4096Hz:
- registerData = (1 << 4) | (1 << 0);
- break;
- case SquareWaveFrequency.Wave_8192Hz:
- registerData = (1 << 4) | (1 << 1);
- break;
- case SquareWaveFrequency.Wave_32768Hz:
- registerData = (1 << 4) | (1 << 0) | (1 << 1);
- break;
- case SquareWaveFrequency.Wave_Low:
- registerData = 0;
- break;
- case SquareWaveFrequency.Wave_High:
- registerData = (1 << 7);
- break;
- default:
- throw new NotSupportedException();
- }
+ SquareWaveFrequency.Wave_1000Hz => (byte)(1 << 4),
+ SquareWaveFrequency.Wave_4096Hz => (byte)((1 << 4) | (1 << 0)),
+ SquareWaveFrequency.Wave_8192Hz => (byte)((1 << 4) | (1 << 1)),
+ SquareWaveFrequency.Wave_32768Hz => (byte)((1 << 4) | (1 << 0) | (1 << 1)),
+ SquareWaveFrequency.Wave_Low => (byte)0,
+ SquareWaveFrequency.Wave_High => (byte)(1 << 7),
+ _ => throw new NotSupportedException(),
+ };
// control register is at 0x07
- i2cBus.Write((byte)Address.Default, new byte[] { 0x07, registerData }); //register and value
+ i2cBus.Write((byte)Addresses.Default, new byte[] { 0x07, registerData }); //register and value
}
static byte ToBCD(ushort i)
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/RTCs.Ds1307.csproj b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/RTCs.Ds1307.csproj
index 42947d433e..50b9c86ed3 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/RTCs.Ds1307.csproj
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Driver/RTCs.Ds1307.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Samples/Ds1307_Sample/Ds1307_Sample.csproj b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Samples/Ds1307_Sample/Ds1307_Sample.csproj
index 60d7492d84..80dc4abef1 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Samples/Ds1307_Sample/Ds1307_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds1307/Samples/Ds1307_Sample/Ds1307_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.Enums.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.Enums.cs
deleted file mode 100644
index 1273ab15c6..0000000000
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.Enums.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Meadow.Foundation.RTCs
-{
- public partial class Ds3231 : Ds323x
- {
- ///
- /// Valid addresses for the sensor.
- ///
- public enum Address : byte
- {
- ///
- /// Bus address 0x68
- ///
- Address_0x68 = 0x68,
- ///
- /// Default bus address
- ///
- Default = Address_0x68
- }
- }
-}
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.cs
index c8fbf5d88b..c4dc836559 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.cs
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds3231.cs
@@ -13,11 +13,8 @@ public partial class Ds3231 : Ds323x
/// Digital pin connected to the alarm interrupt pin on the RTC.
/// The I2C Bus the peripheral is connected to
/// I2C Bus address of the peripheral
- public Ds3231(
- II2cBus i2cBus,
- IPin interruptPin = null,
- byte address = (byte)Address.Default)
- : base(new I2cPeripheral(i2cBus, address), interruptPin)
+ public Ds3231(II2cBus i2cBus, IPin interruptPin = null, byte address = (byte)Addresses.Default)
+ : base(new I2cCommunications(i2cBus, address), interruptPin)
{ }
///
@@ -29,8 +26,8 @@ public Ds3231(
public Ds3231(
II2cBus i2cBus,
IDigitalInputPort interruptPort = null,
- byte address = (byte)Address.Default)
- : base(new I2cPeripheral(i2cBus, address), interruptPort)
+ byte address = (byte)Addresses.Default)
+ : base(new I2cCommunications(i2cBus, address), interruptPort)
{
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Enums.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Enums.cs
index 878ba0d47f..ff5a192471 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Enums.cs
@@ -2,6 +2,21 @@
{
public partial class Ds323x
{
+ ///
+ /// Valid I2C addresses for the sensor
+ ///
+ public enum Addresses : byte
+ {
+ ///
+ /// Bus address 0x68
+ ///
+ Address_0x68 = 0x68,
+ ///
+ /// Default bus address
+ ///
+ Default = Address_0x68
+ }
+
///
/// Possible values for the alarm that can be set or alarm that has been raised
///
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Registers.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Registers.cs
new file mode 100644
index 0000000000..bd95f825ab
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.Registers.cs
@@ -0,0 +1,31 @@
+namespace Meadow.Foundation.RTCs
+{
+ public partial class Ds323x
+ {
+ ///
+ /// Register addresses in the sensor
+ ///
+ static class Registers
+ {
+ public static readonly byte Seconds = 0x00;
+ public static readonly byte Minutes = 0x01;
+ public static readonly byte Hours = 0x02;
+ public static readonly byte Day = 0x03;
+ public static readonly byte Date = 0x04;
+ public static readonly byte Month = 0x05;
+ public static readonly byte Year = 0x06;
+ public static readonly byte Alarm1Seconds = 0x07;
+ public static readonly byte Alarm1Minutes = 0x08;
+ public static readonly byte Alarm1Hours = 0x09;
+ public static readonly byte Alarm1DayDate = 0x0a;
+ public static readonly byte Alarm2Minutes = 0x0b;
+ public static readonly byte Alarm2Hours = 0x0c;
+ public static readonly byte Alarm2DayDate = 0x0d;
+ public static readonly byte Control = 0x0e;
+ public static readonly byte ControlStatus = 0x0f;
+ public static readonly byte AgingOffset = 0x10;
+ public static readonly byte TemperatureMSB = 0x11;
+ public static readonly byte TemperatureLSB = 0x12;
+ }
+ }
+}
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.cs b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.cs
index d3dd5d40a2..1a7e8ab4b8 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.cs
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/Ds323x.cs
@@ -7,33 +7,12 @@ namespace Meadow.Foundation.RTCs
///
/// DS323X real-time clock
///
- public partial class Ds323x : IDisposable
+ public partial class Ds323x : II2cPeripheral, IDisposable
{
///
- /// Register addresses in the sensor
+ /// The default I2C address for the peripheral
///
- static class Registers
- {
- public static readonly byte Seconds = 0x00;
- public static readonly byte Minutes = 0x01;
- public static readonly byte Hours = 0x02;
- public static readonly byte Day = 0x03;
- public static readonly byte Date = 0x04;
- public static readonly byte Month = 0x05;
- public static readonly byte Year = 0x06;
- public static readonly byte Alarm1Seconds = 0x07;
- public static readonly byte Alarm1Minutes = 0x08;
- public static readonly byte Alarm1Hours = 0x09;
- public static readonly byte Alarm1DayDate = 0x0a;
- public static readonly byte Alarm2Minutes = 0x0b;
- public static readonly byte Alarm2Hours = 0x0c;
- public static readonly byte Alarm2DayDate = 0x0d;
- public static readonly byte Control = 0x0e;
- public static readonly byte ControlStatus = 0x0f;
- public static readonly byte AgingOffset = 0x10;
- public static readonly byte TemperatureMSB = 0x11;
- public static readonly byte TemperatureLSB = 0x12;
- }
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
///
/// Number of registers that hold the date and time information.
@@ -83,15 +62,14 @@ static class Registers
AlarmRaised alarm1Delegate;
AlarmRaised alarm2Delegate;
bool interruptCreatedInternally;
-
- Memory readBuffer;
+ readonly Memory readBuffer;
///
/// Create a new Ds323x object
///
- protected Ds323x(I2cPeripheral peripheral, IPin interruptPin)
+ protected Ds323x(I2cCommunications i2cComms, IPin interruptPin)
{
- ds323x = peripheral;
+ this.i2cComms = i2cComms;
if (interruptPin != null)
{
@@ -107,9 +85,9 @@ protected Ds323x(I2cPeripheral peripheral, IPin interruptPin)
///
/// Create a new Ds323x object
///
- protected Ds323x(I2cPeripheral peripheral, IDigitalInputPort interruptPort)
+ protected Ds323x(I2cCommunications i2cComms, IDigitalInputPort interruptPort)
{
- ds323x = peripheral;
+ this.i2cComms = i2cComms;
Initialize(interruptPort);
}
@@ -205,12 +183,12 @@ public DateTime CurrentDateTime
get
{
var data = readBuffer.Span[0..DATE_TIME_REGISTERS_SIZE];
- ds323x.ReadRegister(Registers.Seconds, data);
+ i2cComms.ReadRegister(Registers.Seconds, data);
return DecodeDateTimeRegisters(data);
}
set
{
- ds323x.WriteRegister(Registers.Seconds, EncodeDateTimeRegisters(value));
+ i2cComms.WriteRegister(Registers.Seconds, EncodeDateTimeRegisters(value));
}
}
@@ -222,16 +200,16 @@ public Units.Temperature Temperature
get
{
var data = readBuffer.Span[0..2];
- ds323x.ReadRegister(Registers.TemperatureMSB, data);
+ i2cComms.ReadRegister(Registers.TemperatureMSB, data);
var temperature = (ushort)((data[0] << 2) | (data[1] >> 6));
return new Units.Temperature(temperature * 0.25, Units.Temperature.UnitType.Celsius);
}
}
///
- /// DS323x Real Time Clock object.
+ /// I2C Communication bus used to communicate with the i2cComms
///
- protected II2cPeripheral ds323x { get; }
+ protected II2cCommunications i2cComms;
///
/// Interrupt port attached to the DS323x RTC module.
@@ -247,8 +225,8 @@ public Units.Temperature Temperature
///
protected byte ControlRegister
{
- get { return ds323x.ReadRegister(Registers.Control); }
- set { ds323x.WriteRegister(Registers.Control, value); }
+ get { return i2cComms.ReadRegister(Registers.Control); }
+ set { i2cComms.WriteRegister(Registers.Control, value); }
}
///
@@ -260,8 +238,8 @@ protected byte ControlRegister
///
protected byte ControlStatusRegister
{
- get { return ds323x.ReadRegister(Registers.ControlStatus); }
- set { ds323x.WriteRegister(Registers.ControlStatus, value); }
+ get { return i2cComms.ReadRegister(Registers.ControlStatus); }
+ set { i2cComms.WriteRegister(Registers.ControlStatus, value); }
}
///
@@ -300,7 +278,8 @@ protected DateTime DecodeDateTimeRegisters(Span data)
{
var seconds = Converters.BCDToByte(data[0]);
var minutes = Converters.BCDToByte(data[1]);
- byte hour = 0;
+ byte hour;
+
if ((data[2] & 0x40) != 0)
{
hour = Converters.BCDToByte((byte)(data[2] & 0x1f));
@@ -313,7 +292,7 @@ protected DateTime DecodeDateTimeRegisters(Span data)
{
hour = Converters.BCDToByte((byte)(data[2] & 0x3f));
}
- var wday = data[3];
+
var day = Converters.BCDToByte(data[4]);
var month = Converters.BCDToByte((byte)(data[5] & 0x7f));
var year = (ushort)(1900 + Converters.BCDToByte(data[6]));
@@ -394,7 +373,7 @@ protected byte DayOfWeekToByte(DayOfWeek day)
/// Type of alarm to set.
public void SetAlarm(Alarm alarm, DateTime time, AlarmType type)
{
- byte[] data = null;
+ byte[] data;
var register = Registers.Alarm1Seconds;
var element = 0;
@@ -468,7 +447,7 @@ public void SetAlarm(Alarm alarm, DateTime time, AlarmType type)
data[2] |= 0x40;
break;
}
- ds323x.WriteRegister(register, data);
+ i2cComms.WriteRegister(register, data);
//
// Turn the relevant alarm on.
//
@@ -545,7 +524,7 @@ public void ClearInterrupt(Alarm alarm)
public void DisplayRegisters()
{
var data = readBuffer.Span[0..0x12];
- ds323x.ReadRegister(0, data);
+ i2cComms.ReadRegister(0, data);
DebugInformation.DisplayRegisters(0, data);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/RTCs.Ds323x.csproj b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/RTCs.Ds323x.csproj
index 5bd57930d0..42ebda30c8 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/RTCs.Ds323x.csproj
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Driver/RTCs.Ds323x.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Samples/Ds323x_Sample/Ds323x_Sample.csproj b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Samples/Ds323x_Sample/Ds323x_Sample.csproj
index 21cde7cfae..e551c88435 100644
--- a/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Samples/Ds323x_Sample/Ds323x_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/RTCs.Ds323x/Samples/Ds323x_Sample/Ds323x_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.Enums.cs
index 48fab5431f..f0cf2c078f 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.Enums.cs
@@ -3,7 +3,7 @@
public partial class AdafruitMPRLS
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
@@ -17,4 +17,4 @@ public enum Addresses : byte
Default = Address_0x18
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.cs
index f868283c67..af9fa08623 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/AdafruitMPRLS.cs
@@ -3,22 +3,22 @@
using Meadow.Units;
using Meadow.Utilities;
using System;
+using System.Threading;
using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
/// Device driver for the Adafruit MPRLS Ported Pressure Sensor Breakout
- /// https://www.adafruit.com/product/3965
- /// Device datasheets also available here: https://sensing.honeywell.com/micropressure-mpr-series
///
- public partial class AdafruitMPRLS : ByteCommsSensorBase<(Pressure? Pressure, Pressure? RawPsiMeasurement)>, IBarometricPressureSensor
+ public partial class AdafruitMPRLS :
+ ByteCommsSensorBase<(Pressure? Pressure, Pressure? RawPsiMeasurement)>,
+ II2cPeripheral, IBarometricPressureSensor
{
- //Defined in section 6.6.1 of the datasheet.
- private readonly byte[] mprlsMeasurementCommand = { 0xAA, 0x00, 0x00 };
-
- private const int MINIMUM_PSI = 0;
- private const int MAXIMUM_PSI = 25;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
///
/// Raised when a new reading has been made. Events will only be raised
@@ -57,6 +57,11 @@ public partial class AdafruitMPRLS : ByteCommsSensorBase<(Pressure? Pressure, Pr
///
public bool InternalMathSaturated { get; set; }
+ private readonly byte[] mprlsMeasurementCommand = { 0xAA, 0x00, 0x00 };
+
+ private const int MINIMUM_PSI = 0;
+ private const int MAXIMUM_PSI = 25;
+
///
/// Represents an Adafruit MPRLS Ported Pressure Sensor
///
@@ -82,21 +87,18 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Pressure? Pressure,
/// Convenience method to get the current Pressure. For frequent reads, use
/// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
///
- protected override async Task<(Pressure? Pressure, Pressure? RawPsiMeasurement)> ReadSensor()
+ protected override Task<(Pressure? Pressure, Pressure? RawPsiMeasurement)> ReadSensor()
{
- return await Task.Run(async () =>
+ return Task.Run(() =>
{
- //Send the command to the sensor to tell it to do the thing.
- Peripheral.Write(mprlsMeasurementCommand);
+ BusComms.Write(mprlsMeasurementCommand);
- //Datasheet says wait 5 ms.
- await Task.Delay(5);
+ Thread.Sleep(5);
while (true)
{
- Peripheral.Read(ReadBuffer.Span[0..1]);
+ BusComms.Read(ReadBuffer.Span[0..1]);
- //From section 6.5 of the datasheet.
IsDevicePowered = BitHelpers.GetBitValue(ReadBuffer.Span[0], 6);
IsDeviceBusy = BitHelpers.GetBitValue(ReadBuffer.Span[0], 5);
HasMemoryIntegrityFailed = BitHelpers.GetBitValue(ReadBuffer.Span[0], 2);
@@ -106,23 +108,20 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Pressure? Pressure,
{
throw new InvalidOperationException("Sensor pressure has exceeded max value!");
}
-
if (HasMemoryIntegrityFailed)
{
throw new InvalidOperationException("Sensor internal memory integrity check failed!");
}
-
- if (!(IsDeviceBusy))
+ if (!IsDeviceBusy)
{
break;
}
}
- Peripheral.Read(ReadBuffer.Span[0..4]);
+ BusComms.Read(ReadBuffer.Span[0..4]);
var rawPSIMeasurement = (ReadBuffer.Span[1] << 16) | (ReadBuffer.Span[2] << 8) | ReadBuffer.Span[3];
- //From Section 8.0 of the datasheet.
var calculatedPSIMeasurement = (rawPSIMeasurement - 1677722) * (MAXIMUM_PSI - MINIMUM_PSI);
calculatedPSIMeasurement /= 15099494 - 1677722;
calculatedPSIMeasurement += MINIMUM_PSI;
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/Sensors.Atmospheric.AdafruitMPRLS.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/Sensors.Atmospheric.AdafruitMPRLS.csproj
index 57e451e87c..9e932b1491 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/Sensors.Atmospheric.AdafruitMPRLS.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Driver/Sensors.Atmospheric.AdafruitMPRLS.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Samples/AdafruitMPRLS_Sample/AdafruitMPRLS_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Samples/AdafruitMPRLS_Sample/AdafruitMPRLS_Sample.csproj
index 46752a6b39..c97e7de334 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Samples/AdafruitMPRLS_Sample/AdafruitMPRLS_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.AdafruitMPRLS/Samples/AdafruitMPRLS_Sample/AdafruitMPRLS_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.Address.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.Address.cs
index 73108a76ca..7ab8d4ff68 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.Address.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.Address.cs
@@ -56,9 +56,9 @@ public enum MeasurementModes
}
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x48
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.cs
index 6d0576862c..1026a6e232 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Bh1900Nux.cs
@@ -1,6 +1,5 @@
using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
-using Meadow.Units;
using System;
using System.Threading.Tasks;
@@ -9,7 +8,7 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
/// Represents a Bh1900Nux temperature sensor
///
- public partial class Bh1900Nux : ByteCommsSensorBase, ITemperatureSensor
+ public partial class Bh1900Nux : ByteCommsSensorBase, ITemperatureSensor, II2cPeripheral
{
///
/// Raised when the temperature value changes
@@ -21,15 +20,20 @@ public partial class Bh1900Nux : ByteCommsSensorBase, ITemper
///
public Units.Temperature? Temperature => Conditions;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new Bh1900Nux object
///
/// The I2C bus
/// The I2C address
- public Bh1900Nux(II2cBus i2cBus, Address address)
+ public Bh1900Nux(II2cBus i2cBus, Addresses address)
: base(i2cBus, (byte)address, 2, 2)
{
- if (address < Address.Address_0x48 || address > Address.Address_0x4f)
+ if (address < Addresses.Address_0x48 || address > Addresses.Address_0x4f)
{
throw new ArgumentOutOfRangeException("Bh1900Nux address must be in the range of 0x48-0x4f");
}
@@ -43,7 +47,7 @@ public Bh1900Nux(II2cBus i2cBus, Address address)
/// The I2C bus
/// The I2C address
public Bh1900Nux(II2cBus i2cBus, byte address)
- : this(i2cBus, (Address)address)
+ : this(i2cBus, (Addresses)address)
{ }
///
@@ -51,18 +55,18 @@ public Bh1900Nux(II2cBus i2cBus, byte address)
///
public void Reset()
{
- Peripheral?.WriteRegister((byte)Register.Reset, 0x01);
+ BusComms?.WriteRegister((byte)Register.Reset, 0x01);
}
int GetConfig()
{
- Peripheral?.ReadRegister((byte)Register.Configuration, ReadBuffer.Span[0..2]);
+ BusComms?.ReadRegister((byte)Register.Configuration, ReadBuffer.Span[0..2]);
return ReadBuffer.Span[0] << 8 | ReadBuffer.Span[1];
}
void SetConfig(int cfg)
{
- Peripheral?.WriteRegister((byte)Register.Configuration, new byte[] { (byte)(cfg >> 8), (byte)(cfg & 0xff) });
+ BusComms?.WriteRegister((byte)Register.Configuration, new byte[] { (byte)(cfg >> 8), (byte)(cfg & 0xff) });
}
///
@@ -156,13 +160,13 @@ public Units.Temperature LowLimit
{
get
{
- Peripheral?.ReadRegister((byte)Register.TLow, ReadBuffer.Span[0..2]);
+ BusComms?.ReadRegister((byte)Register.TLow, ReadBuffer.Span[0..2]);
return RegisterToTemp(ReadBuffer);
}
set
{
- Peripheral?.WriteRegister((byte)Register.TLow, TempToBytes(value));
+ BusComms?.WriteRegister((byte)Register.TLow, TempToBytes(value));
}
}
@@ -173,13 +177,13 @@ public Units.Temperature HighLimit
{
get
{
- Peripheral?.ReadRegister((byte)Register.THigh, ReadBuffer.Span[0..2]);
+ BusComms?.ReadRegister((byte)Register.THigh, ReadBuffer.Span[0..2]);
return RegisterToTemp(ReadBuffer);
}
set
{
- Peripheral?.WriteRegister((byte)Register.THigh, TempToBytes(value));
+ BusComms?.WriteRegister((byte)Register.THigh, TempToBytes(value));
}
}
@@ -208,19 +212,16 @@ private Units.Temperature RegisterToTemp(Memory data)
/// Read the temperature
///
/// The current temperature value
- protected override async Task ReadSensor()
+ protected override Task ReadSensor()
{
- return await Task.Run(() =>
- {
- // 12-bit data
- // Negative numbers are represented in binary twos complement format. The
- // Temperature Register is 0x0000 until the first conversion complete after a software
- // reset or power - on.
- // Measurement Temperature Value [°C] = Temperature Data [11:0] x 0.0625
- Peripheral?.ReadRegister((byte)Register.Temperature, ReadBuffer.Span[0..2]);
+ // 12-bit data
+ // Negative numbers are represented in binary twos complement format. The
+ // Temperature Register is 0x0000 until the first conversion complete after a software
+ // reset or power - on.
+ // Measurement Temperature Value [°C] = Temperature Data [11:0] x 0.0625
+ BusComms?.ReadRegister((byte)Register.Temperature, ReadBuffer.Span[0..2]);
- return RegisterToTemp(ReadBuffer);
- });
+ return Task.FromResult(RegisterToTemp(ReadBuffer));
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Sensors.Atmospheric.Bh1900Nux.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Sensors.Atmospheric.Bh1900Nux.csproj
index ce7f600d98..d62e2c62de 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Sensors.Atmospheric.Bh1900Nux.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Driver/Sensors.Atmospheric.Bh1900Nux.csproj
@@ -23,6 +23,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/Bh1900Nux_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/Bh1900Nux_Sample.csproj
index 2eea9cb741..fb31b7cdd8 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/Bh1900Nux_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/Bh1900Nux_Sample.csproj
@@ -12,7 +12,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/MeadowApp.cs
index d3c1476524..e3b76d4bab 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bh1900Nux/Samples/Bh1900Nux_Sample/MeadowApp.cs
@@ -17,7 +17,7 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- _sensor = new Bh1900Nux(Device.CreateI2cBus(), Bh1900Nux.Address.Default);
+ _sensor = new Bh1900Nux(Device.CreateI2cBus(), Bh1900Nux.Addresses.Default);
var consumer = Bh1900Nux.CreateObserver(
handler: result =>
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Addresses.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Address.cs
similarity index 92%
rename from Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Addresses.cs
rename to Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Address.cs
index 29136e0326..d252eafac3 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Addresses.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Address.cs
@@ -3,7 +3,7 @@
public partial class Bme280
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Register.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Register.cs
new file mode 100644
index 0000000000..d490a4b996
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.Register.cs
@@ -0,0 +1,15 @@
+namespace Meadow.Foundation.Sensors.Atmospheric
+{
+ public partial class Bme280
+ {
+ internal enum Register : byte
+ {
+ ChipID = 0xd0,
+ Reset = 0xe0,
+ Humidity = 0xf2,
+ Status = 0xf3,
+ Measurement = 0xf4,
+ Configuration = 0xf5,
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.cs
index a5c46e7676..0b841337f8 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280.cs
@@ -9,24 +9,6 @@
namespace Meadow.Foundation.Sensors.Atmospheric
{
- // TODO: for standby durations of 1,000ms and less, the sensor
- // will actually handle the reading loop. you put it into `Normal`
- // mode and set it to one of the known `StandbyDuration`s.
- //
- // So perhaps this should be an option. From a method signature
- // standpoint, i think that we would add an overload that took
- // a known `StandbyDuration` instead of an int.
- //
- // With that said, however, as far as I can tell, the sensor won't
- // send an interrupt when a new reading is taken, so i'm not sure
- // how we would synchronize with it, since the time that each read
- // takes is determined by the samples, filter, etc. -b
- //
- // TODO: for longer standby durations, we should put the sensor into
- // Modes.Sleep to save power. Need to figure out what the stanby
- // duration threshold is for that. i'm guessing 5 seconds might be a
- // good value.
-
///
/// BME280 Temperature, Pressure and Humidity Sensor
///
@@ -36,7 +18,7 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Bme280 :
PollingSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>,
- ITemperatureSensor, IHumiditySensor, IBarometricPressureSensor
+ ITemperatureSensor, IHumiditySensor, IBarometricPressureSensor, ISpiPeripheral, II2cPeripheral
{
///
/// Temperature changed event
@@ -79,9 +61,9 @@ public partial class Bme280 :
public Oversample HumiditySampleCount { get; set; } = Oversample.OversampleX8;
///
- /// Communication bus used to read and write to the BME280 sensor.
+ /// Communication bus used to read and write to the BME280 sensor
///
- private readonly Bme280Comms bme280Comms;
+ private readonly IByteCommunications bme280Comms;
///
/// Compensation data from the sensor
@@ -109,6 +91,39 @@ public partial class Bme280 :
///
public RelativeHumidity? Humidity => Conditions.Humidity;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(10000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => ((ISpiCommunications)bme280Comms).BusSpeed;
+ set => ((ISpiCommunications)bme280Comms).BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => ((ISpiCommunications)bme280Comms).BusMode;
+ set => ((ISpiCommunications)bme280Comms).BusMode = value;
+ }
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Initializes a new instance of the BME280 class
///
@@ -116,7 +131,7 @@ public partial class Bme280 :
/// I2C address of the sensor (default = 0x77)
public Bme280(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
- bme280Comms = new Bme280I2C(i2cBus, address);
+ bme280Comms = new I2cCommunications(i2cBus, address);
configuration = new Configuration(); // here to avoid the warning
Initialize();
}
@@ -137,7 +152,7 @@ public Bme280(ISpiBus spiBus, IPin chipSelectPin) :
/// The port for the chip select pin
public Bme280(ISpiBus spiBus, IDigitalOutputPort chipSelectPort)
{
- bme280Comms = new Bme280Spi(spiBus, chipSelectPort);
+ bme280Comms = new SpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
configuration = new Configuration(); // here to avoid the warning
Initialize();
}
@@ -192,7 +207,6 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
{
//TODO: set an update flag on the oversample properties and set
// these once, unless the update flag has been set.
- // update configuration
configuration.TemperatureOverSampling = TemperatureSampleCount;
configuration.PressureOversampling = PressureSampleCount;
configuration.HumidityOverSampling = HumiditySampleCount;
@@ -206,131 +220,55 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
await Task.Delay(100); //give the BME280 time to read new values
}
- return await Task.Run(() =>
+ (Units.Temperature Temperature, RelativeHumidity Humidity, Pressure Pressure) conditions;
+
+ bme280Comms.ReadRegister(0xf7, readBuffer.Span[0..8]);
+
+ var adcTemperature = (readBuffer.Span[3] << 12) | (readBuffer.Span[4] << 4) | ((readBuffer.Span[5] >> 4) & 0x0f);
+ var tvar1 = (((adcTemperature >> 3) - (compensationData.T1 << 1)) * compensationData.T2) >> 11;
+ var tvar2 = (((((adcTemperature >> 4) - compensationData.T1) *
+ ((adcTemperature >> 4) - compensationData.T1)) >> 12) * compensationData.T3) >> 14;
+ var tfine = tvar1 + tvar2;
+
+ conditions.Temperature = new Units.Temperature((float)(((tfine * 5) + 128) >> 8) / 100, TU.Celsius);
+
+ long pvar1 = tfine - 128000;
+ var pvar2 = pvar1 * pvar1 * compensationData.P6;
+ pvar2 += (pvar1 * compensationData.P5) << 17;
+ pvar2 += (long)compensationData.P4 << 35;
+ pvar1 = ((pvar1 * pvar1 * compensationData.P8) >> 8) + ((pvar1 * compensationData.P2) << 12);
+ pvar1 = ((((long)1 << 47) + pvar1) * compensationData.P1) >> 33;
+ if (pvar1 == 0)
{
+ conditions.Pressure = new Pressure(0, PU.Pascal);
+ }
+ else
+ {
+ var adcPressure = (readBuffer.Span[0] << 12) | (readBuffer.Span[1] << 4) | ((readBuffer.Span[2] >> 4) & 0x0f);
+ long pressure = 1048576 - adcPressure;
+ pressure = (((pressure << 31) - pvar2) * 3125) / pvar1;
+ pvar1 = (compensationData.P9 * (pressure >> 13) * (pressure >> 13)) >> 25;
+ pvar2 = (compensationData.P8 * pressure) >> 19;
+ pressure = ((pressure + pvar1 + pvar2) >> 8) + ((long)compensationData.P7 << 4);
+ conditions.Pressure = new Pressure((double)pressure / 256, PU.Pascal);
+ }
+
+ var adcHumidity = (readBuffer.Span[6] << 8) | readBuffer.Span[7];
+ var v_x1_u32r = tfine - 76800;
+
+ v_x1_u32r = ((((adcHumidity << 14) - (compensationData.H4 << 20) - (compensationData.H5 * v_x1_u32r)) +
+ 16384) >> 15) *
+ ((((((((v_x1_u32r * compensationData.H6) >> 10) *
+ (((v_x1_u32r * compensationData.H3) >> 11) + 32768)) >> 10) + 2097152) *
+ compensationData.H2) + 8192) >> 14);
+ v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * compensationData.H1) >> 4);
+
+ v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
+ v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
+
+ conditions.Humidity = new RelativeHumidity((v_x1_u32r >> 12) / 1024, HU.Percent);
- (Units.Temperature Temperature, RelativeHumidity Humidity, Pressure Pressure) conditions;
-
- // readily read the readings from the reading register into the read buffer
- bme280Comms.ReadRegisters(0xf7, readBuffer.Span[0..8]);
- //
- // Temperature calculation from section 4.2.3 of the datasheet.
- //
- // Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
- // t_fine carries fine temperature as global value:
- //
- // BME280_S32_t t_fine;
- // BME280_S32_t BME280_compensate_T_int32(BME280_S32_t adc_T)
- // {
- // BME280_S32_t var1, var2, T;
- // var1 = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11;
- // var2 = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) *
- // ((BME280_S32_t)dig_T3)) >> 14;
- // t_fine = var1 + var2;
- // T = (t_fine * 5 + 128) >> 8;
- // return T;
- // }
- //
- var adcTemperature = (readBuffer.Span[3] << 12) | (readBuffer.Span[4] << 4) | ((readBuffer.Span[5] >> 4) & 0x0f);
- var tvar1 = (((adcTemperature >> 3) - (compensationData.T1 << 1)) * compensationData.T2) >> 11;
- var tvar2 = (((((adcTemperature >> 4) - compensationData.T1) *
- ((adcTemperature >> 4) - compensationData.T1)) >> 12) * compensationData.T3) >> 14;
- var tfine = tvar1 + tvar2;
- //
- conditions.Temperature = new Units.Temperature((float)(((tfine * 5) + 128) >> 8) / 100, TU.Celsius);
- //
- // Pressure calculation from section 4.2.3 of the datasheet.
- //
- // Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
- // Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
- //
- // BME280_U32_t BME280_compensate_P_int64(BME280_S32_t adc_P)
- // {
- // BME280_S64_t var1, var2, p;
- // var1 = ((BME280_S64_t)t_fine) - 128000;
- // var2 = var1 * var1 * (BME280_S64_t)dig_P6;
- // var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17);
- // var2 = var2 + (((BME280_S64_t)dig_P4)<<35);
- // var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12);
- // var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33;
- // if (var1 == 0)
- // {
- // return 0; // avoid exception caused by division by zero
- // }
- // p = 1048576-adc_P;
- // p = (((p<<31)-var2)*3125)/var1;
- // var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
- // var2 = (((BME280_S64_t)dig_P8) * p) >> 19;
- // p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4);
- // return (BME280_U32_t)p;
- // }
- //
- long pvar1 = tfine - 128000;
- var pvar2 = pvar1 * pvar1 * compensationData.P6;
- pvar2 += (pvar1 * compensationData.P5) << 17;
- pvar2 += (long)compensationData.P4 << 35;
- pvar1 = ((pvar1 * pvar1 * compensationData.P8) >> 8) + ((pvar1 * compensationData.P2) << 12);
- pvar1 = ((((long)1 << 47) + pvar1) * compensationData.P1) >> 33;
- if (pvar1 == 0)
- {
- conditions.Pressure = new Pressure(0, PU.Pascal);
- }
- else
- {
- var adcPressure = (readBuffer.Span[0] << 12) | (readBuffer.Span[1] << 4) | ((readBuffer.Span[2] >> 4) & 0x0f);
- long pressure = 1048576 - adcPressure;
- pressure = (((pressure << 31) - pvar2) * 3125) / pvar1;
- pvar1 = (compensationData.P9 * (pressure >> 13) * (pressure >> 13)) >> 25;
- pvar2 = (compensationData.P8 * pressure) >> 19;
- pressure = ((pressure + pvar1 + pvar2) >> 8) + ((long)compensationData.P7 << 4);
- //
- conditions.Pressure = new Pressure((double)pressure / 256, PU.Pascal);
- }
- //
- // Humidity calculations from section 4.2.3 of the datasheet.
- //
- // Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
- // Output value of “47445” represents 47445/1024 = 46.333 %RH
- //
- // BME280_U32_t bme280_compensate_H_int32(BME280_S32_t adc_H)
- // {
- // BME280_S32_t v_x1_u32r;
- // v_x1_u32r = (t_fine - ((BME280_S32_t)76800));
- // v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) +
- // ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r *
- // ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) *
- // ((BME280_S32_t)dig_H2) + 8192) >> 14));
- // v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4));
- // v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
- // v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
- // return (BME280_U32_t)(v_x1_u32r>>12);
- // }
- //
- var adcHumidity = (readBuffer.Span[6] << 8) | readBuffer.Span[7];
- var v_x1_u32r = tfine - 76800;
-
- v_x1_u32r = ((((adcHumidity << 14) - (compensationData.H4 << 20) - (compensationData.H5 * v_x1_u32r)) +
- 16384) >> 15) *
- ((((((((v_x1_u32r * compensationData.H6) >> 10) *
- (((v_x1_u32r * compensationData.H3) >> 11) + 32768)) >> 10) + 2097152) *
- compensationData.H2) + 8192) >> 14);
- v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * compensationData.H1) >> 4);
-
- //v_x1_u32r = (((((adcHumidity << 14) - (((int) _compensationData.H4) << 20) - (((int) _compensationData.H5) * v_x1_u32r)) +
- // ((int) 16384)) >> 15) * (((((((v_x1_u32r * ((int) _compensationData.H6)) >> 10) * (((v_x1_u32r *
- // ((int) _compensationData.H3)) >> 11) + ((int) 32768))) >> 10) + ((int) 2097152)) *
- // ((int) _compensationData.H2) + 8192) >> 14));
- //v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int) _compensationData.H1)) >> 4));
- //
- // Makes sure the humidity reading is in the range [0..100].
- //
- v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
- v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
- //
- conditions.Humidity = new RelativeHumidity((v_x1_u32r >> 12) / 1024, HU.Percent);
-
- return conditions;
- });
+ return conditions;
}
///
/// Update the configuration for the BME280.
@@ -350,16 +288,16 @@ protected void UpdateConfiguration(Configuration configuration)
//
// Put to sleep to allow the configuration to be changed.
//
- bme280Comms.WriteRegister(Bme280Comms.Register.Measurement, 0x00);
+ bme280Comms.WriteRegister((byte)Register.Measurement, 0x00);
var data = (byte)((((byte)configuration.Standby << 5) & 0xe0) | (((byte)configuration.Filter << 2) & 0x1c));
- bme280Comms.WriteRegister(Bme280Comms.Register.Configuration, data);
+ bme280Comms.WriteRegister((byte)Register.Configuration, data);
data = (byte)((byte)configuration.HumidityOverSampling & 0x07);
- bme280Comms.WriteRegister(Bme280Comms.Register.Humidity, data);
+ bme280Comms.WriteRegister((byte)Register.Humidity, data);
data = (byte)((((byte)configuration.TemperatureOverSampling << 5) & 0xe0) |
(((byte)configuration.PressureOversampling << 2) & 0x1c) |
((byte)configuration.Mode & 0x03));
- bme280Comms.WriteRegister(Bme280Comms.Register.Measurement, data);
+ bme280Comms.WriteRegister((byte)Register.Measurement, data);
}
///
@@ -370,7 +308,7 @@ protected void UpdateConfiguration(Configuration configuration)
///
public void Reset()
{
- bme280Comms.WriteRegister(Bme280Comms.Register.Reset, 0xb6);
+ bme280Comms.WriteRegister((byte)Register.Reset, 0xb6);
UpdateConfiguration(configuration);
}
@@ -389,7 +327,7 @@ public void Reset()
protected void ReadCompensationData()
{
// read the temperature and pressure data into the internal read buffer
- bme280Comms.ReadRegisters(0x88, readBuffer.Span[0..24]);
+ bme280Comms.ReadRegister(0x88, readBuffer.Span[0..24]);
// Temperature
compensationData.T1 = (ushort)(readBuffer.Span[0] + (readBuffer.Span[1] << 8));
@@ -410,10 +348,10 @@ protected void ReadCompensationData()
// non-sequential registers
// first one
- bme280Comms.ReadRegisters(0xa1, readBuffer.Span[0..1]);
+ bme280Comms.ReadRegister(0xa1, readBuffer.Span[0..1]);
compensationData.H1 = readBuffer.Span[0];
// 2-6
- bme280Comms.ReadRegisters(0xe1, readBuffer.Span[0..7]);
+ bme280Comms.ReadRegister(0xe1, readBuffer.Span[0..7]);
compensationData.H2 = (short)(readBuffer.Span[0] + (readBuffer.Span[1] << 8));
compensationData.H3 = readBuffer.Span[2];
compensationData.H4 = (short)((readBuffer.Span[3] << 4) + (readBuffer.Span[4] & 0xf));
@@ -427,7 +365,7 @@ protected void ReadCompensationData()
///
public byte GetChipID()
{
- bme280Comms.ReadRegisters((byte)Bme280Comms.Register.ChipID, readBuffer.Span[0..1]);
+ bme280Comms.ReadRegister((byte)Register.ChipID, readBuffer.Span[0..1]);
return readBuffer.Span[0];
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280Comms.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280Comms.cs
deleted file mode 100644
index 5d5ff042d1..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280Comms.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal abstract class Bme280Comms
- {
- ///
- /// Registers used to control the BME280.
- ///
- internal enum Register : byte
- {
- ChipID = 0xd0,
- Reset = 0xe0,
- Humidity = 0xf2,
- Status = 0xf3,
- Measurement = 0xf4,
- Configuration = 0xf5,
- }
-
- public abstract void WriteRegister(Register register, byte value);
- public abstract void ReadRegisters(byte startRegister, Span readBuffer);
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280I2C.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280I2C.cs
deleted file mode 100644
index 99c82800d4..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280I2C.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal class Bme280I2C : Bme280Comms
- {
- protected I2cPeripheral i2CPeripheral;
-
- internal Bme280I2C(II2cBus i2c, byte busAddress)
- {
- if ((busAddress != 0x76) && (busAddress != 0x77))
- {
- throw new ArgumentOutOfRangeException(nameof(busAddress), "Address should be 0x76 or 0x77");
- }
- i2CPeripheral = new I2cPeripheral(i2c, busAddress);
- }
-
- public override void ReadRegisters(byte startRegister, Span readBuffer)
- {
- i2CPeripheral.ReadRegister(startRegister, readBuffer);
- }
-
- public override void WriteRegister(Register register, byte value)
- {
- i2CPeripheral.WriteRegister((byte)register, value);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280SPI.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280SPI.cs
deleted file mode 100644
index d8546153c5..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Bme280SPI.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Linq;
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal class Bme280Spi : Bme280Comms
- {
- ISpiPeripheral spiPeripheral;
-
- internal Bme280Spi(ISpiBus spi, IDigitalOutputPort? chipSelect = null)
- {
- spiPeripheral = new SpiPeripheral(spi, chipSelect);
- }
-
- public override void ReadRegisters(byte startRegister, Span readBuffer)
- {
- spiPeripheral.ReadRegister(startRegister, readBuffer);
-
- // skip past the byte where we clocked out the register address
- for (int i = 1; i < readBuffer.Length; i++) {
- readBuffer[i - 1] = readBuffer[i];
- }
- }
-
- public override void WriteRegister(Register register, byte value)
- {
- spiPeripheral.WriteRegister(((byte)register), value);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Sensors.Atmospheric.Bme280.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Sensors.Atmospheric.Bme280.csproj
index b046cdc658..3b63737624 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Sensors.Atmospheric.Bme280.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Driver/Sensors.Atmospheric.Bme280.csproj
@@ -26,6 +26,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Samples/Bme280_Sample/Bme280_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Samples/Bme280_Sample/Bme280_Sample.csproj
index 84fc1b96db..410dc88451 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Samples/Bme280_Sample/Bme280_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme280/Samples/Bme280_Sample/Bme280_Sample.csproj
@@ -12,7 +12,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Calibration.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Calibration.cs
index 27e5cc6e89..07fee937c9 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Calibration.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Calibration.cs
@@ -1,4 +1,6 @@
-namespace Meadow.Foundation.Sensors.Atmospheric
+using Meadow.Hardware;
+
+namespace Meadow.Foundation.Sensors.Atmospheric
{
partial class Bme68x
{
@@ -41,43 +43,43 @@ internal class Calibration
public sbyte ResHeatVal { get; set; }
public sbyte RangeSwErr { get; set; }
- public void LoadCalibrationDataFromSensor(Bme68xComms sensor)
+ public void LoadCalibrationDataFromSensor(IByteCommunications byteComms)
{
// Read temperature calibration data.
- T1 = sensor.ReadRegisterAsUShort((byte)Registers.T1);
- T2 = (short)sensor.ReadRegisterAsUShort((byte)Registers.T2);
- T3 = sensor.ReadRegister((byte)Registers.T3);
+ T1 = byteComms.ReadRegisterAsUShort((byte)Registers.T1);
+ T2 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.T2);
+ T3 = byteComms.ReadRegister((byte)Registers.T3);
// Read humidity calibration data.
- H1 = (ushort)((sensor.ReadRegister((byte)Registers.H1_MSB) << 4) | (sensor.ReadRegister((byte)Registers.H1_LSB) & 0x0F));
- H2 = (ushort)((sensor.ReadRegister((byte)Registers.H2_MSB) << 4) | (sensor.ReadRegister((byte)Registers.H2_LSB) >> 4));
- H3 = (sbyte)sensor.ReadRegister((byte)Registers.H3);
- H4 = (sbyte)sensor.ReadRegister((byte)Registers.H4);
- H5 = (sbyte)sensor.ReadRegister((byte)Registers.H5);
- H6 = sensor.ReadRegister((byte)Registers.H6);
- H7 = (sbyte)(sensor.ReadRegister((byte)Registers.H7));
+ H1 = (ushort)((byteComms.ReadRegister((byte)Registers.H1_MSB) << 4) | (byteComms.ReadRegister((byte)Registers.H1_LSB) & 0x0F));
+ H2 = (ushort)((byteComms.ReadRegister((byte)Registers.H2_MSB) << 4) | (byteComms.ReadRegister((byte)Registers.H2_LSB) >> 4));
+ H3 = (sbyte)byteComms.ReadRegister((byte)Registers.H3);
+ H4 = (sbyte)byteComms.ReadRegister((byte)Registers.H4);
+ H5 = (sbyte)byteComms.ReadRegister((byte)Registers.H5);
+ H6 = byteComms.ReadRegister((byte)Registers.H6);
+ H7 = (sbyte)(byteComms.ReadRegister((byte)Registers.H7));
// Read pressure calibration data.
- P1 = sensor.ReadRegisterAsUShort((byte)Registers.P1_LSB);
- P2 = (short)sensor.ReadRegisterAsUShort((byte)Registers.P2_LSB);
- P3 = sensor.ReadRegister((byte)Registers.P3);
- P4 = (short)sensor.ReadRegisterAsUShort((byte)Registers.P4_LSB);
- P5 = (short)sensor.ReadRegisterAsUShort((byte)Registers.P5_LSB);
- P6 = sensor.ReadRegister((byte)Registers.P6);
- P7 = sensor.ReadRegister((byte)Registers.P7);
- P8 = (short)sensor.ReadRegisterAsUShort((byte)Registers.P8_LSB);
- P9 = (short)sensor.ReadRegisterAsUShort((byte)Registers.P9_LSB);
- P10 = sensor.ReadRegister((byte)Registers.P10);
+ P1 = byteComms.ReadRegisterAsUShort((byte)Registers.P1_LSB);
+ P2 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.P2_LSB);
+ P3 = byteComms.ReadRegister((byte)Registers.P3);
+ P4 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.P4_LSB);
+ P5 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.P5_LSB);
+ P6 = byteComms.ReadRegister((byte)Registers.P6);
+ P7 = byteComms.ReadRegister((byte)Registers.P7);
+ P8 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.P8_LSB);
+ P9 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.P9_LSB);
+ P10 = byteComms.ReadRegister((byte)Registers.P10);
// read gas calibration data.
- Gh1 = (sbyte)sensor.ReadRegister((byte)Registers.GH1);
- Gh2 = (short)sensor.ReadRegisterAsUShort((byte)Registers.GH2);
- Gh3 = (sbyte)sensor.ReadRegister((byte)Registers.GH3);
+ Gh1 = (sbyte)byteComms.ReadRegister((byte)Registers.GH1);
+ Gh2 = (short)byteComms.ReadRegisterAsUShort((byte)Registers.GH2);
+ Gh3 = (sbyte)byteComms.ReadRegister((byte)Registers.GH3);
// read heater calibration data
- ResHeatRange = (byte)(sensor.ReadRegister(((byte)Registers.RES_HEAT_RANGE) & 0x30) >> 4);
- RangeSwErr = (sbyte)(sensor.ReadRegister(((byte)Registers.RANGE_SW_ERR) & 0xF0) >> 4);
- ResHeatVal = (sbyte)sensor.ReadRegister((byte)Registers.RES_HEAT_VAL);
+ ResHeatRange = (byte)(byteComms.ReadRegister(((byte)Registers.RES_HEAT_RANGE) & 0x30) >> 4);
+ RangeSwErr = (sbyte)(byteComms.ReadRegister(((byte)Registers.RANGE_SW_ERR) & 0xF0) >> 4);
+ ResHeatVal = (sbyte)byteComms.ReadRegister((byte)Registers.RES_HEAT_VAL);
}
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Enums.cs
index 7e3399012c..cd479c7b00 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.Enums.cs
@@ -3,7 +3,7 @@
partial class Bme68x
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.cs
index 49a43a4116..6a7f3c4f0c 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68x.cs
@@ -21,7 +21,7 @@ public abstract partial class Bme68x :
RelativeHumidity? Humidity,
Pressure? Pressure,
Resistance? GasResistance)>,
- ITemperatureSensor, IHumiditySensor, IBarometricPressureSensor
+ ITemperatureSensor, IHumiditySensor, IBarometricPressureSensor, ISpiPeripheral, II2cPeripheral
{
///
/// Raised when the temperature value changes
@@ -85,10 +85,10 @@ public HeaterProfileType HeaterProfile
throw new ArgumentOutOfRangeException(nameof(value));
}
- var profile = sensor.ReadRegister((byte)Registers.CTRL_GAS_1);
+ var profile = busComms.ReadRegister((byte)Registers.CTRL_GAS_1);
profile = (byte)((profile & 0x0F) | (byte)value);
- sensor.WriteRegister((byte)Registers.CTRL_GAS_1, profile);
+ busComms.WriteRegister((byte)Registers.CTRL_GAS_1, profile);
heaterProfile = value;
}
@@ -109,11 +109,11 @@ public FilteringMode FilterMode
throw new ArgumentOutOfRangeException(nameof(value));
}
- var filter = sensor.ReadRegister((byte)Registers.CONFIG);
+ var filter = busComms.ReadRegister((byte)Registers.CONFIG);
byte mask = 0x1C;
filter = (byte)((filter & (byte)~mask) | (byte)value << 2);
- sensor.WriteRegister((byte)Registers.CONFIG, filter);
+ busComms.WriteRegister((byte)Registers.CONFIG, filter);
filterMode = value;
}
}
@@ -127,11 +127,11 @@ public bool HeaterIsEnabled
get => heaterIsEnabled;
set
{
- var heaterStatus = sensor.ReadRegister((byte)Registers.CTRL_GAS_0);
+ var heaterStatus = busComms.ReadRegister((byte)Registers.CTRL_GAS_0);
var mask = 0x08;
heaterStatus = (byte)((heaterStatus & (byte)~mask) | Convert.ToByte(!value) << 3);
- sensor.WriteRegister((byte)Registers.CTRL_GAS_0, heaterStatus);
+ busComms.WriteRegister((byte)Registers.CTRL_GAS_0, heaterStatus);
heaterIsEnabled = value;
}
}
@@ -145,24 +145,53 @@ public bool GasConversionIsEnabled
get => gasConversionIsEnabled;
set
{
- var gasConversion = sensor.ReadRegister((byte)Registers.CTRL_GAS_1);
+ var gasConversion = busComms.ReadRegister((byte)Registers.CTRL_GAS_1);
byte mask = 0x10;
gasConversion = (byte)((gasConversion & (byte)~mask) | Convert.ToByte(value) << 4);
- sensor.WriteRegister((byte)Registers.CTRL_GAS_1, gasConversion);
+ busComms.WriteRegister((byte)Registers.CTRL_GAS_1, gasConversion);
gasConversionIsEnabled = value;
}
}
bool gasConversionIsEnabled = false;
+ ///
+ /// The default SPI bus speed for the device
+ ///
+ public Frequency DefaultSpiBusSpeed => new Frequency(10000, Frequency.UnitType.Kilohertz);
+
+ ///
+ /// The SPI bus speed for the device
+ ///
+ public Frequency SpiBusSpeed
+ {
+ get => ((Bme68xSpiCommunications)busComms).BusSpeed;
+ set => ((Bme68xSpiCommunications)busComms).BusSpeed = value;
+ }
+
+ ///
+ /// The default SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode DefaultSpiBusMode => SpiClockConfiguration.Mode.Mode0;
+
+ ///
+ /// The SPI bus mode for the device
+ ///
+ public SpiClockConfiguration.Mode SpiBusMode
+ {
+ get => ((Bme68xSpiCommunications)busComms).BusMode;
+ set => ((Bme68xSpiCommunications)busComms).BusMode = value;
+ }
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Communication bus used to read and write to the BME68x sensor
///
- ///
- /// The BME has both I2C and SPI interfaces. The ICommunicationBus allows the
- /// selection to be made in the constructor.
- ///
- readonly Bme68xComms sensor;
+ readonly IByteCommunications busComms;
///
/// The current temperature
@@ -204,11 +233,11 @@ public bool GasConversionIsEnabled
/// Creates a new instance of the BME68x class
///
/// I2C Bus to use for communicating with the sensor
- /// I2C address of the sensor.
+ /// I2C address
protected Bme68x(II2cBus i2cBus, byte address = (byte)Addresses.Default)
{
configuration = new Configuration();
- sensor = new Bme68xI2C(i2cBus, address);
+ busComms = new I2cCommunications(i2cBus, address);
Initialize();
}
@@ -230,11 +259,11 @@ protected Bme68x(ISpiBus spiBus, IPin chipSelectPin) :
/// The BMP68x configuration (optional)
protected Bme68x(ISpiBus spiBus, IDigitalOutputPort chipSelectPort, Configuration? configuration = null)
{
- sensor = new Bme68xSPI(spiBus, chipSelectPort);
+ busComms = new Bme68xSpiCommunications(spiBus, chipSelectPort, DefaultSpiBusSpeed, DefaultSpiBusMode);
this.configuration = configuration ?? new Configuration();
- byte value = sensor.ReadRegister((byte)Registers.STATUS);
- sensor.WriteRegister((byte)Registers.STATUS, value);
+ byte value = busComms.ReadRegister((byte)Registers.STATUS);
+ busComms.WriteRegister((byte)Registers.STATUS, value);
Initialize();
}
@@ -247,17 +276,17 @@ protected void Initialize()
Reset();
calibration = new Calibration();
- calibration.LoadCalibrationDataFromSensor(sensor);
+ calibration.LoadCalibrationDataFromSensor(busComms);
// Init the temp and pressure registers
var status = (byte)((((byte)configuration.TemperatureOversample << 5) & 0xe0) |
(((byte)configuration.PressureOversample << 2) & 0x1c));
- sensor.WriteRegister((byte)Registers.CTRL_MEAS, status);
+ busComms.WriteRegister((byte)Registers.CTRL_MEAS, status);
// Init the humidity registers
status = (byte)((byte)configuration.HumidityOversample & 0x07);
- sensor.WriteRegister((byte)Registers.CTRL_HUM, status);
+ busComms.WriteRegister((byte)Registers.CTRL_HUM, status);
//enable gas readings
GasConversionIsEnabled = true;
@@ -268,7 +297,7 @@ protected void Initialize()
///
public void Reset()
{
- sensor.WriteRegister((byte)Registers.RESET, 0xB6);
+ busComms.WriteRegister((byte)Registers.RESET, 0xB6);
}
///
@@ -284,8 +313,8 @@ public void ConfigureHeatingProfile(HeaterProfileType profile, Units.Temperature
var heaterResistance = CalculateHeaterResistance(targetTemperature, ambientTemperature);
var heaterDuration = CalculateHeaterDuration(duration);
- sensor.WriteRegister((byte)(Registers.GAS_WAIT_0 + (byte)profile), heaterDuration);
- sensor.WriteRegister((byte)(Registers.RES_HEAT_0 + (byte)profile), heaterResistance);
+ busComms.WriteRegister((byte)(Registers.GAS_WAIT_0 + (byte)profile), heaterDuration);
+ busComms.WriteRegister((byte)(Registers.RES_HEAT_0 + (byte)profile), heaterResistance);
// cache heater configuration
if (heaterConfigs.Exists(config => config.HeaterProfile == profile))
@@ -302,7 +331,7 @@ public void ConfigureHeatingProfile(HeaterProfileType profile, Units.Temperature
/// The power mode
public PowerMode GetPowerMode()
{
- var status = sensor.ReadRegister((byte)Registers.CTRL_MEAS);
+ var status = busComms.ReadRegister((byte)Registers.CTRL_MEAS);
return (PowerMode)(status & 0x03);
}
@@ -313,10 +342,10 @@ public PowerMode GetPowerMode()
/// The to set.
public void SetPowerMode(PowerMode powerMode)
{
- var status = sensor.ReadRegister((byte)Registers.CTRL_MEAS);
+ var status = busComms.ReadRegister((byte)Registers.CTRL_MEAS);
byte mask = 0x03;
status = (byte)((status & (byte)~mask) | (byte)powerMode);
- sensor.WriteRegister((byte)Registers.CTRL_MEAS, status);
+ busComms.WriteRegister((byte)Registers.CTRL_MEAS, status);
}
///
@@ -386,42 +415,42 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
/// Reads data from the sensor
///
/// The latest sensor reading
- protected override async Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure, Resistance? GasResistance)> ReadSensor()
+ protected override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure, Resistance? GasResistance)> ReadSensor()
{
configuration.TemperatureOversample = TemperatureOversampleMode;
configuration.PressureOversample = PressureOversampleMode;
configuration.HumidityOversample = HumidityOversampleMode;
- return await Task.Run(() =>
+ return Task.Run(() =>
{
- (Units.Temperature Temperature, RelativeHumidity Humidity, Pressure Pressure, Resistance GasResistance) conditions;
+ (Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure, Resistance? GasResistance) conditions;
//set onetime measurement
SetPowerMode(PowerMode.Forced);
// Read the current control register
- var status = sensor.ReadRegister((byte)Registers.CTRL_MEAS);
+ var status = busComms.ReadRegister((byte)Registers.CTRL_MEAS);
// Force a sample
status = BitHelpers.SetBit(status, 0x00, true);
- sensor.WriteRegister((byte)Registers.CTRL_MEAS, status);
+ busComms.WriteRegister((byte)Registers.CTRL_MEAS, status);
// Wait for the sample to be taken.
do
{
- status = sensor.ReadRegister((byte)Registers.CTRL_MEAS);
+ status = busComms.ReadRegister((byte)Registers.CTRL_MEAS);
} while (BitHelpers.GetBitValue(status, 0x00));
//read temperature
byte[] data = new byte[3];
- sensor.ReadRegister((byte)Registers.TEMPDATA, data);
+ busComms.ReadRegister((byte)Registers.TEMPDATA, data);
var rawTemperature = (data[0] << 12) | (data[1] << 4) | ((data[2] >> 4) & 0x0);
//read humidity
- var rawHumidity = sensor.ReadRegisterAsUShort((byte)Registers.HUMIDITYDATA, ByteOrder.BigEndian);
+ var rawHumidity = busComms.ReadRegisterAsUShort((byte)Registers.HUMIDITYDATA, ByteOrder.BigEndian);
//read pressure
- sensor.ReadRegister((byte)Registers.PRESSUREDATA, data);
+ busComms.ReadRegister((byte)Registers.PRESSUREDATA, data);
var rawPressure = (data[0] << 12) | (data[1] << 4) | ((data[2] >> 4) & 0x0);
if (GasConversionIsEnabled)
@@ -429,8 +458,8 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
Thread.Sleep(GetMeasurementDuration(HeaterProfile));
// Read 10 bit gas resistance value from registers
- var gasResRaw = sensor.ReadRegister((byte)Registers.GAS_RES);
- var gasRange = sensor.ReadRegister((byte)Registers.GAS_RANGE);
+ var gasResRaw = busComms.ReadRegister((byte)Registers.GAS_RES);
+ var gasRange = busComms.ReadRegister((byte)Registers.GAS_RANGE);
var gasRes = (ushort)((ushort)(gasResRaw << 2) + (byte)(gasRange >> 6));
gasRange &= 0x0F;
conditions.GasResistance = CalculateGasResistance(gasRes, gasRange);
@@ -444,7 +473,6 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
conditions.Pressure = CompensatePressure(rawPressure);
conditions.Humidity = CompensateHumidity(rawHumidity);
-
return conditions;
});
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xComms.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xComms.cs
deleted file mode 100644
index 37da523603..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xComms.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal abstract class Bme68xComms
- {
- public abstract void WriteRegister(byte address, byte value);
-
- public abstract void ReadRegister(byte address, Span readBuffer);
-
- public abstract byte ReadRegister(byte address);
-
- public abstract ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian);
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xI2C.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xI2C.cs
deleted file mode 100644
index b281ee5d1e..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xI2C.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal class Bme68xI2C : Bme68xComms
- {
- protected I2cPeripheral i2CPeripheral;
-
- internal Bme68xI2C(II2cBus i2c, byte busAddress)
- {
- i2CPeripheral = new I2cPeripheral(i2c, busAddress);
- }
-
- public override byte ReadRegister(byte address) => i2CPeripheral.ReadRegister(address);
-
- public override ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian) => i2CPeripheral.ReadRegisterAsUShort(address, order);
-
- public override void ReadRegister(byte address, Span readBuffer)
- {
- i2CPeripheral.ReadRegister(address, readBuffer);
- }
-
- public override void WriteRegister(byte register, byte value)
- {
- i2CPeripheral.WriteRegister(register, value);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSPI.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSpiCommunications.cs
similarity index 79%
rename from Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSPI.cs
rename to Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSpiCommunications.cs
index 39bc03ceda..e82dc1b9d9 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSPI.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Bme68xSpiCommunications.cs
@@ -1,9 +1,10 @@
-using System;
-using Meadow.Hardware;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
namespace Meadow.Foundation.Sensors.Atmospheric
{
- internal class Bme68xSPI : Bme68xComms
+ internal class Bme68xSpiCommunications : SpiCommunications
{
///
/// Register pages (for SPI only)
@@ -26,13 +27,11 @@ internal enum SpiRegisterPage : byte
Page1 = 0x00,
}
- ISpiPeripheral spiPeripheral;
-
SpiRegisterPage currentPage = SpiRegisterPage.Page1;
- internal Bme68xSPI(ISpiBus spi, IDigitalOutputPort? chipSelect = null)
+ internal Bme68xSpiCommunications(ISpiBus spiBus, IDigitalOutputPort? chipSelect, Frequency busSpeed, SpiClockConfiguration.Mode busMode)
+ : base(spiBus, chipSelect, busSpeed, busMode, 32, 32)
{
- spiPeripheral = new SpiPeripheral(spi, chipSelect, 32, 32);
}
public override byte ReadRegister(byte address)
@@ -42,7 +41,7 @@ public override byte ReadRegister(byte address)
//adjust register for paging
if (address > 0x7F) { address -= 0x7F; }
- return spiPeripheral.ReadRegister(address);
+ return base.ReadRegister(address);
}
public override ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
@@ -52,7 +51,7 @@ public override ushort ReadRegisterAsUShort(byte address, ByteOrder order = Byte
//adjust register for paging
if (address > 0x7F) { address -= 0x7F; }
- return spiPeripheral.ReadRegisterAsUShort(address, order);
+ return base.ReadRegisterAsUShort(address, order);
}
public override void ReadRegister(byte startRegister, Span readBuffer)
@@ -62,9 +61,7 @@ public override void ReadRegister(byte startRegister, Span readBuffer)
//adjust register for paging
if (startRegister > 0x7F) { startRegister -= 0x7F; }
- spiPeripheral.ReadRegister(startRegister, readBuffer);
-
- return;
+ base.ReadRegister(startRegister, readBuffer);
}
public override void WriteRegister(byte register, byte value)
@@ -74,7 +71,7 @@ public override void WriteRegister(byte register, byte value)
//adjust register for paging
if (register > 0x7F) { register -= 0x7F; }
- spiPeripheral.WriteRegister(register, value);
+ base.WriteRegister(register, value);
}
void SetPageForRegister(byte register)
@@ -85,7 +82,7 @@ void SetPageForRegister(byte register)
//swap the page
currentPage = (currentPage == SpiRegisterPage.Page0) ? SpiRegisterPage.Page1 : SpiRegisterPage.Page0;
//write the page to the status register
- spiPeripheral.WriteRegister(0x73, (byte)currentPage);
+ base.WriteRegister(0x73, (byte)currentPage);
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme680.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme680.cs
index 2441006989..5024dc58e4 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme680.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme680.cs
@@ -3,7 +3,7 @@
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// BME680 Temperature, Pressure, Humidity and gas sensor
+ /// BME680 Temperature, Pressure, Humidity and gas busComms
///
///
/// This class implements the functionality necessary to read the temperature, pressure, humidity and VOS
@@ -13,8 +13,8 @@ public partial class Bme680 : Bme68x
///
/// Creates a new instance of the Bme680 class
///
- /// I2C Bus to use for communicating with the sensor
- /// I2C address of the sensor
+ /// I2C Bus to use for communicating with the busComms
+ /// I2C address of the busComms
public Bme680(II2cBus i2cBus, byte address = (byte)Addresses.Default) : base(i2cBus, address)
{ }
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme688.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme688.cs
index 1d4d20cc49..388dc6e385 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme688.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Drivers/Bme688.cs
@@ -3,7 +3,7 @@
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// BME688 Temperature, Pressure, Humidity and gas sensor
+ /// BME688 Temperature, Pressure, Humidity and gas busComms
///
///
/// This class implements the functionality necessary to read the temperature, pressure, humidity and VOS
@@ -13,8 +13,8 @@ public partial class Bme688 : Bme68x
///
/// Creates a new instance of the BME688 class
///
- /// I2C Bus to use for communicating with the sensor
- /// I2C address of the sensor
+ /// I2C Bus to use for communicating with the busComms
+ /// I2C address of the busComms
public Bme688(II2cBus i2cBus, byte address = (byte)Addresses.Default) : base(i2cBus, address)
{ }
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Sensors.Atmospheric.Bme68x.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Sensors.Atmospheric.Bme68x.csproj
index e6c1297e25..8df91d23c0 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Sensors.Atmospheric.Bme68x.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Driver/Sensors.Atmospheric.Bme68x.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/Bme680_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/Bme680_Sample.csproj
index 83f1e815c1..fa9f774f7d 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/Bme680_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/Bme680_Sample.csproj
@@ -13,7 +13,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/MeadowApp.cs
index 8348ce5884..a8cdef775a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme680_Sample/MeadowApp.cs
@@ -32,7 +32,7 @@ public override Task Initialize()
//c# 8 pattern match syntax. checks for !null and assigns var.
if (result.Old?.Temperature is { } oldTemp &&
result.Old?.Humidity is { } oldHumidity &&
- result.New.Temperature is { } newTemp &&
+ result.New.Temperature is { } newTemp &&
result.New.Humidity is { } newHumidity)
{
return ((newTemp - oldTemp).Abs().Celsius > 0.5 &&
@@ -44,7 +44,7 @@ result.New.Temperature is { } newTemp &&
sensor?.Subscribe(consumer);
- if(sensor != null)
+ if (sensor != null)
{
sensor.Updated += (sender, result) =>
{
@@ -67,7 +67,7 @@ result.New.Temperature is { } newTemp &&
void EnableGasHeater()
{
- if(sensor != null)
+ if (sensor != null)
{
sensor.GasConversionIsEnabled = true;
sensor.HeaterIsEnabled = true;
@@ -94,7 +94,7 @@ void CreateI2CSensor()
async Task ReadConditions()
{
- if(sensor == null) { return; }
+ if (sensor == null) { return; }
var (Temperature, Humidity, Pressure, Resistance) = await sensor.Read();
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/Bme688_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/Bme688_Sample.csproj
index 83f1e815c1..fa9f774f7d 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/Bme688_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/Bme688_Sample.csproj
@@ -13,7 +13,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/MeadowApp.cs
index 2ad5b80e25..176ee63502 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bme68x/Samples/Bme688_Sample/MeadowApp.cs
@@ -33,7 +33,7 @@ public override Task Initialize()
//c# 8 pattern match syntax. checks for !null and assigns var.
if (result.Old?.Temperature is { } oldTemp &&
result.Old?.Humidity is { } oldHumidity &&
- result.New.Temperature is { } newTemp &&
+ result.New.Temperature is { } newTemp &&
result.New.Humidity is { } newHumidity)
{
return ((newTemp - oldTemp).Abs().Celsius > 0.5 &&
@@ -45,7 +45,7 @@ result.New.Temperature is { } newTemp &&
sensor?.Subscribe(consumer);
- if(sensor != null)
+ if (sensor != null)
{
sensor.Updated += (sender, result) =>
{
@@ -95,7 +95,7 @@ void CreateI2CSensor()
async Task ReadConditions()
{
- if(sensor == null) { return; }
+ if (sensor == null) { return; }
var (Temperature, Humidity, Pressure, Resistance) = await sensor.Read();
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.Enums.cs
index 7d5e91e036..d7c56df4b7 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.Enums.cs
@@ -3,7 +3,7 @@
public partial class Bmp085
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.cs
index 4a071ad2a7..c1dc593e84 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Bmp085.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
@@ -12,23 +12,28 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Bmp085 :
ByteCommsSensorBase<(Units.Temperature? Temperature, Pressure? Pressure)>,
- ITemperatureSensor, IBarometricPressureSensor
+ ITemperatureSensor, IBarometricPressureSensor, II2cPeripheral
{
///
/// Raised when the temperature value changes
///
public event EventHandler> TemperatureUpdated = delegate { };
-
+
///
/// Raised when the pressure value changes
///
public event EventHandler> PressureUpdated = delegate { };
- // Oversampling for measurements. Please see the datasheet for this sensor for more information.
- byte oversamplingSetting;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ readonly byte oversamplingSetting;
- // These wait times correspond to the oversampling settings.
- // Please see the datasheet for this sensor for more information.
+ ///
+ /// These wait times correspond to the oversampling settings
+ ///
readonly byte[] pressureWaitTime = { 5, 8, 14, 26 };
// Calibration data backing stores
@@ -45,12 +50,12 @@ public partial class Bmp085 :
private short _md;
///
- /// Last value read from the Pressure sensor.
+ /// Last value read from the Pressure sensor
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// Last value read from the Pressure sensor.
+ /// Last value read from the Pressure sensor
///
public Pressure? Pressure => Conditions.Pressure;
@@ -87,13 +92,13 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
}
///
- /// Calculates the compensated pressure and temperature.
+ /// Calculates the compensated pressure and temperature
///
protected override Task<(Units.Temperature? Temperature, Pressure? Pressure)> ReadSensor()
{
(Units.Temperature? Temperature, Pressure? Pressure) conditions;
- long x1, x2, x3, b3, b4, b5, b6, b7, p;
+ long x1, x2, x3, b4, b5, b6, b7, p;
long ut = ReadUncompensatedTemperature();
@@ -111,24 +116,15 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
x1 = (_b2 * (b6 * b6 >> 12)) >> 11;
x2 = _ac2 * b6 >> 11;
x3 = x1 + x2;
-
- switch (oversamplingSetting)
+ var b3 = oversamplingSetting switch
{
- case 0:
- b3 = ((_ac1 * 4 + x3) + 2) >> 2;
- break;
- case 1:
- b3 = ((_ac1 * 4 + x3) + 2) >> 1;
- break;
- case 2:
- b3 = ((_ac1 * 4 + x3) + 2);
- break;
- case 3:
- b3 = ((_ac1 * 4 + x3) + 2) << 1;
- break;
- default:
- throw new Exception("Oversampling setting must be 0-3");
- }
+ 0 => (_ac1 * 4 + x3 + 2) >> 2,
+ 1 => (_ac1 * 4 + x3 + 2) >> 1,
+ 2 => (_ac1 * 4 + x3 + 2),
+ 3 => (_ac1 * 4 + x3 + 2) << 1,
+ _ => throw new Exception("Oversampling setting must be 0-3"),
+ };
+
x1 = _ac3 * b6 >> 13;
x2 = (_b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
@@ -148,53 +144,34 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
private long ReadUncompensatedTemperature()
{
- // write register address
- // TODO: delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF4, 0x2E });
WriteBuffer.Span[0] = 0xf4;
WriteBuffer.Span[1] = 0x2e;
- Peripheral?.Write(WriteBuffer.Span[0..2]);
+ BusComms?.Write(WriteBuffer.Span[0..2]);
- // Required as per datasheet.
Thread.Sleep(5);
- // write register address
- // TODO: Delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF6 });
WriteBuffer.Span[0] = 0xf6;
- Peripheral?.Write(WriteBuffer.Span[0]);
+ BusComms?.Write(WriteBuffer.Span[0]);
- // get MSB and LSB result
- // TODO: Delete after validating
- //byte[] data = new byte[2];
- //data = Peripheral.ReadBytes(2);
- Peripheral?.Read(ReadBuffer.Span[0..2]);
+ BusComms?.Read(ReadBuffer.Span[0..2]);
- return ((ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1]);
+ return (ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1];
}
private long ReadUncompensatedPressure()
{
- // write register address
- // TODO: Delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF4, (byte)(0x34 + (oversamplingSetting << 6)) });
WriteBuffer.Span[0] = 0xf4;
WriteBuffer.Span[1] = (byte)(0x34 + (oversamplingSetting << 6));
- // insert pressure waittime using oversampling setting as index.
Thread.Sleep(pressureWaitTime[oversamplingSetting]);
- // get MSB and LSB result
- // TODO: delete after validating
- //byte[] data = new byte[3];
- //data = Peripheral.ReadRegisters(0xF6, 3);
- Peripheral?.ReadRegister(0xf6, ReadBuffer.Span[0..3]);
+ BusComms?.ReadRegister(0xf6, ReadBuffer.Span[0..3]);
return ((ReadBuffer.Span[0] << 16) | (ReadBuffer.Span[1] << 8) | (ReadBuffer.Span[2])) >> (8 - oversamplingSetting);
}
///
- /// Retrieves the factory calibration data stored in the sensor.
+ /// Retrieves the factory calibration data stored in the sensor
///
private void GetCalibrationData()
{
@@ -213,14 +190,7 @@ private void GetCalibrationData()
private short ReadShort(byte address)
{
- // TODO: i think we already have a method that does this. I'm just not sure
- // which endian it is. not sure what the last statement here is dooing
-
- // get MSB and LSB result
- // TODO: delete after validating
- //byte[] data = new byte[2];
- //data = Peripheral.ReadRegisters(address, 2);
- Peripheral?.ReadRegister(address, ReadBuffer.Span[0..2]);
+ BusComms?.ReadRegister(address, ReadBuffer.Span[0..2]);
return (short)((ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1]);
}
@@ -231,4 +201,4 @@ private short ReadShort(byte address)
async Task ISensor.Read()
=> (await Read()).Pressure.Value;
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Sensors.Atmospheric.Bmp085.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Sensors.Atmospheric.Bmp085.csproj
index fbd33386c7..295379a480 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Sensors.Atmospheric.Bmp085.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Driver/Sensors.Atmospheric.Bmp085.csproj
@@ -16,14 +16,11 @@
Bosch BMP085 I2C barometric pressure sensor
enable
-
- 8.0
-
-
- 8.0
+
+ 10.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Samples/Bmp085_Sample/Bmp085_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Samples/Bmp085_Sample/Bmp085_Sample.csproj
index 97286583d6..c0fa8e1c7f 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Samples/Bmp085_Sample/Bmp085_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp085/Samples/Bmp085_Sample/Bmp085_Sample.csproj
@@ -16,7 +16,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.Enums.cs
index 5e165926b6..8dd4755e8a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.Enums.cs
@@ -2,42 +2,42 @@
{
public partial class Bmp180
{
- ///
- /// Valid addresses for the sensor
- ///
- public enum Addresses : byte
- {
- ///
- /// Bus address 0x77
- ///
- Address_0x77 = 0x77,
- ///
- /// Default bus address
- ///
- Default = Address_0x77
- }
+ ///
+ /// Valid I2C addresses for the sensor
+ ///
+ public enum Addresses : byte
+ {
+ ///
+ /// Bus address 0x77
+ ///
+ Address_0x77 = 0x77,
+ ///
+ /// Default bus address
+ ///
+ Default = Address_0x77
+ }
- ///
- /// BMP180 device mode
- ///
- public enum DeviceMode
- {
- ///
- /// Ultra low power mode
- ///
- UltraLowPower = 0,
- ///
- /// Standard / normal mode
- ///
- Standard = 1,
- ///
- /// High resolution mode
- ///
- HighResolution = 2,
- ///
- /// Ultra high resolution mode
- ///
- UltraHighResolution = 3
- }
- }
+ ///
+ /// BMP180 device mode
+ ///
+ public enum DeviceMode
+ {
+ ///
+ /// Ultra low power mode
+ ///
+ UltraLowPower = 0,
+ ///
+ /// Standard / normal mode
+ ///
+ Standard = 1,
+ ///
+ /// High resolution mode
+ ///
+ HighResolution = 2,
+ ///
+ /// Ultra high resolution mode
+ ///
+ UltraHighResolution = 3
+ }
+ }
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.cs
index 407e13a8e1..45b4b686fa 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Bmp180.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
@@ -12,22 +12,26 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Bmp180 :
ByteCommsSensorBase<(Units.Temperature? Temperature, Pressure? Pressure)>,
- ITemperatureSensor, IBarometricPressureSensor
+ ITemperatureSensor, IBarometricPressureSensor, II2cPeripheral
{
///
/// Raised when the temperature value changes
///
public event EventHandler> TemperatureUpdated = delegate { };
-
+
///
/// Raised when the pressure value changes
///
public event EventHandler> PressureUpdated = delegate { };
- // Oversampling for measurements
- private byte oversamplingSetting;
+ ///
+ /// Oversampling for measurements
+ ///
+ private readonly byte oversamplingSetting;
- // These wait times correspond to the oversampling settings
+ ///
+ /// These wait times correspond to the oversampling settings
+ ///
private readonly byte[] pressureWaitTime = { 5, 8, 14, 26 };
// Calibration data backing stores
@@ -54,9 +58,9 @@ public partial class Bmp180 :
public Pressure? Pressure => Conditions.Pressure;
///
- /// Default SPI bus speed
+ /// The default I2C address for the peripheral
///
- public static Frequency DEFAULT_SPEED = new Frequency(40000, Frequency.UnitType.Kilohertz);
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
///
/// Create a new BMP180 object
@@ -95,113 +99,79 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
///
protected override Task<(Units.Temperature? Temperature, Pressure? Pressure)> ReadSensor()
{
- return Task.Run(() =>
+ (Units.Temperature? Temperature, Pressure? Pressure) conditions;
+
+ long x1, x2, x3, b4, b5, b6, b7, p;
+ long ut = ReadUncompensatedTemperature();
+ long up = ReadUncompensatedPressure();
+
+ // calculate the compensated temperature
+ x1 = (ut - _ac6) * _ac5 >> 15;
+ x2 = (_mc << 11) / (x1 + _md);
+ b5 = x1 + x2;
+
+ conditions.Temperature = new Units.Temperature((float)((b5 + 8) >> 4) / 10, Units.Temperature.UnitType.Celsius);
+
+ // calculate the compensated pressure
+ b6 = b5 - 4000;
+ x1 = (_b2 * (b6 * b6 >> 12)) >> 11;
+ x2 = _ac2 * b6 >> 11;
+ x3 = x1 + x2;
+ var b3 = oversamplingSetting switch
{
- (Units.Temperature? Temperature, Pressure? Pressure) conditions;
-
- long x1, x2, x3, b3, b4, b5, b6, b7, p;
-
- long ut = ReadUncompensatedTemperature();
-
- long up = ReadUncompensatedPressure();
-
- // calculate the compensated temperature
- x1 = (ut - _ac6) * _ac5 >> 15;
- x2 = (_mc << 11) / (x1 + _md);
- b5 = x1 + x2;
-
- conditions.Temperature = new Units.Temperature((float)((b5 + 8) >> 4) / 10, Units.Temperature.UnitType.Celsius);
-
- // calculate the compensated pressure
- b6 = b5 - 4000;
- x1 = (_b2 * (b6 * b6 >> 12)) >> 11;
- x2 = _ac2 * b6 >> 11;
- x3 = x1 + x2;
-
- switch (oversamplingSetting)
- {
- case 0:
- b3 = ((_ac1 * 4 + x3) + 2) >> 2;
- break;
- case 1:
- b3 = ((_ac1 * 4 + x3) + 2) >> 1;
- break;
- case 2:
- b3 = ((_ac1 * 4 + x3) + 2);
- break;
- case 3:
- b3 = ((_ac1 * 4 + x3) + 2) << 1;
- break;
- default:
- throw new Exception("Oversampling setting must be 0-3");
- }
- x1 = _ac3 * b6 >> 13;
- x2 = (_b1 * (b6 * b6 >> 12)) >> 16;
- x3 = ((x1 + x2) + 2) >> 2;
- b4 = (_ac4 * (x3 + 32768)) >> 15;
- b7 = (up - b3) * (50000 >> oversamplingSetting);
- p = (b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2);
- x1 = (p >> 8) * (p >> 8);
- x1 = (x1 * 3038) >> 16;
- x2 = (-7357 * p) >> 16;
-
- int value = (int)(p + ((x1 + x2 + 3791) >> 4));
-
- conditions.Pressure = new Pressure(value, Units.Pressure.UnitType.Pascal);
-
- return conditions;
- });
+ 0 => ((_ac1 * 4 + x3) + 2) >> 2,
+ 1 => ((_ac1 * 4 + x3) + 2) >> 1,
+ 2 => ((_ac1 * 4 + x3) + 2),
+ 3 => ((_ac1 * 4 + x3) + 2) << 1,
+ _ => throw new Exception("Oversampling setting must be 0-3"),
+ };
+ x1 = _ac3 * b6 >> 13;
+ x2 = (_b1 * (b6 * b6 >> 12)) >> 16;
+ x3 = ((x1 + x2) + 2) >> 2;
+ b4 = (_ac4 * (x3 + 32768)) >> 15;
+ b7 = (up - b3) * (50000 >> oversamplingSetting);
+ p = (b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2);
+ x1 = (p >> 8) * (p >> 8);
+ x1 = (x1 * 3038) >> 16;
+ x2 = (-7357 * p) >> 16;
+
+ int value = (int)(p + ((x1 + x2 + 3791) >> 4));
+
+ conditions.Pressure = new Pressure(value, Units.Pressure.UnitType.Pascal);
+
+ return Task.FromResult(conditions);
}
private long ReadUncompensatedTemperature()
{
- // write register address
- // TODO: delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF4, 0x2E });
WriteBuffer.Span[0] = 0xf4;
WriteBuffer.Span[1] = 0x2e;
- Peripheral?.Write(WriteBuffer.Span[0..2]);
+ BusComms?.Write(WriteBuffer.Span[0..2]);
- // Required as per datasheet.
Thread.Sleep(5);
- // write register address
- // TODO: Delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF6 });
WriteBuffer.Span[0] = 0xf6;
- Peripheral?.Write(WriteBuffer.Span[0]);
+ BusComms?.Write(WriteBuffer.Span[0]);
- // get MSB and LSB result
- // TODO: Delete after validating
- //byte[] data = new byte[2];
- //data = Peripheral.ReadBytes(2);
- Peripheral?.Read(ReadBuffer.Span[0..2]);
+ BusComms?.Read(ReadBuffer.Span[0..2]);
return ((ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1]);
}
private long ReadUncompensatedPressure()
{
- // write register address
- // TODO: Delete after validating
- //Peripheral.WriteBytes(new byte[] { 0xF4, (byte)(0x34 + (oversamplingSetting << 6)) });
WriteBuffer.Span[0] = 0xf4;
WriteBuffer.Span[1] = (byte)(0x34 + (oversamplingSetting << 6));
- // insert pressure waittime using oversampling setting as index.
Thread.Sleep(pressureWaitTime[oversamplingSetting]);
- // get MSB and LSB result
- // TODO: delete after validating
- //byte[] data = new byte[3];
- //data = Peripheral.ReadRegisters(0xF6, 3);
- Peripheral?.ReadRegister(0xf6, ReadBuffer.Span[0..3]);
+ BusComms?.ReadRegister(0xf6, ReadBuffer.Span[0..3]);
return ((ReadBuffer.Span[0] << 16) | (ReadBuffer.Span[1] << 8) | (ReadBuffer.Span[2])) >> (8 - oversamplingSetting);
}
///
- /// Retrieves the factory calibration data stored in the sensor.
+ /// Retrieves the factory calibration data stored in the sensor
///
private void GetCalibrationData()
{
@@ -220,14 +190,7 @@ private void GetCalibrationData()
private short ReadShort(byte address)
{
- // TODO: i think we already have a method that does this. I'm just not sure
- // which endian it is. not sure what the last statement here is dooing
-
- // get MSB and LSB result
- // TODO: delete after validating
- //byte[] data = new byte[2];
- //data = Peripheral.ReadRegisters(address, 2);
- Peripheral?.ReadRegister(address, ReadBuffer.Span[0..2]);
+ BusComms?.ReadRegister(address, ReadBuffer.Span[0..2]);
return (short)((ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1]);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Sensors.Atmospheric.Bmp180.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Sensors.Atmospheric.Bmp180.csproj
index 0dcc7dc105..537f9e191d 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Sensors.Atmospheric.Bmp180.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Driver/Sensors.Atmospheric.Bmp180.csproj
@@ -24,6 +24,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Samples/Bmp180_Sample/Bmp180_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Samples/Bmp180_Sample/Bmp180_Sample.csproj
index ea5e26fc25..6b63eb8208 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Samples/Bmp180_Sample/Bmp180_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Bmp180/Samples/Bmp180_Sample/Bmp180_Sample.csproj
@@ -15,7 +15,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.Enums.cs
index 97ad3a3e15..fe5fe1dffd 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.Enums.cs
@@ -3,7 +3,7 @@
public partial class Ccs811
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.cs
index 82ba5f3317..93cbc51566 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Ccs811.cs
@@ -12,7 +12,7 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Ccs811 :
ByteCommsSensorBase<(Concentration? Co2, Concentration? Voc)>,
- ICo2Sensor, IVocSensor
+ ICo2Sensor, IVocSensor, II2cPeripheral
{
private const int ReadBufferSize = 10;
private const int WriteBufferSize = 8;
@@ -39,6 +39,11 @@ public partial class Ccs811 :
///
public Concentration? Voc => Conditions.Voc;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new Ccs811 object
///
@@ -79,31 +84,31 @@ protected void Initialize()
Thread.Sleep(100);
- var id = Peripheral?.ReadRegister((byte)Register.HW_ID);
+ var id = BusComms?.ReadRegister((byte)Register.HW_ID);
if (id != 0x81)
{
throw new Exception("Hardware is not identifying as a CCS811");
}
- Peripheral?.Write((byte)BootloaderCommand.APP_START);
+ BusComms?.Write((byte)BootloaderCommand.APP_START);
SetMeasurementMode(MeasurementMode.ConstantPower1s);
- var mode = Peripheral?.ReadRegister((byte)Register.MEAS_MODE);
+ var mode = BusComms?.ReadRegister((byte)Register.MEAS_MODE);
}
private void ShowDebugInfo()
{
- var ver = Peripheral?.ReadRegister((byte)Register.HW_VERSION);
+ var ver = BusComms?.ReadRegister((byte)Register.HW_VERSION);
Resolver.Log.Info($"hardware version A = 0x{ver:x2}");
- var fwb = Peripheral?.ReadRegister((byte)Register.FW_BOOT_VERSION);
+ var fwb = BusComms?.ReadRegister((byte)Register.FW_BOOT_VERSION);
Resolver.Log.Info($"FWB version = 0x{fwb:x4}");
- var fwa = Peripheral?.ReadRegister((byte)Register.FW_APP_VERSION);
+ var fwa = BusComms?.ReadRegister((byte)Register.FW_APP_VERSION);
Resolver.Log.Info($"FWA version = 0x{fwa:x4}");
// read status
- var status = Peripheral?.ReadRegister((byte)Register.STATUS);
+ var status = BusComms?.ReadRegister((byte)Register.STATUS);
Resolver.Log.Info($"status = 0x{status:x2}");
}
@@ -113,7 +118,7 @@ private void ShowDebugInfo()
/// The baseline value
public ushort GetBaseline()
{
- return Peripheral?.ReadRegister((byte)Register.BASELINE) ?? 0;
+ return BusComms?.ReadRegister((byte)Register.BASELINE) ?? 0;
}
///
@@ -122,7 +127,7 @@ public ushort GetBaseline()
/// The new baseline
public void SetBaseline(ushort value)
{
- Peripheral?.WriteRegister((byte)Register.BASELINE, (byte)value);
+ BusComms?.WriteRegister((byte)Register.BASELINE, (byte)value);
}
///
@@ -131,7 +136,7 @@ public void SetBaseline(ushort value)
/// The measurement mode
public MeasurementMode GetMeasurementMode()
{
- return (MeasurementMode)(Peripheral?.ReadRegister((byte)Register.MEAS_MODE) ?? 0);
+ return (MeasurementMode)(BusComms?.ReadRegister((byte)Register.MEAS_MODE) ?? 0);
}
///
@@ -141,31 +146,28 @@ public MeasurementMode GetMeasurementMode()
public void SetMeasurementMode(MeasurementMode mode)
{
var m = (byte)mode;
- Peripheral?.WriteRegister((byte)Register.MEAS_MODE, m);
+ BusComms?.WriteRegister((byte)Register.MEAS_MODE, m);
}
void Reset()
{
- Peripheral?.Write(new byte[] { (byte)Register.SW_RESET, 0x11, 0xE5, 0x72, 0x8A });
+ BusComms?.Write(new byte[] { (byte)Register.SW_RESET, 0x11, 0xE5, 0x72, 0x8A });
}
///
/// Reads data from the sensor
///
/// The latest sensor reading
- protected override async Task<(Concentration? Co2, Concentration? Voc)> ReadSensor()
+ protected override Task<(Concentration? Co2, Concentration? Voc)> ReadSensor()
{
- return await Task.Run(() =>
- {
- // data is really in just the first 4, but this gets us status and raw data as well
- Peripheral?.ReadRegister((byte)Register.ALG_RESULT_DATA, _readingBuffer);
+ // data is really in just the first 4, but this gets us status and raw data as well
+ BusComms?.ReadRegister((byte)Register.ALG_RESULT_DATA, _readingBuffer);
- (Concentration co2, Concentration voc) state;
- state.co2 = new Concentration(_readingBuffer[0] << 8 | _readingBuffer[1], Concentration.UnitType.PartsPerMillion);
- state.voc = new Concentration(_readingBuffer[2] << 8 | _readingBuffer[3], Concentration.UnitType.PartsPerBillion);
+ (Concentration? co2, Concentration? voc) state;
+ state.co2 = new Concentration(_readingBuffer[0] << 8 | _readingBuffer[1], Concentration.UnitType.PartsPerMillion);
+ state.voc = new Concentration(_readingBuffer[2] << 8 | _readingBuffer[3], Concentration.UnitType.PartsPerBillion);
- return state;
- });
+ return Task.FromResult(state);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Sensors.Atmospheric.Ccs811.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Sensors.Atmospheric.Ccs811.csproj
index 6fecfbc9bd..b483343bec 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Sensors.Atmospheric.Ccs811.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Driver/Sensors.Atmospheric.Ccs811.csproj
@@ -8,7 +8,7 @@
http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
Meadow.Foundation.Sensors.Atmospheric.Ccs811
https://github.com/WildernessLabs/Meadow.Foundation
- Meadow.Foundation, VOC, Air, Ccs811
+ Meadow.Foundation,VOC,Air,quality,Ccs811
0.1.17
true
Ccs811 I2C VOC Air Quality Sensor
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/Ccs811_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/Ccs811_Sample.csproj
index c97ba8a43c..dd489af886 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/Ccs811_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/Ccs811_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/MeadowApp.cs
index 3a261bfe60..c6c29d3add 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ccs811/Samples/Ccs811_Sample/MeadowApp.cs
@@ -16,8 +16,8 @@ public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
- var i2c = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
- sensor = new Ccs811(i2c);
+ var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Fast);
+ sensor = new Ccs811(i2cBus);
var consumer = Ccs811.CreateObserver(
handler: result =>
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.Enums.cs
index d7859084cd..75422d5c88 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.Enums.cs
@@ -8,7 +8,7 @@
public abstract partial class DhtBase
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.cs
index ca8d9b6ee8..f1c2f21b64 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/DhtBase.cs
@@ -1,17 +1,16 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// Provide a mechanism for reading the Temperature and Humidity from
- /// a DHT temperature and Humidity sensor.
+ /// Base class for th DHT family Temperature and Humidity sensors
///
- public abstract partial class DhtBase :
+ public abstract partial class DhtBase :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
ITemperatureSensor, IHumiditySensor
{
@@ -26,25 +25,24 @@ public abstract partial class DhtBase :
public event EventHandler> HumidityUpdated = delegate { };
private readonly BusType protocol;
- private int lastMeasurement = 0;
///
- /// The temperature
+ /// The current temperature
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// The relative humidity
+ /// The current relative humidity
///
public RelativeHumidity? Humidity => Conditions.Humidity;
///
- /// How last read went, true for success, false for failure
+ /// Was the last sensor read succesful, true for success, false for failure
///
public bool WasLastReadSuccessful { get; internal set; }
///
- /// Create a DHT sensor through I2C (Only DHT12)
+ /// Create a DHT sensor through I2C
///
/// The I2C bus connected to the sensor
/// The I2C address
@@ -62,11 +60,11 @@ public DhtBase(II2cBus i2cBus, byte address = (byte)Addresses.Default)
///
internal virtual void ReadData()
{
- if (protocol == BusType.OneWire)
+ if (protocol == BusType.OneWire)
{
ReadDataOneWire();
- }
- else
+ }
+ else
{
ReadDataI2c();
}
@@ -85,16 +83,14 @@ internal virtual void ReadDataOneWire()
///
internal virtual void ReadDataI2c()
{
- Peripheral?.Write(0x00);
- Peripheral?.Read(ReadBuffer.Span[0..5]);
+ BusComms?.Write(0x00);
+ BusComms?.Read(ReadBuffer.Span[0..5]);
- lastMeasurement = Environment.TickCount;
-
- if ((ReadBuffer.Span[4] == ((ReadBuffer.Span[0] + ReadBuffer.Span[1] + ReadBuffer.Span[2] + ReadBuffer.Span[3]) & 0xFF)))
+ if ((ReadBuffer.Span[4] == ((ReadBuffer.Span[0] + ReadBuffer.Span[1] + ReadBuffer.Span[2] + ReadBuffer.Span[3]) & 0xFF)))
{
WasLastReadSuccessful = (ReadBuffer.Span[0] != 0) || (ReadBuffer.Span[2] != 0);
- }
- else
+ }
+ else
{
WasLastReadSuccessful = false;
}
@@ -118,10 +114,12 @@ internal virtual void ReadDataI2c()
/// The updated sensor data
protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> changeResult)
{
- if (changeResult.New.Temperature is { } temp) {
+ if (changeResult.New.Temperature is { } temp)
+ {
TemperatureUpdated?.Invoke(this, new ChangeResult(temp, changeResult.Old?.Temperature));
}
- if (changeResult.New.Humidity is { } humidity) {
+ if (changeResult.New.Humidity is { } humidity)
+ {
HumidityUpdated?.Invoke(this, new ChangeResult(humidity, changeResult.Old?.Humidity));
}
base.RaiseEventsAndNotify(changeResult);
@@ -135,11 +133,11 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
{
(Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
- if (protocol == BusType.I2C)
+ if (protocol == BusType.I2C)
{
ReadDataI2c();
- }
- else
+ }
+ else
{
ReadDataOneWire();
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht10.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht10.cs
index df78623d84..f10e36019f 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht10.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht10.cs
@@ -11,11 +11,9 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public class Dht10 : DhtBase
{
- private const byte CMD_INIT = 0b_1110_0001;
- private const byte CMD_START = 0b_1010_1100;
- private const byte CMD_SOFTRESET = 0b_1011_1010;
-
- //private new byte[] _readBuffer = new byte[6];
+ private const byte CMD_INIT = 0b_1110_0001;
+ private const byte CMD_START = 0b_1010_1100;
+ private const byte CMD_SOFTRESET = 0b_1011_1010;
///
/// Create a new Dht10 object.
@@ -25,20 +23,20 @@ public class Dht10 : DhtBase
public Dht10(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address)
{
- Peripheral?.Write(CMD_SOFTRESET);
+ BusComms?.Write(CMD_SOFTRESET);
Thread.Sleep(20);
- Peripheral?.Write(CMD_INIT);
+ BusComms?.Write(CMD_INIT);
}
internal override void ReadDataI2c()
{
WasLastReadSuccessful = true;
- Peripheral?.Write(CMD_START);
+ BusComms?.Write(CMD_START);
Thread.Sleep(75);
-
+
//data stored in the read buffer
- Peripheral?.Read(ReadBuffer.Span);
+ BusComms?.Read(ReadBuffer.Span);
}
internal override float GetHumidity()
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht12.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht12.cs
index 2b6e38a371..36818a7258 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht12.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Drivers/Dht12.cs
@@ -8,8 +8,13 @@ namespace Meadow.Foundation.Sensors.Atmospheric
/// 0 - 95% humidity +/- 4%
/// Currently only supports I2C
///
- public class Dht12 : DhtBase
+ public class Dht12 : DhtBase, II2cPeripheral
{
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new Dht12 object
///
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Sensors.Atmospheric.Dhtxx.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Sensors.Atmospheric.Dhtxx.csproj
index 069e5093c9..3d2c5706c7 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Sensors.Atmospheric.Dhtxx.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Driver/Sensors.Atmospheric.Dhtxx.csproj
@@ -24,6 +24,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht10_Sample/Dht10_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht10_Sample/Dht10_Sample.csproj
index 817e4fd8ce..a6ac2afe10 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht10_Sample/Dht10_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht10_Sample/Dht10_Sample.csproj
@@ -13,7 +13,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht12_Sample/Dht12_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht12_Sample/Dht12_Sample.csproj
index 817e4fd8ce..a6ac2afe10 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht12_Sample/Dht12_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Dhtxx/Samples/Dht12_Sample/Dht12_Sample.csproj
@@ -13,7 +13,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.Enums.cs
index 9fc95a27e4..c087fed902 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.Enums.cs
@@ -3,7 +3,7 @@
public partial class Hih6130
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.cs
index 443f7d2a49..3a4510fb9d 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Hih6130.cs
@@ -1,25 +1,23 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// Provide a mechanism for reading the Temperature and Humidity from
- /// a HIH6130 temperature and Humidity sensor.
+ /// Represents an HIH6130 Temperature and Humidity sensor
///
public partial class Hih6130 :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Raised when the temperature value changes
///
public event EventHandler> TemperatureUpdated = delegate { };
-
+
///
/// Raised when the humidity value changes
///
@@ -35,6 +33,11 @@ public partial class Hih6130 :
///
public RelativeHumidity? Humidity => Conditions.Humidity;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new HIH6130 object using the default parameters for the component.
///
@@ -51,10 +54,12 @@ public Hih6130(II2cBus i2cBus, byte address = (byte)Addresses.Default)
///
protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> changeResult)
{
- if (changeResult.New.Temperature is { } temp) {
+ if (changeResult.New.Temperature is { } temp)
+ {
TemperatureUpdated?.Invoke(this, new ChangeResult(temp, changeResult.Old?.Temperature));
}
- if (changeResult.New.Humidity is { } humidity) {
+ if (changeResult.New.Humidity is { } humidity)
+ {
HumidityUpdated?.Invoke(this, new ChangeResult(humidity, changeResult.Old?.Humidity));
}
base.RaiseEventsAndNotify(changeResult);
@@ -68,12 +73,12 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
(Units.Temperature Temperature, RelativeHumidity Humidity) conditions;
// send a start signal on the I2C bus to notify the sensor to read.
- Peripheral?.Write(0);
+ BusComms?.Write(0);
// Sensor takes 35ms to make a valid reading.
await Task.Delay(40);
// read data from the sensor
- Peripheral?.Read(base.ReadBuffer.Span);
+ BusComms?.Read(base.ReadBuffer.Span);
//
// Data format:
//
@@ -82,7 +87,7 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
// Byte 2: T13 T12 T11 T10 T9 T8 T7 T6
// Byte 4: T5 T4 T3 T2 T1 T0 XX XX
//
- if ((ReadBuffer.Span[0] & 0xc0) != 0)
+ if ((ReadBuffer.Span[0] & 0xc0) != 0)
{
throw new Exception("Status indicates readings are invalid.");
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Sensors.Atmospheric.Hih6130.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Sensors.Atmospheric.Hih6130.csproj
index 96166010f9..fd1e126a99 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Sensors.Atmospheric.Hih6130.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Driver/Sensors.Atmospheric.Hih6130.csproj
@@ -24,6 +24,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Samples/Hih6130_Sample/Hih6130_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Samples/Hih6130_Sample/Hih6130_Sample.csproj
index 7bc56e1bd4..44c5f7a8a5 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Samples/Hih6130_Sample/Hih6130_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Hih6130/Samples/Hih6130_Sample/Hih6130_Sample.csproj
@@ -16,7 +16,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Extras/Htu31d.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Extras/Htu31d.Enums.cs
index ded356fe6b..d8e3e61c56 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Extras/Htu31d.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Extras/Htu31d.Enums.cs
@@ -3,7 +3,7 @@
public partial class Htu31d
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu21d.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu21d.cs
index d8b228e476..df61f72e6c 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu21d.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu21d.cs
@@ -33,11 +33,11 @@ public Htu21d(II2cBus i2cBus, byte address = (byte)Addresses.Default, TimeSpan?
///
/// Initialize HTU21D
///
- protected void Initialize ()
+ protected void Initialize()
{
- Peripheral?.Write((byte)Registers.SOFT_RESET);
-
- Thread.Sleep(100);
+ BusComms?.Write((byte)Registers.SOFT_RESET);
+
+ Thread.Sleep(100);
SetResolution(SensorResolution.TEMP11_HUM11);
}
@@ -48,51 +48,46 @@ protected void Initialize ()
/// The latest sensor reading
protected override async Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
{
- (Units.Temperature Temperature, RelativeHumidity Humidity) conditions;
+ (Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
- return await Task.Run(() =>
- {
- // humidity
- Peripheral?.Write((byte)Registers.HUMDITY_MEASURE_NOHOLD);
- Thread.Sleep(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
-
- Peripheral?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
- var humidityReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
- var humidity = (125 * (float)humidityReading / 65536) - 6;
- humidity = Math.Clamp(humidity, 0, 100);
- conditions.Humidity = new RelativeHumidity(humidity, HU.Percent);
-
- // temperature
- Peripheral?.Write((byte)Registers.TEMPERATURE_MEASURE_NOHOLD);
- Thread.Sleep(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
-
- Peripheral?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
- var temperatureReading = (short)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
- conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), Units.Temperature.UnitType.Celsius);
-
- return conditions;
- });
+ BusComms?.Write((byte)Registers.HUMDITY_MEASURE_NOHOLD);
+ await Task.Delay(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
+
+ BusComms?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
+ var humidityReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
+ var humidity = (125 * (float)humidityReading / 65536) - 6;
+ humidity = Math.Clamp(humidity, 0, 100);
+ conditions.Humidity = new RelativeHumidity(humidity, HU.Percent);
+
+ BusComms?.Write((byte)Registers.TEMPERATURE_MEASURE_NOHOLD);
+ await Task.Delay(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
+
+ BusComms?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
+ var temperatureReading = (short)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
+ conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), Units.Temperature.UnitType.Celsius);
+
+ return conditions;
}
-
- ///
- /// Turn the heater on or off
+
+ ///
+ /// Turn the heater on or off
///
/// Heater status, true = turn heater on, false = turn heater off.
public void Heater(bool heaterOn)
{
- if (Peripheral == null) return;
+ if (BusComms == null) return;
- var register = Peripheral.ReadRegister((byte)Registers.READ_HEATER_REGISTER);
+ var register = BusComms.ReadRegister((byte)Registers.READ_HEATER_REGISTER);
register &= 0xfd;
if (heaterOn)
{
register |= 0x02;
}
- Peripheral.WriteRegister((byte)Registers.WRITE_HEATER_REGISTER, register);
+ BusComms.WriteRegister((byte)Registers.WRITE_HEATER_REGISTER, register);
}
-
- //Set sensor resolution
+
+ //Set sensor resolution
/*******************************************************************************************/
//Sets the sensor resolution to one of four levels
//Page 12:
@@ -103,9 +98,9 @@ public void Heater(bool heaterOn)
//Power on default is 0/0
void SetResolution(SensorResolution resolution)
{
- if (Peripheral == null) return;
+ if (BusComms == null) return;
- var register = Peripheral.ReadRegister((byte)Registers.READ_USER_REGISTER);
+ var register = BusComms.ReadRegister((byte)Registers.READ_USER_REGISTER);
var res = (byte)resolution;
@@ -114,7 +109,7 @@ void SetResolution(SensorResolution resolution)
register |= res; //Mask in the requested resolution bits
//Request a write to user register
- Peripheral.WriteRegister((byte)Registers.WRITE_USER_REGISTER, register); //Write the new resolution bits
+ BusComms.WriteRegister((byte)Registers.WRITE_USER_REGISTER, register); //Write the new resolution bits
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu31d.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu31d.cs
index 8ee64cdfda..c8cd0cdd4c 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu31d.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Drivers/Htu31d.cs
@@ -29,63 +29,58 @@ public Htu31d(II2cBus i2cBus, byte address = (byte)Addresses.Default, TimeSpan?
/// Read atmospheric data from sensor
///
///
- protected override async Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
+ protected async override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
{
- (Units.Temperature Temperature, RelativeHumidity Humidity) conditions;
+ (Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
- return await Task.Run(() =>
- {
- Peripheral?.Write((byte)Commands.Conversion);
- Thread.Sleep(20); // Maximum conversion time is 20ms
- Peripheral?.ReadRegister((byte)Commands.ReadTempHumidity, ReadBuffer.Span[0..5]);// 2 bytes for temp, checksum, 2 bytes humidity, checksum
+ BusComms?.Write((byte)Commands.Conversion);
+ await Task.Delay(20); // Maximum conversion time is 20ms
+ BusComms?.ReadRegister((byte)Commands.ReadTempHumidity, ReadBuffer.Span[0..5]);// 2 bytes for temp, checksum, 2 bytes humidity, checksum
- // temperature
- var temperatureReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
- conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), Units.Temperature.UnitType.Celsius);
+ var temperatureReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
+ conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), Units.Temperature.UnitType.Celsius);
- // humidity
- var humidityReading = (ushort)((ReadBuffer.Span[3] << 8) + ReadBuffer.Span[4]);
- var humidity = (125 * (float)humidityReading / 65536) - 6;
- humidity = Math.Clamp(humidity, 0, 100);
- conditions.Humidity = new RelativeHumidity(humidity, HU.Percent);
+ var humidityReading = (ushort)((ReadBuffer.Span[3] << 8) + ReadBuffer.Span[4]);
+ var humidity = (125 * (float)humidityReading / 65536) - 6;
+ humidity = Math.Clamp(humidity, 0, 100);
+ conditions.Humidity = new RelativeHumidity(humidity, HU.Percent);
- return conditions;
- });
+ return conditions;
}
-
+
///
- /// Turn the heater on or off
+ /// Turn the heater on or off
///
/// Heater status, true = turn heater on, false = turn heater off
public void Heater(bool heaterOn)
{
- if(heaterOn)
- {
- Peripheral?.WriteRegister((byte)Commands.HeaterOn, 1);
- }
- else
+ if (heaterOn)
{
- Peripheral?.WriteRegister((byte)Commands.HeaterOff, 1);
+ BusComms?.WriteRegister((byte)Commands.HeaterOn, 1);
+ }
+ else
+ {
+ BusComms?.WriteRegister((byte)Commands.HeaterOff, 1);
}
}
-
+
///
/// Reset the sensor
///
- public void Reset()
+ public void Reset()
{
- Peripheral?.WriteRegister((byte)Commands.Reset, 1);
+ BusComms?.WriteRegister((byte)Commands.Reset, 1);
Thread.Sleep(15); //could make this async ...
}
private UInt32 GetSerial()
{
- if (Peripheral == null) return 0;
+ if (BusComms == null) return 0;
var data = new byte[4];
- Peripheral.ReadRegister((byte)Commands.ReadSerial, data);
+ BusComms.ReadRegister((byte)Commands.ReadSerial, data);
UInt32 serial;
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Htux1dBase.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Htux1dBase.cs
index 01b6f6a939..b8b530164b 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Htux1dBase.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Htux1dBase.cs
@@ -7,7 +7,7 @@
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
@@ -26,7 +26,7 @@ public enum Addresses : byte
///
public abstract class Htux1dBase :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Temperature changed event
@@ -38,6 +38,11 @@ public abstract class Htux1dBase :
///
public event EventHandler> HumidityUpdated = delegate { };
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Default I2C bus speed
///
@@ -70,7 +75,7 @@ public Htux1dBase(II2cBus i2cBus, byte address = (byte)Addresses.Default, TimeSp
}
///
- /// Inheritance-safe way to raise events and notify observers.
+ /// Inheritance-safe way to raise events and notify observers
///
/// New temperature and humidity values
protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> changeResult)
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Sensors.Atmospheric.Htux1d.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Sensors.Atmospheric.Htux1d.csproj
index 133d810927..ec728f1170 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Sensors.Atmospheric.Htux1d.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Driver/Sensors.Atmospheric.Htux1d.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu21d_Sample/Htu21d_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu21d_Sample/Htu21d_Sample.csproj
index 1aea63c6d8..d85e67fc66 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu21d_Sample/Htu21d_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu21d_Sample/Htu21d_Sample.csproj
@@ -13,7 +13,7 @@
9.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu31d_Sample/Htu31d_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu31d_Sample/Htu31d_Sample.csproj
index 1aea63c6d8..d85e67fc66 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu31d_Sample/Htu31d_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Htu2xd/Samples/Htu31d_Sample/Htu31d_Sample.csproj
@@ -13,7 +13,7 @@
9.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.Addresses.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.Addresses.cs
index 0ee5b7501a..76a03b1658 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.Addresses.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.Addresses.cs
@@ -3,7 +3,7 @@
public partial class Mpl3115a2
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.cs
index 6472078044..284a7281e6 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Mpl3115a2.cs
@@ -1,9 +1,8 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
@@ -12,7 +11,7 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Mpl3115a2 :
ByteCommsSensorBase<(Units.Temperature? Temperature, Pressure? Pressure)>,
- ITemperatureSensor, IBarometricPressureSensor
+ ITemperatureSensor, IBarometricPressureSensor, II2cPeripheral
{
///
/// Event raised when temperature value changes
@@ -43,10 +42,10 @@ public partial class Mpl3115a2 :
///
public bool Standby
{
- get => (Peripheral?.ReadRegister(Registers.Control1) & 0x01) > 0;
+ get => (BusComms?.ReadRegister(Registers.Control1) & 0x01) > 0;
set
{
- var status = Peripheral?.ReadRegister(Registers.Control1) ?? 0;
+ var status = BusComms?.ReadRegister(Registers.Control1) ?? 0;
if (value)
{
status &= (byte)~ControlRegisterBits.Active;
@@ -55,14 +54,19 @@ public bool Standby
{
status |= ControlRegisterBits.Active;
}
- Peripheral?.WriteRegister(Registers.Control1, status);
+ BusComms?.WriteRegister(Registers.Control1, status);
}
}
///
/// Get the status register from the sensor
///
- public byte Status => Peripheral?.ReadRegister(Registers.Status) ?? 0;
+ public byte Status => BusComms?.ReadRegister(Registers.Status) ?? 0;
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
///
/// Create a new MPL3115A2 object with the default address and speed settings
@@ -72,15 +76,15 @@ public bool Standby
public Mpl3115a2(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address)
{
- if (Peripheral?.ReadRegister(Registers.WhoAmI) != 0xc4)
+ if (BusComms?.ReadRegister(Registers.WhoAmI) != 0xc4)
{
throw new Exception("Unexpected device ID, expected 0xc4");
}
- Peripheral?.WriteRegister(Registers.Control1,
+ BusComms?.WriteRegister(Registers.Control1,
(byte)(ControlRegisterBits.Active |
ControlRegisterBits.OverSample128));
- Peripheral?.WriteRegister(Registers.DataConfiguration,
+ BusComms?.WriteRegister(Registers.DataConfiguration,
(byte)(ConfigurationRegisterBits.DataReadyEvent |
ConfigurationRegisterBits.EnablePressureEvent |
ConfigurationRegisterBits.EnableTemperatureEvent));
@@ -91,29 +95,22 @@ public Mpl3115a2(II2cBus i2cBus, byte address = (byte)Addresses.Default)
///
protected override async Task<(Units.Temperature? Temperature, Pressure? Pressure)> ReadSensor()
{
- return await Task.Run(() =>
+ (Units.Temperature? Temperature, Pressure? Pressure) conditions;
+ // Force the sensor to make a reading by setting the OST bit in Control
+ // register 1 (see 7.17.1 of the datasheet).
+ Standby = false;
+ // Pause until both temperature and pressure readings are available
+ while ((Status & 0x06) != 0x06)
{
- (Units.Temperature? Temperature, Pressure? Pressure) conditions;
- //
- // Force the sensor to make a reading by setting the OST bit in Control
- // register 1 (see 7.17.1 of the datasheet).
- //
- Standby = false;
- //
- // Pause until both temperature and pressure readings are available.
- //
- while ((Status & 0x06) != 0x06)
- {
- Thread.Sleep(5);
- }
+ await Task.Delay(5);
+ }
- Thread.Sleep(100);
- Peripheral?.ReadRegister(Registers.PressureMSB, ReadBuffer.Span);
- conditions.Pressure = new Pressure(DecodePresssure(ReadBuffer.Span[0], ReadBuffer.Span[1], ReadBuffer.Span[2]), Units.Pressure.UnitType.Pascal);
- conditions.Temperature = new Units.Temperature(DecodeTemperature(ReadBuffer.Span[3], ReadBuffer.Span[4]), Units.Temperature.UnitType.Celsius);
+ await Task.Delay(100);
+ BusComms?.ReadRegister(Registers.PressureMSB, ReadBuffer.Span);
+ conditions.Pressure = new Pressure(DecodePresssure(ReadBuffer.Span[0], ReadBuffer.Span[1], ReadBuffer.Span[2]), Units.Pressure.UnitType.Pascal);
+ conditions.Temperature = new Units.Temperature(DecodeTemperature(ReadBuffer.Span[3], ReadBuffer.Span[4]), Units.Temperature.UnitType.Celsius);
- return conditions;
- });
+ return conditions;
}
///
@@ -152,25 +149,6 @@ private float DecodePresssure(byte msb, byte csb, byte lsb)
return (float)(pressure / 64.0);
}
- ///
- /// Encode the pressure into the sensor reading byes.
- /// This method is used to allow the target pressure and pressure window
- /// properties to be set.
- ///
- /// Pressure in Pascals to encode.
- /// Array holding the three byte values for the sensor.
- private byte[] EncodePressure(double pressure)
- {
- var result = new byte[3];
- var temp = (uint)(pressure * 64);
- result[2] = (byte)(temp & 0xff);
- temp >>= 8;
- result[1] = (byte)(temp & 0xff);
- temp >>= 8;
- result[0] = (byte)(temp & 0xff);
- return result;
- }
-
///
/// Decode the two bytes representing the temperature into degrees C.
///
@@ -185,31 +163,14 @@ private float DecodeTemperature(byte msb, byte lsb)
return (float)(temperature / 256.0);
}
- ///
- /// Encode a temperature into sensor reading bytes.
- /// This method is needed in order to allow the temperature target
- /// and window properties to work.
- ///
- /// Temperature to encode.
- /// Temperature tuple containing the two bytes for the sensor.
- private byte[] EncodeTemperature(double temperature)
- {
- var result = new byte[2];
- var temp = (ushort)(temperature * 256);
- result[1] = (byte)(temp & 0xff);
- temp >>= 8;
- result[0] = (byte)(temp & 0xff);
- return result;
- }
-
///
/// Reset the sensor
///
public void Reset()
{
- var data = Peripheral?.ReadRegister(Registers.Control1) ?? 0;
+ var data = BusComms?.ReadRegister(Registers.Control1) ?? 0;
data |= 0x04;
- Peripheral?.WriteRegister(Registers.Control1, data);
+ BusComms?.WriteRegister(Registers.Control1, data);
}
async Task ISensor.Read()
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Sensors.Atmospheric.Mpl3115a2.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Sensors.Atmospheric.Mpl3115a2.csproj
index 53aed54aa5..175b7eb156 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Sensors.Atmospheric.Mpl3115a2.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Driver/Sensors.Atmospheric.Mpl3115a2.csproj
@@ -25,6 +25,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Samples/Mpl3115a2_Sample/Mpl3115a2_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Samples/Mpl3115a2_Sample/Mpl3115a2_Sample.csproj
index 96dea2fbfd..d6ca5cf127 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Samples/Mpl3115a2_Sample/Mpl3115a2_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Mpl3115a2/Samples/Mpl3115a2_Sample/Mpl3115a2_Sample.csproj
@@ -16,7 +16,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.Enums.cs
index f613f650cb..97688decd5 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.Enums.cs
@@ -3,7 +3,7 @@
public partial class Ms5611
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
@@ -43,5 +43,13 @@ public enum Resolution
///
OSR_4096 = 4
}
+
+ enum Commands : byte
+ {
+ Reset = 0x1e,
+ ConvertD1 = 0x40,
+ ConvertD2 = 0x50,
+ ReadADC = 0x00,
+ }
}
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.cs
index dff77efe67..910600ab03 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611.cs
@@ -10,9 +10,9 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
/// Represents an Ms5611 pressure and temperature sensor
///
- public partial class Ms5611:
+ public partial class Ms5611 :
ByteCommsSensorBase<(Units.Temperature? Temperature, Pressure? Pressure)>,
- ITemperatureSensor, IBarometricPressureSensor
+ ITemperatureSensor, IBarometricPressureSensor, II2cPeripheral
{
///
/// Temperature changed event
@@ -25,17 +25,26 @@ public partial class Ms5611:
public event EventHandler> PressureUpdated = delegate { };
///
- /// The temperature, in degrees celsius (°C), from the last reading
+ /// The current temperature
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// The pressure, in hectopascals (hPa), from the last reading. 1 hPa
- /// is equal to one millibar, or 1/10th of a kilopascal (kPa)/centibar
+ /// The current pressure
///
public Pressure? Pressure => Conditions.Pressure;
- private Ms5611Base ms5611;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
+
+ readonly Resolution resolution;
///
/// Connect to the Ms5611 using I2C
@@ -45,7 +54,8 @@ public partial class Ms5611:
///
public Ms5611(II2cBus i2cBus, byte address = (byte)Addresses.Default, Resolution resolution = Resolution.OSR_1024)
{
- ms5611 = new Ms5611I2c(i2cBus, address, resolution);
+ i2cComms = new I2cCommunications(i2cBus, address);
+ this.resolution = resolution;
}
///
@@ -69,17 +79,14 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
/// Reads data from the sensor
///
/// The latest sensor reading
- protected override async Task<(Units.Temperature? Temperature, Pressure? Pressure)> ReadSensor()
+ protected override Task<(Units.Temperature? Temperature, Pressure? Pressure)> ReadSensor()
{
- return await Task.Run(() => {
+ (Units.Temperature? Temperature, Pressure? Pressure) conditions;
- (Units.Temperature Temperature, Pressure Pressure) conditions;
+ conditions.Temperature = new Units.Temperature(ReadTemperature(), Units.Temperature.UnitType.Celsius);
+ conditions.Pressure = new Pressure(ReadPressure(), Units.Pressure.UnitType.Millibar);
- conditions.Temperature = new Units.Temperature(ReadTemperature(), Units.Temperature.UnitType.Celsius);
- conditions.Pressure = new Pressure(ReadPressure(), Units.Pressure.UnitType.Millibar);
-
- return conditions;
- });
+ return Task.FromResult(conditions);
}
///
@@ -87,31 +94,37 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
///
public void Reset()
{
- ms5611.Reset();
+ var cmd = (byte)Commands.Reset;
+
+ i2cComms.Write(cmd);
}
private void BeginTempConversion()
{
- ms5611.BeginTempConversion();
+ var cmd = (byte)((byte)Commands.ConvertD2 + 2 * (byte)resolution);
+ i2cComms.Write(cmd);
}
private void BeginPressureConversion()
{
- ms5611.BeginPressureConversion();
+ var cmd = (byte)((byte)Commands.ConvertD1 + 2 * (byte)resolution);
+ i2cComms.Write(cmd);
}
private byte[] ReadData()
{
- return ms5611.ReadData();
+ var data = new byte[3];
+ i2cComms.ReadRegister((byte)Commands.ReadADC, data);
+ return data;
}
int ReadTemperature()
{
- ms5611.BeginTempConversion();
+ BeginTempConversion();
Thread.Sleep(10); // 1 + 2 * Resolution
// we get back 24 bits (3 bytes), regardless of the resolution we're asking for
- var data = ms5611.ReadData();
+ var data = ReadData();
var result = data[2] | data[1] << 8 | data[0] << 16;
@@ -120,12 +133,12 @@ int ReadTemperature()
int ReadPressure()
{
- ms5611.BeginPressureConversion();
+ BeginPressureConversion();
Thread.Sleep(10); // 1 + 2 * Resolution
// we get back 24 bits (3 bytes), regardless of the resolution we're asking for
- var data = ms5611.ReadData();
+ var data = ReadData();
var result = data[2] | data[1] << 8 | data[0] << 16;
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Base.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Base.cs
deleted file mode 100644
index 09242ad794..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Base.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal abstract class Ms5611Base
- {
- protected Ms5611.Resolution Resolution { get; set; }
-
- public abstract void Reset();
- public abstract void BeginTempConversion();
- public abstract void BeginPressureConversion();
- public abstract byte[] ReadData();
-
- protected enum Commands : byte
- {
- Reset = 0x1e,
- ConvertD1 = 0x40,
- ConvertD2 = 0x50,
- ReadADC = 0x00,
- }
-
- internal Ms5611Base(Ms5611.Resolution resolution)
- {
- Resolution = resolution;
- }
- }
-}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611I2c.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611I2c.cs
deleted file mode 100644
index bab6e42bda..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611I2c.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using Meadow.Hardware;
-
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal class Ms5611I2c : Ms5611Base
- {
- private I2cPeripheral i2CPeripheral;
-
- internal Ms5611I2c(II2cBus i2cBus, byte address, Ms5611.Resolution resolution)
- : base(resolution)
- {
- i2CPeripheral = new I2cPeripheral(i2cBus, address);
- }
-
- public override void Reset()
- {
- var cmd = (byte)Commands.Reset;
-
- i2CPeripheral.Write(cmd);
- }
-
- public override void BeginTempConversion()
- {
- var cmd = (byte)((byte)Commands.ConvertD2 + 2 * (byte)Resolution);
- i2CPeripheral.Write(cmd);
- }
-
- public override void BeginPressureConversion()
- {
- var cmd = (byte)((byte)Commands.ConvertD1 + 2 * (byte)Resolution);
- i2CPeripheral.Write(cmd);
- }
-
- public override byte[] ReadData()
- {
- var data = new byte[3];
- i2CPeripheral.ReadRegister((byte)Commands.ReadADC, data);
- return data;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Spi.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Spi.cs
deleted file mode 100644
index f289527ec2..0000000000
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Ms5611Spi.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Meadow.Hardware;
-using System;
-
-/*
-namespace Meadow.Foundation.Sensors.Atmospheric
-{
- internal class Ms5611Spi : Ms5611Base
- {
- private ISpiBus spiBus;
- private IPin chipSelect;
-
- internal Ms5611Spi(ISpiBus spi, IPin chipSelect, Ms5611.Resolution resolution)
- : base(resolution)
- {
- spiBus = spi;
- this.chipSelect = chipSelect;
-
- throw new NotImplementedException();
- }
-
- public override void BeginPressureConversion()
- {
- throw new NotImplementedException();
- }
-
- public override void BeginTempConversion()
- {
- throw new NotImplementedException();
- }
-
- public override byte[] ReadData()
- {
- throw new NotImplementedException();
- }
-
- public override void Reset()
- {
- throw new NotImplementedException();
- }
- }
-}
-*/
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Sensors.Atmospheric.Ms5611.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Sensors.Atmospheric.Ms5611.csproj
index 458403c40f..6042b50e48 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Sensors.Atmospheric.Ms5611.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Driver/Sensors.Atmospheric.Ms5611.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Samples/Ms5611_Sample/Ms5611_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Samples/Ms5611_Sample/Ms5611_Sample.csproj
index dc31d63b0c..3bf81b3e91 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Samples/Ms5611_Sample/Ms5611_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Ms5611/Samples/Ms5611_Sample/Ms5611_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sensors.Atmospheric.Sgp40.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sensors.Atmospheric.Sgp40.csproj
index 713dc1301f..22f7dd3466 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sensors.Atmospheric.Sgp40.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sensors.Atmospheric.Sgp40.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.Enums.cs
index 7cfd7dfbb9..6cfe42ba6e 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.Enums.cs
@@ -5,9 +5,9 @@ namespace Meadow.Foundation.Sensors.Atmospheric
public partial class Sgp40
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x59
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.cs
index c45f354849..b53405a698 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Driver/Sgp40.cs
@@ -1,38 +1,43 @@
-using System;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
using System.Threading;
using System.Threading.Tasks;
-using Meadow.Hardware;
-using Meadow.Units;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
/// Provides access to the Sensiron SGP40 VOC sensor
///
- public partial class Sgp40 : ByteCommsSensorBase
+ public partial class Sgp40 : ByteCommsSensorBase, II2cPeripheral
{
///
///
public event EventHandler> VocIndexUpdated = delegate { };
///
- /// The VOC Index, from the last reading.
+ /// The VOC Index, from the last reading
///
public int VocIndex => Conditions;
///
- /// Serial number of the device.
+ /// Serial number of the device
///
public ulong SerialNumber { get; private set; }
- private byte[]? _compensationData = null;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ private byte[]? compensationData = null;
///
/// Creates a new SGP40 VOC sensor.
///
/// Sensor address (default to 0x40).
/// I2CBus.
- public Sgp40(II2cBus i2cBus, byte address = (byte)Address.Default)
+ public Sgp40(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address, 9, 8)
{
Initialize();
@@ -43,14 +48,11 @@ public Sgp40(II2cBus i2cBus, byte address = (byte)Address.Default)
///
protected void Initialize()
{
- // write buffer for initialization commands only can be two bytes.
- Span tx = WriteBuffer.Span[0..2];
-
- Peripheral?.Write(sgp4x_get_serial_number);
+ BusComms?.Write(sgp4x_get_serial_number);
- Thread.Sleep(1); // per the data sheet
+ Thread.Sleep(1);
- Peripheral?.Read(ReadBuffer.Span[0..9]);
+ BusComms?.Read(ReadBuffer.Span[0..9]);
var bytes = ReadBuffer.ToArray();
@@ -63,11 +65,11 @@ protected void Initialize()
/// true on sucessful test, otherwise false
public bool RunSelfTest()
{
- Peripheral?.Write(sgp40_execute_self_test);
+ BusComms?.Write(sgp40_execute_self_test);
Thread.Sleep(325); // test requires 320ms to complete
- Peripheral?.Read(ReadBuffer.Span[0..3]);
+ BusComms?.Read(ReadBuffer.Span[0..3]);
return ReadBuffer.Span[0..1][0] == 0xd4;
}
@@ -76,27 +78,24 @@ public bool RunSelfTest()
/// Reads data from the sensor
///
/// The latest sensor reading
- protected async override Task ReadSensor()
+ protected override Task ReadSensor()
{
- return await Task.Run(() =>
+ if (compensationData != null)
{
- if(_compensationData != null)
- {
- Peripheral?.Write(_compensationData);
- }
- else
- {
- Peripheral?.Write(sgp40_measure_raw_signal_uncompensated);
- }
+ BusComms?.Write(compensationData);
+ }
+ else
+ {
+ BusComms?.Write(sgp40_measure_raw_signal_uncompensated);
+ }
- Thread.Sleep(30); // per the data sheet
+ Thread.Sleep(30); // per the data sheet
- Peripheral?.Read(ReadBuffer.Span[0..3]);
+ BusComms?.Read(ReadBuffer.Span[0..3]);
- var data = ReadBuffer.Span[0..3].ToArray();
+ var data = ReadBuffer.Span[0..3].ToArray();
- return data[0] << 8 | data[1];
- });
+ return Task.FromResult(data[0] << 8 | data[1]);
}
///
@@ -115,7 +114,7 @@ protected override void RaiseEventsAndNotify(IChangeResult changeResult)
///
public void TurnHeaterOff()
{
- Peripheral?.Write(sgp4x_turn_heater_off);
+ BusComms?.Write(sgp4x_turn_heater_off);
}
///
@@ -125,19 +124,19 @@ public void TurnHeaterOff()
/// Temperature compensation
public void SetCompensationData(RelativeHumidity humidity, Units.Temperature temperature)
{
- _compensationData = new byte[8];
+ compensationData = new byte[8];
- Array.Copy(sgp40_measure_raw_signal, 0, _compensationData, 0, 2);
+ Array.Copy(sgp40_measure_raw_signal, 0, compensationData, 0, 2);
var rh = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder((ushort)(humidity.Percent * 65535 / 100)));
- _compensationData[2] = rh[0];
- _compensationData[3] = rh[1];
- _compensationData[4] = Crc(rh);
+ compensationData[2] = rh[0];
+ compensationData[3] = rh[1];
+ compensationData[4] = Crc(rh);
var t = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder((ushort)(temperature.Celsius * 65535 / 175)));
- _compensationData[5] = t[0];
- _compensationData[6] = t[1];
- _compensationData[7] = Crc(t);
+ compensationData[5] = t[0];
+ compensationData[6] = t[1];
+ compensationData[7] = Crc(t);
}
///
@@ -145,7 +144,7 @@ public void SetCompensationData(RelativeHumidity humidity, Units.Temperature tem
///
public void ClearCompensationData()
{
- _compensationData = null;
+ compensationData = null;
}
private byte Crc(byte[] data)
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Samples/Sgp40_Sample/Sgp40_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Samples/Sgp40_Sample/Sgp40_Sample.csproj
index a5f3503b2f..2b30bdac49 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Samples/Sgp40_Sample/Sgp40_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sgp40/Samples/Sgp40_Sample/Sgp40_Sample.csproj
@@ -16,7 +16,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sensors.Atmospheric.Sht31d.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sensors.Atmospheric.Sht31d.csproj
index c74c923e1b..7a5fea5a38 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sensors.Atmospheric.Sht31d.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sensors.Atmospheric.Sht31d.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.Enums.cs
index 3a0967e913..45e166d7ef 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.Enums.cs
@@ -3,7 +3,7 @@
public partial class Sht31d
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.cs
index b158aad366..ba269dba85 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31D/Driver/Sht31d.cs
@@ -1,21 +1,17 @@
-using System;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// Provide a mechanism for reading the temperature and humidity from
- /// a SHT31D temperature / humidity sensor.
+ /// Represents a SHT31 Dtemperature and humidity sensor
///
- ///
- /// Readings from the sensor are made in Single-shot mode.
- ///
public partial class Sht31d :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Temperature changed event
@@ -28,19 +24,24 @@ public partial class Sht31d :
public event EventHandler> HumidityUpdated = delegate { };
///
- /// The temperature, in degrees celsius (°C), from the last reading.
+ /// The temperature from the last reading
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// The humidity, in percent relative humidity, from the last reading..
+ /// The humidity, in percent relative humidity, from the last reading
///
public RelativeHumidity? Humidity => Conditions.Humidity;
///
- /// Create a new SHT31D object.
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// Create a new SHT31D object
///
- /// Sensor address (should be 0x44 or 0x45).
+ /// Sensor address (should be 0x44 or 0x45)
/// I2cBus (0-1000 KHz).
public Sht31d(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address, readBufferSize: 6, writeBufferSize: 2)
@@ -74,7 +75,7 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
WriteBuffer.Span[0] = 0x2c;
WriteBuffer.Span[1] = 0x06;
- Peripheral?.Exchange(WriteBuffer.Span, ReadBuffer.Span);
+ BusComms?.Exchange(WriteBuffer.Span, ReadBuffer.Span);
var humidity = (100 * (float)((ReadBuffer.Span[3] << 8) + ReadBuffer.Span[4])) / 65535;
var tempC = ((175 * (float)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1])) / 65535) - 45;
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31d/Samples/Sht31d_Sample/Sht31d_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31d/Samples/Sht31d_Sample/Sht31d_Sample.csproj
index 3071051cb0..ef2dfaeaae 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31d/Samples/Sht31d_Sample/Sht31d_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht31d/Samples/Sht31d_Sample/Sht31d_Sample.csproj
@@ -15,7 +15,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sensors.Atmospheric.Sht4x.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sensors.Atmospheric.Sht4x.csproj
index 6a3dea1f4c..c1fc3bf958 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sensors.Atmospheric.Sht4x.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sensors.Atmospheric.Sht4x.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.Enums.cs
index d4fc18e4ab..182b23105a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.Enums.cs
@@ -3,7 +3,7 @@
public partial class Sht4x
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.cs
index 262a873aac..888cab9f6d 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Driver/Sht4x.cs
@@ -1,22 +1,18 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
///
- /// Provide a mechanism for reading the temperature and humidity from
- /// a SHT4x temperature / humidity sensor (SHT40, SHT41, SHT45, etc.)
+ /// Represent a SHT4x temperature and humidity sensor (SHT40, SHT41, SHT45, etc.)
///
- ///
- /// Readings from the sensor are made in Single-shot mode.
- ///
public partial class Sht4x :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Precision of sensor reading
@@ -34,24 +30,28 @@ public partial class Sht4x :
public event EventHandler> HumidityUpdated = delegate { };
///
- /// The curren temperature -from the last reading.
+ /// The current temperature
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// The humidity, in percent relative humidity, from the last reading
+ /// The current humidity
///
public RelativeHumidity? Humidity => Conditions.Humidity;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new SHT4x object
///
- /// Sensor address (0x44 or 0x45)
+ /// Sensor address
/// I2cBus
public Sht4x(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address, readBufferSize: 6, writeBufferSize: 2)
- {
- }
+ { }
///
/// Raise events for subscribers
@@ -108,24 +108,21 @@ protected int GetDelayForPrecision(Precision precision)
///
/// Get a reading from the sensor and set the Temperature and Humidity properties.
///
- protected async override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
+ protected override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
{
- (Units.Temperature Temperature, RelativeHumidity Humidity) conditions;
+ (Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
- return await Task.Run(() =>
- {
- Peripheral?.Write((byte)ReadPrecision);
- Thread.Sleep(GetDelayForPrecision(ReadPrecision));
- Peripheral?.Read(ReadBuffer.Span[0..5]);
+ BusComms?.Write((byte)ReadPrecision);
+ Thread.Sleep(GetDelayForPrecision(ReadPrecision));
+ BusComms?.Read(ReadBuffer.Span[0..5]);
- var temperature = (175 * (float)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]) / 65535) - 45;
- var humidity = (125 * (float)((ReadBuffer.Span[3] << 8) + ReadBuffer.Span[4]) / 65535) - 6;
+ var temperature = (175 * (float)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]) / 65535) - 45;
+ var humidity = (125 * (float)((ReadBuffer.Span[3] << 8) + ReadBuffer.Span[4]) / 65535) - 6;
- conditions.Humidity = new RelativeHumidity(humidity);
- conditions.Temperature = new Units.Temperature(temperature, Units.Temperature.UnitType.Celsius);
+ conditions.Humidity = new RelativeHumidity(humidity);
+ conditions.Temperature = new Units.Temperature(temperature, Units.Temperature.UnitType.Celsius);
- return conditions;
- });
+ return Task.FromResult(conditions);
}
async Task ISensor.Read()
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Samples/Sht4x_Sample/Sht4x_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Samples/Sht4x_Sample/Sht4x_Sample.csproj
index 6c79440e11..e7c9fd8b45 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Samples/Sht4x_Sample/Sht4x_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Sht4x/Samples/Sht4x_Sample/Sht4x_Sample.csproj
@@ -12,7 +12,7 @@
9.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Sensors.Atmospheric.Si70xx.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Sensors.Atmospheric.Si70xx.csproj
index cb277ca00b..5fc42134c2 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Sensors.Atmospheric.Si70xx.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Sensors.Atmospheric.Si70xx.csproj
@@ -25,6 +25,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.Enums.cs
index a482d5a057..9ccc39f6fb 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.Enums.cs
@@ -3,9 +3,9 @@
public partial class Si70xx
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
- public enum Address : byte
+ public enum Addresses : byte
{
///
/// Bus address 0x40
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.cs
index 6d98648bd1..97825e052e 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Driver/Si70xx.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
using HU = Meadow.Units.RelativeHumidity.UnitType;
using TU = Meadow.Units.Temperature.UnitType;
@@ -11,29 +11,24 @@ namespace Meadow.Foundation.Sensors.Atmospheric
{
///
/// Provide access to the Si70xx series (Si7020, Si7021, and Si7030)
- /// temperature and humidity sensors.
+ /// temperature and humidity sensors
///
public partial class Si70xx :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Raised when the temperature value changes
///
public event EventHandler> TemperatureUpdated = delegate { };
-
+
///
/// Raised when the humidity value changes
///
public event EventHandler> HumidityUpdated = delegate { };
///
- /// Default SPI bus speed
- ///
- public static Frequency DEFAULT_SPEED = new Frequency(400, Frequency.UnitType.Kilohertz);
-
- ///
- /// The temperature, from the last reading
+ /// The temperature from the last reading
///
public Units.Temperature? Temperature => Conditions.Temperature;
@@ -57,12 +52,17 @@ public partial class Si70xx :
///
public byte FirmwareRevision { get; private set; }
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new SI7021 temperature and humidity sensor
///
/// I2CBus
/// I2C address (default to 0x40)
- public Si70xx(II2cBus i2cBus, byte address = (byte)Address.Default)
+ public Si70xx(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address, 8, 3)
{
Initialize();
@@ -72,7 +72,7 @@ public Si70xx(II2cBus i2cBus, byte address = (byte)Address.Default)
///
protected void Reset()
{
- Peripheral?.Write(CMD_RESET);
+ BusComms?.Write(CMD_RESET);
Thread.Sleep(100);
}
@@ -89,7 +89,7 @@ protected void Initialize()
tx[0] = READ_ID_PART1;
tx[1] = READ_ID_PART2;
- Peripheral?.Exchange(tx, ReadBuffer.Span);
+ BusComms?.Exchange(tx, ReadBuffer.Span);
for (var index = 0; index < 4; index++)
{
SerialNumber <<= 8;
@@ -98,7 +98,7 @@ protected void Initialize()
tx[0] = READ_2ND_ID_PART1;
tx[1] = READ_2ND_ID_PART2;
- Peripheral?.Exchange(tx, ReadBuffer.Span);
+ BusComms?.Exchange(tx, ReadBuffer.Span);
SerialNumber <<= 8;
SerialNumber += ReadBuffer.Span[0];
@@ -128,33 +128,30 @@ protected void Initialize()
{
(Units.Temperature Temperature, RelativeHumidity Humidity) conditions;
- return await Task.Run(() =>
+ BusComms?.Write(HUMDITY_MEASURE_NOHOLD);
+ await Task.Delay(25); // Maximum conversion time is 12ms (page 5 of the datasheet).
+ BusComms?.Read(ReadBuffer.Span); // 2 data bytes plus a checksum (we ignore the checksum here)
+ var humidityReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
+ conditions.Humidity = new RelativeHumidity(((125 * (float)humidityReading) / 65536) - 6, HU.Percent);
+ if (conditions.Humidity < new RelativeHumidity(0, HU.Percent))
{
- Peripheral?.Write(HUMDITY_MEASURE_NOHOLD);
- Thread.Sleep(25); // Maximum conversion time is 12ms (page 5 of the datasheet).
- Peripheral?.Read(ReadBuffer.Span); // 2 data bytes plus a checksum (we ignore the checksum here)
- var humidityReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
- conditions.Humidity = new RelativeHumidity(((125 * (float)humidityReading) / 65536) - 6, HU.Percent);
- if (conditions.Humidity < new RelativeHumidity(0, HU.Percent))
- {
- conditions.Humidity = new RelativeHumidity(0, HU.Percent);
- }
- else
+ conditions.Humidity = new RelativeHumidity(0, HU.Percent);
+ }
+ else
+ {
+ if (conditions.Humidity > new RelativeHumidity(100, HU.Percent))
{
- if (conditions.Humidity > new RelativeHumidity(100, HU.Percent))
- {
- conditions.Humidity = new RelativeHumidity(100, HU.Percent);
- }
+ conditions.Humidity = new RelativeHumidity(100, HU.Percent);
}
+ }
- Peripheral?.Write(TEMPERATURE_MEASURE_NOHOLD);
- Thread.Sleep(25); // Maximum conversion time is 12ms (page 5 of the datasheet).
- Peripheral?.Read(ReadBuffer.Span); // 2 data bytes plus a checksum (we ignore the checksum here)
- var temperatureReading = (short)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
- conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), TU.Celsius);
+ BusComms?.Write(TEMPERATURE_MEASURE_NOHOLD);
+ Thread.Sleep(25); // Maximum conversion time is 12ms (page 5 of the datasheet).
+ BusComms?.Read(ReadBuffer.Span); // 2 data bytes plus a checksum (we ignore the checksum here)
+ var temperatureReading = (short)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
+ conditions.Temperature = new Units.Temperature((float)((175.72 * temperatureReading / 65536) - 46.85), TU.Celsius);
- return conditions;
- });
+ return conditions;
}
///
@@ -181,14 +178,14 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
/// Heater status, true = turn heater on, false = turn heater off.
public void Heater(bool onOrOff)
{
- var register = Peripheral?.ReadRegister((byte)Register.USER_REG_1) ?? 0;
+ var register = BusComms?.ReadRegister((byte)Register.USER_REG_1) ?? 0;
register &= 0xfd;
if (onOrOff)
{
register |= 0x02;
}
- Peripheral?.WriteRegister((byte)Register.USER_REG_1, register);
+ BusComms?.WriteRegister((byte)Register.USER_REG_1, register);
}
///
@@ -203,7 +200,7 @@ public void Heater(bool onOrOff)
/// The resolution to set
void SetResolution(SensorResolution resolution)
{
- var register = Peripheral?.ReadRegister((byte)Register.USER_REG_1) ?? 0;
+ var register = BusComms?.ReadRegister((byte)Register.USER_REG_1) ?? 0;
var res = (byte)resolution;
@@ -212,7 +209,7 @@ void SetResolution(SensorResolution resolution)
register |= res; //Mask in the requested resolution bits
//Request a write to user register
- Peripheral?.WriteRegister((byte)Register.USER_REG_1, register); //Write the new resolution bits
+ BusComms?.WriteRegister((byte)Register.USER_REG_1, register); //Write the new resolution bits
}
async Task ISensor.Read()
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Samples/Si70xx_Sample/Si70xx_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Samples/Si70xx_Sample/Si70xx_Sample.csproj
index 40a7e040f3..7dfadf704a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Samples/Si70xx_Sample/Si70xx_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Si70xx/Samples/Si70xx_Sample/Si70xx_Sample.csproj
@@ -16,7 +16,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Sensors.Atmospheric.Th02.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Sensors.Atmospheric.Th02.csproj
index da6600897e..2ca53c1ae0 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Sensors.Atmospheric.Th02.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Sensors.Atmospheric.Th02.csproj
@@ -21,6 +21,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.Enums.cs
index 4bff8370ec..a6b4a83752 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.Enums.cs
@@ -3,7 +3,7 @@
public partial class Th02
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.cs
index 66333be82b..a6df4dbe01 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Driver/Th02.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Atmospheric
{
@@ -13,7 +13,7 @@ namespace Meadow.Foundation.Sensors.Atmospheric
///
public partial class Th02 :
ByteCommsSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity)>,
- ITemperatureSensor, IHumiditySensor
+ ITemperatureSensor, IHumiditySensor, II2cPeripheral
{
///
/// Event raised when the temperature changes
@@ -26,23 +26,27 @@ public partial class Th02 :
public event EventHandler> HumidityUpdated = delegate { };
///
- /// Last value read from the Temperature sensor.
+ /// The current temperatute
///
public Units.Temperature? Temperature => Conditions.Temperature;
///
- /// Last value read from the Pressure sensor.
+ /// The current humidity
///
public RelativeHumidity? Humidity => Conditions.Humidity;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Provide a mechanism for reading the temperature and humidity from
/// a Th02 temperature / humidity sensor
///
public Th02(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address)
- {
- }
+ { }
///
/// Raise all change events for subscribers
@@ -64,47 +68,44 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? T
///
/// Calculates the compensated pressure and temperature.
///
- protected override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
+ protected async override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
{
- return Task.Run(() =>
+ (Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
+
+ // Read the humidity
+ BusComms?.WriteRegister((byte)Registers.Config, MeasureHumidity);
+
+ // Maximum conversion time should be 40ms
+ while ((BusComms?.ReadRegister((byte)Registers.Status) & 0x01) > 0)
{
- (Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
-
- // Read the humidity
- Peripheral?.WriteRegister((byte)Registers.Config, MeasureHumidity);
-
- // Maximum conversion time should be 40ms
- while ((Peripheral?.ReadRegister((byte)Registers.Status) & 0x01) > 0)
- {
- Thread.Sleep(40);
- }
-
- byte[] data = new byte[2];
-
- Peripheral?.ReadRegister((byte)Registers.DataHigh, data);
- int temp = data[0] << 8;
- temp |= data[1];
- temp >>= 4;
-
- conditions.Humidity = new RelativeHumidity(temp / 16.0 - 24);
-
- // Read the temperature
- Peripheral?.WriteRegister((byte)Registers.Config, MeasureTemperature);
-
- // Maximum conversion time should be 40ms
- while ((Peripheral?.ReadRegister((byte)Registers.Status) & 0x01) > 0)
- {
- Thread.Sleep(40);
- }
-
- Peripheral?.ReadRegister((byte)Registers.DataHigh, data);
- temp = data[0] << 8;
- temp |= data[1];
- temp >>= 2; //drop the two unused bits (14 bit value)
- conditions.Temperature = new Units.Temperature(temp / 32.0 - 50, Units.Temperature.UnitType.Celsius);
-
- return conditions;
- });
+ await Task.Delay(40);
+ }
+
+ byte[] data = new byte[2];
+
+ BusComms?.ReadRegister((byte)Registers.DataHigh, data);
+ int temp = data[0] << 8;
+ temp |= data[1];
+ temp >>= 4;
+
+ conditions.Humidity = new RelativeHumidity(temp / 16.0 - 24);
+
+ // Read the temperature
+ BusComms?.WriteRegister((byte)Registers.Config, MeasureTemperature);
+
+ // Maximum conversion time should be 40ms
+ while ((BusComms?.ReadRegister((byte)Registers.Status) & 0x01) > 0)
+ {
+ Thread.Sleep(40);
+ }
+
+ BusComms?.ReadRegister((byte)Registers.DataHigh, data);
+ temp = data[0] << 8;
+ temp |= data[1];
+ temp >>= 2; //drop the two unused bits (14 bit value)
+ conditions.Temperature = new Units.Temperature(temp / 32.0 - 50, Units.Temperature.UnitType.Celsius);
+
+ return conditions;
}
async Task ISensor.Read()
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Samples/Th02_Sample/Th02_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Samples/Th02_Sample/Th02_Sample.csproj
index df7937ed1c..c4398f5377 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Samples/Th02_Sample/Th02_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Atmospheric.Th02/Samples/Th02_Sample/Th02_Sample.csproj
@@ -15,7 +15,7 @@
8.0
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.Enums.cs
index 4b8b202e1a..45091d733b 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.Enums.cs
@@ -3,7 +3,7 @@
public partial class Mlx90640
{
///
- /// Valid addresses for the sensor
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.cs
index 71e0ef23ab..8684713fc8 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Mlx90640.cs
@@ -1,5 +1,5 @@
-using System;
-using Meadow.Hardware;
+using Meadow.Hardware;
+using System;
using System.Threading;
namespace Meadow.Foundation.Sensors.Camera
@@ -8,7 +8,7 @@ namespace Meadow.Foundation.Sensors.Camera
/// Represents the MLX90640 32x24 IR array
/// The MLX90640 is a fully calibrated 32x24 pixels thermal IR array
///
- public partial class Mlx90640
+ public partial class Mlx90640 : II2cPeripheral
{
///
/// Camera serial number as a string
@@ -18,9 +18,9 @@ public partial class Mlx90640
///
/// Emissivity
///
- public float Emissivity
+ public float Emissivity
{
- get => emissivity;
+ get => emissivity;
set
{
if (value > 1)
@@ -35,13 +35,13 @@ public float Emissivity
{
emissivity = value;
}
- }
+ }
}
///
/// Reflected temperature
///
- public Meadow.Units.Temperature ReflectedTemperature { get; set; }
+ public Units.Temperature ReflectedTemperature { get; set; }
///
/// Camera configuration
@@ -53,7 +53,15 @@ public float Emissivity
const byte OpenAirTaShift = 8;
const short DeviceId1Register = 0x2407;
- readonly II2cPeripheral i2CPeripheral;
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// I2C Communication bus used to communicate with the peripheral
+ ///
+ protected readonly II2cCommunications i2cComms;
float emissivity;
@@ -67,7 +75,7 @@ public Mlx90640(II2cBus i2cBus,
byte address = (byte)Addresses.Default,
float emissivity = 0.95f)
{
- i2CPeripheral = new I2cPeripheral(i2cBus, address);
+ i2cComms = new I2cCommunications(i2cBus, address);
Emissivity = emissivity;
Config = new Mlx90640Config();
@@ -75,7 +83,7 @@ public Mlx90640(II2cBus i2cBus,
}
///
- /// Initialize the MLX90640. Read the MLX90640 serial number and EEProm
+ /// Initialize the MLX90640 and read the MLX90640 serial number and EEProm
///
void Initialize()
{
@@ -100,7 +108,7 @@ void Initialize()
public float[] ReadRawData()
{
ushort[] mlx90640Frame = new ushort[834];
- float[] frameBuffer =new float[32 * 24];
+ float[] frameBuffer = new float[32 * 24];
for (byte page = 0; page < 2; page++)
{
@@ -163,12 +171,11 @@ public void SetMode(Mode mode)
bool GetFrameData(ref ushort[] frameData)
{
- ushort dataReady = 1;
ushort[] controlRegister1 = new ushort[1];
ushort[] statusRegister = new ushort[1];
byte cnt = 0;
- dataReady = 0;
+ ushort dataReady = 0;
while (dataReady == 0)
{
I2CRead(0x8000, 1, ref statusRegister);
@@ -194,7 +201,7 @@ bool GetFrameData(ref ushort[] frameData)
if (cnt > 4)
return false;
- I2CRead(0x800D, 1, ref controlRegister1);
+ I2CRead(0x800D, 1, ref controlRegister1);
frameData[832] = controlRegister1[0];
frameData[833] = (ushort)(statusRegister[0] & 0x0001);
@@ -208,9 +215,9 @@ void I2CRead(int startAddress, ushort readLen, ref ushort[] data)
while (readLen > 0)
{
- ushort toRead16 = (int)(MaxBufferSize / 2);
+ ushort toRead16 = MaxBufferSize / 2;
- if (readLen < (int)(MaxBufferSize / 2))
+ if (readLen < MaxBufferSize / 2)
toRead16 = readLen;
cmd[0] = (byte)(startAddress >> 8);
@@ -218,13 +225,13 @@ void I2CRead(int startAddress, ushort readLen, ref ushort[] data)
Span writeBuffer = new Span(cmd);
Span tempBuf = new Span(new byte[toRead16 * 2]);
- i2CPeripheral.Exchange(writeBuffer, tempBuf);
+ i2cComms.Exchange(writeBuffer, tempBuf);
// we now have to swap every two bytes
int index = 0;
for (int i = bufferIndex; i < bufferIndex + toRead16; i++)
{
- data[i] = (ushort)((ushort)(tempBuf[index] * 256) + (ushort)tempBuf[index + 1]); ;
+ data[i] = (ushort)((ushort)(tempBuf[index] * 256) + tempBuf[index + 1]); ;
index += 2;
}
@@ -244,7 +251,7 @@ bool I2CWrite(ushort writeAddress, ushort data)
cmd[2] = (byte)(data >> 8);
cmd[3] = (byte)(data & 0x00FF);
- i2CPeripheral.Write(cmd);
+ i2cComms.Write(cmd);
Thread.Sleep(1);
@@ -322,7 +329,7 @@ void CalculateTo(ushort[] frameData, Mlx90640Config mlx90640, float emissivity,
{
if (irDataCP[i] > 32767)
irDataCP[i] = irDataCP[i] - 65536;
-
+
irDataCP[i] = irDataCP[i] * gain;
}
@@ -402,8 +409,8 @@ float GetTa(ushort[] frameData, Mlx90640Config mlx90640)
ptatArt = frameData[768];
if (ptatArt > 32767)
ptatArt -= 65536;
-
- ptatArt = (float)((ptat / (ptat * mlx90640.AlphaPTAT + ptatArt)) * Math.Pow(2, (double)18));
+
+ ptatArt = (float)((ptat / (ptat * mlx90640.AlphaPTAT + ptatArt)) * Math.Pow(2, 18));
ta = (float)((ptatArt / (1 + mlx90640.KvPTAT * (vdd - 3.3)) - mlx90640.VPTAT25));
ta = ta / mlx90640.KtPTAT + 25;
@@ -425,7 +432,7 @@ float GetVdd(ushort[] frameData, Mlx90640Config mlx90640)
}
resolutionRAM = (frameData[832] & 0x0C00) >> 10;
- resolutionCorrection = (float)(Math.Pow(2, (double)mlx90640.ResolutionEE) / Math.Pow(2, (double)resolutionRAM));
+ resolutionCorrection = (float)(Math.Pow(2, mlx90640.ResolutionEE) / Math.Pow(2, resolutionRAM));
vdd = (float)((resolutionCorrection * vdd - mlx90640.Vdd25) / mlx90640.KVdd + 3.3);
return vdd;
@@ -480,7 +487,7 @@ void ExtractPTATParameters(ref ushort[] eeData)
KvPTAT = (eeData[50] & 0xFC00) >> 10;
if (KvPTAT > 31)
KvPTAT -= 64;
-
+
KvPTAT /= 4096;
KtPTAT = eeData[50] & 0x03FF;
@@ -517,7 +524,7 @@ void ExtractTgcParameters(ref ushort[] eeData)
tgc = eeData[60] & 0x00FF;
if (tgc > 127)
tgc -= 256;
-
+
tgc /= 32.0f;
Config.Tgc = tgc;
@@ -539,7 +546,7 @@ void ExtractKsTaParameters(ref ushort[] eeData)
KsTa = (eeData[60] & 0xFF00) >> 8;
if (KsTa > 127)
KsTa -= 256;
-
+
KsTa /= 8192.0f;
Config.KsTa = KsTa;
@@ -637,10 +644,10 @@ void ExtractAlphaParameters(ref ushort[] eeData)
alphaTemp[p] = (eeData[64 + p] & 0x03F0) >> 4;
if (alphaTemp[p] > 31)
alphaTemp[p] = alphaTemp[p] - 64;
-
+
alphaTemp[p] = alphaTemp[p] * (1 << accRemScale);
alphaTemp[p] = (alphaRef + (accRow[i] << accRowScale) + (accColumn[j] << accColumnScale) + alphaTemp[p]);
- alphaTemp[p] = (float)(alphaTemp[p] / Math.Pow(2, (double)alphaScale));
+ alphaTemp[p] = (float)(alphaTemp[p] / Math.Pow(2, alphaScale));
alphaTemp[p] = alphaTemp[p] - Config.Tgc * (Config.CpAlpha[0] + Config.CpAlpha[1]) / 2;
alphaTemp[p] = ScaleAlpha / alphaTemp[p];
}
@@ -651,7 +658,7 @@ void ExtractAlphaParameters(ref ushort[] eeData)
{
if (alphaTemp[i] > temp)
temp = alphaTemp[i];
-
+
}
alphaScale = 0;
@@ -670,7 +677,7 @@ void ExtractAlphaParameters(ref ushort[] eeData)
for (int i = 0; i < 768; i++)
{
- temp = (float)(alphaTemp[i] * Math.Pow(2, (double)alphaScale));
+ temp = (float)(alphaTemp[i] * Math.Pow(2, alphaScale));
Config.Alpha[i] = (short)(temp + 0.5);
}
@@ -775,13 +782,13 @@ void ExtractKtaPixelParameters(ref ushort[] eeData)
KtaRoCe = (sbyte)((eeData[55] & 0xFF00) >> 8);
if (KtaRoCe > 127)
KtaRoCe = (sbyte)(KtaRoCe - 256);
-
+
KtaRC[1] = KtaRoCe;
KtaReCe = (sbyte)((eeData[55] & 0x00FF));
if (KtaReCe > 127)
KtaReCe = (sbyte)(KtaReCe - 256);
-
+
KtaRC[3] = KtaReCe;
ktaScale1 = (byte)(((eeData[56] & 0x00F0) >> 4) + 8);
@@ -796,10 +803,10 @@ void ExtractKtaPixelParameters(ref ushort[] eeData)
ktaTemp[p] = (eeData[64 + p] & 0x000E) >> 1;
if (ktaTemp[p] > 3)
ktaTemp[p] = ktaTemp[p] - 8;
-
+
ktaTemp[p] = ktaTemp[p] * (1 << ktaScale2);
ktaTemp[p] = KtaRC[split] + ktaTemp[p];
- ktaTemp[p] = (float)(ktaTemp[p] / Math.Pow(2, (double)ktaScale1));
+ ktaTemp[p] = (float)(ktaTemp[p] / Math.Pow(2, ktaScale1));
}
}
@@ -808,7 +815,7 @@ void ExtractKtaPixelParameters(ref ushort[] eeData)
{
if (Math.Abs(ktaTemp[i]) > temp)
temp = Math.Abs(ktaTemp[i]);
-
+
}
ktaScale1 = 0;
@@ -820,7 +827,7 @@ void ExtractKtaPixelParameters(ref ushort[] eeData)
for (int i = 0; i < 768; i++)
{
- temp = (float)(ktaTemp[i] * Math.Pow(2, (double)ktaScale1));
+ temp = (float)(ktaTemp[i] * Math.Pow(2, ktaScale1));
if (temp < 0)
Config.Kta[i] = (sbyte)(temp - 0.5);
else
@@ -846,25 +853,25 @@ void ExtractKvPixelParameters(ref ushort[] eeData)
KvRoCo = (sbyte)((eeData[52] & 0xF000) >> 12);
if (KvRoCo > 7)
KvRoCo = (sbyte)(KvRoCo - 16);
-
+
KvT[0] = KvRoCo;
KvReCo = (sbyte)((eeData[52] & 0x0F00) >> 8);
if (KvReCo > 7)
KvReCo = (sbyte)(KvReCo - 16);
-
+
KvT[2] = KvReCo;
KvRoCe = (sbyte)((eeData[52] & 0x00F0) >> 4);
if (KvRoCe > 7)
KvRoCe = (sbyte)(KvRoCe - 16);
-
+
KvT[1] = KvRoCe;
KvReCe = (sbyte)((eeData[52] & 0x000F));
if (KvReCe > 7)
KvReCe = (sbyte)(KvReCe - 16);
-
+
KvT[3] = KvReCe;
kvScale = (byte)((eeData[56] & 0x0F00) >> 8);
@@ -876,7 +883,7 @@ void ExtractKvPixelParameters(ref ushort[] eeData)
int p = 32 * i + j;
split = (byte)(2 * (p / 32 - (p / 64) * 2) + p % 2);
kvTemp[p] = KvT[split];
- kvTemp[p] = (float)(kvTemp[p] / Math.Pow(2, (double)kvScale));
+ kvTemp[p] = (float)(kvTemp[p] / Math.Pow(2, kvScale));
}
}
@@ -885,7 +892,7 @@ void ExtractKvPixelParameters(ref ushort[] eeData)
{
if (Math.Abs(kvTemp[i]) > temp)
temp = Math.Abs(kvTemp[i]);
-
+
}
kvScale = 0;
@@ -897,7 +904,7 @@ void ExtractKvPixelParameters(ref ushort[] eeData)
for (int i = 0; i < 768; i++)
{
- temp = (float)(kvTemp[i] * Math.Pow(2, (double)kvScale));
+ temp = (float)(kvTemp[i] * Math.Pow(2, kvScale));
if (temp < 0)
Config.Kv[i] = (sbyte)(temp - 0.5);
else
@@ -929,7 +936,7 @@ void ExtractCILCParameters(ref ushort[] eeData)
{
ilChessC[1] = ilChessC[1] - 32;
}
-
+
ilChessC[1] = ilChessC[1] / 2.0f;
ilChessC[2] = (eeData[53] & 0xF800) >> 11;
@@ -937,7 +944,7 @@ void ExtractCILCParameters(ref ushort[] eeData)
{
ilChessC[2] = ilChessC[2] - 32;
}
-
+
ilChessC[2] = ilChessC[2] / 8.0f;
Config.CalibrationModeEE = calibrationModeEE;
@@ -996,16 +1003,16 @@ void ExtractCPParameters(ref ushort[] eeData)
}
ktaScale1 = (byte)(((eeData[56] & 0x00F0) >> 4) + 8);
- Config.CpKta = (float)(cpKta / Math.Pow(2, (double)ktaScale1));
+ Config.CpKta = (float)(cpKta / Math.Pow(2, ktaScale1));
cpKv = (eeData[59] & 0xFF00) >> 8;
if (cpKv > 127)
{
cpKv -= 256;
}
-
+
kvScale = (byte)((eeData[56] & 0x0F00) >> 8);
- Config.CpKv = (float)(cpKv / Math.Pow(2, (double)kvScale));
+ Config.CpKv = (float)(cpKv / Math.Pow(2, kvScale));
Config.CpAlpha[0] = alphaSP[0];
Config.CpAlpha[1] = alphaSP[1];
@@ -1033,7 +1040,7 @@ void ExtractDeviatingPixels(ref ushort[] eeData)
}
- if(Config.BrokenPixels.Count > 1 )
+ if (Config.BrokenPixels.Count > 1)
{
for (pixCnt = 0; pixCnt < Config.BrokenPixels.Count; pixCnt++)
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Sensors.Camera.Mlx90640.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Sensors.Camera.Mlx90640.csproj
index 1852bc1f84..04cb4004b2 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Sensors.Camera.Mlx90640.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Driver/Sensors.Camera.Mlx90640.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Samples/Mlx90640_Sample/Mlx90640_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Samples/Mlx90640_Sample/Mlx90640_Sample.csproj
index 902cd346e8..9fe420dbde 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Samples/Mlx90640_Sample/Mlx90640_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Mlx90640/Samples/Mlx90640_Sample/Mlx90640_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Driver/Sensors.Camera.Vc0706.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Driver/Sensors.Camera.Vc0706.csproj
index 11c0c96579..05c688529a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Driver/Sensors.Camera.Vc0706.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Driver/Sensors.Camera.Vc0706.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Samples/Vc0706_Sample/Vc0706_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Samples/Vc0706_Sample/Vc0706_Sample.csproj
index 9fba944813..76f5a7cfb2 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Samples/Vc0706_Sample/Vc0706_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Camera.Vc0706/Samples/Vc0706_Sample/Vc0706_Sample.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Driver/Sensors.Distance.Hcsr04.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Driver/Sensors.Distance.Hcsr04.csproj
index 01afc7693d..0072bb0676 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Driver/Sensors.Distance.Hcsr04.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Driver/Sensors.Distance.Hcsr04.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Samples/Hcsr04_Sample/Hcsr04_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Samples/Hcsr04_Sample/Hcsr04_Sample.csproj
index 8acdbb04e8..7d32d67f2f 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Samples/Hcsr04_Sample/Hcsr04_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Hcsr04/Samples/Hcsr04_Sample/Hcsr04_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.I2c.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.I2c.cs
index 9880fcb62c..a120826d69 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.I2c.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.I2c.cs
@@ -1,11 +1,16 @@
-using System.Threading;
-using Meadow.Hardware;
+using Meadow.Hardware;
using Meadow.Units;
+using System.Threading;
namespace Meadow.Foundation.Sensors.Distance
{
- public partial class MaxBotix
+ public partial class MaxBotix : II2cPeripheral
{
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Creates a new MaxBotix object communicating over I2C
///
@@ -13,7 +18,7 @@ public partial class MaxBotix
/// The distance sensor type
/// The I2C address
public MaxBotix(II2cBus i2cBus, SensorType sensor, byte address = (byte)Addresses.Default)
- :base(i2cBus, address)
+ : base(i2cBus, address)
{
sensorType = sensor;
communication = CommunicationType.I2C;
@@ -23,13 +28,13 @@ public MaxBotix(II2cBus i2cBus, SensorType sensor, byte address = (byte)Addresse
void StartI2cSensor(byte address)
{
- Peripheral.ReadRegister(address);
+ BusComms.ReadRegister(address);
Thread.Sleep(100);
}
Length ReadSensorI2c()
{
- return new Length(Peripheral.ReadRegisterAsUShort(0x51), GetUnitsForSensor(sensorType));
+ return new Length(BusComms.ReadRegisterAsUShort(0x51), GetUnitsForSensor(sensorType));
}
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.enums.cs
index 8b31aa0a42..1bc972d847 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/MaxBotix.enums.cs
@@ -3,7 +3,7 @@
public partial class MaxBotix
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/Sensors.Distance.MaxBotix.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/Sensors.Distance.MaxBotix.csproj
index 6f9cbeaa26..233efc917e 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/Sensors.Distance.MaxBotix.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Driver/Sensors.Distance.MaxBotix.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Samples/MaxBotix_Sample/MaxBotix_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Samples/MaxBotix_Sample/MaxBotix_Sample.csproj
index f45e574b78..442e13c818 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Samples/MaxBotix_Sample/MaxBotix_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.MaxBotix/Samples/MaxBotix_Sample/MaxBotix_Sample.csproj
@@ -6,7 +6,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Sensors.Distance.Vl53l0x.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Sensors.Distance.Vl53l0x.csproj
index 72fa456699..683357de86 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Sensors.Distance.Vl53l0x.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Sensors.Distance.Vl53l0x.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.Enums.cs
index bc308765ce..00eba29ad0 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.Enums.cs
@@ -6,7 +6,7 @@
public partial class Vl53l0x
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.cs
index 0a02e4f120..73e5772ada 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Driver/Vl53l0x.cs
@@ -10,7 +10,7 @@ namespace Meadow.Foundation.Sensors.Distance
///
/// Represents the Vl53l0x distance sensor
///
- public partial class Vl53l0x : ByteCommsSensorBase, IRangeFinder
+ public partial class Vl53l0x : ByteCommsSensorBase, IRangeFinder, II2cPeripheral
{
///
/// Distance updated event
@@ -36,20 +36,25 @@ public bool IsShutdown
}
///
- /// The distance to the measured object.
+ /// The distance to the measured object
///
public Length? Distance { get; protected set; } = new Length(0);
///
- /// Minimum valid distance in mm.
+ /// Minimum valid distance
///
public Length MinimumDistance => new Length(30, Length.UnitType.Millimeters);
///
- /// Maximum valid distance in mm (CurrentDistance returns -1 if above).
+ /// Maximum valid distance (CurrentDistance returns -1 if above)
///
public Length MaximumDistance => new Length(2000, Length.UnitType.Millimeters);
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
readonly IDigitalOutputPort shutdownPort;
byte stopVariable;
@@ -61,8 +66,7 @@ public bool IsShutdown
/// I2C address
public Vl53l0x(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: this(i2cBus, null, address)
- {
- }
+ { }
///
/// Creates a new Vl53l0x object
@@ -106,18 +110,18 @@ protected async Task Initialize()
throw new Exception("Failed to find expected ID register values");
}
- Peripheral.WriteRegister(0x88, 0x00);
- Peripheral.WriteRegister(0x80, 0x01);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x00, 0x00);
+ BusComms.WriteRegister(0x88, 0x00);
+ BusComms.WriteRegister(0x80, 0x01);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x00, 0x00);
stopVariable = Read(0x91);
- Peripheral.WriteRegister(0x00, 0x01);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x80, 0x00);
+ BusComms.WriteRegister(0x00, 0x01);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x80, 0x00);
- Peripheral.WriteRegister((byte)Register.SystemSequenceConfig, 0xFF);
+ BusComms.WriteRegister((byte)Register.SystemSequenceConfig, 0xFF);
var spadInfo = GetSpadInfo();
int spadCount = spadInfo.Item1;
bool spad_is_aperture = spadInfo.Item2;
@@ -125,11 +129,11 @@ protected async Task Initialize()
byte[] ref_spad_map = new byte[7];
ref_spad_map[0] = (byte)Register.GlobalConfigSpadEnablesRef0;
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister((byte)Register.DynamicSpadRefEnStartOffset, 0x00);
- Peripheral.WriteRegister((byte)Register.DynamicSpadNumRequestedRefSpad, 0x2C);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister((byte)Register.GlobalConfigRefEnStartSelect, 0xB4);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister((byte)Register.DynamicSpadRefEnStartOffset, 0x00);
+ BusComms.WriteRegister((byte)Register.DynamicSpadNumRequestedRefSpad, 0x2C);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister((byte)Register.GlobalConfigRefEnStartSelect, 0xB4);
var first_spad_to_enable = (spad_is_aperture) ? 12 : 0;
var spads_enabled = 0;
@@ -146,100 +150,100 @@ protected async Task Initialize()
}
}
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x00, 0x00);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x09, 0x00);
- Peripheral.WriteRegister(0x10, 0x00);
- Peripheral.WriteRegister(0x11, 0x00);
- Peripheral.WriteRegister(0x24, 0x01);
- Peripheral.WriteRegister(0x25, 0xFF);
- Peripheral.WriteRegister(0x75, 0x00);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x4E, 0x2C);
- Peripheral.WriteRegister(0x48, 0x00);
- Peripheral.WriteRegister(0x30, 0x20);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x30, 0x09);
- Peripheral.WriteRegister(0x54, 0x00);
- Peripheral.WriteRegister(0x31, 0x04);
- Peripheral.WriteRegister(0x32, 0x03);
- Peripheral.WriteRegister(0x40, 0x83);
- Peripheral.WriteRegister(0x46, 0x25);
- Peripheral.WriteRegister(0x60, 0x00);
- Peripheral.WriteRegister(0x27, 0x00);
- Peripheral.WriteRegister(0x50, 0x06);
- Peripheral.WriteRegister(0x51, 0x00);
- Peripheral.WriteRegister(0x52, 0x96);
- Peripheral.WriteRegister(0x56, 0x08);
- Peripheral.WriteRegister(0x57, 0x30);
- Peripheral.WriteRegister(0x61, 0x00);
- Peripheral.WriteRegister(0x62, 0x00);
- Peripheral.WriteRegister(0x64, 0x00);
- Peripheral.WriteRegister(0x65, 0x00);
- Peripheral.WriteRegister(0x66, 0xA0);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x22, 0x32);
- Peripheral.WriteRegister(0x47, 0x14);
- Peripheral.WriteRegister(0x49, 0xFF);
- Peripheral.WriteRegister(0x4A, 0x00);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x7A, 0x0A);
- Peripheral.WriteRegister(0x7B, 0x00);
- Peripheral.WriteRegister(0x78, 0x21);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x23, 0x34);
- Peripheral.WriteRegister(0x42, 0x00);
- Peripheral.WriteRegister(0x44, 0xFF);
- Peripheral.WriteRegister(0x45, 0x26);
- Peripheral.WriteRegister(0x46, 0x05);
- Peripheral.WriteRegister(0x40, 0x40);
- Peripheral.WriteRegister(0x0E, 0x06);
- Peripheral.WriteRegister(0x20, 0x1A);
- Peripheral.WriteRegister(0x43, 0x40);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x34, 0x03);
- Peripheral.WriteRegister(0x35, 0x44);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x31, 0x04);
- Peripheral.WriteRegister(0x4B, 0x09);
- Peripheral.WriteRegister(0x4C, 0x05);
- Peripheral.WriteRegister(0x4D, 0x04);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x44, 0x00);
- Peripheral.WriteRegister(0x45, 0x20);
- Peripheral.WriteRegister(0x47, 0x08);
- Peripheral.WriteRegister(0x48, 0x28);
- Peripheral.WriteRegister(0x67, 0x00);
- Peripheral.WriteRegister(0x70, 0x04);
- Peripheral.WriteRegister(0x71, 0x01);
- Peripheral.WriteRegister(0x72, 0xFE);
- Peripheral.WriteRegister(0x76, 0x00);
- Peripheral.WriteRegister(0x77, 0x00);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x0D, 0x01);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x80, 0x01);
- Peripheral.WriteRegister(0x01, 0xF8);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x8E, 0x01);
- Peripheral.WriteRegister(0x00, 0x01);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x80, 0x00);
-
- Peripheral.WriteRegister((byte)Register.SystemInterruptConfigGpio, 0x04);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x00, 0x00);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x09, 0x00);
+ BusComms.WriteRegister(0x10, 0x00);
+ BusComms.WriteRegister(0x11, 0x00);
+ BusComms.WriteRegister(0x24, 0x01);
+ BusComms.WriteRegister(0x25, 0xFF);
+ BusComms.WriteRegister(0x75, 0x00);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x4E, 0x2C);
+ BusComms.WriteRegister(0x48, 0x00);
+ BusComms.WriteRegister(0x30, 0x20);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x30, 0x09);
+ BusComms.WriteRegister(0x54, 0x00);
+ BusComms.WriteRegister(0x31, 0x04);
+ BusComms.WriteRegister(0x32, 0x03);
+ BusComms.WriteRegister(0x40, 0x83);
+ BusComms.WriteRegister(0x46, 0x25);
+ BusComms.WriteRegister(0x60, 0x00);
+ BusComms.WriteRegister(0x27, 0x00);
+ BusComms.WriteRegister(0x50, 0x06);
+ BusComms.WriteRegister(0x51, 0x00);
+ BusComms.WriteRegister(0x52, 0x96);
+ BusComms.WriteRegister(0x56, 0x08);
+ BusComms.WriteRegister(0x57, 0x30);
+ BusComms.WriteRegister(0x61, 0x00);
+ BusComms.WriteRegister(0x62, 0x00);
+ BusComms.WriteRegister(0x64, 0x00);
+ BusComms.WriteRegister(0x65, 0x00);
+ BusComms.WriteRegister(0x66, 0xA0);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x22, 0x32);
+ BusComms.WriteRegister(0x47, 0x14);
+ BusComms.WriteRegister(0x49, 0xFF);
+ BusComms.WriteRegister(0x4A, 0x00);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x7A, 0x0A);
+ BusComms.WriteRegister(0x7B, 0x00);
+ BusComms.WriteRegister(0x78, 0x21);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x23, 0x34);
+ BusComms.WriteRegister(0x42, 0x00);
+ BusComms.WriteRegister(0x44, 0xFF);
+ BusComms.WriteRegister(0x45, 0x26);
+ BusComms.WriteRegister(0x46, 0x05);
+ BusComms.WriteRegister(0x40, 0x40);
+ BusComms.WriteRegister(0x0E, 0x06);
+ BusComms.WriteRegister(0x20, 0x1A);
+ BusComms.WriteRegister(0x43, 0x40);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x34, 0x03);
+ BusComms.WriteRegister(0x35, 0x44);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x31, 0x04);
+ BusComms.WriteRegister(0x4B, 0x09);
+ BusComms.WriteRegister(0x4C, 0x05);
+ BusComms.WriteRegister(0x4D, 0x04);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x44, 0x00);
+ BusComms.WriteRegister(0x45, 0x20);
+ BusComms.WriteRegister(0x47, 0x08);
+ BusComms.WriteRegister(0x48, 0x28);
+ BusComms.WriteRegister(0x67, 0x00);
+ BusComms.WriteRegister(0x70, 0x04);
+ BusComms.WriteRegister(0x71, 0x01);
+ BusComms.WriteRegister(0x72, 0xFE);
+ BusComms.WriteRegister(0x76, 0x00);
+ BusComms.WriteRegister(0x77, 0x00);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x0D, 0x01);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x80, 0x01);
+ BusComms.WriteRegister(0x01, 0xF8);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x8E, 0x01);
+ BusComms.WriteRegister(0x00, 0x01);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x80, 0x00);
+
+ BusComms.WriteRegister((byte)Register.SystemInterruptConfigGpio, 0x04);
var gpio_hv_mux_active_high = Read((byte)Register.GpioHvMuxActiveHigh);
- Peripheral.WriteRegister((byte)Register.GpioHvMuxActiveHigh, (byte)(gpio_hv_mux_active_high & ~0x10));
+ BusComms.WriteRegister((byte)Register.GpioHvMuxActiveHigh, (byte)(gpio_hv_mux_active_high & ~0x10));
- Peripheral.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
- Peripheral.WriteRegister((byte)Register.SystemSequenceConfig, 0xE8);
+ BusComms.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
+ BusComms.WriteRegister((byte)Register.SystemSequenceConfig, 0xE8);
- Peripheral.WriteRegister((byte)Register.SystemSequenceConfig, 0x01);
+ BusComms.WriteRegister((byte)Register.SystemSequenceConfig, 0x01);
PerformSingleRefCalibration(0x40);
- Peripheral.WriteRegister((byte)Register.SystemSequenceConfig, 0x02);
+ BusComms.WriteRegister((byte)Register.SystemSequenceConfig, 0x02);
PerformSingleRefCalibration(0x00);
- Peripheral.WriteRegister((byte)Register.SystemSequenceConfig, 0xE8);
+ BusComms.WriteRegister((byte)Register.SystemSequenceConfig, 0xE8);
}
///
@@ -285,7 +289,7 @@ public void SetAddress(byte newAddress)
return;
byte address = (byte)(newAddress & 0x7F);
- Peripheral.WriteRegister((byte)Register.I2CSlaveDeviceAddress, address);
+ BusComms.WriteRegister((byte)Register.I2CSlaveDeviceAddress, address);
}
///
@@ -317,19 +321,19 @@ public async Task ShutDown(bool state)
///
protected Tuple GetSpadInfo()
{
- Peripheral.WriteRegister(0x80, 0x01);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x00, 0x00);
- Peripheral.WriteRegister(0xFF, 0x06);
+ BusComms.WriteRegister(0x80, 0x01);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x00, 0x00);
+ BusComms.WriteRegister(0xFF, 0x06);
var result = (byte)(Read(0x83) | 0x04);
- Peripheral.WriteRegister(0x83, result);
+ BusComms.WriteRegister(0x83, result);
- Peripheral.WriteRegister(0xFF, 0x07);
- Peripheral.WriteRegister(0x81, 0x01);
- Peripheral.WriteRegister(0x94, 0x6B);
+ BusComms.WriteRegister(0xFF, 0x07);
+ BusComms.WriteRegister(0x81, 0x01);
+ BusComms.WriteRegister(0x94, 0x6B);
- Peripheral.WriteRegister(0x83, 0x00);
+ BusComms.WriteRegister(0x83, 0x00);
int tCount = 0;
while (Read(0x83) == 0x00)
@@ -342,21 +346,21 @@ protected Tuple GetSpadInfo()
}
}
- Peripheral.WriteRegister(0x83, 0x01);
+ BusComms.WriteRegister(0x83, 0x01);
var tmp = Read(0x92);
var count = tmp & 0x7F;
var is_aperture = ((tmp >> 7) & 0x01) == 1;
- Peripheral.WriteRegister(0x81, 0x00);
- Peripheral.WriteRegister(0xFF, 0x06);
+ BusComms.WriteRegister(0x81, 0x00);
+ BusComms.WriteRegister(0xFF, 0x06);
var t = (byte)(Read(0x83) & ~0x04);
- Peripheral.WriteRegister(0xFF, t);
+ BusComms.WriteRegister(0xFF, t);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x00, 0x01);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x80, 0x00);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x00, 0x01);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x80, 0x00);
return new Tuple(count, is_aperture);
}
@@ -368,7 +372,7 @@ protected Tuple GetSpadInfo()
///
protected void PerformSingleRefCalibration(byte vhvInitByte)
{
- Peripheral.WriteRegister((byte)Register.RangeStart, (byte)(0x01 | vhvInitByte & 0xFF));
+ BusComms.WriteRegister((byte)Register.RangeStart, (byte)(0x01 | vhvInitByte & 0xFF));
int tCount = 0;
@@ -382,33 +386,33 @@ protected void PerformSingleRefCalibration(byte vhvInitByte)
}
}
- Peripheral.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
- Peripheral.WriteRegister((byte)Register.RangeStart, 0x00);
+ BusComms.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
+ BusComms.WriteRegister((byte)Register.RangeStart, 0x00);
}
byte Read(byte address)
{
- var result = Peripheral.ReadRegister(address);
+ var result = BusComms.ReadRegister(address);
return result;
}
int Read16(byte address)
{
- //var result = Peripheral.ReadRegisters(address, 2);
- Peripheral.ReadRegister(address, ReadBuffer.Span[0..2]);
+ //var result = BusComms.ReadRegisters(address, 2);
+ BusComms.ReadRegister(address, ReadBuffer.Span[0..2]);
return (ReadBuffer.Span[0] << 8) | ReadBuffer.Span[1];
}
async Task GetRawRangeData()
{
- Peripheral.WriteRegister(0x80, 0x01);
- Peripheral.WriteRegister(0xFF, 0x01);
- Peripheral.WriteRegister(0x00, 0x00);
- Peripheral.WriteRegister(0x91, stopVariable);
- Peripheral.WriteRegister(0x00, 0x01);
- Peripheral.WriteRegister(0xFF, 0x00);
- Peripheral.WriteRegister(0x80, 0x00);
- Peripheral.WriteRegister((byte)Register.RangeStart, 0x01);
+ BusComms.WriteRegister(0x80, 0x01);
+ BusComms.WriteRegister(0xFF, 0x01);
+ BusComms.WriteRegister(0x00, 0x00);
+ BusComms.WriteRegister(0x91, stopVariable);
+ BusComms.WriteRegister(0x00, 0x01);
+ BusComms.WriteRegister(0xFF, 0x00);
+ BusComms.WriteRegister(0x80, 0x00);
+ BusComms.WriteRegister((byte)Register.RangeStart, 0x01);
int tCount = 0;
while ((byte)(Read((byte)Register.RangeStart) & 0x01) > 0)
@@ -435,7 +439,7 @@ async Task GetRawRangeData()
}
var range_mm = Read16((byte)Register.ResultRangeStatus + 10);
- Peripheral.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
+ BusComms.WriteRegister((byte)Register.GpioHvMuxActiveHigh, 0x01);
return range_mm;
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/MeadowApp.cs
index 65d6be25ea..7bbbed3b6c 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/MeadowApp.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Threading.Tasks;
-using Meadow;
+using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Sensors.Distance;
using Meadow.Hardware;
using Meadow.Units;
+using System;
+using System.Threading.Tasks;
using LU = Meadow.Units.Length.UnitType;
namespace Sensors.Distance.Vl53l0x_Sample
@@ -20,7 +20,7 @@ public override Task Initialize()
Resolver.Log.Info("Initializing hardware...");
var i2cBus = Device.CreateI2cBus(I2cBusSpeed.FastPlus);
- sensor = new Vl53l0x(i2cBus, (byte)Vl53l0x.Addresses.Default);
+ sensor = new Vl53l0x(i2cBus);
sensor.DistanceUpdated += Sensor_Updated;
@@ -39,10 +39,10 @@ private void Sensor_Updated(object sender, IChangeResult result)
if (result.New == null) { return; }
if (result.New < new Length(0, LU.Millimeters))
- {
+ {
Resolver.Log.Info("out of range.");
}
- else
+ else
{
Resolver.Log.Info($"{result.New.Millimeters}mm / {result.New.Inches:n3}\"");
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/Vl53l0x_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/Vl53l0x_Sample.csproj
index 25a856b8d8..85df091c69 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/Vl53l0x_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Distance.Vl53l0x/Samples/Vl53l0x_Sample/Vl53l0x_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.Enums.cs
index 62da821d61..dd97bda25a 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.Enums.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.Enums.cs
@@ -8,7 +8,7 @@
public partial class Ags01Db
{
///
- /// Valid addresses for the sensor.
+ /// Valid I2C addresses for the sensor
///
public enum Addresses : byte
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.cs
index 933acd97c2..5c5f39cac9 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Ags01Db.cs
@@ -1,7 +1,7 @@
-using System;
-using System.Threading.Tasks;
using Meadow.Hardware;
using Meadow.Units;
+using System;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Environmental
{
@@ -10,7 +10,7 @@ namespace Meadow.Foundation.Sensors.Environmental
/// Pinout (left to right, label side down): VDD, SDA, GND, SCL
/// Note: requires pullup resistors on SDA/SCL
///
- public partial class Ags01Db : ByteCommsSensorBase
+ public partial class Ags01Db : ByteCommsSensorBase, II2cPeripheral
{
const byte CRC_POLYNOMIAL = 0x31;
const byte CRC_INIT = 0xFF;
@@ -30,6 +30,11 @@ public partial class Ags01Db : ByteCommsSensorBase
///
public Concentration? Concentration { get; private set; }
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new Ags01Db object
///
@@ -41,26 +46,22 @@ public Ags01Db(II2cBus i2cBus, byte address = (byte)Addresses.Default)
}
///
- /// Get ASG01DB VOC Gas Concentration and
- /// Update the Concentration property.
+ /// Get ASG01DB VOC Gas Concentration and update the Concentration property
///
- protected override Task ReadSensor()
+ protected override Task ReadSensor()
{
- return Task.Run(() =>
- {
- WriteBuffer.Span[0] = ASG_DATA_MSB;
- WriteBuffer.Span[1] = ASG_DATA_LSB;
+ WriteBuffer.Span[0] = ASG_DATA_MSB;
+ WriteBuffer.Span[1] = ASG_DATA_LSB;
- Peripheral.Exchange(WriteBuffer.Span[0..1], ReadBuffer.Span);
+ BusComms.Exchange(WriteBuffer.Span[0..1], ReadBuffer.Span);
- var value = ReadBuffer.Span[0] << 8 | ReadBuffer.Span[1];
+ var value = ReadBuffer.Span[0] << 8 | ReadBuffer.Span[1];
- var voc = value / 10.0;//should be ppm
+ var voc = value / 10.0;//ppm
- Concentration = new Concentration(voc, Units.Concentration.UnitType.PartsPerMillion);
+ Concentration = new Concentration(voc, Units.Concentration.UnitType.PartsPerMillion);
- return Concentration.Value;
- });
+ return Task.FromResult(Concentration.Value);
}
///
@@ -74,10 +75,10 @@ public byte GetVersion()
WriteBuffer.Span[0] = ASG_VERSION_MSB;
WriteBuffer.Span[1] = ASG_VERSION_LSB;
- Peripheral.Exchange(WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
+ BusComms.Exchange(WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
// CRC check
- if (!CheckCrc8(ReadBuffer.Slice(0, 1).ToArray(), 1, ReadBuffer.Span[1]))
+ if (!CheckCrc8(ReadBuffer[..1].ToArray(), 1, ReadBuffer.Span[1]))
{
return unchecked((byte)-1);
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Sensors.Environmental.Ags01Db.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Sensors.Environmental.Ags01Db.csproj
index 3fa445deee..6521e34226 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Sensors.Environmental.Ags01Db.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Driver/Sensors.Environmental.Ags01Db.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Samples/Ags01Db_Sample/Ags01Db_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Samples/Ags01Db_Sample/Ags01Db_Sample.csproj
index 24305de7ec..23b61a416e 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Samples/Ags01Db_Sample/Ags01Db_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ags01Db/Samples/Ags01Db_Sample/Ags01Db_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Ens160.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Ens160.cs
index 998cfaa5db..44b8b02b2b 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Ens160.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Ens160.cs
@@ -1,21 +1,21 @@
-using System;
-using System.Threading.Tasks;
using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Peripherals.Sensors.Environmental;
using Meadow.Units;
using Meadow.Utilities;
+using System;
+using System.Threading.Tasks;
namespace Meadow.Foundation.Sensors.Environmental
{
///
/// Represents an ENS160 Digital Metal-Oxide Multi-Gas Sensor
///
- public partial class Ens160 :
- ByteCommsSensorBase<(Concentration? CO2Concentration,
- Concentration? EthanolConcentration,
- Concentration? TVOCConcentration)>,
- IConcentrationSensor
+ public partial class Ens160 :
+ ByteCommsSensorBase<(Concentration? CO2Concentration,
+ Concentration? EthanolConcentration,
+ Concentration? TVOCConcentration)>,
+ IConcentrationSensor, II2cPeripheral
{
///
/// Raised when the CO2 concentration changes
@@ -62,10 +62,15 @@ public partial class Ens160 :
///
public OperatingMode CurrentOperatingMode
{
- get => (OperatingMode)Peripheral.ReadRegister((byte)Registers.OPMODE);
- set => Peripheral.WriteRegister((byte)Registers.OPMODE, (byte)value);
+ get => (OperatingMode)BusComms.ReadRegister((byte)Registers.OPMODE);
+ set => BusComms.WriteRegister((byte)Registers.OPMODE, (byte)value);
}
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
///
/// Create a new ENS160 object
///
@@ -88,8 +93,8 @@ public Ens160(II2cBus i2cBus, byte address = (byte)Addresses.Default)
///
protected async Task Initialize()
{
- Peripheral.WriteRegister((byte)Registers.COMMAND, (byte)Commands.NOP);
- Peripheral.WriteRegister((byte)Registers.COMMAND, (byte)Commands.CLRGPR);
+ BusComms.WriteRegister((byte)Registers.COMMAND, (byte)Commands.NOP);
+ BusComms.WriteRegister((byte)Registers.COMMAND, (byte)Commands.CLRGPR);
await Task.Delay(10);
await Reset();
@@ -101,7 +106,7 @@ protected async Task Initialize()
///
public Task Reset()
{
- Peripheral.WriteRegister((byte)Registers.OPMODE, (byte)OperatingMode.Reset);
+ BusComms.WriteRegister((byte)Registers.OPMODE, (byte)OperatingMode.Reset);
return Task.Delay(10);
}
@@ -112,7 +117,7 @@ public Task Reset()
/// ID as a ushort (2 bytes)
public ushort GetDeviceID()
{
- return Peripheral.ReadRegisterAsUShort((byte)Registers.PART_ID);
+ return BusComms.ReadRegisterAsUShort((byte)Registers.PART_ID);
}
///
@@ -121,11 +126,11 @@ public ushort GetDeviceID()
/// The major, minor, release values as a ttuple of bytes
public (byte Major, byte Minor, byte Release) GetFirmwareVersion()
{
- Peripheral.WriteRegister((byte)Registers.COMMAND, (byte)Commands.GET_APPVER);
+ BusComms.WriteRegister((byte)Registers.COMMAND, (byte)Commands.GET_APPVER);
var version = new byte[3];
- Peripheral.ReadRegister((byte)Registers.GPR_READ_4);
+ BusComms.ReadRegister((byte)Registers.GPR_READ_4);
return (version[0], version[1], version[2]);
}
@@ -135,7 +140,7 @@ public ushort GetDeviceID()
///
void ClearGPRRegisters()
{
- Peripheral.WriteRegister((byte)Registers.COMMAND, (byte)Commands.CLRGPR);
+ BusComms.WriteRegister((byte)Registers.COMMAND, (byte)Commands.CLRGPR);
}
///
@@ -146,7 +151,7 @@ public void SetTemperature(Units.Temperature ambientTemperature)
{
ushort temp = (ushort)(ambientTemperature.Kelvin * 64);
- Peripheral.WriteRegister((byte)Registers.TEMP_IN, temp);
+ BusComms.WriteRegister((byte)Registers.TEMP_IN, temp);
}
///
@@ -157,7 +162,7 @@ public void SetHumidity(RelativeHumidity humidity)
{
ushort hum = (ushort)(humidity.Percent * 64);
- Peripheral.WriteRegister((byte)Registers.RH_IN, hum);
+ BusComms.WriteRegister((byte)Registers.RH_IN, hum);
}
///
@@ -165,7 +170,7 @@ public void SetHumidity(RelativeHumidity humidity)
///
public UBAAirQualityIndex GetAirQualityIndex()
{
- var value = Peripheral.ReadRegister((byte)Registers.DATA_AQI);
+ var value = BusComms.ReadRegister((byte)Registers.DATA_AQI);
var aqi = value >> 5;
@@ -174,33 +179,33 @@ public UBAAirQualityIndex GetAirQualityIndex()
bool IsNewDataAvailable()
{
- var value = Peripheral.ReadRegister((byte)Registers.DATA_STATUS);
+ var value = BusComms.ReadRegister((byte)Registers.DATA_STATUS);
return BitHelpers.GetBitValue(value, 0x02);
}
bool IsNewGPRAvailable()
{
- var value = Peripheral.ReadRegister((byte)Registers.DATA_STATUS);
+ var value = BusComms.ReadRegister((byte)Registers.DATA_STATUS);
return BitHelpers.GetBitValue(value, 0x03);
}
Concentration GetTotalVolotileOrganicCompounds()
{
- var con = Peripheral.ReadRegisterAsUShort((byte)Registers.DATA_TVOC);
+ var con = BusComms.ReadRegisterAsUShort((byte)Registers.DATA_TVOC);
return new Concentration(con, Units.Concentration.UnitType.PartsPerBillion);
}
Concentration GetCO2Concentration()
{
- var con = Peripheral.ReadRegisterAsUShort((byte)Registers.DATA_ECO2);
+ var con = BusComms.ReadRegisterAsUShort((byte)Registers.DATA_ECO2);
return new Concentration(con, Units.Concentration.UnitType.PartsPerMillion);
}
Concentration GetEthanolConcentration()
{
- var con = Peripheral.ReadRegisterAsUShort((byte)Registers.DATA_ETOH);
+ var con = BusComms.ReadRegisterAsUShort((byte)Registers.DATA_ETOH);
return new Concentration(con, Units.Concentration.UnitType.PartsPerBillion);
}
@@ -210,7 +215,7 @@ Concentration GetEthanolConcentration()
/// Temperature
public Units.Temperature GetTemperature()
{
- var temp = Peripheral.ReadRegisterAsUShort((byte)Registers.DATA_T);
+ var temp = BusComms.ReadRegisterAsUShort((byte)Registers.DATA_T);
return new Units.Temperature(temp / 64.0, Units.Temperature.UnitType.Kelvin);
}
@@ -220,7 +225,7 @@ public Units.Temperature GetTemperature()
///
public RelativeHumidity GetHumidity()
{
- var hum = Peripheral.ReadRegisterAsUShort((byte)Registers.DATA_T);
+ var hum = BusComms.ReadRegisterAsUShort((byte)Registers.DATA_T);
return new RelativeHumidity(hum / 512.0);
}
@@ -246,27 +251,24 @@ public override void StopUpdating()
/// Get Scdx40 C02 Gas Concentration and
/// Update the Concentration property
///
- protected override async Task<(Concentration? CO2Concentration,
+ protected override Task<(Concentration? CO2Concentration,
Concentration? EthanolConcentration,
Concentration? TVOCConcentration)> ReadSensor()
{
- return await Task.Run(() =>
- {
- (Concentration? CO2Concentration, Concentration? EthanolConcentration, Concentration? TVOCConcentration) conditions;
+ (Concentration? CO2Concentration, Concentration? EthanolConcentration, Concentration? TVOCConcentration) conditions;
- conditions.CO2Concentration = GetCO2Concentration();
- conditions.EthanolConcentration = GetEthanolConcentration();
- conditions.TVOCConcentration = GetTotalVolotileOrganicCompounds();
+ conditions.CO2Concentration = GetCO2Concentration();
+ conditions.EthanolConcentration = GetEthanolConcentration();
+ conditions.TVOCConcentration = GetTotalVolotileOrganicCompounds();
- return conditions;
- });
+ return Task.FromResult(conditions);
}
///
/// Raise change events for subscribers
///
/// The change result with the current sensor data
- protected void RaiseChangedAndNotify(IChangeResult<(Concentration? CO2Concentration, Concentration? EthanolConcentration, Concentration? TVOCConcentration)> changeResult)
+ protected override void RaiseEventsAndNotify(IChangeResult<(Concentration? CO2Concentration, Concentration? EthanolConcentration, Concentration? TVOCConcentration)> changeResult)
{
if (changeResult.New.CO2Concentration is { } concentration)
{
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Sensors.Environmental.Ens160.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Sensors.Environmental.Ens160.csproj
index 492a80dc04..be41a70ceb 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Sensors.Environmental.Ens160.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Driver/Sensors.Environmental.Ens160.csproj
@@ -17,6 +17,6 @@
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/Ens160_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/Ens160_Sample.csproj
index a0633d896f..8c07ca3633 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/Ens160_Sample.csproj
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/Ens160_Sample.csproj
@@ -9,7 +9,7 @@
App
-
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/MeadowApp.cs
index 3f34254395..4e22b203a1 100644
--- a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Ens160/Samples/Ens160_Sample/MeadowApp.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Threading.Tasks;
-using Meadow;
+using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Sensors.Environmental;
+using System;
+using System.Threading.Tasks;
namespace Sensors.Environmental.Ens160_Sample
{
@@ -17,10 +17,10 @@ public override Task Initialize()
Resolver.Log.Info("Initializing...");
var i2cBus = Device.CreateI2cBus(Meadow.Hardware.I2cBusSpeed.Standard);
-
+
sensor = new Ens160(i2cBus, (byte)Ens160.Addresses.Address_0x53);
-
+
var consumer = Ens160.CreateObserver(
handler: result =>
{
@@ -46,7 +46,7 @@ public override Task Initialize()
Resolver.Log.Info($" CO2 Concentration: {result.New.CO2Concentration?.PartsPerMillion:N0}ppm");
Resolver.Log.Info($" Ethanol Concentraion: {result.New.EthanolConcentration?.PartsPerBillion:N0}ppb");
Resolver.Log.Info($" TVOC Concentraion: {result.New.TVOCConcentration?.PartsPerBillion:N0}ppb");
- Resolver.Log.Info($" AQI: {sensor.GetAirQualityIndex()}");
+ Resolver.Log.Info($" AQI: {sensor.GetAirQualityIndex()}");
};
}
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Datasheet/23-minipid2-manual-3-pin-v1.4-final-version.pdf b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Datasheet/23-minipid2-manual-3-pin-v1.4-final-version.pdf
new file mode 100644
index 0000000000..487783c6be
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Datasheet/23-minipid2-manual-3-pin-v1.4-final-version.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.Enums.cs
new file mode 100644
index 0000000000..8ece9f0cd7
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.Enums.cs
@@ -0,0 +1,44 @@
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ partial class MiniPID2
+ {
+ ///
+ /// The MiniPID 2 Volatile Organic Compounds (VOC) sensor variant
+ ///
+ public enum MiniPID2Type : byte
+ {
+ ///
+ /// MiniPID 2 PartsPerMillion VOC Sensor
+ ///
+ PPM,
+ ///
+ /// MiniPID 2 PartsPerMillion Wide Range VOC Sensor
+ ///
+ PPM_WR,
+ ///
+ /// MiniPID 2 PartsPerBillion VOC Sensor
+ ///
+ PPB,
+ ///
+ /// MiniPID 2 PartsPerBillion Wide Range VOC Sensor
+ ///
+ PPB_WR,
+ ///
+ /// MiniPID 2 High Sensitivity VOC Sensor
+ ///
+ HS,
+ ///
+ /// MiniPID 2 10.0 eV VOC Sensor
+ ///
+ _10ev,
+ ///
+ /// MiniPID 2 11.7 eV VOC Sensor
+ ///
+ _11_7eV,
+ ///
+ /// The number of supported sensors
+ ///
+ count
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.cs
new file mode 100644
index 0000000000..302bef2418
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/MiniPID2.cs
@@ -0,0 +1,222 @@
+using Meadow.Hardware;
+using Meadow.Peripherals.Sensors.Environmental;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// Represents an IonScience MiniPID2 analog photoionisation (PID) Volatile Organic Compounds (VOC) sensor
+ ///
+ public partial class MiniPID2 : SamplingSensorBase, IConcentrationSensor
+ {
+ ///
+ /// Raised when the VOC concentration changes
+ ///
+ public event EventHandler> ConcentrationUpdated = delegate { };
+
+ ///
+ /// Raised when the VOC concentration changes
+ ///
+ public event EventHandler> VOCConcentrationUpdated = delegate { };
+
+ ///
+ /// The current VOC concentration value
+ ///
+ public Concentration? Concentration { get; protected set; }
+
+ ///
+ /// The MiniPID2 device type
+ ///
+ public MiniPID2Type MiniPID2DeviceType { get; protected set; }
+
+ ///
+ /// AnalogInputPort connected to temperature sensor
+ ///
+ protected IAnalogInputPort AnalogInputPort { get; }
+
+ SensorCalibration[] calibrations;
+
+ ///
+ /// Create a new MiniPID2 object
+ ///
+ /// The analog data pin connected to the sensor
+ /// The MiniPID sensor type
+ /// How many samples to take during a given reading.
+ /// These are automatically averaged to reduce noise
+ /// The time between sample readings
+ public MiniPID2(IPin analogPin,
+ MiniPID2Type pid2Type,
+ int sampleCount = 5,
+ TimeSpan? sampleInterval = null) :
+ this(analogPin.CreateAnalogInputPort(sampleCount,
+ sampleInterval ?? TimeSpan.FromMilliseconds(40),
+ new Voltage(3.3, Voltage.UnitType.Volts)), pid2Type)
+ {
+ }
+
+ ///
+ /// Create a new MiniPID2 object
+ ///
+ /// The analog port connected to the sensor
+ /// The MiniPID sensor type
+ public MiniPID2(IAnalogInputPort analogInputPort, MiniPID2Type pid2Type)
+ {
+ MiniPID2DeviceType = pid2Type;
+ AnalogInputPort = analogInputPort;
+ Initialize();
+ }
+
+ ///
+ /// Set the sensor voltage offset
+ /// Useful for compensating for air conditions
+ ///
+ /// Offset voltage
+ /// The sensor to change
+ public void SetOffsetForSensor(Voltage offset, MiniPID2Type sensorType)
+ {
+ calibrations[(int)sensorType].Offset = offset;
+ }
+
+ ///
+ /// Get the voltage offset for a sensor
+ ///
+ /// The sensor
+ /// The offset as voltage
+ public Voltage GetOffsetForSensor(MiniPID2Type sensorType)
+ => calibrations[(int)sensorType].Offset;
+
+ ///
+ /// Initialize the sensor
+ ///
+ void Initialize()
+ {
+ static SensorCalibration GetCalibration(int airOffsetLow, int airOffsetHigh, double sensitivity, double minimumPPB)
+ {
+ return new SensorCalibration(new Voltage((airOffsetLow + airOffsetHigh) / 2, Voltage.UnitType.Millivolts),
+ new Voltage(sensitivity, Voltage.UnitType.Millivolts),
+ new Concentration(minimumPPB, Units.Concentration.UnitType.PartsPerBillion));
+ }
+
+ calibrations = new SensorCalibration[(int)MiniPID2Type.count];
+
+ calibrations[(int)MiniPID2Type.PPM] = GetCalibration(51, 65, 65, 100);
+ calibrations[(int)MiniPID2Type.PPM_WR] = GetCalibration(51, 64, 40, 500);
+ calibrations[(int)MiniPID2Type.PPB] = GetCalibration(51, 80, 30, 1);
+ calibrations[(int)MiniPID2Type.PPB_WR] = GetCalibration(51, 80, 5, 20);
+ calibrations[(int)MiniPID2Type.HS] = GetCalibration(100, 200, 600, 0.5);
+ calibrations[(int)MiniPID2Type._10ev] = GetCalibration(51, 80, 15, 5);
+ calibrations[(int)MiniPID2Type._11_7eV] = GetCalibration(51, 90, 1, 100);
+
+ AnalogInputPort.Subscribe
+ (
+ IAnalogInputPort.CreateObserver(
+ result =>
+ {
+ ChangeResult changeResult = new ChangeResult()
+ {
+ New = VoltageToConcentration(result.New),
+ Old = Concentration
+ };
+ Concentration = changeResult.New;
+ RaiseEventsAndNotify(changeResult);
+ }
+ )
+ );
+ }
+
+ ///
+ /// Convenience method to get the current concentration. For frequent reads, use
+ /// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
+ ///
+ /// The concentration averages of the given sample count
+ protected override async Task ReadSensor()
+ {
+ var voltage = await AnalogInputPort.Read();
+ var newConcentration = VoltageToConcentration(voltage);
+ Concentration = newConcentration;
+ return newConcentration;
+ }
+
+ ///
+ /// Starts updating the sensor on the updateInterval frequency specified
+ ///
+ public override void StartUpdating(TimeSpan? updateInterval = null)
+ {
+ lock (samplingLock)
+ {
+ if (IsSampling) { return; }
+ IsSampling = true;
+ AnalogInputPort.StartUpdating(updateInterval);
+ }
+ }
+
+ ///
+ /// Stops sampling the concentration
+ ///
+ public override void StopUpdating()
+ {
+ lock (samplingLock)
+ {
+ if (!IsSampling) { return; }
+ IsSampling = false;
+ AnalogInputPort.StopUpdating();
+ }
+ }
+
+ ///
+ /// Method to notify subscribers to ConcentrationUpdated event handler
+ ///
+ ///
+ protected override void RaiseEventsAndNotify(IChangeResult changeResult)
+ {
+ ConcentrationUpdated?.Invoke(this, changeResult);
+ base.RaiseEventsAndNotify(changeResult);
+ }
+
+ ///
+ /// Converts voltage to Concentration
+ ///
+ ///
+ /// Concentration
+ protected Concentration VoltageToConcentration(Voltage voltage)
+ {
+ int i = (int)MiniPID2DeviceType;
+
+ var ppm = (voltage.Millivolts - calibrations[i].Offset.Millivolts) / calibrations[i].Sensitivity.Millivolts;
+
+ if (ppm < calibrations[i].MinimumDetectionLimit.PartsPerMillion)
+ {
+ return calibrations[i].MinimumDetectionLimit;
+ }
+
+ return new Concentration(ppm, Units.Concentration.UnitType.PartsPerMillion);
+ }
+
+ struct SensorCalibration
+ {
+ public SensorCalibration(Voltage offset, Voltage sensitivity, Concentration minimumDetectionLimit)
+ {
+ Offset = offset;
+ Sensitivity = sensitivity;
+ MinimumDetectionLimit = minimumDetectionLimit;
+ }
+
+ ///
+ /// The offset to compensate for air quality/conditions
+ ///
+ public Voltage Offset { get; set; }
+
+ ///
+ /// Sensitivity mv/ppm as voltage
+ ///
+ public Voltage Sensitivity { get; set; }
+
+ ///
+ /// The minimum concentration returned by the sensor
+ ///
+ public Concentration MinimumDetectionLimit { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/Sensors.Environmental.MiniPID2.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/Sensors.Environmental.MiniPID2.csproj
new file mode 100644
index 0000000000..a69b3481a4
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Driver/Sensors.Environmental.MiniPID2.csproj
@@ -0,0 +1,22 @@
+
+
+ true
+ icon.png
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ MiniPID2
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Sensors.Environmental.MiniPID2
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow,Meadow.Foundation,Environmental,MiniPID2,VOC,photoionisation,PID,gas,AQI,air,quality
+ 0.1.0
+ true
+ MiniPID2 analog photoionisation (PID) VOC sensor
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..ea59c52d29
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MeadowApp.cs
@@ -0,0 +1,54 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Sensors.Environmental;
+using System;
+using System.Threading.Tasks;
+
+namespace Sensors.Environmental.Ens160_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ MiniPID2 sensor;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initializing...");
+
+ sensor = new MiniPID2(Device.Pins.A01, MiniPID2.MiniPID2Type.PPB_WR);
+
+ var consumer = MiniPID2.CreateObserver(
+ handler: result =>
+ {
+ Resolver.Log.Info($"Observer: VOC concentration changed by threshold; new: {result.New.PartsPerBillion:N1}ppm");
+ },
+ filter: result =>
+ {
+ if (result.Old is { } oldCon &&
+ result.New is { } newCon)
+ {
+ return Math.Abs((newCon - oldCon).PartsPerMillion) > 10;
+ }
+ return false;
+ }
+ );
+
+ sensor?.Subscribe(consumer);
+
+ if (sensor != null)
+ {
+ sensor.Updated += (sender, result) =>
+ {
+ Resolver.Log.Info($" VOC Concentraion: {result.New.PartsPerMillion:N1}ppm");
+ };
+ }
+
+ sensor?.StartUpdating(TimeSpan.FromSeconds(2));
+
+ return base.Initialize();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MiniPID2_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MiniPID2_Sample.csproj
new file mode 100644
index 0000000000..a679cd628b
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/MiniPID2_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.MiniPID2/Samples/MiniPID2_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM-User-Guide_v3.5.pdf b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM-User-Guide_v3.5.pdf
new file mode 100644
index 0000000000..6e73a59c0d
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM-User-Guide_v3.5.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM_RS485_v2.1.pdf b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM_RS485_v2.1.pdf
new file mode 100644
index 0000000000..e2c90b8e1e
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Datasheet/NextPM_RS485_v2.1.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/CommandManager.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/CommandManager.cs
new file mode 100644
index 0000000000..2308911940
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/CommandManager.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Linq;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ internal static class CommandManager
+ {
+ public static (int commandLength, int expectedResponseLength) GenerateCommand(NextPm.CommandByte command, byte[] buffer, params byte[] payload)
+ {
+ buffer[0] = NextPm.SensorAddress;
+ buffer[1] = (byte)command;
+
+ var payloadLength = 2;
+
+ if (payload != null && payload.Length > 0)
+ {
+ Array.Copy(payload, 0, buffer, 2, payload.Length);
+ payloadLength += payload.Length;
+ }
+
+ buffer[payloadLength] = CalculateChecksum(buffer, 0, payloadLength);
+
+ switch (command)
+ {
+ case NextPm.CommandByte.ReadFirmware:
+ return (3, 6);
+ case NextPm.CommandByte.ReadTempAndHumidity:
+ return (3, 8);
+ case NextPm.CommandByte.ReadWriteFanSpeed:
+ return (payloadLength + 1, 6);
+ case NextPm.CommandByte.SetPowerMode:
+ return (payloadLength + 1, 4);
+ case NextPm.CommandByte.ReadSensorState:
+ return (3, 4);
+ case NextPm.CommandByte.Read10sConcentrations:
+ case NextPm.CommandByte.Read60sConcentrations:
+ case NextPm.CommandByte.Read900sConcentrations:
+ return (3, 16);
+ default: throw new NotImplementedException();
+ }
+ }
+
+ public static byte CalculateChecksum(byte[] data, int start, int length)
+ {
+ return (byte)(0x100 - (data.Skip(start).Take(length).Sum(d => d) % 256));
+ }
+
+ public static bool ValidateChecksum(byte[] data, int start, int length)
+ {
+ var expected = CalculateChecksum(data, start, length - 1);
+ return expected == data[start + length - 1];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Constants.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Constants.cs
new file mode 100644
index 0000000000..e29d294d50
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Constants.cs
@@ -0,0 +1,7 @@
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ public partial class NextPm
+ {
+ internal const byte SensorAddress = 0x81; // fixed address, per the data sheet
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Enums.cs
new file mode 100644
index 0000000000..f6f8cb06f6
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Enums.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ public partial class NextPm
+ {
+ internal enum CommandByte : byte
+ {
+ Read10sConcentrations = 0x11,
+ Read60sConcentrations = 0x12,
+ Read900sConcentrations = 0x13,
+ ReadTempAndHumidity = 0x14,
+ SetPowerMode = 0x15,
+ ReadSensorState = 0x16,
+ ReadFirmware = 0x17,
+ ReadWriteFanSpeed = 0x21,
+ ReadWriteModbusAddress = 0x22
+ }
+
+ [Flags]
+ internal enum SensorStatus : byte
+ {
+ Sleep = 1 << 0,
+ Degraded = 1 << 1,
+ NotReady = 1 << 2,
+ HeaterError = 1 << 3,
+ TempHumidyError = 1 << 4,
+ FanError = 1 << 5,
+ MemoryError = 1 << 6,
+ LaserError = 1 << 7,
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Serial.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Serial.cs
new file mode 100644
index 0000000000..c95578a5c2
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.Serial.cs
@@ -0,0 +1,83 @@
+using Meadow.Hardware;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// Represents a TERA Sensor NextPM particulate matter sensor
+ ///
+ public partial class NextPm
+ {
+ private ISerialPort _port;
+ // dev note: these common buffers are used to minimize heap allocations during serial communications with the sensor
+ private byte[] _readBuffer = new byte[16];
+ private byte[] _writeBuffer = new byte[16];
+
+ private ISerialPort InitializePort(ISerialPort port)
+ {
+ if (port.IsOpen)
+ {
+ port.Close();
+ }
+
+ port.BaudRate = 115200;
+ port.DataBits = 8;
+ port.Parity = Parity.Even;
+ port.StopBits = StopBits.One;
+
+ return port;
+ }
+
+ private async Task SendCommand(CommandByte command, params byte[] payload)
+ {
+ var parameters = CommandManager.GenerateCommand(command, _writeBuffer, payload);
+
+ if (!_port.IsOpen)
+ {
+ _port.Open();
+ }
+
+ _port.Write(_writeBuffer, 0, parameters.commandLength);
+
+ var read = 0;
+ var expected = parameters.expectedResponseLength;
+ var timeoutMs = 3000;
+ var readDelay = 500;
+
+ await Task.Delay(100); // initial device response delay
+
+ Array.Clear(_readBuffer, 0, _readBuffer.Length);
+
+ do
+ {
+ read += _port.Read(_readBuffer, read, _readBuffer.Length - read);
+ if (read >= expected) break;
+
+ if (read > 2 && _readBuffer[1] != (byte)command && _readBuffer[1] == 0x16)
+ {
+ var status = (SensorStatus)_readBuffer[2];
+ // typically a "fail" due to the device being in sleep state
+ throw new TeraException($"Device status: {status}");
+ }
+
+ await Task.Delay(readDelay);
+ timeoutMs -= readDelay;
+ } while (timeoutMs > 0);
+
+ if (read < expected)
+ {
+ throw new TeraException("Serial timeout");
+ }
+ else
+ {
+ var checksumIsValid = CommandManager.ValidateChecksum(_readBuffer, 0, parameters.expectedResponseLength);
+
+ if (!checksumIsValid)
+ {
+ throw new TeraException("Invalid response checksum");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.cs
new file mode 100644
index 0000000000..88f43e0985
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/NextPm.cs
@@ -0,0 +1,284 @@
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// Represents a TERA Sensor NextPM serial particulate matter sensor
+ ///
+ public partial class NextPm :
+ PollingSensorBase<(
+ ParticulateReading? reading10s,
+ ParticulateReading? reading1min,
+ ParticulateReading? reading15min,
+ Units.Temperature? temperature,
+ RelativeHumidity? humidity)>,
+ IDisposable, IPowerControllablePeripheral
+ {
+ ///
+ /// Raised when a new 10-second average reading is taken
+ ///
+ public event EventHandler> Readings10sUpdated = delegate { };
+ ///
+ /// Raised when a new 1-minute average reading is taken
+ ///
+ public event EventHandler> Readings1minUpdated = delegate { };
+ ///
+ /// Raised when a new 15-minute average reading is taken
+ ///
+ public event EventHandler> Readings15minUpdated = delegate { };
+ ///
+ /// Raised when a new temperature reading is taken
+ ///
+ public event EventHandler> TemperatureUpdated = delegate { };
+ ///
+ /// Raised when a new humidity reading is taken
+ ///
+ public event EventHandler> HumidityUpdated = delegate { };
+
+ ///
+ /// Returns true if the object is disposed, otherwise false
+ ///
+ public bool IsDisposed { get; private set; }
+
+ ///
+ /// Creates a NextPm instance
+ ///
+ ///
+ public NextPm(SerialPortName portName)
+ : this(portName.CreateSerialPort())
+ {
+ }
+
+ ///
+ /// Creates a NextPm instance
+ ///
+ ///
+ public NextPm(ISerialPort port)
+ {
+ _port = InitializePort(port);
+
+ _port.Open();
+ }
+
+ ///
+ /// Gets the sensor's firmware
+ ///
+ /// The sensor's firmware version
+ public async Task GetFirmwareVersion()
+ {
+ await SendCommand(CommandByte.ReadFirmware);
+ return (short)(_readBuffer[3] << 8 | _readBuffer[4]);
+ }
+
+ ///
+ /// Checks to see if the sensor is in Sleep mode
+ ///
+ /// True if the sensor is in Sleep mode
+ public async Task IsAsleep()
+ {
+ await SendCommand(CommandByte.ReadSensorState);
+ return ((SensorStatus)_readBuffer[2] & SensorStatus.Sleep) == SensorStatus.Sleep;
+ }
+
+ ///
+ /// Puts the device into Sleep mode
+ ///
+ public async Task PowerOff()
+ {
+ await SendCommand(CommandByte.SetPowerMode, 0x01);
+ }
+
+ ///
+ /// Wakes the device from Sleep mode
+ ///
+ public async Task PowerOn()
+ {
+ await SendCommand(CommandByte.SetPowerMode, 0x00);
+ }
+
+ ///
+ /// Gets the fan speed (in percentage)
+ ///
+ public async Task GetFanSpeed()
+ {
+ await SendCommand(CommandByte.ReadWriteFanSpeed, 0x00, 0x00);
+
+ // dev note:
+ // this offset doesn't match the data sheet. The data sheet says there should be 1 byte of response data, but I'm seeing 2 bytes.
+ // data sheet also says the value range should be 30-100, but with 2 bytes I see a value of 290, so totally guessing on this reponse here
+ // the data sheet also says it should be 5 bytes, but the sensor requires 6 or it will give an error
+ return _readBuffer[4];
+ }
+
+ ///
+ /// Sets the sensor fan speed (in percentage)
+ ///
+ ///
+ ///
+ public async Task SetFanSpeed(int speedPercent)
+ {
+ // dev note:
+ // the sensor seems to accept the command, but I can' hear any difference in fan speed from 30 to 100%
+ if (speedPercent < 30 || speedPercent > 100)
+ {
+ throw new ArgumentOutOfRangeException(nameof(speedPercent), "Valid range is 30-100");
+ }
+
+ await SendCommand(CommandByte.ReadWriteFanSpeed, 0x00, (byte)speedPercent);
+ }
+
+ ///
+ /// Gets the sensor's current Temperature and Humidity readings
+ ///
+ public async Task<(Units.Temperature temperature, RelativeHumidity humidity)> GetTemperatureAndHumidity()
+ {
+ await SendCommand(CommandByte.ReadTempAndHumidity);
+
+ var rawTemp = (_readBuffer[3] << 8 | _readBuffer[4]) / 100d;
+ var realTemp = 0.9754 * rawTemp - 4.2488; // math from data sheet
+ var rawHumidity = (_readBuffer[5] << 8 | _readBuffer[6]) / 100d;
+ var realHumidity = 1.1768 * rawHumidity - 4.727; // math from data sheet
+
+ return (new Units.Temperature(realTemp, Units.Temperature.UnitType.Celsius),
+ new RelativeHumidity(realHumidity));
+ }
+
+ ///
+ /// Gets the average particulate reading for the past 10 seconds
+ ///
+ public async Task Get10SecondAverageReading()
+ {
+ await SendCommand(CommandByte.Read10sConcentrations);
+ return new ParticulateReading(_readBuffer, 3);
+ }
+
+ ///
+ /// Gets the average particulate reading for the past 60 seconds
+ ///
+ public async Task Get1MinuteAverageReading()
+ {
+ await SendCommand(CommandByte.Read60sConcentrations);
+ return new ParticulateReading(_readBuffer, 3);
+ }
+
+ ///
+ /// Gets the average particulate reading for the past 15 minutes
+ ///
+ public async Task Get15MinuteAverageReading()
+ {
+ await SendCommand(CommandByte.Read900sConcentrations);
+ return new ParticulateReading(_readBuffer, 3);
+ }
+
+ ///
+ protected override void RaiseEventsAndNotify(IChangeResult<(
+ ParticulateReading? reading10s,
+ ParticulateReading? reading1min,
+ ParticulateReading? reading15min,
+ Units.Temperature? temperature,
+ RelativeHumidity? humidity)> changeResult)
+ {
+ if (changeResult.New.reading10s is { } r10)
+ {
+ Readings10sUpdated?.Invoke(this, new ChangeResult(r10, changeResult.Old?.reading10s));
+ }
+ if (changeResult.New.reading1min is { } r1)
+ {
+ Readings1minUpdated?.Invoke(this, new ChangeResult(r1, changeResult.Old?.reading10s));
+ }
+ if (changeResult.New.reading15min is { } r15)
+ {
+ Readings15minUpdated?.Invoke(this, new ChangeResult(r15, changeResult.Old?.reading10s));
+ }
+ if (changeResult.New.temperature is { } temperature)
+ {
+ TemperatureUpdated?.Invoke(this, new ChangeResult(temperature, changeResult.Old?.temperature));
+ }
+ if (changeResult.New.humidity is { } humidity)
+ {
+ HumidityUpdated?.Invoke(this._port, new ChangeResult(humidity, changeResult.Old?.humidity));
+ }
+ base.RaiseEventsAndNotify(changeResult);
+ }
+
+ ///
+ protected override async Task<(
+ ParticulateReading? reading10s,
+ ParticulateReading? reading1min,
+ ParticulateReading? reading15min,
+ Units.Temperature? temperature,
+ RelativeHumidity? humidity)> ReadSensor()
+ {
+ (ParticulateReading? reading10s, ParticulateReading? reading1min, ParticulateReading? reading15min, Units.Temperature? temperature, RelativeHumidity? humidity) conditions;
+
+ // data sheet indicates you should always read all 4 bytes, in order, for valid data
+ try
+ {
+ conditions.reading10s = await Get10SecondAverageReading();
+ }
+ catch (TeraException)
+ {
+ // data likely not ready, or device is asleep
+ conditions.reading10s = null;
+ }
+
+ try
+ {
+ conditions.reading1min = await Get1MinuteAverageReading();
+ }
+ catch (TeraException)
+ {
+ // data likely not ready, or device is asleep
+ conditions.reading1min = null;
+ }
+
+ try
+ {
+ conditions.reading15min = await Get15MinuteAverageReading();
+ }
+ catch (TeraException)
+ {
+ // data likely not ready, or device is asleep
+ conditions.reading15min = null;
+ }
+
+ try
+ {
+ var th = await GetTemperatureAndHumidity();
+ conditions.temperature = th.temperature;
+ conditions.humidity = th.humidity;
+ }
+ catch (TeraException)
+ {
+ // data likely not ready, or device is asleep
+ conditions.temperature = null;
+ conditions.humidity = null;
+ }
+
+ return conditions;
+ }
+
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!IsDisposed)
+ {
+ if (disposing)
+ {
+ _port?.Dispose();
+ }
+ IsDisposed = true;
+ }
+ }
+
+ ///
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/ParticulateReading.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/ParticulateReading.cs
new file mode 100644
index 0000000000..fa98e3bd74
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/ParticulateReading.cs
@@ -0,0 +1,44 @@
+using Meadow.Units;
+using System;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// A collection of particulate density readings
+ ///
+ public struct ParticulateReading
+ {
+ private byte[] _data;
+
+ internal ParticulateReading(byte[] rawData, int offset)
+ {
+ _data = new byte[12];
+ Array.Copy(rawData, offset, _data, 0, 12);
+ }
+
+ ///
+ /// Count of 1-micron particles
+ ///
+ public ParticleDensity CountOf1micronParticles => new ParticleDensity(_data[0] << 8 | _data[1], ParticleDensity.UnitType.ParticlesPerLiter);
+ ///
+ /// Count of 2.5 micron particles
+ ///
+ public ParticleDensity CountOf2_5micronParticles => new ParticleDensity(_data[2] << 8 | _data[3], ParticleDensity.UnitType.ParticlesPerLiter);
+ ///
+ /// Count of 10 micron particles
+ ///
+ public ParticleDensity CountOf10micronParticles => new ParticleDensity(_data[4] << 8 | _data[5], ParticleDensity.UnitType.ParticlesPerLiter);
+ ///
+ /// Density of 1 micron particles
+ ///
+ public Density EnvironmentalPM_1micron => new Density((_data[6] << 8 | _data[7]) / 10d, Density.UnitType.MicroGramsPerMetersCubed);
+ ///
+ /// Density of 2.5 micron particles
+ ///
+ public Density EnvironmentalPM_2_5micron => new Density((_data[8] << 8 | _data[9]) / 10d, Density.UnitType.MicroGramsPerMetersCubed);
+ ///
+ /// Density of 10 micron particles
+ ///
+ public Density EnvironmentalPM_10micron => new Density((_data[10] << 8 | _data[11]) / 10d, Density.UnitType.MicroGramsPerMetersCubed);
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/Sensors.Environmental.NextPm.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/Sensors.Environmental.NextPm.csproj
new file mode 100644
index 0000000000..adb8b0141f
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/Sensors.Environmental.NextPm.csproj
@@ -0,0 +1,25 @@
+
+
+ true
+ icon.png
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ NextPm
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Sensors.Environmental.NextPm
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow,Meadow.Foundation,Environmental,NextPM,tera,gas,particle,particulate,matter,AQI,air,quality
+ 0.1.0
+ enable
+ true
+ TERA Sensor NextPM serial particulate matter sensor
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/TeraException.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/TeraException.cs
new file mode 100644
index 0000000000..16e47dc703
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Driver/TeraException.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// Exception thrown by a TERA NextPM sensor
+ ///
+ public sealed class TeraException : Exception
+ {
+ internal TeraException(string message) : base(message) { }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..500d4cd702
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/MeadowApp.cs
@@ -0,0 +1,56 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Sensors.Environmental;
+using System.Threading.Tasks;
+
+namespace NextPm_Sample
+{
+ // Change F7FeatherV2 to F7FeatherV1 for V1.x boards
+ public class MeadowApp : App
+ {
+ //
+
+ NextPm nextPm;
+
+ public override Task Initialize()
+ {
+ var port = Device
+ .PlatformOS
+ .GetSerialPortName("COM1")
+ .CreateSerialPort();
+
+ nextPm = new NextPm(port);
+
+ nextPm.Readings10sUpdated += NextPm_Readings10sUpdated;
+
+ return Task.CompletedTask;
+ }
+
+ private void NextPm_Readings10sUpdated(object sender, IChangeResult e)
+ {
+ Resolver.Log.Info($"Past 10 seconds");
+ Resolver.Log.Info($" {e.New.CountOf1micronParticles.ParticlesPerLiter:0} 1 micron particles per liter");
+ Resolver.Log.Info($" {e.New.CountOf2_5micronParticles.ParticlesPerLiter:0} 2.5 micron particles per liter");
+ Resolver.Log.Info($" {e.New.CountOf10micronParticles.ParticlesPerLiter:0} 10 micron particles per liter");
+ Resolver.Log.Info($" {e.New.EnvironmentalPM_1micron.MicroGramsPerMetersCubed:0} ug/L^3 1 micron particles");
+ Resolver.Log.Info($" {e.New.EnvironmentalPM_2_5micron.MicroGramsPerMetersCubed:0} ug/L^3 1 micron particles");
+ Resolver.Log.Info($" {e.New.EnvironmentalPM_10micron.MicroGramsPerMetersCubed:0} ug/L^3 1 micron particles");
+ }
+
+ public override async Task Run()
+ {
+ Resolver.Log.Info("Run...");
+
+ var firmware = await nextPm.GetFirmwareVersion();
+ Resolver.Log.Info($"Firmware: 0x{firmware:X4}");
+
+ var tempAndHumidity = await nextPm.GetTemperatureAndHumidity();
+ Resolver.Log.Info($"Temp: {tempAndHumidity.temperature:0.0}C Humidity: {tempAndHumidity.humidity}%");
+
+ nextPm.StartUpdating();
+ }
+
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/NextPm_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/NextPm_Sample.csproj
new file mode 100644
index 0000000000..0eaafa71c7
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/NextPm_Sample.csproj
@@ -0,0 +1,17 @@
+
+
+ netstandard2.1
+ true
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.NextPm/Samples/NextPm_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Datasheet/4505_PMSA003I_series_data_manual_English_V2.6.pdf b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Datasheet/4505_PMSA003I_series_data_manual_English_V2.6.pdf
new file mode 100644
index 0000000000..204bb5e244
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Datasheet/4505_PMSA003I_series_data_manual_English_V2.6.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Constants.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Constants.cs
new file mode 100644
index 0000000000..53aaead995
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Constants.cs
@@ -0,0 +1,7 @@
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ public partial class Pmsa003i
+ { // This is reversed because we reverse the whole message because it is big-endian and it makes converting values easier
+ private static readonly byte[] Preamble = { 0x4d, 0x42 };
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Enums.cs
new file mode 100644
index 0000000000..82cb2a69cb
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.Enums.cs
@@ -0,0 +1,21 @@
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ public partial class Pmsa003i
+ {
+ ///
+ /// Valid I2C addresses for the sensor
+ ///
+ internal enum Addresses : byte
+ {
+ ///
+ /// Bus address 0x52
+ /// ADDR is low
+ ///
+ Address_0x12 = 0x12,
+ ///
+ /// Default bus address
+ ///
+ Default = Address_0x12
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.cs
new file mode 100644
index 0000000000..fa653f2606
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Environmental.Pmsa003I/Driver/Pmsa003i.cs
@@ -0,0 +1,299 @@
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Sensors.Environmental
+{
+ ///
+ /// Represents a Pmsa003i AQI particulate matter sensor
+ ///
+ public partial class Pmsa003i :
+ ByteCommsSensorBase<(
+ Density? StandardParticulateMatter_1micron, //Particulate Matter 1 micron or less
+ Density? StandardParticulateMatter_2_5micron, //Particulate Matter 2.5 micron or less
+ Density? StandardParticulateMatter_10micron, //Particulate Matter 10 micron or less
+ Density? EnvironmentalParticulateMatter_1micron,
+ Density? EnvironmentalParticulateMatter_2_5micron,
+ Density? EnvironmentalParticulateMatter_10micron,
+ ParticleDensity? ParticleDensity_0_3microns,
+ ParticleDensity? ParticleDensity_0_5microns,
+ ParticleDensity? ParticleDensity_10microns,
+ ParticleDensity? ParticleDensity_25microns,
+ ParticleDensity? ParticleDensity_50microns,
+ ParticleDensity? ParticleDensity_100microns)>,
+ II2cPeripheral
+ {
+ ///
+ /// Raised when the Standard particulate matter PM1.0 density changes
+ ///
+ public event EventHandler> StandardPM_1micronUpdated = delegate { };
+
+ ///
+ /// Raised when the Standard particulate matter PM2.5 density changes
+ ///
+ public event EventHandler> StandardPM_2_5micronUpdated = delegate { };
+
+ ///
+ /// Raised when the Standard particulate matter PM10.0 density changes
+ ///
+ public event EventHandler> StandardPM_10micronUpdated = delegate { };
+
+ ///
+ /// Raised when the Environment particulate matter PM1.0 density changes
+ ///
+ public event EventHandler> EnvironmentalPM_1micronUpdated = delegate { };
+
+ ///
+ /// Raised when the Environment particulate matter PM2.5 density changes
+ ///
+ public event EventHandler> EnvironmentalPM_2_5micronUpdated = delegate { };
+
+ ///
+ /// Raised when the Environment particulate matter PM10.0 density changes
+ ///
+ public event EventHandler> EnvironmentalPM_10micronUpdated = delegate { };
+
+ ///
+ /// Raised when the number of of 0-0.3 micron particles (in 0.1 liters of air) changes
+ ///
+ public event EventHandler> CountOf0_3micronParticlesUpdated = delegate { };
+
+ ///
+ /// Raised when the number of of 0.3-0.5 micron particles (in 0.1 liters of air) changes
+ ///
+ public event EventHandler> CountOf0_5micronParticlesUpdated = delegate { };
+
+ ///
+ /// Raised when the number of of 0.5-10 micron particles changes
+ ///
+ public event EventHandler> CountOf10micronParticlesUpdated = delegate { };
+
+ ///
+ /// Raised when the number of of 10-25 micron particles (in 0.1 liters of air) changes
+ ///
+ public event EventHandler> CountOf25micronParticlesUpdated = delegate { };
+
+ ///
+ /// Raised when the number of of 25-50 micron particles (in 0.1 liters of air) changes
+ ///
+ public event EventHandler> CountOf50micronParticlesUpdated = delegate { };
+
+ ///
+ /// Raised when the number of 50-100 micron particles (in 0.1 liters of air) changes
+ ///
+ public event EventHandler> CountOf100micronParticlesUpdated = delegate { };
+
+ ///
+ /// Standard particulate matter PM1.0 density
+ ///
+ public Density? PM1_0Std => Conditions.StandardParticulateMatter_1micron;
+
+ ///
+ /// Standard particulate matter PM2.5 density
+ ///
+ public Density? PM2_5Std => Conditions.StandardParticulateMatter_2_5micron;
+
+ ///
+ /// Standard particulate matter PM10 density
+ ///
+ public Density? PM10_0Std => Conditions.StandardParticulateMatter_10micron;
+
+ ///
+ /// Standard particulate matter PM1.0 density
+ ///
+ public Density? PM1_0Env => Conditions.EnvironmentalParticulateMatter_1micron;
+
+ ///
+ /// Standard particulate matter PM2.5 density
+ ///
+ public Density? PM2_5Env => Conditions.EnvironmentalParticulateMatter_2_5micron;
+
+ ///
+ /// Standard particulate matter PM10 density
+ ///
+ public Density? PM10_0Env => Conditions.EnvironmentalParticulateMatter_10micron;
+
+ ///
+ /// Particle density of 0 - 0.3 micron particles inair
+ ///
+ public ParticleDensity? CountOf0_3micronParticles => Conditions.ParticleDensity_0_3microns;
+ ///
+ /// Particle density of of 0.3 - 0.5 micron particles in air
+ ///
+ public ParticleDensity? CountOf0_5micronParticles => Conditions.ParticleDensity_0_5microns;
+ ///
+ /// Particle density of of 0.5 - 10 micron particles in air
+ ///
+ public ParticleDensity? CountOf10micronParticles => Conditions.ParticleDensity_10microns;
+ ///
+ /// Particle density of of 0.5 - 10 micron particles in air
+ ///
+ public ParticleDensity? CountOf25micronParticles => Conditions.ParticleDensity_25microns;
+ ///
+ /// Particle density of of 10 - 50 micron particles in air
+ ///
+ public ParticleDensity? CountOf50micronParticles => Conditions.ParticleDensity_50microns;
+ ///
+ /// Particle density of of 50 - 100 micron particles in air
+ ///
+ public ParticleDensity? CountOf100micronParticles => Conditions.ParticleDensity_100microns;
+
+ ///
+ /// The default I2C address for the peripheral
+ ///
+ public byte DefaultI2cAddress => (byte)Addresses.Default;
+
+ ///
+ /// Create a new PMSA003I sensor object
+ ///
+ ///
+ /// The I2C bus
+ public Pmsa003i(II2cBus i2cBus)
+ : base(i2cBus, (byte)Addresses.Default)
+ { }
+
+ ///
+ /// Starts updating the sensor on the updateInterval frequency specified
+ ///
+ public override void StartUpdating(TimeSpan? updateInterval = null)
+ {
+ base.StartUpdating(updateInterval);
+ }
+
+ ///
+ /// Stop updating the sensor
+ /// The sensor will not respond to commands for 500ms
+ /// The call will delay the calling thread for 500ms
+ ///
+ public override void StopUpdating()
+ {
+ base.StopUpdating();
+ }
+
+ ///
+ /// Read data from the sensor
+ ///
+ ///
+ ///
+ protected override Task<(
+ Density? StandardParticulateMatter_1micron,
+ Density? StandardParticulateMatter_2_5micron,
+ Density? StandardParticulateMatter_10micron,
+ Density? EnvironmentalParticulateMatter_1micron,
+ Density? EnvironmentalParticulateMatter_2_5micron,
+ Density? EnvironmentalParticulateMatter_10micron,
+ ParticleDensity? ParticleDensity_0_3microns,
+ ParticleDensity? ParticleDensity_0_5microns,
+ ParticleDensity? ParticleDensity_10microns,
+ ParticleDensity? ParticleDensity_25microns,
+ ParticleDensity? ParticleDensity_50microns,
+ ParticleDensity? ParticleDensity_100microns)> ReadSensor()
+ {
+ var buffer = new byte[32];
+ BusComms.Read(buffer);
+ var span = buffer.AsSpan();
+ span.Reverse();
+ if (buffer[30..32].SequenceEqual(Preamble) == false)
+ {
+ throw new Exception("Preamble mismatch!");
+ }
+ var messageLength = BitConverter.ToUInt16(span[28..30]);
+ if (messageLength != 28)
+ {
+ throw new Exception("Message is corrupt or has invalid length");
+ }
+
+ // this is in big-endian format, so we need to reverse things...
+ var pm10Standard = new Density(BitConverter.ToUInt16(span[26..28]), Density.UnitType.MicroGramsPerMetersCubed);
+ var pm25Standard = new Density(BitConverter.ToUInt16(span[24..26]), Density.UnitType.MicroGramsPerMetersCubed);
+ var pm100Standard = new Density(BitConverter.ToUInt16(span[22..24]), Density.UnitType.MicroGramsPerMetersCubed);
+ var pm10Environmental = new Density(BitConverter.ToUInt16(span[20..22]), Density.UnitType.MicroGramsPerMetersCubed);
+ var pm25Environmental = new Density(BitConverter.ToUInt16(span[18..20]), Density.UnitType.MicroGramsPerMetersCubed);
+ var pm100Environmental = new Density(BitConverter.ToUInt16(span[16..18]), Density.UnitType.MicroGramsPerMetersCubed);
+ var p03um = new ParticleDensity(BitConverter.ToUInt16(span[14..16]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+ var p05um = new ParticleDensity(BitConverter.ToUInt16(span[12..14]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+ var p10um = new ParticleDensity(BitConverter.ToUInt16(span[10..12]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+ var p25um = new ParticleDensity(BitConverter.ToUInt16(span[8..10]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+ var p50um = new ParticleDensity(BitConverter.ToUInt16(span[6..8]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+ var p100um = new ParticleDensity(BitConverter.ToUInt16(span[4..6]), ParticleDensity.UnitType.ParticlesPerCentiliter);
+
+ Conditions = (pm10Standard, pm25Standard, pm100Standard, pm10Environmental, pm25Environmental,
+ pm100Environmental, p03um, p05um, p10um, p25um, p50um, p100um);
+
+ return Task.FromResult(Conditions);
+ }
+
+ ///
+ /// Raise change events for subscribers
+ ///
+ /// The change result with the current sensor data
+ protected override void RaiseEventsAndNotify(
+ IChangeResult<(Density? StandardParticulateMatter_1micron,
+ Density? StandardParticulateMatter_2_5micron,
+ Density? StandardParticulateMatter_10micron,
+ Density? EnvironmentalParticulateMatter_1micron,
+ Density? EnvironmentalParticulateMatter_2_5micron,
+ Density? EnvironmentalParticulateMatter_10micron,
+ ParticleDensity? ParticleDensity_0_3microns,
+ ParticleDensity? ParticleDensity_0_5microns,
+ ParticleDensity? ParticleDensity_10microns,
+ ParticleDensity? ParticleDensity_25microns,
+ ParticleDensity? ParticleDensity_50microns,
+ ParticleDensity? ParticleDensity_100microns)> changeResult)
+ {
+ if (changeResult.New.StandardParticulateMatter_1micron is { } SPM0_1)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(SPM0_1, changeResult.Old.Value.StandardParticulateMatter_1micron));
+ }
+ if (changeResult.New.StandardParticulateMatter_2_5micron is { } SPM0_2_5)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(SPM0_2_5, changeResult.Old.Value.StandardParticulateMatter_2_5micron));
+ }
+ if (changeResult.New.StandardParticulateMatter_10micron is { } SPM0_10)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(SPM0_10, changeResult.Old.Value.StandardParticulateMatter_10micron));
+ }
+ if (changeResult.New.EnvironmentalParticulateMatter_1micron is { } EM0_1)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(EM0_1, changeResult.Old.Value.EnvironmentalParticulateMatter_1micron));
+ }
+ if (changeResult.New.EnvironmentalParticulateMatter_2_5micron is { } EM0_2_5)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(EM0_2_5, changeResult.Old.Value.EnvironmentalParticulateMatter_2_5micron));
+ }
+ if (changeResult.New.EnvironmentalParticulateMatter_10micron is { } EM0_10)
+ {
+ StandardPM_1micronUpdated?.Invoke(this, new ChangeResult(EM0_10, changeResult.Old.Value.EnvironmentalParticulateMatter_10micron));
+ }
+
+ if (changeResult.New.ParticleDensity_0_3microns is { } P_0_3)
+ {
+ CountOf0_3micronParticlesUpdated?.Invoke(this, new ChangeResult(P_0_3, changeResult.Old.Value.ParticleDensity_0_3microns));
+ }
+ if (changeResult.New.ParticleDensity_0_5microns is { } P_0_5)
+ {
+ CountOf0_5micronParticlesUpdated?.Invoke(this, new ChangeResult(P_0_5, changeResult.Old.Value.ParticleDensity_0_5microns));
+ }
+ if (changeResult.New.ParticleDensity_10microns is { } P_10)
+ {
+ CountOf10micronParticlesUpdated?.Invoke(this, new ChangeResult(P_10, changeResult.Old.Value.ParticleDensity_10microns));
+ }
+ if (changeResult.New.ParticleDensity_25microns is { } P_25)
+ {
+ CountOf25micronParticlesUpdated?.Invoke(this, new ChangeResult(P_25, changeResult.Old.Value.ParticleDensity_25microns));
+ }
+ if (changeResult.New.ParticleDensity_50microns is { } P_50)
+ {
+ CountOf50micronParticlesUpdated?.Invoke(this, new ChangeResult(P_50, changeResult.Old.Value.ParticleDensity_50microns));
+ }
+ if (changeResult.New.ParticleDensity_100microns is { } P_100)
+ {
+ CountOf100micronParticlesUpdated?.Invoke(this, new ChangeResult