Skip to content

Commit

Permalink
Merge pull request #902 from WildernessLabs/feature/pcan
Browse files Browse the repository at this point in the history
Feature/pcan
  • Loading branch information
adrianstevens authored Jul 29, 2024
2 parents 81b41a9 + 3007854 commit 4a89327
Show file tree
Hide file tree
Showing 40 changed files with 2,160 additions and 177 deletions.
10 changes: 10 additions & 0 deletions Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,14 @@ private void DigitalInChanged(object sender, DigitalPortResult result)
{
UpdateEvents(GetNormalizedState(result.New.State));
}

/// <inheritdoc/>
protected override bool GetNormalizedState(bool state)
{
return DigitalIn.Resistor switch
{
ResistorMode.ExternalPullUp or ResistorMode.InternalPullUp => !state,
_ => state,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ protected PushButtonBase(IDigitalInputPort inputPort)
/// Returns the sanitized state of the button
/// Inverts the state when using a pull-up resistor
/// </summary>
protected bool GetNormalizedState(bool state)
protected virtual bool GetNormalizedState(bool state)
{
return DigitalIn.Resistor switch
{
Expand Down
317 changes: 158 additions & 159 deletions Source/Meadow.Foundation.Core/Sensors/Hid/DigitalJoystick.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,187 +3,186 @@
using Meadow.Peripherals.Sensors.Hid;
using System;

namespace Meadow.Foundation.Sensors.Hid
namespace Meadow.Foundation.Sensors.Hid;

/// <summary>
/// Represents a 4 switch digital joystick / directional pad (D-pad)
/// </summary>
public class DigitalJoystick : IDigitalJoystick, IDisposable
{
/// <summary>
/// Represents a 4 switch digital joystick / directional pad (D-pad)
/// Get the current digital joystick position
/// </summary>
public DigitalJoystickPosition? Position { get; protected set; } = DigitalJoystickPosition.Center;

/// <summary>
/// Raised when the digital joystick position changes
/// </summary>
public class DigitalJoystick : IDigitalJoystick, IDisposable
public event EventHandler<ChangeResult<DigitalJoystickPosition>> Updated = default!;

/// <summary>
/// The PushButton class for the up digital joystick switch
/// </summary>
public PushButton ButtonUp { get; protected set; }
/// <summary>
/// The PushButton class for the down digital joystick switch
/// </summary>
public PushButton ButtonDown { get; protected set; }
/// <summary>
/// The PushButton class for the left digital joystick switch
/// </summary>
public PushButton ButtonLeft { get; protected set; }
/// <summary>
/// The PushButton class for the right digital joystick switch
/// </summary>
public PushButton ButtonRight { get; protected set; }

/// <summary>
/// Is the object disposed
/// </summary>
public bool IsDisposed { get; private set; }

/// <summary>
/// Did we create the port(s) used by the peripheral
/// </summary>
private readonly bool createdPorts = false;
private readonly IDigitalInterruptPort portUp;
private readonly IDigitalInterruptPort portDown;
private readonly IDigitalInterruptPort portLeft;
private readonly IDigitalInterruptPort portRight;

/// <summary>
/// Create a new DigitalJoystick object
/// </summary>
/// <param name="pinUp">The pin connected to the up switch</param>
/// <param name="pinDown">The pin connected to the down switch</param>
/// <param name="pinLeft">The pin connected to the left switch</param>
/// <param name="pinRight">The pin connected to the right switch</param>
/// <param name="resistorMode">The resistor mode for all pins</param>
public DigitalJoystick(IPin pinUp, IPin pinDown, IPin pinLeft, IPin pinRight, ResistorMode resistorMode)
: this(pinUp.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinDown.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinLeft.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinRight.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode))
{
/// <summary>
/// Get the current digital joystick position
/// </summary>
public DigitalJoystickPosition? Position { get; protected set; } = DigitalJoystickPosition.Center;

/// <summary>
/// Raised when the digital joystick position changes
/// </summary>
public event EventHandler<ChangeResult<DigitalJoystickPosition>> Updated = default!;

/// <summary>
/// The PushButton class for the up digital joystick switch
/// </summary>
public PushButton ButtonUp { get; protected set; }
/// <summary>
/// The PushButton class for the down digital joystick switch
/// </summary>
public PushButton ButtonDown { get; protected set; }
/// <summary>
/// The PushButton class for the left digital joystick switch
/// </summary>
public PushButton ButtonLeft { get; protected set; }
/// <summary>
/// The PushButton class for the right digital joystick switch
/// </summary>
public PushButton ButtonRight { get; protected set; }

/// <summary>
/// Is the object disposed
/// </summary>
public bool IsDisposed { get; private set; }

/// <summary>
/// Did we create the port(s) used by the peripheral
/// </summary>
readonly bool createdPorts = false;

readonly IDigitalInterruptPort portUp;
readonly IDigitalInterruptPort portDown;
readonly IDigitalInterruptPort portLeft;
readonly IDigitalInterruptPort portRight;

/// <summary>
/// Create a new DigitalJoystick object
/// </summary>
/// <param name="pinUp">The pin connected to the up switch</param>
/// <param name="pinDown">The pin connected to the down switch</param>
/// <param name="pinLeft">The pin connected to the left switch</param>
/// <param name="pinRight">The pin connected to the right switch</param>
/// <param name="resistorMode">The resistor mode for all pins</param>
public DigitalJoystick(IPin pinUp, IPin pinDown, IPin pinLeft, IPin pinRight, ResistorMode resistorMode)
: this(pinUp.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinDown.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinLeft.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode),
pinRight.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, resistorMode))
{
createdPorts = true;
}
createdPorts = true;
}

/// <summary>
/// Create a new DigitalJoystick object
/// </summary>
/// <param name="portUp">The digital port for the up switch</param>
/// <param name="portDown">The digital port for the down switch</param>
/// <param name="portLeft">The digital port for the left switch</param>
/// <param name="portRight">The digital port for the right switch</param>
public DigitalJoystick(IDigitalInterruptPort portUp,
IDigitalInterruptPort portDown,
IDigitalInterruptPort portLeft,
IDigitalInterruptPort portRight)
{
ButtonUp = new PushButton(this.portUp = portUp);
ButtonDown = new PushButton(this.portDown = portDown);
ButtonLeft = new PushButton(this.portLeft = portLeft);
ButtonRight = new PushButton(this.portRight = 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;
}
/// <summary>
/// Create a new DigitalJoystick object
/// </summary>
/// <param name="portUp">The digital port for the up switch</param>
/// <param name="portDown">The digital port for the down switch</param>
/// <param name="portLeft">The digital port for the left switch</param>
/// <param name="portRight">The digital port for the right switch</param>
public DigitalJoystick(IDigitalInterruptPort portUp,
IDigitalInterruptPort portDown,
IDigitalInterruptPort portLeft,
IDigitalInterruptPort portRight)
{
Resolver.Log.Info($"DJ Up resistor: {portUp.Resistor}");
ButtonUp = new PushButton(this.portUp = portUp);
ButtonDown = new PushButton(this.portDown = portDown);
ButtonLeft = new PushButton(this.portLeft = portLeft);
ButtonRight = new PushButton(this.portRight = portRight);

ButtonUp.PressStarted += PressStarted;
ButtonDown.PressStarted += PressStarted;
ButtonLeft.PressStarted += PressStarted;
ButtonRight.PressStarted += PressStarted;

ButtonUp.PressEnded += PressEnded;
ButtonDown.PressEnded += PressEnded;
ButtonLeft.PressEnded += PressEnded;
ButtonRight.PressEnded += PressEnded;
}

private void PressEnded(object sender, EventArgs e)
=> Update();
private void PressEnded(object sender, EventArgs e)
=> Update();

private void PressStarted(object sender, EventArgs e)
=> Update();
private void PressStarted(object sender, EventArgs e)
=> Update();

private void Update()
{
var isLeftPressed = ButtonLeft.State;
var isRightPressed = ButtonRight.State;
var isUpPressed = ButtonUp.State;
var isDownPressed = ButtonDown.State;
private 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);
var newPosition = GetDigitalPosition(isLeftPressed, isRightPressed, isUpPressed, isDownPressed);

if (newPosition != Position)
{
Updated?.Invoke(this, new ChangeResult<DigitalJoystickPosition>(newPosition, Position));
Position = newPosition;
}
if (newPosition != Position)
{
Updated?.Invoke(this, new ChangeResult<DigitalJoystickPosition>(newPosition, Position));
Position = newPosition;
}
}

private 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;
private DigitalJoystickPosition GetDigitalPosition(bool isLeftPressed, bool isRightPressed, bool isUpPressed, bool isDownPressed)
{
if (isRightPressed)
{ //Right
if (isUpPressed)
{
return DigitalJoystickPosition.UpRight;
}
else if (isUpPressed)
{ //Up
return DigitalJoystickPosition.Up;
if (isDownPressed)
{
return DigitalJoystickPosition.DownRight;
}
else if (isDownPressed)
{ //Down
return DigitalJoystickPosition.Down;
return DigitalJoystickPosition.Right;
}
else if (isLeftPressed)
{ //Left
if (isUpPressed)
{
return DigitalJoystickPosition.UpLeft;
}
else
{ //Center
return DigitalJoystickPosition.Center;
if (isDownPressed)
{
return DigitalJoystickPosition.DownLeft;
}
return DigitalJoystickPosition.Left;
}

///<inheritdoc/>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
else if (isUpPressed)
{ //Up
return DigitalJoystickPosition.Up;
}
else if (isDownPressed)
{ //Down
return DigitalJoystickPosition.Down;
}
else
{ //Center
return DigitalJoystickPosition.Center;
}
}

/// <summary>
/// Dispose of the object
/// </summary>
/// <param name="disposing">Is disposing</param>
protected virtual void Dispose(bool disposing)
///<inheritdoc/>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Dispose of the object
/// </summary>
/// <param name="disposing">Is disposing</param>
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (!IsDisposed)
if (disposing && createdPorts)
{
if (disposing && createdPorts)
{
portDown?.Dispose();
portLeft?.Dispose();
portRight?.Dispose();
portUp?.Dispose();
}

IsDisposed = true;
portDown?.Dispose();
portLeft?.Dispose();
portRight?.Dispose();
portUp?.Dispose();
}

IsDisposed = true;
}
}
}
Loading

0 comments on commit 4a89327

Please sign in to comment.