wiringPi- Access GPIO pins on Raspberry Pi via wiringPi library

Copyright© Patrick Pelletier 2017
PortabilityRaspberry Pi
Safe HaskellNone




This is a Haskell binding to the wiringPi library. The functions here (mostly) correspond directly to the functions in the C library, except for how initialization and pin numbering are handled. To use this library, you must either run as root, or set the WIRINGPI_GPIOMEM environment variable. However, if you set WIRINGPI_GPIOMEM, then PWM does not work, so to use PWM you must be root.



data Pin Source #

Represents a pin number. The constructor determines which one of the three pin numbering schemes is used. See the README for details, and a pretty picture. == returns true for the same physical pin, even if different pin numbering schemes are used.


Wpi Int

use wiringPi pin number

Gpio Int

use BCM_GPIO numbering (these are the numbers on the Adafruit cobbler and on pinout.xyz).

Phys Int

use physical pin numbers on P1 connector


Eq Pin Source # 


(==) :: Pin -> Pin -> Bool #

(/=) :: Pin -> Pin -> Bool #

Ord Pin Source # 


compare :: Pin -> Pin -> Ordering #

(<) :: Pin -> Pin -> Bool #

(<=) :: Pin -> Pin -> Bool #

(>) :: Pin -> Pin -> Bool #

(>=) :: Pin -> Pin -> Bool #

max :: Pin -> Pin -> Pin #

min :: Pin -> Pin -> Pin #

Read Pin Source # 
Show Pin Source # 


showsPrec :: Int -> Pin -> ShowS #

show :: Pin -> String #

showList :: [Pin] -> ShowS #

data Mode Source #

Pin mode, used with pinMode.



digital input


digital output


pulse-width modulation; only supported on wiringPi pins 1, 23, 24, and 26


clock output; only supported on wiringPi pins 7, 21, 22, and 29

data Pud Source #

Use with pullUpDnControl to enable internal pull-up or pull-down resistor.



disable pull-up/pull-down


enable pull-down resistor


enable pull-up resistor


Bounded Pud Source # 


minBound :: Pud #

maxBound :: Pud #

Enum Pud Source # 


succ :: Pud -> Pud #

pred :: Pud -> Pud #

toEnum :: Int -> Pud #

fromEnum :: Pud -> Int #

enumFrom :: Pud -> [Pud] #

enumFromThen :: Pud -> Pud -> [Pud] #

enumFromTo :: Pud -> Pud -> [Pud] #

enumFromThenTo :: Pud -> Pud -> Pud -> [Pud] #

Eq Pud Source # 


(==) :: Pud -> Pud -> Bool #

(/=) :: Pud -> Pud -> Bool #

Ord Pud Source # 


compare :: Pud -> Pud -> Ordering #

(<) :: Pud -> Pud -> Bool #

(<=) :: Pud -> Pud -> Bool #

(>) :: Pud -> Pud -> Bool #

(>=) :: Pud -> Pud -> Bool #

max :: Pud -> Pud -> Pud #

min :: Pud -> Pud -> Pud #

Read Pud Source # 
Show Pud Source # 


showsPrec :: Int -> Pud -> ShowS #

show :: Pud -> String #

showList :: [Pud] -> ShowS #

data IntEdge Source #

Interrupt levels, used with wiringPiISR.



no initialization of the pin will happen


interrupt on a falling edge of the incoming signal


interrupt on a rising edge of the incoming signal


interrupt on both rising edge and falling edge of the incoming signal

type PwmValue = Word16 Source #

Value used with pwmWrite. Typically ranges from 0-1024, but the range can be increased up to 4096 by calling pwmSetRange.

Setup function

See WiringPi Setup functions. Unlike the C version of wiringPi, the Haskell binding will automatically call the setup function the first time a wiringPi function is called. The only reason to call it manually is if you want to check for errors earlier than your first call. It is also harmless to call it multiple times. In the Haskell binding the "GPIO" numbering scheme is always used internally, but the Pin constructors allow you to choose whichever numbering scheme you want, on a pin-by-pin basis. This avoids having to choose a single pin numbering scheme at initialization time, as you do with the C library.

wiringPiSetupGpio :: IO () Source #

Initialize the wiringPi library. This is optional, because it will automatically be called on the first use of a wiringPi function. Raises an exception if the underlying C function returns an error code. However, in practice, the C function wiringPiSetupGpio terminates the program on error. Setting the environment variable WIRINGPI_CODES is supposed to change this behavior, but in my experience it doesn't, and the program is still terminated on error.

Core functions

pinMode :: Pin -> Mode -> IO () Source #

pwmWrite :: Pin -> PwmValue -> IO () Source #

Default range is 0-1024, but it can be changed with pwmSetRange.

Additional functions

digitalWriteByte :: Word8 -> IO () Source #

Write 8 bits to the 8 pins that have wiringPi pin numbers 0-7.

pwmSetRange :: PwmValue -> IO () Source #

Change the range used by pwmWrite. Default is 1024. Maxium is 4096.

pwmSetClock :: PwmValue -> IO () Source #

Change the PWM divisor. Range is 2-4095.

piGpioLayout :: IO Int Source #

Returns 1 for very early Rasbperry Pis and 2 for all others. This distinction is because at some point early on, the Raspberry Pi foundation replaced BCM_GPIO 0, 1, and 21 with BCM_GPIO 2, 3, and 27 at the same places on the P1 connector. Also, the user-accessible I²C bus changed from bus 0 to bus 1.

piBoardRev :: IO Int Source #

An alias for piGpioLayout. (The wiringPi C library changed the name from piBoardRev to piGpioLayout in version 2.36, and really piGpioLayout is a much better name for it.)

pinToBcmGpio :: Pin -> Maybe Int Source #

Converts a pin to its "Broadcom GPIO" number. (In other words, the pin number that would be specified with the Gpio constructor.) This relies on unsafePerformIO internally, because the pin mapping depends on the board revision. Returns Nothing if the pin number is invalid; e. g. it is out of range or is a power or ground pin on the physical connector. See the pretty picture for details. (The picture depicts the mapping when piGpioLayout is 2; there is a slightly different mapping when piGpioLayout is 1.)

Interrupt functions

wiringPiISR :: Pin -> IntEdge -> IO () -> IO () Source #

Sets up an interrupt handler for the specified pin. When the pin transitions as specified by IntEdge, the IO action will be executed. Be aware that if interrupts come quickly enough, the IO action might only be called once when the pin has transitioned more than once. If your program uses this function, you must link with -threaded, or deadlock may occur. You should only call wiringPiISR once per pin, because the underlying C library does not support changing or removing an interrupt handler once it has been added.