diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 88289f2..eed3fc2 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -46,19 +46,25 @@ jobs:
repository: WildernessLabs/Meadow.Core
path: Meadow.Core
ref: ${{ env.GITHUB_REF_NAME }} # match Core branch to this branch
- token: ${{ secrets.CI_ACCESS_TOKEN }}
+ token: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Checkout Meadow.Foundation
uses: actions/checkout@v3
with:
repository: WildernessLabs/Meadow.Foundation
path: Meadow.Foundation
ref: ${{ env.GITHUB_REF_NAME }}
-
+ - name: Checkout Meadow.Modbus
+ uses: actions/checkout@v3
+ with:
+ repository: WildernessLabs/Meadow.Modbus
+ path: Meadow.Modbus
+ ref: ${{ env.GITHUB_REF_NAME }}
+
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
- run: dotnet restore ./Meadow.ProjLab/Source/Meadow.ProjectLab/Meadow.ProjectLab.sln
+ run: dotnet restore Meadow.ProjLab/Source/Meadow.ProjectLab.sln
- name: Build
- run: dotnet build -c Release ./Meadow.ProjLab/Source/Meadow.ProjectLab/Meadow.ProjectLab.sln --no-restore
+ run: dotnet build -c Release Meadow.ProjLab/Source/Meadow.ProjectLab.sln --no-restore
diff --git a/Source/Hardware/Design_Files/Schematic_v1.e.pdf b/Hardware/Design_Files/Schematic_v1.e.pdf
similarity index 100%
rename from Source/Hardware/Design_Files/Schematic_v1.e.pdf
rename to Hardware/Design_Files/Schematic_v1.e.pdf
diff --git a/Source/Hardware/Design_Files/Schematic_v2.e.pdf b/Hardware/Design_Files/Schematic_v2.e.pdf
similarity index 100%
rename from Source/Hardware/Design_Files/Schematic_v2.e.pdf
rename to Hardware/Design_Files/Schematic_v2.e.pdf
diff --git a/Source/Hardware/Fabrication_and_Assembly/BOM_v2.e.csv b/Hardware/Fabrication_and_Assembly/BOM_v2.e.csv
similarity index 100%
rename from Source/Hardware/Fabrication_and_Assembly/BOM_v2.e.csv
rename to Hardware/Fabrication_and_Assembly/BOM_v2.e.csv
diff --git a/Source/Hardware/Fabrication_and_Assembly/Gerbers_v2.e.zip b/Hardware/Fabrication_and_Assembly/Gerbers_v2.e.zip
similarity index 100%
rename from Source/Hardware/Fabrication_and_Assembly/Gerbers_v2.e.zip
rename to Hardware/Fabrication_and_Assembly/Gerbers_v2.e.zip
diff --git a/Source/Meadow.ProjectLab.sln b/Source/Meadow.ProjectLab.sln
new file mode 100644
index 0000000..36ba5f9
--- /dev/null
+++ b/Source/Meadow.ProjectLab.sln
@@ -0,0 +1,143 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32929.385
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.ProjectLab", "Meadow.ProjectLab\Meadow.ProjectLab.csproj", "{A263ECD8-AA98-4E1C-B404-EC360584362B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectLab_Demo", "ProjectLab_Demo\ProjectLab_Demo.csproj", "{C9A1FF4C-7210-4EA6-874E-44BE198B2790}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_External", "_External", "{580CAC8F-38C5-4DEA-AAEA-415F5D08982B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Foundation.Core", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Core\Meadow.Foundation.Core.csproj", "{37AAB07A-1F40-4660-97A5-D24890ED7F27}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.F7", "..\..\Meadow.Core\source\Meadow.F7\Meadow.F7.csproj", "{CA35F577-0E8A-496B-A5E3-F7C79FABA169}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Contracts", "..\..\Meadow.Contracts\Source\Meadow.Contracts\Meadow.Contracts.csproj", "{5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Displays.TftSpi", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\Displays.TftSpi\Driver\Displays.TftSpi.csproj", "{2ECCF2AC-44A7-436E-A832-E2A370C3317D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICs.IOExpanders.Mcp23xxx", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\ICs.IOExpanders.Mcp23xxx\Driver\ICs.IOExpanders.Mcp23xxx.csproj", "{FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Atmospheric.Bme68x", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\Sensors.Atmospheric.Bme68x\Driver\Sensors.Atmospheric.Bme68x.csproj", "{F0217A3C-41FC-49A0-8481-64853464D5AB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Light.Bh1750", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\Sensors.Light.Bh1750\Driver\Sensors.Light.Bh1750.csproj", "{CD675B1D-BC88-4DB5-AF45-8079435F52CA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Motion.Bmi270", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\Sensors.Motion.Bmi270\Driver\Sensors.Motion.Bmi270.csproj", "{95770BEF-6864-493C-A8DA-660D3AC582A0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Graphics.MicroGraphics", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Libraries_and_Frameworks\Graphics.MicroGraphics\Driver\Graphics.MicroGraphics.csproj", "{DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Logging", "..\..\Meadow.Logging\lib\Meadow.Logging.csproj", "{A01BAE24-E0E4-458D-A5BA-9C10C4224354}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Modbus", "..\..\Meadow.Modbus\src\Meadow.Modbus\Meadow.Modbus.csproj", "{2D1FC26C-C80D-42E8-92BD-25BE517AC663}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Core", "..\..\Meadow.Core\source\Meadow.Core\Meadow.Core.csproj", "{18EE7297-3E8D-4B94-B6E3-319991927D58}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A263ECD8-AA98-4E1C-B404-EC360584362B}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Release|Any CPU.ActiveCfg = Debug|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Release|Any CPU.Build.0 = Debug|Any CPU
+ {C9A1FF4C-7210-4EA6-874E-44BE198B2790}.Release|Any CPU.Deploy.0 = Debug|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F0217A3C-41FC-49A0-8481-64853464D5AB}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95770BEF-6864-493C-A8DA-660D3AC582A0}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {A01BAE24-E0E4-458D-A5BA-9C10C4224354}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A01BAE24-E0E4-458D-A5BA-9C10C4224354}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A01BAE24-E0E4-458D-A5BA-9C10C4224354}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A01BAE24-E0E4-458D-A5BA-9C10C4224354}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2D1FC26C-C80D-42E8-92BD-25BE517AC663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2D1FC26C-C80D-42E8-92BD-25BE517AC663}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2D1FC26C-C80D-42E8-92BD-25BE517AC663}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2D1FC26C-C80D-42E8-92BD-25BE517AC663}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18EE7297-3E8D-4B94-B6E3-319991927D58}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {37AAB07A-1F40-4660-97A5-D24890ED7F27} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {CA35F577-0E8A-496B-A5E3-F7C79FABA169} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {5FA51D52-0F2C-460A-B0E7-3168A11A1CF0} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {2ECCF2AC-44A7-436E-A832-E2A370C3317D} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {FD0FF1E2-C933-4CFD-84A3-6F4F72C7F048} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {F0217A3C-41FC-49A0-8481-64853464D5AB} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {CD675B1D-BC88-4DB5-AF45-8079435F52CA} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {95770BEF-6864-493C-A8DA-660D3AC582A0} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {DB4C8FC0-18A8-4735-933B-D1FCE59FC1E3} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {A01BAE24-E0E4-458D-A5BA-9C10C4224354} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {2D1FC26C-C80D-42E8-92BD-25BE517AC663} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ {18EE7297-3E8D-4B94-B6E3-319991927D58} = {580CAC8F-38C5-4DEA-AAEA-415F5D08982B}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C1A24E3C-F7F9-4EB3-8A7F-5C6AB7C2A43D}
+ EndGlobalSection
+EndGlobal
diff --git a/Source/Meadow.ProjectLab/Extensions.cs b/Source/Meadow.ProjectLab/Extensions.cs
deleted file mode 100644
index 136e90e..0000000
--- a/Source/Meadow.ProjectLab/Extensions.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Meadow.Devices
-{
- public static class Extensions
- {
- public static bool IsV1Hardware(this ProjectLab p)
- {
- var t = p.Hardware is ProjectLabHardwareV1;
- return t;
- }
-
- public static bool IsV2Hardware(this ProjectLab p)
- {
- var t = p.Hardware is ProjectLabHardwareV2;
- return t;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/IProjectLabHardware.cs b/Source/Meadow.ProjectLab/IProjectLabHardware.cs
index 44d0d03..9120bdc 100644
--- a/Source/Meadow.ProjectLab/IProjectLabHardware.cs
+++ b/Source/Meadow.ProjectLab/IProjectLabHardware.cs
@@ -1,15 +1,31 @@
-using Meadow.Foundation.Displays;
+using Meadow.Foundation.Audio;
+using Meadow.Foundation.Displays;
+using Meadow.Foundation.Sensors.Accelerometers;
+using Meadow.Foundation.Sensors.Atmospheric;
using Meadow.Foundation.Sensors.Buttons;
+using Meadow.Foundation.Sensors.Light;
+using Meadow.Hardware;
+using Meadow.Modbus;
namespace Meadow.Devices
{
- internal interface IProjectLabHardware
+ public interface IProjectLabHardware
{
- public St7789 GetDisplay();
- public PushButton GetLeftButton();
- public PushButton GetRightButton();
- public PushButton GetUpButton();
- public PushButton GetDownButton();
- public string GetRevisionString();
+ public ISpiBus SpiBus { get; }
+ public II2cBus I2cBus { get; }
+ public ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One);
+
+ public St7789? Display { get; }
+ public Bh1750? LightSensor { get; }
+ public Bme688? EnvironmentalSensor { get; }
+ public Bmi270? MotionSensor { get; }
+ public PiezoSpeaker? Speaker { get; }
+
+ public PushButton? LeftButton { get; }
+ public PushButton? RightButton { get; }
+ public PushButton? UpButton { get; }
+ public PushButton? DownButton { get; }
+
+ public string RevisionString { get; }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/Meadow.ProjectLab.csproj b/Source/Meadow.ProjectLab/Meadow.ProjectLab.csproj
index 7c83d22..2fc5a00 100644
--- a/Source/Meadow.ProjectLab/Meadow.ProjectLab.csproj
+++ b/Source/Meadow.ProjectLab/Meadow.ProjectLab.csproj
@@ -7,23 +7,30 @@
Library
ProjectLab
Wilderness Labs, Inc
- http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ https://github.com/WildernessLabs/Meadow.ProjectLab
Meadow.ProjectLab
- https://github.com/WildernessLabs/Meadow.Foundation
+ https://github.com/WildernessLabs/Meadow.ProjectLab
Meadow.ProjectLab, Meadow, ProjectLab
- 0.1.0
+ 0.2.0
true
Base convenience library for the Meadow ProjLab board
enable
+
+
+
+
+
+
-
-
+
+
+
-
\ No newline at end of file
+
diff --git a/Source/Meadow.ProjectLab/Meadow.ProjectLab.sln b/Source/Meadow.ProjectLab/Meadow.ProjectLab.sln
deleted file mode 100644
index dd8cf71..0000000
--- a/Source/Meadow.ProjectLab/Meadow.ProjectLab.sln
+++ /dev/null
@@ -1,27 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.3.32929.385
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.ProjectLab", "Meadow.ProjectLab.csproj", "{1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Release|Any CPU.Build.0 = Release|Any CPU
- {1DB94D06-E8DE-477D-9C7A-AFC9323FAE40}.Release|Any CPU.Deploy.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {C1A24E3C-F7F9-4EB3-8A7F-5C6AB7C2A43D}
- EndGlobalSection
-EndGlobal
diff --git a/Source/Meadow.ProjectLab/ProjectLab.cs b/Source/Meadow.ProjectLab/ProjectLab.cs
index 76ac9f1..0ee64f4 100644
--- a/Source/Meadow.ProjectLab/ProjectLab.cs
+++ b/Source/Meadow.ProjectLab/ProjectLab.cs
@@ -1,55 +1,50 @@
+using System;
using Meadow.Foundation.Audio;
using Meadow.Foundation.Displays;
using Meadow.Foundation.ICs.IOExpanders;
-using Meadow.Foundation.Leds;
using Meadow.Foundation.Sensors.Accelerometers;
using Meadow.Foundation.Sensors.Atmospheric;
using Meadow.Foundation.Sensors.Buttons;
using Meadow.Foundation.Sensors.Light;
using Meadow.Hardware;
using Meadow.Logging;
+using Meadow.Modbus;
using Meadow.Units;
-using System;
namespace Meadow.Devices
{
- public class ProjectLab
+ public class ProjectLab : IProjectLabHardware
{
protected Logger? Logger { get; } = Resolver.Log;
- public ISpiBus SpiBus { get; }
- public II2cBus I2CBus { get; }
-
- private readonly Lazy led;
- private readonly Lazy display;
- private readonly Lazy lightSensor;
- private readonly Lazy upButton;
- private readonly Lazy downButton;
- private readonly Lazy leftButton;
- private readonly Lazy rightButton;
- private readonly Lazy environmentalSensor;
- private readonly Lazy speaker;
- private readonly Lazy motionSensor;
-
- public RgbPwmLed Led => led.Value;
- public St7789? Display => display.Value;
- public Bh1750? LightSensor => lightSensor.Value;
- public PushButton UpButton => upButton.Value;
- public PushButton DownButton => downButton.Value;
- public PushButton LeftButton => leftButton.Value;
- public PushButton RightButton => rightButton.Value;
- public Bme688? EnvironmentalSensor => environmentalSensor.Value;
- public PiezoSpeaker Speaker => speaker.Value;
- public Bmi270? MotionSensor => motionSensor.Value;
-
- internal IProjectLabHardware Hardware { get; }
-
- public Mcp23008? Mcp_1 { get; }
- public Mcp23008? Mcp_2 { get; }
- public Mcp23008? Mcp_Version { get; }
-
+ protected IProjectLabHardware Hardware { get; set; }
+
+ public II2cBus I2cBus { get; protected set; }
+ public ISpiBus SpiBus { get; protected set; }
+ public St7789? Display => Hardware.Display;
+ public Bh1750? LightSensor => Hardware.LightSensor;
+ public Bme688? EnvironmentalSensor => Hardware.EnvironmentalSensor;
+ public Bmi270? MotionSensor => Hardware.MotionSensor;
+ public PiezoSpeaker? Speaker => Hardware.Speaker;
+ public PushButton? LeftButton => Hardware.LeftButton;
+ public PushButton? RightButton => Hardware.RightButton;
+ public PushButton? UpButton => Hardware.UpButton;
+ public PushButton? DownButton => Hardware.DownButton;
+ public string RevisionString => Hardware.RevisionString;
+
+ ///
+ /// Create an instance of the ProjectLab class
+ ///
+ ///
public ProjectLab()
{
- // check to see if we have an MCP23008 - it was introduced in v2 hardware
+ // v2+ stuff
+ Mcp23008? mcp_1 = null;
+ Mcp23008? mcp_2 = null;
+ Mcp23008? mcp_Version = null;
+
+ Logger?.Debug("Initializing Project Lab...");
+
+ // make sure not getting instantiated before the App Initialize method
if (Resolver.Device == null)
{
var msg = "ProjLab instance must be created no earlier than App.Initialize()";
@@ -66,7 +61,6 @@ public ProjectLab()
throw new Exception(msg);
}
- // create our busses
Logger?.Info("Creating comms busses...");
var config = new SpiClockConfiguration(
new Frequency(48000, Frequency.UnitType.Kilohertz),
@@ -78,13 +72,11 @@ public ProjectLab()
device.Pins.CIPO,
config);
- Logger?.Info("SPI Bus instantiated.");
-
- I2CBus = device.CreateI2cBus();
+ Logger?.Info("SPI Bus instantiated");
- Logger?.Info("I2C Bus instantiated.");
+ I2cBus = device.CreateI2cBus();
- // determine hardware
+ Logger?.Info("I2C Bus instantiated");
try
{
@@ -93,185 +85,74 @@ public ProjectLab()
device.Pins.D09, InterruptMode.EdgeRising, ResistorMode.InternalPullDown);
IDigitalOutputPort mcp_Reset = device.CreateDigitalOutputPort(device.Pins.D14);
- Mcp_1 = new Mcp23008(I2CBus, address: 0x20, mcp1_int, mcp_Reset);
+ mcp_1 = new Mcp23008(I2cBus, address: 0x20, mcp1_int, mcp_Reset);
- Logger?.Info("Mcp_1 up.");
+ Logger?.Info("Mcp_1 up");
}
catch (Exception e)
{
- Logger?.Trace($"Failed to create MCP1: {e.Message}");
+ Logger?.Trace($"Failed to create MCP1: {e.Message}, could be a v1 board");
}
+
+ IDigitalInputPort? mcp2_int = null;
try
{
- // MCP the Second
- IDigitalInputPort mcp2_int = device.CreateDigitalInputPort(
- device.Pins.D10, InterruptMode.EdgeRising, ResistorMode.InternalPullDown);
- Mcp_2 = new Mcp23008(I2CBus, address: 0x21, mcp2_int);
+ if(mcp_1 != null)
+ {
+ // MCP the Second
+ if (device.Pins.D10.Supports(c => c.InterruptCapable))
+ {
+ mcp2_int = device.CreateDigitalInputPort(
+ device.Pins.D10, InterruptMode.EdgeRising, ResistorMode.InternalPullDown);
+ }
- Logger?.Info("Mcp_2 up.");
+ mcp_2 = new Mcp23008(I2cBus, address: 0x21, mcp2_int);
+
+ Logger?.Info("Mcp_2 up");
+ }
}
catch (Exception e)
{
Logger?.Trace($"Failed to create MCP2: {e.Message}");
+ mcp2_int?.Dispose();
}
+
try
{
- Mcp_Version = new Mcp23008(I2CBus, address: 0x27);
- Logger?.Info("Mcp_Version up.");
+ if (mcp_1 != null)
+ {
+ mcp_Version = new Mcp23008(I2cBus, address: 0x27);
+ Logger?.Info("Mcp_Version up");
+ }
}
catch (Exception e)
{
Logger?.Trace($"ERR creating the MCP that has version information: {e.Message}");
}
- if (Mcp_1 == null)
+ if (mcp_1 == null)
{
- Hardware = new ProjectLabHardwareV1(device, SpiBus);
+ Logger?.Info("Instantiating Project Lab v1 specific hardware");
+ Hardware = new ProjectLabHardwareV1(device, SpiBus, I2cBus);
}
else
{
- Hardware = new ProjectLabHardwareV2(Mcp_1, Mcp_Version, device, SpiBus);
- }
-
- // lazy load all components
- try
- {
- led = new Lazy(() =>
- new RgbPwmLed(
- device: device,
- redPwmPin: device.Pins.OnboardLedRed,
- greenPwmPin: device.Pins.OnboardLedGreen,
- bluePwmPin: device.Pins.OnboardLedBlue));
-
- display = new Lazy(() =>
- {
- try
- {
- return Hardware.GetDisplay();
- }
- catch (Exception ex)
- {
- Resolver.Log.Error($"Unable to create the ST7789 Display Light Sensor: {ex.Message}");
- return default;
- }
- });
-
-
- lightSensor = new Lazy(() =>
- {
- try
- {
- return new Bh1750(
- i2cBus: I2CBus,
- measuringMode: Bh1750.MeasuringModes.ContinuouslyHighResolutionMode, // the various modes take differing amounts of time.
- lightTransmittance: 0.5, // lower this to increase sensitivity, for instance, if it's behind a semi opaque window
- address: (byte)Bh1750.Addresses.Address_0x23);
- }
- catch (Exception ex)
- {
- Resolver.Log.Error($"Unable to create the BH1750 Light Sensor: {ex.Message}");
- return default;
- }
- });
-
-
- rightButton = new Lazy(Hardware.GetRightButton());
-
- if (!this.IsV1Hardware())
- {
- upButton = new Lazy(Hardware.GetUpButton());
- leftButton = new Lazy(Hardware.GetLeftButton());
- downButton = new Lazy(Hardware.GetDownButton());
- }
-
- environmentalSensor = new Lazy(() =>
- {
- try
- {
- return new Bme688(I2CBus, (byte)Bme688.Addresses.Address_0x76);
- }
- catch (Exception ex)
- {
- Resolver.Log.Error($"Unable to create the BME680 Environmental Sensor: {ex.Message}");
- return default;
- }
- });
-
- speaker = new Lazy(new PiezoSpeaker(device, device.Pins.D11));
-
- motionSensor = new Lazy(() =>
- {
- try
- {
- return new Bmi270(I2CBus);
- }
- catch (Exception ex)
- {
- Resolver.Log.Error($"Unable to create the BMI270 IMU: {ex.Message}");
- return default;
- }
- });
- }
-
- catch (Exception ex)
- {
- Logger?.Error($"Error initializing ProjectLab: {ex.Message}");
+ Logger?.Info("Instantiating Project Lab v2 specific hardware");
+ Hardware = new ProjectLabHardwareV2(device, SpiBus, I2cBus, mcp_1, mcp_2, mcp_Version);
}
}
- public string HardwareRevision
+ ///
+ /// Gets a ModbusRtuClient for the on-baord RS485 connector
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One)
{
- get => Hardware.GetRevisionString();
+ return Hardware.GetModbusRtuClient(baudRate, dataBits, parity, stopBits);
}
-
- public static (
- IPin MB1_CS,
- IPin MB1_INT,
- IPin MB1_PWM,
- IPin MB1_AN,
- IPin MB1_SO,
- IPin MB1_SI,
- IPin MB1_SCK,
- IPin MB1_SCL,
- IPin MB1_SDA,
-
- IPin MB2_CS,
- IPin MB2_INT,
- IPin MB2_PWM,
- IPin MB2_AN,
- IPin MB2_SO,
- IPin MB2_SI,
- IPin MB2_SCK,
- IPin MB2_SCL,
- IPin MB2_SDA,
-
- IPin A0,
- IPin D03,
- IPin D04
- ) Pins = (
- Resolver.Device.GetPin("D14"),
- Resolver.Device.GetPin("D03"),
- Resolver.Device.GetPin("D04"),
- Resolver.Device.GetPin("A00"),
- Resolver.Device.GetPin("CIPO"),
- Resolver.Device.GetPin("COPI"),
- Resolver.Device.GetPin("SCK"),
- Resolver.Device.GetPin("D08"),
- Resolver.Device.GetPin("D07"),
-
- Resolver.Device.GetPin("A02"),
- Resolver.Device.GetPin("D04"),
- Resolver.Device.GetPin("D03"),
- Resolver.Device.GetPin("A01"),
- Resolver.Device.GetPin("CIPO"),
- Resolver.Device.GetPin("COPI"),
- Resolver.Device.GetPin("SCK"),
- Resolver.Device.GetPin("D08"),
- Resolver.Device.GetPin("D07"),
-
- Resolver.Device.GetPin("A00"),
- Resolver.Device.GetPin("D03"),
- Resolver.Device.GetPin("D04")
- );
}
}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs
new file mode 100644
index 0000000..dafe69b
--- /dev/null
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs
@@ -0,0 +1,191 @@
+using Meadow.Foundation.Audio;
+using Meadow.Foundation.Displays;
+using Meadow.Foundation.Sensors.Accelerometers;
+using Meadow.Foundation.Sensors.Atmospheric;
+using Meadow.Foundation.Sensors.Buttons;
+using Meadow.Foundation.Sensors.Light;
+using Meadow.Hardware;
+using Meadow.Logging;
+using Meadow.Modbus;
+using System;
+
+namespace Meadow.Devices
+{
+ ///
+ /// Contains common elements of Project Lab Hardware
+ ///
+ public abstract class ProjectLabHardwareBase : IProjectLabHardware
+ {
+ protected Logger? Logger { get; } = Resolver.Log;
+
+ //==== properties
+
+ ///
+ /// Gets the SPI Bus
+ ///
+ public ISpiBus SpiBus { get; }
+ ///
+ /// Gets the I2C Bus
+ ///
+ public II2cBus I2cBus { get; }
+ ///
+ /// Gets the BH1750 Light Sensor on the Project Lab board
+ ///
+ public Bh1750? LightSensor { get; }
+ ///
+ /// Gets the BME688 environmental sensor on the Project Lab board
+ ///
+ public Bme688? EnvironmentalSensor { get; }
+ ///
+ /// Gets the Piezo noise maker on the Project Lab board
+ ///
+ public PiezoSpeaker? Speaker { get; }
+ ///
+ /// Gets the BMI inertial movement unit (IMU) on the Project Lab board
+ ///
+ public Bmi270? MotionSensor { get; }
+ ///
+ /// Gets the ST7789 Display on the Project Lab board
+ ///
+ public abstract St7789? Display { get; }
+ ///
+ /// Gets the Up PushButton on the Project Lab board
+ ///
+ public abstract PushButton? UpButton { get; }
+ ///
+ /// Gets the Down PushButton on the Project Lab board
+ ///
+ public abstract PushButton? DownButton { get; }
+ ///
+ /// Gets the Left PushButton on the Project Lab board
+ ///
+ public abstract PushButton? LeftButton { get; }
+ ///
+ /// Gets the Right PushButton on the Project Lab board
+ ///
+ public abstract PushButton? RightButton { get; }
+ ///
+ /// Gets the ProjectLab board hardware revision
+ ///
+ public virtual string RevisionString { get; set; } = "unknown";
+
+ public ProjectLabHardwareBase(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2cBus i2cBus)
+ {
+ this.SpiBus = spiBus;
+ this.I2cBus = i2cBus;
+
+ //==== Initialize the shared/common stuff
+ try
+ {
+ Logger?.Info("Instantiating light sensor.");
+ LightSensor = new Bh1750(
+ i2cBus: I2cBus,
+ measuringMode: Bh1750.MeasuringModes.ContinuouslyHighResolutionMode, // the various modes take differing amounts of time.
+ lightTransmittance: 0.5, // lower this to increase sensitivity, for instance, if it's behind a semi opaque window
+ address: (byte)Bh1750.Addresses.Address_0x23);
+ Logger?.Info("Light sensor up.");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Error($"Unable to create the BH1750 Light Sensor: {ex.Message}");
+ }
+
+ try
+ {
+ Logger?.Info("Instantiating environmental sensor.");
+ EnvironmentalSensor = new Bme688(I2cBus, (byte)Bme688.Addresses.Address_0x76);
+ Logger?.Info("Environmental sensor up.");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Error($"Unable to create the BME688 Environmental Sensor: {ex.Message}");
+ }
+
+ try
+ {
+ Logger?.Info("Instantiating speaker.");
+ Speaker = new PiezoSpeaker(device, device.Pins.D11);
+ Logger?.Info("Speaker up.");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Error($"Unable to create the Piezo Speaker: {ex.Message}");
+ }
+
+ try
+ {
+ Logger?.Info("Instantiating motion sensor.");
+ MotionSensor = new Bmi270(I2cBus);
+ Logger?.Info("Motion sensor up.");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Error($"Unable to create the BMI270 IMU: {ex.Message}");
+ }
+
+ }
+
+ ///
+ /// Gets a ModbusRtuClient for the on-baord RS485 connector
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One);
+
+ ///
+ /// Gets the pin definitions for the Project Lab board
+ ///
+ public static (
+ IPin MB1_CS,
+ IPin MB1_INT,
+ IPin MB1_PWM,
+ IPin MB1_AN,
+ IPin MB1_SO,
+ IPin MB1_SI,
+ IPin MB1_SCK,
+ IPin MB1_SCL,
+ IPin MB1_SDA,
+
+ IPin MB2_CS,
+ IPin MB2_INT,
+ IPin MB2_PWM,
+ IPin MB2_AN,
+ IPin MB2_SO,
+ IPin MB2_SI,
+ IPin MB2_SCK,
+ IPin MB2_SCL,
+ IPin MB2_SDA,
+
+ IPin A0,
+ IPin D03,
+ IPin D04
+ ) Pins = (
+ Resolver.Device.GetPin("D14"),
+ Resolver.Device.GetPin("D03"),
+ Resolver.Device.GetPin("D04"),
+ Resolver.Device.GetPin("A00"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("D08"),
+ Resolver.Device.GetPin("D07"),
+
+ Resolver.Device.GetPin("A02"),
+ Resolver.Device.GetPin("D04"),
+ Resolver.Device.GetPin("D03"),
+ Resolver.Device.GetPin("A01"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("D08"),
+ Resolver.Device.GetPin("D07"),
+
+ Resolver.Device.GetPin("A00"),
+ Resolver.Device.GetPin("D03"),
+ Resolver.Device.GetPin("D04")
+ );
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
index 87b8900..b15948a 100644
--- a/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
@@ -1,86 +1,77 @@
-using Meadow.Foundation.Displays;
-using Meadow.Foundation.Graphics;
-using Meadow.Foundation.Sensors.Buttons;
-using Meadow.Hardware;
-using System;
-
-namespace Meadow.Devices
-{
- internal class ProjectLabHardwareV1 : IProjectLabHardware
- {
- private IF7FeatherMeadowDevice device;
- private ISpiBus spiBus;
- private St7789? display;
- private PushButton? rightButton;
- private string revision = "v1.x";
-
- public ProjectLabHardwareV1(IF7FeatherMeadowDevice device, ISpiBus spiBus)
- {
- this.device = device;
- this.spiBus = spiBus;
- }
-
- public string GetRevisionString()
- {
- return revision;
- }
-
- public St7789 GetDisplay()
- {
- if (display == null)
- {
- display = new St7789(
- device: device,
- spiBus: spiBus,
- chipSelectPin: device.Pins.A03,
- dcPin: device.Pins.A04,
- resetPin: device.Pins.A05,
- width: 240, height: 240,
- colorMode: ColorType.Format16bppRgb565);
- }
-
- return display;
- }
-
- public PushButton GetLeftButton()
- {
- if (Resolver.Device is F7FeatherV2)
- {
- // D10 no interrupts
- }
- throw new PlatformNotSupportedException("A hardware bug prevents usage of the Left button on ProjectLab v1 hardware.");
- }
-
- public PushButton GetRightButton()
- {
- if (rightButton == null)
- {
- rightButton = new PushButton(
- Resolver.Device.CreateDigitalInputPort(
- device.Pins.D05,
- InterruptMode.EdgeBoth,
- ResistorMode.InternalPullDown));
- }
- return rightButton;
- }
-
- public PushButton GetUpButton()
- {
- // D15
- if (Resolver.Device is F7FeatherV2)
- {
- // D15 no interrupts
- }
- throw new PlatformNotSupportedException("A hardware bug prevents usage of the Up button on ProjectLab v1 hardware.");
- }
-
- public PushButton GetDownButton()
- {
- if (Resolver.Device is F7FeatherV2)
- {
- // D02 no interrupts
- }
- throw new PlatformNotSupportedException("A hardware bug prevents usage of the Down button on ProjectLab v1 hardware.");
- }
- }
+using Meadow.Foundation.Displays;
+using Meadow.Foundation.Graphics;
+using Meadow.Foundation.Sensors.Buttons;
+using Meadow.Hardware;
+using Meadow.Modbus;
+using System;
+
+namespace Meadow.Devices
+{
+ internal class ProjectLabHardwareV1 : ProjectLabHardwareBase
+ {
+ private string revision = "v1.x";
+
+ ///
+ /// Gets the ST7789 Display on the Project Lab board
+ ///
+ public override St7789? Display { get; }
+ ///
+ /// Gets the Up PushButton on the Project Lab board
+ ///
+ public override PushButton? UpButton { get; }
+ ///
+ /// Gets the Down PushButton on the Project Lab board
+ ///
+ public override PushButton? DownButton { get; }
+ ///
+ /// Gets the Left PushButton on the Project Lab board
+ ///
+ public override PushButton? LeftButton { get; }
+ ///
+ /// Gets the Right PushButton on the Project Lab board
+ ///
+ public override PushButton? RightButton { get; }
+
+ public ProjectLabHardwareV1(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2cBus i2cBus)
+ : base(device, spiBus, i2cBus)
+ {
+ //---- create our display
+ Logger?.Info("Instantiating display.");
+ Display = new St7789(
+ device: device,
+ spiBus: SpiBus,
+ chipSelectPin: device.Pins.A03,
+ dcPin: device.Pins.A04,
+ resetPin: device.Pins.A05,
+ width: 240, height: 240,
+ colorMode: ColorType.Format16bppRgb565);
+
+ //---- buttons
+ Logger?.Info("Instantiating buttons.");
+ LeftButton = GetPushButton(device, device.Pins.D10);
+ RightButton = GetPushButton(device, device.Pins.D05);
+ UpButton = GetPushButton(device, device.Pins.D15);
+ DownButton = GetPushButton(device, device.Pins.D02);
+ Logger?.Info("Buttons up.");
+ }
+
+ public override string RevisionString => revision;
+
+ private PushButton GetPushButton(IF7FeatherMeadowDevice device, IPin pin)
+ => new PushButton(Resolver.Device, pin, ResistorMode.InternalPullDown);
+
+ public override ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One)
+ {
+ if (Resolver.Device is F7FeatherV1 device)
+ {
+ var port = device.CreateSerialPort(device.SerialPortNames.Com4, baudRate, dataBits, parity, stopBits);
+ port.WriteTimeout = port.ReadTimeout = TimeSpan.FromSeconds(5);
+ var serialEnable = device.CreateDigitalOutputPort(device.Pins.D09, false);
+ return new ModbusRtuClient(port, serialEnable);
+ }
+
+ // this is v1 instance hardware, so we should never get here
+ throw new NotSupportedException();
+ }
+ }
}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
index 9e890dd..1145ffb 100644
--- a/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
@@ -3,110 +3,115 @@
using Meadow.Foundation.ICs.IOExpanders;
using Meadow.Foundation.Sensors.Buttons;
using Meadow.Hardware;
+using Meadow.Modbus;
+using System;
using System.Threading;
namespace Meadow.Devices
{
- internal class ProjectLabHardwareV2 : IProjectLabHardware
+ internal class ProjectLabHardwareV2 : ProjectLabHardwareBase
{
- private IF7FeatherMeadowDevice device;
- private ISpiBus spiBus;
private Mcp23008 mcp1;
+ private Mcp23008 mcp2;
private Mcp23008? mcpVersion;
- private St7789? display;
- private PushButton? leftButton;
- private PushButton? rightButton;
- private PushButton? upButton;
- private PushButton? downButton;
- private string? revision;
+ ///
+ /// Gets the ST7789 Display on the Project Lab board
+ ///
+ public override St7789? Display { get; }
+ ///
+ /// Gets the Up PushButton on the Project Lab board
+ ///
+ public override PushButton? UpButton { get; }
+ ///
+ /// Gets the Down PushButton on the Project Lab board
+ ///
+ public override PushButton? DownButton { get; }
+ ///
+ /// Gets the Left PushButton on the Project Lab board
+ ///
+ public override PushButton? LeftButton { get; }
+ ///
+ /// Gets the Right PushButton on the Project Lab board
+ ///
+ public override PushButton? RightButton { get; }
- public ProjectLabHardwareV2(Mcp23008 mcp1, Mcp23008? mcpVersion, IF7FeatherMeadowDevice device, ISpiBus spiBus)
+ public ProjectLabHardwareV2(
+ IF7FeatherMeadowDevice device,
+ ISpiBus spiBus,
+ II2cBus i2cBus,
+ Mcp23008 mcp1, Mcp23008 mcp2, Mcp23008? mcpVersion
+ ) : base(device, spiBus, i2cBus)
{
- this.device = device;
- this.spiBus = spiBus;
this.mcp1 = mcp1;
+ this.mcp2 = mcp2;
this.mcpVersion = mcpVersion;
- }
-
- public string GetRevisionString()
- {
- // TODO: figure this out from MCP3?
- if (revision == null)
- {
- if (mcpVersion == null)
- {
- revision = $"v2.x";
- }
- else
- {
- byte rev = mcpVersion.ReadFromPorts(Mcp23xxx.PortBank.A);
- //mapping? 0 == d2.d?
- revision = $"v2.{rev}";
- }
- }
- return revision;
- }
- public St7789 GetDisplay()
- {
- if (display == null)
- {
- var chipSelectPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP5);
- var dcPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP6);
- var resetPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP7);
+ //---- instantiate display
+ Logger?.Info("Instantiating display.");
+ var chipSelectPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP5);
+ var dcPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP6);
+ var resetPort = mcp1.CreateDigitalOutputPort(mcp1.Pins.GP7);
+ Thread.Sleep(50);
- Thread.Sleep(50);
+ Display = new St7789(
+ spiBus: SpiBus,
+ chipSelectPort: chipSelectPort,
+ dataCommandPort: dcPort,
+ resetPort: resetPort,
+ width: 240, height: 240,
+ colorMode: ColorType.Format16bppRgb565);
+ Logger?.Info("Display up.");
- display = new St7789(
- spiBus: spiBus,
- chipSelectPort: chipSelectPort,
- dataCommandPort: dcPort,
- resetPort: resetPort,
- width: 240, height: 240,
- colorMode: ColorType.Format16bppRgb565);
- }
- return display;
+ //---- buttons
+ Logger?.Info("Instantiating buttons.");
+ var leftPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP2, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ LeftButton = new PushButton(leftPort);
+ var rightPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP1, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ RightButton = new PushButton(rightPort);
+ var upPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP0, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ UpButton = new PushButton(upPort);
+ var downPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP3, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ DownButton = new PushButton(downPort);
+ Logger?.Info("Buttons up.");
}
- public PushButton GetLeftButton()
+ public override string RevisionString
{
- if (leftButton == null)
+ get
{
- var leftPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP2, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
- leftButton = new PushButton(leftPort);
+ // TODO: figure this out from MCP3?
+ if (revision == null)
+ {
+ if (mcpVersion == null)
+ {
+ revision = $"v2.x";
+ }
+ else
+ {
+ byte rev = mcpVersion.ReadFromPorts(Mcp23xxx.PortBank.A);
+ //mapping? 0 == d2.d?
+ revision = $"v2.{rev}";
+ }
+ }
+ return revision;
}
- return leftButton;
}
+ protected string? revision;
- public PushButton GetRightButton()
+ public override ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One)
{
- if (rightButton == null)
+ if (Resolver.Device is F7FeatherV2 device)
{
- var rightPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP1, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
- rightButton = new PushButton(rightPort);
- }
- return rightButton;
- }
+ var port = device.CreateSerialPort(device.SerialPortNames.Com4, baudRate, dataBits, parity, stopBits);
+ port.WriteTimeout = port.ReadTimeout = TimeSpan.FromSeconds(5);
+ var serialEnable = mcp2.CreateDigitalOutputPort(mcp2.Pins.GP0, false);
- public PushButton GetUpButton()
- {
- if (upButton == null)
- {
- var upPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP0, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
- upButton = new PushButton(upPort);
+ return new ModbusRtuClient(port, serialEnable);
}
- return upButton;
- }
- public PushButton GetDownButton()
- {
- if (downButton == null)
- {
- var downPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP3, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
- downButton = new PushButton(downPort);
- }
- return downButton;
+ // this is v2 instance hardware, so we should never get here
+ throw new NotSupportedException();
}
}
}
\ No newline at end of file
diff --git a/Source/ProjectLab_Demo/DisplayController.cs b/Source/ProjectLab_Demo/DisplayController.cs
index 97604f3..94813b8 100644
--- a/Source/ProjectLab_Demo/DisplayController.cs
+++ b/Source/ProjectLab_Demo/DisplayController.cs
@@ -88,11 +88,9 @@ public bool RightButtonState
bool isUpdating = false;
bool needsUpdate = false;
- bool isV1 = false;
- public DisplayController(IGraphicsDisplay display, bool isV1)
+ public DisplayController(IGraphicsDisplay display)
{
- this.isV1 = isV1;
graphics = new MicroGraphics(display)
{
Rotation = RotationType._90Degrees,
@@ -128,7 +126,7 @@ public void Update()
void DrawStatus(string label, string value, Color color, int yPosition)
{
graphics.DrawText(x: 2, y: yPosition, label, color: color);
- graphics.DrawText(x: 238, y: yPosition, value, alignment: TextAlignment.Right, color: color);
+ graphics.DrawText(x: 238, y: yPosition, value, alignmentH: HorizontalAlignment.Right, color: color);
}
void Draw()
@@ -171,19 +169,9 @@ void Draw()
}
}
- if (isV1)
- {
- DrawStatus("Left:", $"disabled", WildernessLabsColors.ChileanFire, 200);
- DrawStatus("Down:", $"disabled", WildernessLabsColors.ChileanFire, 180);
- DrawStatus("Up:", $"disabled", WildernessLabsColors.ChileanFire, 160);
- }
- else
- {
- DrawStatus("Left:", $"{(LeftButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 200);
- DrawStatus("Down:", $"{(DownButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 180);
- DrawStatus("Up:", $"{(UpButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 160);
- }
-
+ DrawStatus("Left:", $"{(LeftButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 200);
+ DrawStatus("Down:", $"{(DownButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 180);
+ DrawStatus("Up:", $"{(UpButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 160);
DrawStatus("Right:", $"{(RightButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 220);
}
}
diff --git a/Source/ProjectLab_Demo/MeadowApp.cs b/Source/ProjectLab_Demo/MeadowApp.cs
index e19e468..b0064bd 100644
--- a/Source/ProjectLab_Demo/MeadowApp.cs
+++ b/Source/ProjectLab_Demo/MeadowApp.cs
@@ -1,9 +1,11 @@
-using Meadow;
+using System;
+using System.Threading.Tasks;
+using Meadow;
using Meadow.Devices;
using Meadow.Foundation;
+using Meadow.Foundation.Leds;
+using Meadow.Peripherals.Leds;
using Meadow.Units;
-using System;
-using System.Threading.Tasks;
namespace ProjLab_Demo
{
@@ -11,129 +13,143 @@ namespace ProjLab_Demo
public class MeadowApp : App
{
DisplayController displayController;
+ RgbPwmLed onboardLed;
ProjectLab projLab;
public override Task Initialize()
{
Console.WriteLine("Initialize hardware...");
+ //==== RGB LED
+ Resolver.Log.Info("Initializing onboard RGB LED.");
+ onboardLed = new RgbPwmLed(device: Device,
+ redPwmPin: Device.Pins.OnboardLedRed,
+ greenPwmPin: Device.Pins.OnboardLedGreen,
+ bluePwmPin: Device.Pins.OnboardLedBlue,
+ CommonType.CommonAnode);
+ Resolver.Log.Info("RGB LED up.");
+
+ //==== instantiate the project lab hardware
projLab = new ProjectLab();
- Resolver.Log.Info($"Running on ProjectLab Hardware {projLab.HardwareRevision}");
+ Resolver.Log.Info($"Running on ProjectLab Hardware {projLab.RevisionString}");
+ //---- display controller (handles display updates)
if (projLab.Display is { } display)
{
- displayController = new DisplayController(display, projLab.IsV1Hardware());
+ Resolver.Log.Info("Creating DisplayController.");
+ displayController = new DisplayController(display);
+ Resolver.Log.Info("DisplayController up.");
}
//---- BH1750 Light Sensor
if (projLab.LightSensor is { } bh1750)
{
- Resolver.Log.Info($"Light sensor created");
bh1750.Updated += Bh1750Updated;
- bh1750.StartUpdating(TimeSpan.FromSeconds(5));
}
//---- BME688 Atmospheric sensor
if (projLab.EnvironmentalSensor is { } bme688)
{
- Resolver.Log.Info($"Environmental sensor created");
bme688.Updated += Bme688Updated;
- bme688.StartUpdating(TimeSpan.FromSeconds(5));
}
//---- BMI270 Accel/IMU
if (projLab.MotionSensor is { } bmi270)
{
- Resolver.Log.Info($"IMU created");
bmi270.Updated += Bmi270Updated;
- bmi270.StartUpdating(TimeSpan.FromSeconds(5));
}
//---- buttons
if (projLab.RightButton is { } rightButton)
{
- Resolver.Log.Info($"Right button created");
rightButton.PressStarted += (s, e) => displayController.RightButtonState = true;
rightButton.PressEnded += (s, e) => displayController.RightButtonState = false;
}
- if (projLab.IsV2Hardware())
+ if (projLab.DownButton is { } downButton)
+ {
+ downButton.PressStarted += (s, e) => displayController.DownButtonState = true;
+ downButton.PressEnded += (s, e) => displayController.DownButtonState = false;
+ }
+ if (projLab.LeftButton is { } leftButton)
{
- if (projLab.DownButton is { } downButton)
- {
- Resolver.Log.Info($"Down button created");
- downButton.PressStarted += (s, e) => displayController.DownButtonState = true;
- downButton.PressEnded += (s, e) => displayController.DownButtonState = false;
- }
- if (projLab.LeftButton is { } leftButton)
- {
- Resolver.Log.Info($"Left button created");
- leftButton.PressStarted += (s, e) => displayController.LeftButtonState = true;
- leftButton.PressEnded += (s, e) => displayController.LeftButtonState = false;
- }
- if (projLab.UpButton is { } upButton)
- {
- Resolver.Log.Info($"Up button created");
- upButton.PressStarted += (s, e) => displayController.UpButtonState = true;
- upButton.PressEnded += (s, e) => displayController.UpButtonState = false;
- }
+ leftButton.PressStarted += (s, e) => displayController.LeftButtonState = true;
+ leftButton.PressEnded += (s, e) => displayController.LeftButtonState = false;
}
- else
+ if (projLab.UpButton is { } upButton)
{
- Resolver.Log.Info($"Project Lab V1 hardware does not support the Up button");
- Resolver.Log.Info($"Project Lab V1 hardware does not support the Down button");
- Resolver.Log.Info($"Project Lab V1 hardware does not support the Left button");
+ upButton.PressStarted += (s, e) => displayController.UpButtonState = true;
+ upButton.PressEnded += (s, e) => displayController.UpButtonState = false;
}
//---- heartbeat
- projLab.Led.StartPulse(WildernessLabsColors.PearGreen);
+ onboardLed.StartPulse(WildernessLabsColors.PearGreen);
Console.WriteLine("Initialization complete");
return base.Initialize();
}
- private void Bmi270Updated(object sender, IChangeResult<(Acceleration3D? Acceleration3D, AngularVelocity3D? AngularVelocity3D, Temperature? Temperature)> e)
+ public override Task Run()
{
- Console.WriteLine($"BMI270: {e.New.Acceleration3D.Value.X.Gravity:0.0},{e.New.Acceleration3D.Value.Y.Gravity:0.0},{e.New.Acceleration3D.Value.Z.Gravity:0.0}g");
+ Console.WriteLine("Run...");
+
+ //---- BH1750 Light Sensor
+ if (projLab.LightSensor is { } bh1750)
+ {
+ bh1750.StartUpdating(TimeSpan.FromSeconds(5));
+ }
+
+ //---- BME688 Atmospheric sensor
+ if (projLab.EnvironmentalSensor is { } bme688)
+ {
+ bme688.StartUpdating(TimeSpan.FromSeconds(5));
+ }
+
+ //---- BMI270 Accel/IMU
+ if (projLab.MotionSensor is { } bmi270)
+ {
+ bmi270.StartUpdating(TimeSpan.FromSeconds(5));
+ }
+
if (displayController != null)
{
- displayController.AccelerationConditions = e.New;
+ displayController.Update();
}
+
+ Console.WriteLine("starting blink");
+ onboardLed.StartBlink(WildernessLabsColors.PearGreen, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(2000), 0.5f);
+
+ return base.Run();
}
- private void Bme688Updated(object sender, IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure, Resistance? GasResistance)> e)
+
+ private void Bmi270Updated(object sender, IChangeResult<(Acceleration3D? Acceleration3D, AngularVelocity3D? AngularVelocity3D, Temperature? Temperature)> e)
{
- Console.WriteLine($"BME688: {(int)e.New.Temperature?.Celsius}°C - {(int)e.New.Humidity?.Percent}% - {(int)e.New.Pressure?.Millibar}mbar");
+ Resolver.Log.Info($"BMI270: {e.New.Acceleration3D.Value.X.Gravity:0.0},{e.New.Acceleration3D.Value.Y.Gravity:0.0},{e.New.Acceleration3D.Value.Z.Gravity:0.0}g");
if (displayController != null)
{
- displayController.AtmosphericConditions = e.New;
+ displayController.AccelerationConditions = e.New;
}
}
- private void Bh1750Updated(object sender, IChangeResult e)
+ private void Bme688Updated(object sender, IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure, Resistance? GasResistance)> e)
{
- Console.WriteLine($"BH1750: {e.New.Lux}");
+ Resolver.Log.Info($"BME688: {(int)e.New.Temperature?.Celsius}°C - {(int)e.New.Humidity?.Percent}% - {(int)e.New.Pressure?.Millibar}mbar");
if (displayController != null)
{
- displayController.LightConditions = e.New;
+ displayController.AtmosphericConditions = e.New;
}
}
- public override Task Run()
+ private void Bh1750Updated(object sender, IChangeResult e)
{
- Console.WriteLine("Run...");
-
+ Resolver.Log.Info($"BH1750: {e.New.Lux}");
if (displayController != null)
{
- displayController.Update();
+ displayController.LightConditions = e.New;
}
-
- Console.WriteLine("starting blink");
- projLab.Led.StartBlink(WildernessLabsColors.PearGreen, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(2000), 0.5f);
-
- return base.Run();
}
}
}
\ No newline at end of file
diff --git a/Source/ProjectLab_Demo/ProjectLab_Demo.csproj b/Source/ProjectLab_Demo/ProjectLab_Demo.csproj
index 21d9691..4daa851 100644
--- a/Source/ProjectLab_Demo/ProjectLab_Demo.csproj
+++ b/Source/ProjectLab_Demo/ProjectLab_Demo.csproj
@@ -4,39 +4,10 @@
true
Library
App
- Debug_v1_ProjLab;Release_v1_ProjLab;Debug_v2_ProjLab;Release_v2_ProjLab
-
- obj\Debug\netstandard2.1\netstandard2.1\netstandard2.1
- true
- false
- TRACE;DEBUG;V1_PROJLAB;DEBUG_V1_PROJLAB;NETSTANDARD;NETSTANDARD2_1;
- 8.0
-
-
- obj\Release\netstandard2.1\netstandard2.1\netstandard2.1
- true
- true
- TRACE;RELEASE;V1_PROJLAB;RELEASE_V1_PROJLAB;NETSTANDARD;NETSTANDARD2_1;
- 8.0
-
-
- obj\Debug\netstandard2.1\netstandard2.1\netstandard2.1\netstandard2.1
- true
- false
- TRACE;DEBUG;V2_PROJLAB;DEBUG_V2_PROJLAB;NETSTANDARD;NETSTANDARD2_1;
- 8.0
-
-
- obj\Release\netstandard2.1\netstandard2.1\netstandard2.1\netstandard2.1
- true
- true
- TRACE;RELEASE;V2_PROJLAB;RELEASE_V2_PROJLAB;NETSTANDARD;NETSTANDARD2_1;
+
8.0
-
-
-
PreserveNewest
@@ -48,4 +19,4 @@
-
\ No newline at end of file
+
diff --git a/Source/ProjectLab_Demo/app.config.yaml b/Source/ProjectLab_Demo/app.config.yaml
index b802625..cfffecf 100644
--- a/Source/ProjectLab_Demo/app.config.yaml
+++ b/Source/ProjectLab_Demo/app.config.yaml
@@ -1,6 +1,6 @@
Logging:
LogLevel:
- Default: Trace
+ Default: Information
Lifecycle:
RestartOnAppFailure: false
Update: