// MUNTS-0018 Raspberry Pi Tutorial I/O Board Definitions
// Copyright (C)2021-2024, Philip Munts dba Munts Technologies.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
using IO.Objects.SimpleIO.Device;
using IO.Objects.SimpleIO.GPIO;
using IO.Objects.SimpleIO.Platforms;
using System.Collections.Generic;
namespace IO.Objects.SimpleIO.Platforms
{
///
/// This class provides designators for I/O resources available on the
/// MUNTS-0018
/// Tutorial I/O Board.
///
public static class MUNTS_0018
{
///
/// This class provides designators specific to the 64-Bit
/// Raspberry Pi Zero 2 W
/// interface computer.
///
///
/// The following device tree overlay commands must be added to
/// /boot/config.txt:
///
/// dtoverlay=anyspi,spi0-1,dev="microchip,mcp3204",speed=1000000
/// dtoverlay=pwm-2chan,pin=12,func=4,pin2=19,func2=2
///
///
public static class RaspberryPi
{
// On board LED
///
/// GPIO pin Designator for the on-board LED D1.
///
public static readonly Designator D1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO26;
// On board pushbutton switch
///
/// GPIO pin Designator for the on-board momentary switch
/// SW1.
///
public static readonly Designator SW1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO6;
// Grove GPIO Connectors
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J4 pin D0.
///
public static readonly Designator J4D0 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO23;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J4 pin D1.
///
public static readonly Designator J4D1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO24;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J5 pin D0.
///
public static readonly Designator J5D0 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO5;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J5 pin D1.
///
public static readonly Designator J5D1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO4;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J6 pin D0.
///
///
/// This GPIO pin is normally unusable because GPIO12 is
/// mapped to PWM output PWM0.
///
public static readonly Designator J6D0 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO12;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J6 pin D1.
///
public static readonly Designator J6D1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO13;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J7 pin D0.
///
///
/// This GPIO pin is normally unusable because GPIO19 is
/// mapped to PWM output PWM1.
///
public static readonly Designator J7D0 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO19;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J7 pin D1.
///
public static readonly Designator J7D1 =
IO.Objects.SimpleIO.Platforms.RaspberryPi.GPIO18;
// Servo headers
///
/// Servo position PWM output Designator for Servo Header
/// J2.
///
public static readonly Designator J2PWM =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM0;
///
/// Servo position PWM output Designator for Servo Header
/// J3.
///
public static readonly Designator J3PWM =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM1;
// DC motor control outputs (PWM and direction)
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J6.
///
public static readonly Designator J6PWM =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM0;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove Connector J6.
///
public static readonly Designator J6DIR = J6D1;
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J6 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
///
/// The speed and direction pins need to be swapped for the MD13S.
/// This requires using the MUNTS-0018-MD13S device tree
/// overlay instead of MUNTS-0018 to arrange the Raspberry
/// Pi expansion bus PWM and GPIO pins properly for the MD13S.
///
public static readonly Designator J6PWM_MD13S =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM1;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove ConnectorJ6 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
///
/// The speed and direction pins need to be swapped for the MD13S.
/// This requires using the MUNTS-0018-MD13S device tree
/// overlay instead of MUNTS-0018 to arrange the Raspberry
/// Pi expansion bus PWM and GPIO pins properly for the MD13S.
///
public static readonly Designator J6DIR_MD13S = J6D0;
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J7.
///
public static readonly Designator J7PWM =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM1;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove Connector J6.
///
public static readonly Designator J7DIR = J7D1;
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J7 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
///
/// The speed and direction pins need to be swapped for the MD13S.
/// This requires using the MUNTS-0018-MD13S device tree
/// overlay instead of MUNTS-0018 to arrange the Raspberry
/// Pi expansion bus PWM and GPIO pins properly for the MD13S.
///
public static readonly Designator J7PWM_MD13S =
IO.Objects.SimpleIO.Platforms.RaspberryPi.PWM0;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove ConnectorJ7 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
///
/// The speed and direction pins need to be swapped for the MD13S.
/// This requires using the MUNTS-0018-MD13S device tree
/// overlay instead of MUNTS-0018 to arrange the Raspberry
/// Pi expansion bus PWM and GPIO pins properly for the MD13S.
///
public static readonly Designator J7DIR_MD13S = J7D0;
// I2C buses
///
/// I2C bus Designator for /dev/i2c-1
/// on I2C Grove Connector J9.
///
public static readonly Designator J9I2C =
IO.Objects.SimpleIO.Platforms.RaspberryPi.I2C1;
// Analog inputs (on board MCP3204)
///
/// Analog input Designator for Analog Input Grove Connector
/// J10 pin A0 (MCP3204 input CH2.
///
public static readonly Designator J10A0 = new Designator(0, 2);
///
/// Analog input Designator for Analog Input Grove Connector
/// J10 pin A1 (MCP3204 input CH3.
///
public static readonly Designator J10A1 = new Designator(0, 3);
///
/// Analog input Designator for Analog Input Grove Connector
/// J11 pin A0 (MCP3204 input CH0.
///
public static readonly Designator J11A0 = new Designator(0, 0);
///
/// Analog input Designator for Analog Input Grove Connector
/// J11 pin A1 (MCP3204 input CH1.
///
public static readonly Designator J11A1 = new Designator(0, 1);
// Create lists of valid designators, to be used for error checking
// in the factory functions below.
private static readonly List ValidAnalogInputs =
new List(new[] { J10A0, J10A1, J11A0, J11A1 });
private static readonly List ValidGPIOPins =
new List(new[] { J4D0, J4D1, J5D0, J5D1, J6D0, J6D1, J7D0, J7D1 });
private static readonly List ValidMotorSpeedOutputs =
new List(new[] { J6PWM, J7PWM });
private static readonly List ValidMotorDirectionOutputs =
new List(new[] { J6DIR, J7DIR });
private static readonly List ValidServoOutputs =
new List(new[] { J2PWM, J3PWM });
///
/// Analog input object factory for the on-board analog inputs at
/// connectors J10 and J11.
///
/// Device designator for one of the on-board
/// analog inputs (J10A0, J10A1, J11A0, or
/// J11A1).
/// Analog input object.
public static IO.Interfaces.ADC.Voltage AnalogInputFactory(Designator desg)
{
// Validate analog input designator
if (!ValidAnalogInputs.Contains(desg))
{
throw new System.ArgumentException("Invalid analog input designator.");
}
// Return analog input instance
return new IO.Interfaces.ADC.Input(new IO.Objects.SimpleIO.ADC.Sample(desg, 12), 3.3);
}
///
/// GPIO pin object factory for the on-board button switch at SW1.
///
/// Interrupt edge setting.
/// GPIO input pin object.
public static IO.Interfaces.GPIO.Pin ButtonInputFactory(IO.Objects.SimpleIO.GPIO.Edge edge = IO.Objects.SimpleIO.GPIO.Edge.None)
{
return new IO.Objects.SimpleIO.GPIO.Pin(SW1, IO.Interfaces.GPIO.Direction.Input, false, IO.Objects.SimpleIO.GPIO.Driver.PushPull, edge);
}
///
/// GPIO pin object factory for the on-board LED at D1.
///
/// Initial GPIO output state.
/// GPIO output pin object.
public static IO.Interfaces.GPIO.Pin LEDOutputFactory(bool state = false)
{
return new IO.Objects.SimpleIO.GPIO.Pin(D1, IO.Interfaces.GPIO.Direction.Output, state);
}
///
/// GPIO pin object factory for GPIO pins at connectors J4 to
/// J7.
///
/// Device designator for one of the on-board GPIO
/// pins (J4D0 to J7D1.
/// Data direction.
/// Initial GPIO output state.
/// Output driver setting.
/// Interrupt edge setting.
/// Polarity setting.
/// GPIO pin object.
public static IO.Interfaces.GPIO.Pin GPIOPinFactory(Designator desg,
IO.Interfaces.GPIO.Direction dir, bool state = false,
Driver driver = Driver.PushPull, Edge edge = Edge.None,
Polarity polarity = Polarity.ActiveHigh)
{
// Validate the GPIO pin designator
if (!ValidGPIOPins.Contains(desg))
{
throw new System.ArgumentException("Invalid GPIO pin designator.");
}
// Return GPIO pin instance
return new IO.Objects.SimpleIO.GPIO.Pin(desg, dir, state, driver, edge, polarity);
}
///
/// I2C bus object factory for the on-board I2C
/// bus at connector J9.
///
/// I2C bus object.
public static IO.Interfaces.I2C.Bus I2CBusFactory()
{
return new IO.Objects.SimpleIO.I2C.Bus(J9I2C);
}
///
/// Motor output object factory for the on-board motor outputs
/// at connectors J6 and J7.
///
/// Device designator for the motor speed PWM
/// output (J6PWM or J7PWM).
/// Device designator for the motor direction
/// GPIO output (J6DIR or J7DIR).
/// PWM pulse frequency.
/// Initial motor velocity.
/// Motor output object.
public static IO.Interfaces.Motor.Output MotorOutputFactory(Designator speed,
Designator direction, int frequency, double velocity = 0.0)
{
// Validate the PWM output designator
if (!ValidMotorSpeedOutputs.Contains(speed))
{
throw new System.ArgumentException("Invalid PWM output designator.");
}
// Validate the GPIO output designator
if (!ValidMotorDirectionOutputs.Contains(direction))
{
throw new System.ArgumentException("Invalid GPIO output designator.");
}
IO.Interfaces.PWM.Output S = new IO.Objects.SimpleIO.PWM.Output(speed, frequency);
IO.Interfaces.GPIO.Pin D = new IO.Objects.SimpleIO.GPIO.Pin(direction, IO.Interfaces.GPIO.Direction.Output);
return new IO.Objects.Motor.PWM.Output(D, S, velocity);
}
///
/// Servo output object factory for the on-board servo outputs
/// at headers J2 and J3.
///
/// Device designator for one of the on-board
/// PWM outputs (J2PWM or J3PWM).
/// PWM pulse frequency. Ordinary analog
/// servos operate best at 50 Hz.
/// Servo output object.
public static IO.Interfaces.Servo.Output ServoOutputFactory(Designator desg, int frequency = 50)
{
// Validate the servo output designator
if (!ValidServoOutputs.Contains(desg))
{
throw new System.ArgumentException("Invalid servo output designator.");
}
// Return servo output instance
return new IO.Objects.SimpleIO.Servo.Output(desg, frequency);
}
}
///
/// This class provides designators specific to the 64-Bit
/// Orange Pi Zero 2 W
/// interface computer.
///
///
/// The Orange Pi Zero 2 W does not route PWM signals to GPIO18
/// or GPIO19, so servo header J2 and PWM Grove socket
/// J7 are not usable except as extro GPIO pins.
///
public static class OrangePiZero2W
{
// On board LED
///
/// GPIO pin Designator for the on-board LED D1.
///
public static readonly Designator D1 = OrangePiZero2W_RaspberryPi.GPIO26;
// On board pushbutton switch
///
/// GPIO pin Designator for the on-board momentary switch
/// SW1.
///
public static readonly Designator SW1 = OrangePiZero2W_RaspberryPi.GPIO6;
// Grove GPIO Connectors
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J4 pin D0.
///
public static readonly Designator J4D0 = OrangePiZero2W_RaspberryPi.GPIO23;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J4 pin D1.
///
public static readonly Designator J4D1 = OrangePiZero2W_RaspberryPi.GPIO24;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J5 pin D0.
///
public static readonly Designator J5D0 = OrangePiZero2W_RaspberryPi.GPIO5;
///
/// GPIO pin Designator for Digital I/O Grove Connector
/// J5 pin D1.
///
public static readonly Designator J5D1 = OrangePiZero2W_RaspberryPi.GPIO4;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J6 pin D0.
///
///
/// This GPIO pin is normally unusable because it is configured as a
/// motor speed control PWM output.
///
public static readonly Designator J6D0 = OrangePiZero2W_RaspberryPi.GPIO12;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J6 pin D1.
///
///
/// This GPIO pin is normally unusable because it is configured as a
/// motor direction control GPIO output.
///
public static readonly Designator J6D1 = OrangePiZero2W_RaspberryPi.GPIO13;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J7 pin D0.
///
///
/// Unlike the Raspberry Pi, the Orange Pi Zero 2 W cannot route a
/// PWM output to this pin.
///
public static readonly Designator J7D0 = OrangePiZero2W_RaspberryPi.GPIO19;
///
/// GPIO pin Designator for DC Motor Driver Grove Connector
/// J7 pin D1.
///
///
/// Unlike the Raspberry Pi, the Orange Pi Zero 2 W cannot route a
/// PWM output to this pin.
///
public static readonly Designator J7D1 = OrangePiZero2W_RaspberryPi.GPIO18;
// Servo headers
///
/// PWM output Designator for Servo Header J2.
///
public static readonly Designator J2PWM = OrangePiZero2W_RaspberryPi.PWM0;
// DC motor control outputs (PWM and direction)
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J6.
///
public static readonly Designator J6PWM = OrangePiZero2W_RaspberryPi.PWM0;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove Connector J6.
///
public static readonly Designator J6DIR = J6D1;
///
/// Motor speed PWM output Designator for DC Motor Driver
/// Grove Connector J6 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
public static readonly Designator J6PWM_MD13S = OrangePiZero2W_RaspberryPi.PWM1;
///
/// Motor direction GPIO output pin Designator for DC Motor
/// Driver Grove ConnectorJ6 as configured for the
/// Cytron MD13S
/// Grove motor driver board.
///
public static readonly Designator J6DIR_MD13S = J6D0;
// I2C buses
///
/// I2C bus Designator for I2C Grove
/// Connector J9.
///
public static readonly Designator J9I2C = OrangePiZero2W_RaspberryPi.I2C1;
// Analog inputs (on board MCP3204)
///
/// Analog input Designator for Analog Input Grove Connector
/// J10 pin A0 (MCP3204 input CH2.
///
public static readonly Designator J10A0 = new Designator(0, 2);
///
/// Analog input Designator for Analog Input Grove Connector
/// J10 pin A1 (MCP3204 input CH3.
///
public static readonly Designator J10A1 = new Designator(0, 3);
///
/// Analog input Designator for Analog Input Grove Connector
/// J11 pin A0 (MCP3204 input CH0.
///
public static readonly Designator J11A0 = new Designator(0, 0);
///
/// Analog input Designator for Analog Input Grove Connector
/// J11 pin A1 (MCP3204 input CH1.
///
public static readonly Designator J11A1 = new Designator(0, 1);
// Create lists of valid designators, to be used for error checking
// in the factory functions below.
private static readonly List ValidAnalogInputs =
new List(new[] { J10A0, J10A1, J11A0, J11A1 });
private static readonly List ValidGPIOPins =
new List(new[] { J4D0, J4D1, J5D0, J5D1, J6D0, J6D1, J7D0, J7D1 });
private static readonly List ValidMotorSpeedOutputs =
new List(new[] { J6PWM, J6PWM_MD13S });
private static readonly List ValidMotorDirectionOutputs =
new List(new[] { J6DIR, J6DIR_MD13S });
private static readonly List ValidServoOutputs =
new List(new[] { J2PWM });
///
/// Analog input object factory for the on-board analog inputs at
/// connectors J10 and J11.
///
/// Device designator for one of the on-board
/// analog inputs (J10A0, J10A1, J11A0, or
/// J11A1).
/// Analog input object.
public static IO.Interfaces.ADC.Voltage AnalogInputFactory(Designator desg)
{
// Validate analog input designator
if (!ValidAnalogInputs.Contains(desg))
{
throw new System.ArgumentException("Invalid analog input designator.");
}
// Return analog input instance
return new IO.Interfaces.ADC.Input(new IO.Objects.SimpleIO.ADC.Sample(desg, 12), 3.3);
}
///
/// GPIO pin object factory for the on-board button switch at SW1.
///
/// Interrupt edge setting.
/// GPIO input pin object.
public static IO.Interfaces.GPIO.Pin ButtonInputFactory(IO.Objects.SimpleIO.GPIO.Edge edge = IO.Objects.SimpleIO.GPIO.Edge.None)
{
// Return GPIO pin instance
return new IO.Objects.SimpleIO.GPIO.Pin(SW1, IO.Interfaces.GPIO.Direction.Input, false, IO.Objects.SimpleIO.GPIO.Driver.PushPull, edge);
}
///
/// GPIO pin object factory for the on-board LED at D1.
///
/// Initial GPIO output state.
/// GPIO output pin object.
public static IO.Interfaces.GPIO.Pin LEDOutputFactory(bool state = false)
{
// Return GPIO pin instance
return new IO.Objects.SimpleIO.GPIO.Pin(D1, IO.Interfaces.GPIO.Direction.Output, state);
}
///
/// GPIO pin object factory for GPIO pins at connectors J4 to
/// J7.
///
/// Device designator for one of the on-board GPIO
/// pins (J4D0 to J7D1.
/// Data direction.
/// Initial GPIO output state.
/// Output driver setting.
/// Interrupt edge setting.
/// Polarity setting.
/// GPIO pin object.
public static IO.Interfaces.GPIO.Pin GPIOPinFactory(Designator desg,
IO.Interfaces.GPIO.Direction dir, bool state = false,
Driver driver = Driver.PushPull, Edge edge = Edge.None,
Polarity polarity = Polarity.ActiveHigh)
{
// Validate the GPIO pin designator
if (!ValidGPIOPins.Contains(desg))
{
throw new System.ArgumentException("Invalid GPIO pin designator.");
}
// Return GPIO pin instance
return new IO.Objects.SimpleIO.GPIO.Pin(desg, dir, state, driver, edge, polarity);
}
///
/// I2C bus object factory for the on-board I2C
/// bus at connector J9.
///
/// I2C bus object.
public static IO.Interfaces.I2C.Bus I2CBusFactory()
{
return new IO.Objects.SimpleIO.I2C.Bus(J9I2C);
}
///
/// Motor output object factory for the on-board motor output
/// at connector J6.
///
/// Device designator for the motor speed PWM
/// output (J6PWM).
/// Device designator for the motor direction
/// GPIO output (J6DIR).
/// PWM pulse frequency.
/// Initial motor velocity.
/// Motor output object.
public static IO.Interfaces.Motor.Output MotorOutputFactory(Designator speed,
Designator direction, int frequency, double velocity = 0.0)
{
// Validate the PWM output designator
if (!ValidMotorSpeedOutputs.Contains(speed))
{
throw new System.ArgumentException("Invalid PWM output designator.");
}
// Validate the GPIO output designator
if (!ValidMotorDirectionOutputs.Contains(direction))
{
throw new System.ArgumentException("Invalid GPIO output designator.");
}
IO.Interfaces.PWM.Output S = new IO.Objects.SimpleIO.PWM.Output(speed, frequency);
IO.Interfaces.GPIO.Pin D = new IO.Objects.SimpleIO.GPIO.Pin(direction, IO.Interfaces.GPIO.Direction.Output);
return new IO.Objects.Motor.PWM.Output(D, S, velocity);
}
///
/// Servo output object factory for the on-board servo output
/// at header J2.
///
/// Device designator for one of the on-board
/// PWM outputs (J2PWM).
/// PWM pulse frequency. Ordinary analog
/// servos operate best at 50 Hz.
/// Servo output object.
public static IO.Interfaces.Servo.Output ServoOutputFactory(Designator desg, int frequency = 50)
{
// Validate the servo output designator
if (!ValidServoOutputs.Contains(desg))
{
throw new System.ArgumentException("Invalid servo output designator.");
}
// Return servo output instance
return new IO.Objects.SimpleIO.Servo.Output(desg, frequency);
}
}
}
}