GPIOTools - Maple Help

GPIOTools

Description

 • The GPIOTools package provides functions to manipulate the GPIO interface on the Raspberry Pi, and is supported only on the Raspberry Pi.
 • Each function in the GPIOTools package can be accessed by using either the long form or the short form of the function name in the calling sequence.

Pin Numbering

 • There are several different pin numbering schemes in common use in the Raspberry Pi community:
 – BCM pin numbering uses the GPIO port numbers assigned to the available GPIO pins by the Broadcomm system-on-a-chip on which the Raspberry Pi is based.
 – Wiring Pi pin numbering is a scheme introduced by the Wiring Pi library, and is based on a similar scheme used by Arduino systems.
 – Physical pin numbering refers to the actual pins on the GPIO connector (J8) on the Raspberry Pi board.
 • The GPIOTools:-Open function can accept pin numbers using any of these schemes (as specified by the scheme option). It will return the corresponding BCM pin number, which must be used as the pin number argument to all other GPIOTools functions.

Information Functions

 • The GPIOTools:-Status function prints or returns a detailed table of the current status of the GPIO pins. The following information is shown for each pin:
 – The BCM, Wiring Pi, and Physical pin numbers.
 – The pin's name.
 – The mode the pin is currently set to (input, output, alternate).
 – The current input value or most recently written output value (0 or 1).
 By default, Status prints its output. If the option return_string or return_string=true is passed, the text of the table is returned as a string instead.
 • The GPIOTools:-Hardware function returns the type of hardware on which Maple is running, for example, "Pi 3B".

Opening a GPIO Pin

 • Before a GPIO pin can be used, it must first be opened using the GPIOTools:-Open function. This function has one required argument specifying the pin number to open, and several optional keyword arguments:
 – The scheme keyword argument specifies the pin numbering scheme used for the pin number argument. It's value can be one of "BCM", "WiringPi", or "physical" (all specified as strings).
 – Keyword argument mode can have the value "in", "out", or "pwm", specifying whether the pin is to be used for input, output, or PWM (pulse width modulation) output respectively. The default is "in".
 – If a pin is used for input, the pull keyword argument can be used to specify the status of the input pull-up/down resistor. It's value can be one of "up", "down", or "none". The default is "none".
 • If the pin was opened with a mode of "pwm", then several options control the PWM parameters. Any two of these should be specified, and the third is determined by them:
 – The clock keyword argument specifies the divisor by which the 19.2MHz PWM master clock is to be divided to define the PWM clock. The default is 375, resulting in a 51.2kHz PWM clock.
 – The range keyword argument (alternatively, resolution) specifies the additional divisor by which the PWM clock is divided, and thus the number of discrete pulse widths available. The product of the clock and range arguments, divided into the 19.2MHz master clock, yields the PWM pulse rate. The default range is 1024.
 – The rate keyword argument (alternatively, frequency) is a real value specifing the desired PWM pulse rate in Hz (cycles per second). The default is 50, which is suitable for controlling hobby servo motors. Note that the available rates are constrained by the fixed 19.2MHz master clock, and the integer clock and range divisors. Thus, the actual rate produced may not be exactly the one requested.
 The values passed for these three keyword arguments satisfy the relation, clock * range * rate = 19200000, thus specifying any two fixes the third. The GPIOTools:-PWMInfo function returns a sequence of these three values respectively.

Reading from a GPIO Input Pin

 • After a GPIO pin has been opened for input using the GPIOTools:-Open function, the status of the pin can be read using GPIOTools:-Read. The Read function accepts a single argument, which is the BCM pin number of the pin to read (the number returned by Open).
 • The returned value will be either 0 or 1, depending on whether the input on the specified pin is low or high.

Writing to a GPIO Output Pin

 • A GPIO pin that has been opened for output with GPIOTools:-Open can be written to using GPIOTools:-Write, which takes two arguments:
 – The first argument gives the BCM pin number, as returned by Open.
 – The second argument specifies the value to write, either 0 or 1, which will make the output low (0V) or high (3.3V) respectively.

