mercury-api-0.1.0.0: examples/tmr-gpio.hs
{-# LANGUAGE OverloadedStrings #-}
import Control.Concurrent ( threadDelay )
import Control.Exception ( finally )
import Control.Monad ( when )
import Data.Monoid ( (<>) )
import qualified Data.Text.IO as T ( putStrLn )
import Options.Applicative
( Alternative(many),
Applicative((<*>)),
Parser,
helper,
execParser,
metavar,
info,
header,
fullDesc,
auto,
argument,
(<$>) )
import qualified System.Hardware.MercuryApi as TMR
import qualified System.Hardware.MercuryApi.Params as TMR
import ExampleUtil
data Opts = Opts
{ oUri :: String
, oListen :: Bool
, oGpos :: [TMR.PinNumber]
}
opts :: Parser Opts
opts = Opts
<$> optUri
<*> optListen
<*> many (argument auto (metavar "OUTPUTS..."))
opts' = info (helper <*> opts)
( fullDesc <>
header "tmr-gpio - print GPIs and control GPOs" )
delayMillis :: Int
delayMillis = 100
mkPin :: TMR.PinNumber -> TMR.PinNumber -> TMR.GpioPin
mkPin highPin pin =
TMR.GpioPin
{ TMR.gpId = pin
, TMR.gpHigh = highPin == pin
, TMR.gpOutput = True
}
gpioLoop :: TMR.Reader -> [TMR.PinNumber] -> Integer -> [TMR.GpioPin] -> IO ()
gpioLoop rdr outPins millis oldPins = do
pins <- TMR.gpiGet rdr
when (pins /= oldPins) $ mapM_ T.putStrLn $ TMR.displayGpio pins
when (not $ null outPins) $ do
let oLen = length outPins
pinNo = outPins !! fromIntegral ((millis `div` 1000) `mod` fromIntegral oLen)
gpoPins = map (mkPin pinNo) outPins
TMR.gpoSet rdr gpoPins
threadDelay $ delayMillis * 1000
gpioLoop rdr outPins (millis + fromIntegral delayMillis) pins
main = do
o <- execParser opts'
rdr <- createAndConnect (oUri o) (oListen o)
-- set all the pins to input
TMR.paramSetGpioInputList rdr [1..4]
-- then set some to output
let outPins = oGpos o
TMR.paramSetGpioOutputList rdr outPins
putStrLn $ "cycling among output pins " ++ show outPins
-- now see which inputs are left
inPins <- TMR.paramGetGpioInputList rdr
putStrLn $ "listening on input pins " ++ show inPins
gpioLoop rdr outPins 0 [] `finally` TMR.destroy rdr