Skip to content
This repository was archived by the owner on Jun 14, 2024. It is now read-only.

Updates for v2 of the module #51

Merged
merged 3 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ Please see our [docs folder here](/docs) for an API reference, pin layout and ot

### Dependencies

This project relies on [RaspberryIO](https://github.com/unosquare/raspberryio).
It's an easy-to-use .NET library for interacting with Raspberry Pi's IO functionality.
RaspberryIO is built on [Wiring Pi](http://wiringpi.com/) -
a pin based GPIO access library written in C.
This project relies on [.NET Core IoT Libraries](https://github.com/dotnet/iot).
It is a .NET library for interacting with Raspberry Pi's IO functionality.

## Installation

Expand All @@ -60,7 +58,6 @@ a pin based GPIO access library written in C.
You can grab the latest version of PowerShell IoT by running:

```powershell
sudo WIRINGPI_CODES=1 pwsh
Install-Module Microsoft.PowerShell.IoT
```

Expand Down Expand Up @@ -130,17 +127,12 @@ _NOTE: If you'd rather not use the script, simply copy the `out/Microsoft.PowerS

#### Running

First, you must run pwsh with sudo:
Start PowerShell:

```powershell
sudo WIRINGPI_CODES=1 pwsh
pwsh
```

##### About `WIRINGPI_CODES` environment variable

`Microsoft.PowerShell.IoT` module internally uses [WiringPi library](http://wiringpi.com/reference/setup) which has a default behavior of terminating current process (in this case - PowerShell) even on non-critical errors in setup functions.
To avoid such crashes define `WIRINGPI_CODES` environment variable either when starting PowerShell (see example above) or through configuration scripts - example for an interactive login shell - `echo "export WIRINGPI_CODES=1"|sudo tee -a /etc/profile.d/WiringPiCodes.sh`

If you have the `Microsoft.PowerShell.IoT` module in your PSModulePath:

```powershell
Expand Down
101 changes: 0 additions & 101 deletions ThirdPartyNotices.txt

This file was deleted.

6 changes: 3 additions & 3 deletions docs/rpi3_pin_layout.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Pin layout

PowerShell IoT uses Wiring Pi under the hood.
As such, it follow the Wiring Pi scheme for pin identification.
For all of the `Pin` parameters in this module, use the WiringPi/wPi number listed in the following diagram:
PowerShell IoT uses logical representation of the microcontroller's GPIOs.
Refer to the microcontroller's datasheet to find this information.
In case of Raspberry Pi use the BCM number listed in the following diagram:

## Image reference

Expand Down
125 changes: 58 additions & 67 deletions src/Microsoft.PowerShell.IoT/Gpio/Get/GetGpioPin.cs
Original file line number Diff line number Diff line change
@@ -1,81 +1,72 @@
using System;
using System.Collections;
using System.Management.Automation; // PowerShell namespace.
using System.Management.Automation;
using System.Device.Gpio;

[Cmdlet(VerbsCommon.Get, "GpioPin")]
public class GetGpioPin : Cmdlet
[Cmdlet(VerbsCommon.Get, "GpioPin")]
public class GetGpioPin : GpioCmdletBase
{
[Parameter(Mandatory = false, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, Position = 0)]
public int[] Id { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, Position = 0)]
public int[] Id { get; set; }

[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, Position = 1)]
public PullMode? PullMode { get; set; }
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, Position = 1)]
public PullMode? PullMode { get; set; }

[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public SwitchParameter Raw { get; set; }
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public SwitchParameter Raw { get; set; }

protected override void ProcessRecord()
{
try
{
ArrayList pinList = new ArrayList();
protected override void ProcessRecord()
{
ArrayList pinList = new ArrayList();

if ((this.Id == null) || (this.Id.Length <= 0))
{
foreach (var pin in Unosquare.RaspberryIO.Pi.Gpio.Pins)
{
pinList.Add(pin.PinNumber);
}
}
else
{
pinList.AddRange(this.Id);
}
if ((this.Id == null) || (this.Id.Length <= 0))
{
// TODO: this is "gpio readall" functionality
// do not forget to change Id param to Mandatory = false when this is implemented
}
else
{
pinList.AddRange(this.Id);
}

PinMode mode = PinMode.Input;
if (this.PullMode.HasValue)
{
switch (this.PullMode.Value)
{
case global::PullMode.PullDown: mode = PinMode.InputPullDown; break;
case global::PullMode.PullUp: mode = PinMode.InputPullUp; break;
default: mode = PinMode.Input; break;
};
};

foreach (int pinId in pinList)
{
var pin = Unosquare.RaspberryIO.Pi.Gpio[pinId];
try
{
pin.PinMode = Unosquare.RaspberryIO.Gpio.GpioPinDriveMode.Input;
if (this.PullMode.HasValue)
{
pin.InputPullMode = (Unosquare.RaspberryIO.Gpio.GpioPinResistorPullMode)this.PullMode.Value;
};
}
catch (System.NotSupportedException)
{
// We want to avoid errors like
// System.NotSupportedException : Get - GpioPin : Pin Pin15 'BCM 14 (UART Transmit)' does not support mode 'Input'.Pin capabilities are limited to: UARTTXD
// at the same time we need to return PinInfo for such pins, so we need to continue processing
}
bool pinBoolValue = pin.Read();
foreach (int pinId in pinList)
{
SignalLevel slResult = SignalLevel.Low;

if (this.Raw)
{
WriteObject(pinBoolValue ? SignalLevel.High : SignalLevel.Low);
}
else
{
GpioPinData pinData = new GpioPinData(pinId, pinBoolValue ? SignalLevel.High : SignalLevel.Low, pin);
WriteObject(pinData);
}
}
}
catch (System.TypeInitializationException e) // Unosquare.RaspberryIO.Gpio.GpioController.Initialize throws this TypeInitializationException
{
if (!Unosquare.RaspberryIO.Computer.SystemInfo.Instance.IsRunningAsRoot)
{
throw new PlatformNotSupportedException(Resources.ErrNeedRootPrivileges, e);
}
throw;
}
}
this.EnsureOpenPin(pinId, mode);

if (this.GpioController.Read(pinId) == PinValue.High)
{
slResult = SignalLevel.High;
};

if (this.Raw)
{
WriteObject(slResult);
}
else
{
GpioPinData pinData = new GpioPinData(pinId, slResult);
WriteObject(pinData);
}
}
}
}

public enum PullMode
{
Off = 0,
PullDown = 1,
PullUp = 2
}
Off = 0,
PullDown = 1,
PullUp = 2
}
51 changes: 51 additions & 0 deletions src/Microsoft.PowerShell.IoT/Gpio/GpioCmdletBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Management.Automation;
using System.Device.Gpio;

public class GpioCmdletBase : Cmdlet
{
protected static GpioController StaticGpioController;
protected GpioController GpioController
{
get
{
if (StaticGpioController == null)
{
StaticGpioController = new GpioController();
}
return StaticGpioController;
}
set
{
StaticGpioController = value;
}
}

protected void EnsureOpenPin(int pinId, PinMode mode)
{
if (this.GpioController.IsPinOpen(pinId))
{
if (this.GpioController.GetPinMode(pinId) != mode)
{
this.GpioController.SetPinMode(pinId, mode);
}
}
else
{
this.GpioController.OpenPin(pinId, mode);
}
}
}

[Cmdlet(VerbsCommon.Clear, "GpioResources")]
public class ClearGpioResources : GpioCmdletBase
{
protected override void ProcessRecord()
{
if (GpioCmdletBase.StaticGpioController != null)
{
GpioCmdletBase.StaticGpioController.Dispose();
GpioCmdletBase.StaticGpioController = null;
}
}
}
22 changes: 10 additions & 12 deletions src/Microsoft.PowerShell.IoT/Gpio/GpioPinData.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
public class GpioPinData
{
public int Id;
public SignalLevel Value;
//public Unosquare.RaspberryIO.Gpio.GpioPin PinInfo; //not in use
public int Id;
public SignalLevel Value;

public GpioPinData(int id, SignalLevel value, Unosquare.RaspberryIO.Gpio.GpioPin pinInfo)
{
this.Id = id;
this.Value = value;
//this.PinInfo = pinInfo;
}
public GpioPinData(int id, SignalLevel value)
{
this.Id = id;
this.Value = value;
}
}

public enum SignalLevel
{
Low = 0,
High = 1
}
Low = 0,
High = 1
}
Loading