// 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); } } } }