diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 0715d1b..81cb63a 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -45,7 +45,7 @@ jobs:
with:
repository: WildernessLabs/Meadow.Core
path: Meadow.Core
- ref: ${{ env.GITHUB_REF_NAME }} # match Core branch to this branch
+ ref: develop
token: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Checkout Meadow.Foundation
uses: actions/checkout@v3
diff --git a/Source/Meadow.ProjectLab/IProjectLabHardware.cs b/Source/Meadow.ProjectLab/IProjectLabHardware.cs
index 9120bdc..1a1084c 100644
--- a/Source/Meadow.ProjectLab/IProjectLabHardware.cs
+++ b/Source/Meadow.ProjectLab/IProjectLabHardware.cs
@@ -27,5 +27,31 @@ public interface IProjectLabHardware
public PushButton? DownButton { get; }
public string RevisionString { get; }
+
+ public (IPin AN,
+ IPin RST,
+ IPin CS,
+ IPin SCK,
+ IPin CIPO,
+ IPin COPI,
+ IPin PWM,
+ IPin INT,
+ IPin RX,
+ IPin TX,
+ IPin SCL,
+ IPin SCA) MikroBus1Pins { get; }
+
+ public (IPin AN,
+ IPin RST,
+ IPin CS,
+ IPin SCK,
+ IPin CIPO,
+ IPin COPI,
+ IPin PWM,
+ IPin INT,
+ IPin RX,
+ IPin TX,
+ IPin SCL,
+ IPin SCA) MikroBus2Pins { get; }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/ProjectLab.cs b/Source/Meadow.ProjectLab/ProjectLab.cs
index 086b7e3..3e2dd6f 100644
--- a/Source/Meadow.ProjectLab/ProjectLab.cs
+++ b/Source/Meadow.ProjectLab/ProjectLab.cs
@@ -23,7 +23,7 @@ public static IProjectLabHardware Create()
ISpiBus spiBus;
// v2+ stuff
- Mcp23008? mcp_1 = null;
+ Mcp23008? mcp1 = null;
logger?.Debug("Initializing Project Lab...");
@@ -59,23 +59,27 @@ public static IProjectLabHardware Create()
logger?.Debug("I2C Bus instantiated");
+ IDigitalInputPort? mcp1Interrupt = null;
+ IDigitalOutputPort? mcp1Reset = null;
+
try
{
// MCP the First
- IDigitalInputPort mcp1_int = device.CreateDigitalInputPort(
- device.Pins.D09, InterruptMode.EdgeRising, ResistorMode.InternalPullDown);
- IDigitalOutputPort mcp_Reset = device.CreateDigitalOutputPort(device.Pins.D14);
+ mcp1Interrupt = device.CreateDigitalInputPort(device.Pins.D09, InterruptMode.EdgeRising, ResistorMode.InternalPullDown);
+ mcp1Reset = device.CreateDigitalOutputPort(device.Pins.D14);
- mcp_1 = new Mcp23008(i2cBus, address: 0x20, mcp1_int, mcp_Reset);
+ mcp1 = new Mcp23008(i2cBus, address: 0x20, mcp1Interrupt, mcp1Reset);
logger?.Trace("Mcp_1 up");
}
catch (Exception e)
{
logger?.Debug($"Failed to create MCP1: {e.Message}, could be a v1 board");
+ mcp1Interrupt?.Dispose();
+ mcp1Reset?.Dispose();
}
- if (mcp_1 == null)
+ if (mcp1 == null)
{
logger?.Debug("Instantiating Project Lab v1 specific hardware");
hardware = new ProjectLabHardwareV1(device, spiBus, i2cBus);
@@ -83,7 +87,7 @@ public static IProjectLabHardware Create()
else
{
logger?.Info("Instantiating Project Lab v2 specific hardware");
- hardware = new ProjectLabHardwareV2(device, spiBus, i2cBus, mcp_1);
+ hardware = new ProjectLabHardwareV2(device, spiBus, i2cBus, mcp1);
}
return hardware;
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs
index b043c3c..16d77e6 100644
--- a/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareBase.cs
@@ -16,46 +16,56 @@ namespace Meadow.Devices
///
public abstract class ProjectLabHardwareBase : IProjectLabHardware
{
+ ///
+ /// Get a reference to Meadow Logger
+ ///
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
///
@@ -64,17 +74,27 @@ public abstract class ProjectLabHardwareBase : IProjectLabHardware
/// 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)
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 1
+ ///
+ public abstract (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus1Pins { get; protected set; }
+
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 1
+ ///
+ public abstract (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus2Pins { get; protected set; }
+
+ internal ProjectLabHardwareBase(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2cBus i2cBus)
{
SpiBus = spiBus;
I2cBus = i2cBus;
- //==== Initialize the shared/common stuff
try
{
Logger?.Trace("Instantiating light sensor");
@@ -104,7 +124,7 @@ public ProjectLabHardwareBase(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2
try
{
Logger?.Trace("Instantiating speaker");
- Speaker = new PiezoSpeaker(device, device.Pins.D11);
+ Speaker = new PiezoSpeaker(device.Pins.D11);
Logger?.Trace("Speaker up");
}
catch (Exception ex)
@@ -122,7 +142,6 @@ public ProjectLabHardwareBase(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2
{
Resolver.Log.Error($"Unable to create the BMI270 IMU: {ex.Message}");
}
-
}
///
@@ -139,53 +158,21 @@ public ProjectLabHardwareBase(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2
/// 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 A1,
+ IPin A2,
IPin D03,
- IPin D04
+ IPin D04,
+ IPin D12,
+ IPin D13
) 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("A02"),
Resolver.Device.GetPin("D03"),
- Resolver.Device.GetPin("D04")
+ Resolver.Device.GetPin("D04"),
+ Resolver.Device.GetPin("D12"),
+ Resolver.Device.GetPin("D13")
);
}
}
\ No newline at end of file
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
index b684189..9e35023 100644
--- a/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareV1.cs
@@ -7,7 +7,7 @@
namespace Meadow.Devices
{
- internal class ProjectLabHardwareV1 : ProjectLabHardwareBase
+ public class ProjectLabHardwareV1 : ProjectLabHardwareBase
{
private string revision = "v1.x";
@@ -15,30 +15,43 @@ internal class ProjectLabHardwareV1 : ProjectLabHardwareBase
/// 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)
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 1
+ ///
+ public override (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus1Pins { get; protected set; }
+
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 2
+ ///
+ public override (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus2Pins { get; protected set; }
+
+ internal ProjectLabHardwareV1(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2cBus i2cBus)
: base(device, spiBus, i2cBus)
{
//---- create our display
Logger?.Trace("Instantiating display");
Display = new St7789(
- device: device,
spiBus: SpiBus,
chipSelectPin: device.Pins.A03,
dcPin: device.Pins.A04,
@@ -57,25 +70,57 @@ public ProjectLabHardwareV1(IF7FeatherMeadowDevice device, ISpiBus spiBus, II2cB
UpButton = GetPushButton(device, device.Pins.D15);
DownButton = GetPushButton(device, device.Pins.D02);
Logger?.Trace("Buttons up");
+
+ SetMikroBusPins();
+ }
+
+ void SetMikroBusPins()
+ {
+ MikroBus1Pins =
+ (Resolver.Device.GetPin("A00"),
+ null,
+ Resolver.Device.GetPin("D14"),
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("D04"),
+ Resolver.Device.GetPin("D03"),
+ Resolver.Device.GetPin("D12"),
+ Resolver.Device.GetPin("D13"),
+ Resolver.Device.GetPin("D07"),
+ Resolver.Device.GetPin("D08"));
+
+ MikroBus2Pins =
+ (Resolver.Device.GetPin("A01"),
+ null,
+ Resolver.Device.GetPin("A02"),
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("D03"),
+ Resolver.Device.GetPin("D04"),
+ Resolver.Device.GetPin("D12"),
+ Resolver.Device.GetPin("D13"),
+ Resolver.Device.GetPin("D07"),
+ Resolver.Device.GetPin("D08"));
}
public override string RevisionString => revision;
private PushButton GetPushButton(IF7FeatherMeadowDevice device, IPin pin)
- => new PushButton(Resolver.Device, pin, ResistorMode.InternalPullDown);
+ => new PushButton(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)
+ if (Resolver.Device is F7FeatherBase device)
{
var portName = device.PlatformOS.GetSerialPortName("com4");
var port = device.CreateSerialPort(portName, baudRate, dataBits, parity, stopBits);
port.WriteTimeout = port.ReadTimeout = TimeSpan.FromSeconds(5);
var serialEnable = device.CreateDigitalOutputPort(device.Pins.D09, false);
- return new ModbusRtuClient(port, serialEnable);
+ return new ProjectLabModbusRtuClient(port, serialEnable);
}
- // this is v1 instance hardware, so we should never get here
throw new NotSupportedException();
}
}
diff --git a/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs b/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
index 1b5e144..529d07d 100644
--- a/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
+++ b/Source/Meadow.ProjectLab/ProjectLabHardwareV2.cs
@@ -9,34 +9,59 @@
namespace Meadow.Devices
{
- internal class ProjectLabHardwareV2 : ProjectLabHardwareBase
+ public class ProjectLabHardwareV2 : ProjectLabHardwareBase
{
+ ///
+ /// The MCP23008 IO expander connected to internal peripherals
+ ///
public Mcp23008 Mcp_1 { get; protected set; }
- public Mcp23008 Mcp_2 { get; protected set; }
- public Mcp23008? Mcp_Version { get; protected set; }
+
+ ///
+ /// The MCP23008 IO expander connected to IO headers and terminals on Project Lab
+ ///
+ public Mcp23008? Mcp_2 { get; protected set; }
+
+ ///
+ /// The MCP23008 IO expander that contains the ProjectLab hardware version
+ ///
+ Mcp23008? Mcp_Version { get; set; }
///
/// 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(
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 1
+ ///
+ public override (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus1Pins { get; protected set; }
+
+ ///
+ /// Get the ProjectLab pins for mikroBUS header 2
+ ///
+ public override (IPin AN, IPin RST, IPin CS, IPin SCK, IPin CIPO, IPin COPI, IPin PWM, IPin INT, IPin RX, IPin TX, IPin SCL, IPin SCA) MikroBus2Pins { get; protected set; }
+
+ internal ProjectLabHardwareV2(
IF7FeatherMeadowDevice device,
ISpiBus spiBus,
II2cBus i2cBus,
@@ -105,13 +130,45 @@ Mcp23008 mcp1
var downPort = mcp1.CreateDigitalInputPort(mcp1.Pins.GP3, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
DownButton = new PushButton(downPort);
Logger?.Trace("Buttons up");
+
+ SetMikroBusPins();
+ }
+
+ void SetMikroBusPins()
+ {
+ MikroBus1Pins =
+ (Resolver.Device.GetPin("A02"),
+ Mcp_2.Pins.GP4,
+ Mcp_2.Pins.GP5,
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("D03"),
+ Mcp_2.Pins.GP6,
+ Resolver.Device.GetPin("D13"),
+ Resolver.Device.GetPin("D12"),
+ Resolver.Device.GetPin("D07"),
+ Resolver.Device.GetPin("D08"));
+
+ MikroBus2Pins =
+ (Resolver.Device.GetPin("A03"),
+ Mcp_2.Pins.GP1,
+ Mcp_2.Pins.GP2,
+ Resolver.Device.GetPin("SCK"),
+ Resolver.Device.GetPin("CIPO"),
+ Resolver.Device.GetPin("COPI"),
+ Resolver.Device.GetPin("D04"),
+ Mcp_2.Pins.GP3,
+ Resolver.Device.GetPin("D13"),
+ Resolver.Device.GetPin("D12"),
+ Resolver.Device.GetPin("D07"),
+ Resolver.Device.GetPin("D08"));
}
public override string RevisionString
{
get
{
- // TODO: figure this out from MCP3?
if (revision == null)
{
if (Mcp_Version == null)
@@ -121,28 +178,26 @@ public override string RevisionString
else
{
byte rev = Mcp_Version.ReadFromPorts(Mcp23xxx.PortBank.A);
- //mapping? 0 == d2.d?
revision = $"v2.{rev}";
}
}
return revision;
}
}
- protected string? revision;
+ string? revision;
public override ModbusRtuClient GetModbusRtuClient(int baudRate = 19200, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One)
{
- if (Resolver.Device is F7FeatherV2 device)
+ if (Resolver.Device is F7FeatherBase device)
{
var portName = device.PlatformOS.GetSerialPortName("com4");
var port = device.CreateSerialPort(portName, baudRate, dataBits, parity, stopBits);
port.WriteTimeout = port.ReadTimeout = TimeSpan.FromSeconds(5);
var serialEnable = Mcp_2.CreateDigitalOutputPort(Mcp_2.Pins.GP0, false);
- return new ModbusRtuClient(port, serialEnable);
+ return new ProjectLabModbusRtuClient(port, serialEnable);
}
- // this is v2 instance hardware, so we should never get here
throw new NotSupportedException();
}
}
diff --git a/Source/Meadow.ProjectLab/ProjectLabModbusRtuClient.cs b/Source/Meadow.ProjectLab/ProjectLabModbusRtuClient.cs
new file mode 100644
index 0000000..e842a66
--- /dev/null
+++ b/Source/Meadow.ProjectLab/ProjectLabModbusRtuClient.cs
@@ -0,0 +1,24 @@
+using Meadow.Hardware;
+using Meadow.Modbus;
+using System.Threading;
+
+namespace Meadow.Devices
+{
+ public class ProjectLabModbusRtuClient : ModbusRtuClient
+ {
+ public ProjectLabModbusRtuClient(ISerialPort port, IDigitalOutputPort enablePort)
+ : base(port, enablePort)
+ {
+ // this forces meadow to compile the serial pipeline. Without it, there's a big delay on sending the first byte
+ PostOpenAction = () => { port.Write(new byte[] { 0x00 }); };
+
+ // meadow is not-so-fast, and data will not all get transmitted before the call to the port Write() returns
+ PostWriteDelayAction = (m) =>
+ {
+ var delay = (int)((1d / port.BaudRate) * port.DataBits * 1000d * m.Length) + 3; // +3 to add just a little extra for clients who are a little slow to turn off the enable pin
+ Thread.Sleep(delay);
+ };
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Source/ProjectLab_Demo/MeadowApp.cs b/Source/ProjectLab_Demo/MeadowApp.cs
index f768a1b..469613f 100644
--- a/Source/ProjectLab_Demo/MeadowApp.cs
+++ b/Source/ProjectLab_Demo/MeadowApp.cs
@@ -1,11 +1,11 @@
-using System;
-using System.Threading.Tasks;
-using Meadow;
+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
{
@@ -24,7 +24,7 @@ public override Task Initialize()
//==== RGB LED
Resolver.Log.Info("Initializing onboard RGB LED");
- onboardLed = new RgbPwmLed(device: Device,
+ onboardLed = new RgbPwmLed(
redPwmPin: Device.Pins.OnboardLedRed,
greenPwmPin: Device.Pins.OnboardLedGreen,
bluePwmPin: Device.Pins.OnboardLedBlue,