Writing to a GPIO PWM Output Pin

 • PWM output to a pin previously opened for such by GPIOTools:-Open is done using the GPIOTools:-WritePWM function, which takes two required arguments, and one of two optional arguments:
 – The first argument gives the BCM pin number, as returned by Open.
 – The second argument specifies the value to write, which is either an integer value in the range specified by the range option to Open, or a real value in the range 0..100 or 0..1 depending on the keyword argument.
 – If the keyword argument percent or percent=true is passed, the value argument is interpreted as a percentage, which should be in range 0..100.
 – If the keyword argument fraction or fraction=true is passed, the value argument is interpreted as a fraction, which should be in the range 0..1.
 • If the percent or fraction option is used, the specified value is converted to a value based on the range option to Open, rounded to the nearest integer.

Closing GPIO Pins

 • A GPIO pin previously opened using GPIOTools:-Open can be closed using GPIOTools:-Close, which accepts a single argument specifying the BCM pin number (as returned by Open) of the pin to close.
 Closing a pin restores its mode to input, and disables the pull-up/down resistor, making the pin effectively inert. The pin is also released for use by other applications.
 • The GPIOTools:-CloseAll function closes all previously opened GPIO pins.

Examples

In the following example, an LED is assumed to be connected to physical pin 12 via a 1500 Ohm resistor to the LED's anode. It's cathode is connected to one of the Raspberry Pi's ground pins.

 > $\mathrm{with}\left(\mathrm{GPIOTools}\right)$
 [Close, CloseAll, Hardware, Open, PWMInfo, Read, Status, Write, WritePWM]

Open physical pin 12 in output mode, returning the BCM pin number.

 > $\mathrm{pin}≔\mathrm{Open}\left(12,\mathrm{mode}="out",\mathrm{scheme}="physical"\right)$
 pin := 18

Toggle the LED on and off at a rate of once per second, will simultaneously printing ON and OFF on the terminal.

 > $t≔\mathrm{time}\left[\mathrm{real}\right]\left(\right):$$\mathbf{for}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}i\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathbf{to}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}5\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathbf{do}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{printf}\left("ON"\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{Write}\left(\mathrm{pin},1\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathbf{do}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{Threads}:-\mathrm{Sleep}\left(0.01\right)\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathbf{until}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}t+0.5\le \mathrm{time}\left[\mathrm{real}\right]\left(\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{+=}\left(t,0.5\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{printf}\left("OFF"\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{Write}\left(\mathrm{pin},0\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathbf{do}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{Threads}:-\mathrm{Sleep}\left(0.01\right)\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathbf{until}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}t+0.5\le \mathrm{time}\left[\mathrm{real}\right]\left(\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{+=}\left(t,0.5\right)\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\mathbf{end}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathbf{do}:$$\mathrm{printf}\left("\n"\right)$
 ON  OFF  ON  OFF  ON  OFF  ON  OFF  ON  OFF
 > $\mathrm{Close}\left(\mathrm{pin}\right)$

Reopen the same pin (use the BCM number directly this time, since we know it now) in PWM mode at 750Hz with a resolution of 120.

 > $\mathrm{Open}\left(\mathrm{pin},\mathrm{mode}="pwm",\mathrm{rate}=750,\mathrm{range}=120\right)$
 18

Show what the clock divisor, range, and actual rate ended up being (it is constrained by the 19.2MHz master clock rate and the integer clock and range divisors).

 > $\mathrm{PWMInfo}\left(\right)$
 213, 120, 751.1737089

Turn the LED on and off slowly once per second using the cos function, shifted into the range 0..1, and then (approximately) gamma corrected.

 > $t≔\mathrm{time}\left[\mathrm{real}\right]\left(\right):$$\mathbf{while}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathrm{time}\left[\mathrm{real}\right]\left(\right)
 > $\mathrm{Close}\left(\mathrm{pin}\right)$