-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Control your Arduino board from Haskell.
--   
--   hArduino allows Haskell programs to control Arduino boards
--   (<a>http://www.arduino.cc</a>) and peripherals, using the Firmata
--   protocol (<a>http://firmata.org</a>).
--   
--   For details, see: <a>http://leventerkok.github.io/hArduino</a>.
@package hArduino
@version 1.2


-- | Character to 7-segment display conversion.
module System.Hardware.Arduino.Parts.SevenSegmentCodes

-- | Convert a character to a bit-pattern, suitable for display on a
--   seven-segment display. Note that most characters are just not
--   representable in a 7-segment display, in which case we map it to
--   <a>Nothing</a>. However, some substitutions are done, for instance '('
--   is displayed the same as '['.
--   
--   The return value is a <a>Word8</a>, although only 7-bits are used; the
--   least significant bit will always be 0. With the traditional coding,
--   the bits correspond to segments ABCDEFG0, i.e., most-significant-bit
--   will be for segment A, next for segment B, and so on.
char2SS :: Char -> Maybe Word8


-- | LCD (Liquid Crystal Display) parts supported by hArduino. The Haskell
--   code below has partly been implemented following the Arduino
--   LiquidCrystal project source code:
--   <a>http://code.google.com/p/arduino/source/browse/trunk/libraries/LiquidCrystal/</a>
--   
--   The Hitachi44780 data sheet is at:
--   <a>http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf</a>
--   
--   For an example program using this library, see
--   <a>System.Hardware.Arduino.SamplePrograms.LCD</a>.
module System.Hardware.Arduino.Parts.LCD

-- | LCD's connected to the board
data LCD

-- | Hitachi LCD controller: See:
--   <a>http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller</a>. We
--   model only the 4-bit variant, with RS and EN lines only. (The most
--   common Arduino usage.) The data sheet can be seen at:
--   <a>http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf</a>.
data LCDController
Hitachi44780 :: Pin -> Pin -> Pin -> Pin -> Pin -> Pin -> Int -> Int -> Bool -> LCDController

-- | Hitachi pin <tt> 4</tt>: Register-select
[lcdRS] :: LCDController -> Pin

-- | Hitachi pin <tt> 6</tt>: Enable
[lcdEN] :: LCDController -> Pin

-- | Hitachi pin <tt>11</tt>: Data line <tt>4</tt>
[lcdD4] :: LCDController -> Pin

-- | Hitachi pin <tt>12</tt>: Data line <tt>5</tt>
[lcdD5] :: LCDController -> Pin

-- | Hitachi pin <tt>13</tt>: Data line <tt>6</tt>
[lcdD6] :: LCDController -> Pin

-- | Hitachi pin <tt>14</tt>: Data line <tt>7</tt>
[lcdD7] :: LCDController -> Pin

-- | Number of rows (typically 1 or 2, upto 4)
[lcdRows] :: LCDController -> Int

-- | Number of cols (typically 16 or 20, upto 40)
[lcdCols] :: LCDController -> Int

-- | Set to True if 5x10 dots are used
[dotMode5x10] :: LCDController -> Bool

-- | Register an LCD controller. When registration is complete, the LCD
--   will be initialized so that:
--   
--   <ul>
--   <li>Set display ON (Use <a>lcdDisplayOn</a> / <a>lcdDisplayOff</a> to
--   change.)</li>
--   <li>Set cursor OFF (Use <a>lcdCursorOn</a> / <a>lcdCursorOff</a> to
--   change.)</li>
--   <li>Set blink OFF (Use <a>lcdBlinkOn</a> / <a>lcdBlinkOff</a> to
--   change.)</li>
--   <li>Clear display (Use <a>lcdClear</a> to clear, <a>lcdWrite</a> to
--   display text.)</li>
--   <li>Set entry mode left to write (Use <a>lcdLeftToRight</a> /
--   <a>lcdRightToLeft</a> to control.)</li>
--   <li>Set autoscrolling OFF (Use <a>lcdAutoScrollOff</a> /
--   <a>lcdAutoScrollOn</a> to control.)</li>
--   <li>Put the cursor into home position (Use <a>lcdSetCursor</a> or
--   <a>lcdHome</a> to move around.)</li>
--   </ul>
lcdRegister :: LCDController -> Arduino LCD

-- | Clear the LCD
lcdClear :: LCD -> Arduino ()

-- | Write a string on the LCD at the current cursor position
lcdWrite :: LCD -> String -> Arduino ()

-- | Send the cursor to home position
lcdHome :: LCD -> Arduino ()

-- | Set the cursor location. The pair of arguments is the new column and
--   row numbers respectively:
--   
--   <ul>
--   <li>The first value is the column, the second is the row. (This is
--   counter-intuitive, but is in line with what the standard Arduino
--   programmers do, so we follow the same convention.)</li>
--   <li>Counting starts at 0 (both for column and row no)</li>
--   <li>If the new location is out-of-bounds of your LCD, we will put it
--   the cursor to the closest possible location on the LCD.</li>
--   </ul>
lcdSetCursor :: LCD -> (Int, Int) -> Arduino ()

-- | Turn on auto-scrolling. In the context of the Hitachi44780 controller,
--   this means that each time a letter is added, all the text is moved one
--   space to the left. This can be confusing at first: It does <i>not</i>
--   mean that your strings will continuously scroll: It just means that if
--   you write a string whose length exceeds the column-count of your LCD,
--   then you'll see the tail-end of it. (Of course, this will create a
--   scrolling effect as the string is being printed character by
--   character.)
--   
--   Having said that, it is easy to program a scrolling string program:
--   Simply write your string by calling <a>lcdWrite</a>, and then use the
--   <a>lcdScrollDisplayLeft</a> and <a>lcdScrollDisplayRight</a> functions
--   with appropriate delays to simulate the scrolling.
lcdAutoScrollOn :: LCD -> Arduino ()

-- | Turn off auto-scrolling. See the comments for <a>lcdAutoScrollOn</a>
--   for details. When turned off (which is the default), you will
--   <i>not</i> see the characters at the end of your strings that do not
--   fit into the display.
lcdAutoScrollOff :: LCD -> Arduino ()

-- | Scroll the display to the left by 1 character. Project idea: Using a
--   tilt sensor, scroll the contents of the display left/right depending
--   on the tilt.
lcdScrollDisplayLeft :: LCD -> Arduino ()

-- | Scroll the display to the right by 1 character
lcdScrollDisplayRight :: LCD -> Arduino ()

-- | Set writing direction: Left to Right
lcdLeftToRight :: LCD -> Arduino ()

-- | Set writing direction: Right to Left
lcdRightToLeft :: LCD -> Arduino ()

-- | Blink the cursor
lcdBlinkOn :: LCD -> Arduino ()

-- | Do not blink the cursor
lcdBlinkOff :: LCD -> Arduino ()

-- | Show the cursor
lcdCursorOn :: LCD -> Arduino ()

-- | Hide the cursor. Note that a blinking cursor cannot be hidden, you
--   must first turn off blinking.
lcdCursorOff :: LCD -> Arduino ()

-- | Turn the display on
lcdDisplayOn :: LCD -> Arduino ()

-- | Turn the display off. Note that turning the display off does not mean
--   you are powering it down. It simply means that the characters will not
--   be shown until you turn it back on using <a>lcdDisplayOn</a>. (Also,
--   the contents will <i>not</i> be forgotten when you call this
--   function.) Therefore, this function is useful for temporarily hiding
--   the display contents.
lcdDisplayOff :: LCD -> Arduino ()

-- | An abstract symbol type for user created symbols
data LCDSymbol

-- | Access an internally stored symbol, one that is not available via its
--   ASCII equivalent. See the Hitachi datasheet for possible values:
--   <a>http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf</a>, Table 4
--   on page 17.
--   
--   For instance, to access the symbol right-arrow:
--   
--   <ul>
--   <li>Locate it in the above table: Right-arrow is at the second-to-last
--   row, 7th character from left.</li>
--   <li>Check the upper/higher bits as specified in the table: For
--   Right-arrow, upper bits are <tt>0111</tt> and the lower bits are
--   <tt>1110</tt>; which gives us the code <tt>01111110</tt>, or
--   <tt>0x7E</tt>.</li>
--   <li>So, right-arrow can be accessed by symbol code
--   <a>lcdInternalSymbol</a> <tt>0x7E</tt>, which will give us a
--   <a>LCDSymbol</a> value that can be passed to the <a>lcdWriteSymbol</a>
--   function. The code would look like this: <tt>lcdWriteSymbol lcd
--   (lcdInternalSymbol 0x7E)</tt>.</li>
--   </ul>
lcdInternalSymbol :: Word8 -> LCDSymbol

-- | Display a user created symbol on the LCD. (See <a>lcdCreateSymbol</a>
--   for details.)
lcdWriteSymbol :: LCD -> LCDSymbol -> Arduino ()

-- | Create a custom symbol for later display. Note that controllers have
--   limited capability for such symbols, typically storing no more than 8.
--   The behavior is undefined if you create more symbols than your LCD can
--   handle.
--   
--   The input is a simple description of the glyph, as a list of precisely
--   8 strings, each of which must have 5 characters. Any space character
--   is interpreted as a empty pixel, any non-space is a full pixel,
--   corresponding to the pixel in the 5x8 characters we have on the LCD.
--   For instance, here's a happy-face glyph you can use:
--   
--   <pre>
--   [ "     "
--   , "@   @"
--   , "     "
--   , "     "
--   , "@   @"
--   , " @@@ "
--   , "     "
--   , "     "
--   ]
--   </pre>
lcdCreateSymbol :: LCD -> [String] -> Arduino LCDSymbol

-- | Flash contents of the LCD screen
lcdFlash :: LCD -> Int -> Int -> Arduino ()


-- | hArduino allows Haskell programs to control Arduino boards
--   (<a>http://www.arduino.cc</a>) and peripherals, using the Firmata
--   protocol (<a>http://firmata.org</a>).
--   
--   For details, see: <a>http://leventerkok.github.com/hArduino</a>.
module System.Hardware.Arduino

-- | Run the Haskell program to control the board:
--   
--   <ul>
--   <li>The file path argument should point to the device file that is
--   associated with the board. (<tt>COM1</tt> on Windows,
--   <tt><i>dev</i>cu.usbmodemFD131</tt> on Mac, etc.)</li>
--   <li>The boolean argument controls verbosity. It should remain
--   <a>False</a> unless you have communication issues. The print-out is
--   typically less-than-useful, but it might point to the root cause of
--   the problem.</li>
--   </ul>
--   
--   See <a>System.Hardware.Arduino.Examples.Blink</a> for a simple
--   example.
withArduino :: Bool -> FilePath -> Arduino () -> IO ()

-- | The Arduino monad.
data Arduino a

-- | Declare an analog pin on the board. For instance, to refer to analog
--   pin no 0 simply use <a>analog</a> <tt>0</tt>.
--   
--   Note that <a>analog</a> <tt>0</tt> on an Arduino UNO will be
--   appropriately adjusted internally to refer to pin 14, since UNO has 13
--   digital pins, while on an Arduino MEGA, it will refer to internal pin
--   55, since MEGA has 54 digital pins; and similarly for other boards
--   depending on their capabilities. (Also see the note on <a>pin</a> for
--   pin mappings.)
analog :: Word8 -> Pin

-- | Declare an digital pin on the board. For instance, to refer to digital
--   pin no 12 use <a>digital</a> <tt>12</tt>.
digital :: Word8 -> Pin

-- | Declare a pin by its index. For maximum portability, prefer
--   <a>digital</a> and <a>analog</a> functions, which will adjust pin
--   indexes properly based on which board the program is running on at
--   run-time, as Arduino boards differ in their pin numbers. This function
--   is provided for cases where a pin is used in mixed-mode, i.e., both
--   for digital and analog purposes, as Arduino does not really
--   distinguish pin usage. In these cases, the user has the proof
--   obligation to make sure that the index used is supported on the board
--   with appropriate capabilities.
pin :: Word8 -> Pin

-- | A pin on the Arduino, as specified by the user via <a>pin</a>,
--   <a>digital</a>, and <a>analog</a> functions.
data Pin

-- | The mode for a pin.
data PinMode

-- | Digital input
INPUT :: PinMode

-- | Digital output
OUTPUT :: PinMode

-- | Analog input
ANALOG :: PinMode

-- | PWM (Pulse-Width-Modulation) output
PWM :: PinMode

-- | Servo Motor controller
SERVO :: PinMode

-- | Shift controller
SHIFT :: PinMode

-- | I2C (Inter-Integrated-Circuit) connection
I2C :: PinMode

-- | NB. No explicit support
ONEWIRE :: PinMode

-- | NB. No explicit support
STEPPER :: PinMode

-- | NB. No explicit support
ENCODER :: PinMode

-- | NB. No explicit support
SERIAL :: PinMode

-- | NB. No explicit support
PULLUP :: PinMode

-- | A mode we do not understand or support
UNSUPPORTED :: PinMode

-- | Set the mode on a particular pin on the board
setPinMode :: Pin -> PinMode -> Arduino ()

-- | Read the value of a pin in analog mode; this is a non-blocking call,
--   immediately returning the last sampled value. It returns <tt>0</tt> if
--   the voltage on the pin is 0V, and <tt>1023</tt> if it is 5V, properly
--   scaled. (See <a>setAnalogSamplingInterval</a> for sampling frequency.)
analogRead :: Pin -> Arduino Int

-- | Write a PWM analog value to a pin. The argument is an <a>Int</a>,
--   indicating the duty cycle. <tt>0</tt> means off; <tt>255</tt> means
--   always on. Intermediate values will create a square wave on that pin
--   with the given duty-cycle
analogWrite :: Pin -> Int -> Arduino ()

-- | Set or clear a digital pin on the board
digitalWrite :: Pin -> Bool -> Arduino ()

-- | Read the value of a pin in digital mode; this is a non-blocking call,
--   returning the current value immediately. See <a>waitFor</a> for a
--   version that waits for a change in the pin first.
digitalRead :: Pin -> Arduino Bool

-- | Wait for a change in the value of the digital input pin. Returns the
--   new value. Note that this is a blocking call. For a non-blocking
--   version, see <a>digitalRead</a>, which returns the current value of a
--   pin immediately.
waitFor :: Pin -> Arduino Bool

-- | Wait for a change in any of the given pins. Once a change is detected,
--   all the new values are returned. Similar to <a>waitFor</a>, but is
--   useful when we are watching multiple digital inputs.
waitAny :: [Pin] -> Arduino [Bool]

-- | Wait for any of the given pins to go from low to high. If all of the
--   pins are high to start with, then we first wait for one of them to go
--   low, and then wait for one of them to go back high. Returns the new
--   values.
waitAnyHigh :: [Pin] -> Arduino [Bool]

-- | Wait for any of the given pins to go from high to low. If all of the
--   pins are low to start with, then we first wait for one of them to go
--   high, and then wait for one of them to go back low. Returns the new
--   values.
waitAnyLow :: [Pin] -> Arduino [Bool]

-- | Send down a pulse, and measure how long the pin reports a
--   corresponding pulse, with a potential time-out. The call <tt>pulse p v
--   duration mbTimeOut</tt> does the following:
--   
--   <ul>
--   <li>Set the pin to value <tt>v</tt> for <tt>duration</tt>
--   microseconds.</li>
--   <li>Waits 2 microseconds</li>
--   <li>Waits until pin <tt>p</tt> has value <tt>not v</tt>.</li>
--   <li>Returns, in micro-seconds, the duration the pin stayed <tt>v</tt>,
--   counting from the 2 microsecond wait.</li>
--   </ul>
--   
--   Time-out parameter is used as follows:
--   
--   <ul>
--   <li>If <tt>mbTimeOut</tt> is <tt>Nothing</tt>, then <a>pulse</a> will
--   wait until the pin attains the value required and so long as it holds
--   it. Note that very-long time-out values are unlikely to be
--   accurate.</li>
--   <li>If <tt>mbTimeOut</tt> is <tt>Just t</tt> then, <a>pulse</a> will
--   stop if the above procedure does not complete within the given
--   micro-seconds. In this case, the overall return value is
--   <tt>Nothing</tt>.</li>
--   </ul>
--   
--   NB. Both the time-out value and the return value are given in
--   micro-seconds.
--   
--   NB. As of March 2 2013; StandardFirmata that's distributed with the
--   Arduino-App does <i>not</i> support the Pulse-In command. However,
--   there is a patch to add this command; see:
--   <a>http://github.com/rwldrn/johnny-five/issues/18</a> for details. If
--   you want to use hArduino's <tt>pulseIn</tt> command, then you
--   <i>have</i> to install the above patch. Also see the function
--   <tt>pulseIn_hostOnly</tt>, which works with the distributed
--   StandardFirmata: It implements a version that is not as accurate in
--   its timing, but might be sufficient if high precision is not required.
pulse :: Pin -> Bool -> Int -> Maybe Int -> Arduino (Maybe Int)

-- | A <i>hostOnly</i> version of pulse-in on a digital-pin. Use this
--   function only for cases where the precision required only matters for
--   the host, not for the board. That is, due to the inherent delays
--   involved in Firmata communication, the timing will <i>not</i> be
--   accurate, and should not be expected to work uniformly over different
--   boards. Similar comments apply for <a>pulseOut_hostTiming</a> as well.
--   See the function <a>pulse</a> for a more accurate version.
pulseIn_hostTiming :: Pin -> Bool -> Maybe Int -> Arduino (Maybe Int)

-- | A <i>hostOnly</i> version of pulse-out on a digital-pin. Use this
--   function only for cases where the precision required only matters for
--   the host, not for the board. That is, due to the inherent delays
--   involved in Firmata communication, the timing will <i>not</i> be
--   accurate, and should not be expected to work uniformly over different
--   boards. Similar comments apply for <a>pulseIn_hostTiming</a> as well.
--   See the function <a>pulse</a> for a more accurate version.
pulseOut_hostTiming :: Pin -> Bool -> Int -> Int -> Arduino ()

-- | Set the analog sampling interval, in milliseconds. Arduino uses a
--   default of 19ms to sample analog and I2C signals, which is fine for
--   many applications, but can be modified if needed. The argument should
--   be a number between <tt>10</tt> and <tt>16384</tt>; <tt>10</tt> being
--   the minumum sampling interval supported by Arduino and <tt>16383</tt>
--   being the largest value we can represent in 14 bits that this message
--   can handle. (Note that the largest value is just about <tt>16</tt>
--   seconds, which is plenty infrequent for all practical needs.)
setAnalogSamplingInterval :: Int -> Arduino ()

-- | Turn on/off internal pull-up resistor on an input pin
pullUpResistor :: Pin -> Bool -> Arduino ()

-- | Delay the computaton for a given number of milli-seconds
delay :: Int -> Arduino ()

-- | Time a given action, result is measured in micro-seconds.
time :: Arduino a -> Arduino (Int, a)

-- | Time-out a given action. Time-out amount is in micro-seconds.
timeOut :: Int -> Arduino a -> Arduino (Maybe a)

-- | Retrieve the Firmata firmware version running on the Arduino. The
--   first component is the major, second is the minor. The final value is
--   a human readable identifier for the particular board.
queryFirmware :: Arduino (Word8, Word8, String)


-- | Demonstrates <a>pulseIn_hostTiming</a> and <a>pulseOut_hostTiming</a>
--   functions, sending and receiving pulses to/from the board.
module System.Hardware.Arduino.SamplePrograms.Pulse

-- | Computes the amount of time a push-button is connected to input pin 2
--   on the Arduino. We will wait for at most 5 seconds, as a further
--   demonstration of the time-out facility. Note that the timing is done
--   on the host side, so this measurement is inherently inaccurate.
--   
--   The wiring is straightforward: Simply put a push-button between
--   digital input 2 and +5V, guarded by a 10K resistor:
--   
pulseInDemo :: IO ()

-- | Send pulses on a led as requested by the user. Note that the timing is
--   computed on the host side, thus the duration of the pulse is subject
--   to some error due to the Firmata communication overhead.
--   
--   Wiring: Simply a led on pin 13:
--   
pulseOutDemo :: IO ()


-- | Simple number guessing game on the OSEPP Keyboard shield.
--   
--   <i>Thanks to David Palmer for lending me his OSEPP shield to play
--   with!</i>
module System.Hardware.Arduino.SamplePrograms.NumGuess

-- | The OSepp LCD Shield is a 16x2 LCD using a Hitachi Controller
--   Furthermore, it has backlight, and 5 buttons. The hook-up is quite
--   straightforward, using our existing Hitachi44780 controller as an
--   example. More information on this shield can be found at:
--   
--   
--   <a>http://osepp.com/products/shield-arduino-compatible/16x2-lcd-display-keypad-shield/</a>
osepp :: LCDController

-- | There are 5 keys on the OSepp shield.
data Key
KeyRight :: Key
KeyLeft :: Key
KeyUp :: Key
KeyDown :: Key
KeySelect :: Key

-- | Initialize the shield. This is essentially simply registering the lcd
--   with the HArduino library. In addition, we return two values to the
--   user:
--   
--   <ul>
--   <li>A function to control the back-light</li>
--   <li>A function to read (if any) key-pressed</li>
--   </ul>
initOSepp :: Arduino (LCD, Bool -> Arduino (), Arduino (Maybe Key))

-- | Number guessing game, as a simple LCD demo. User thinks of a number
--   between <tt>0</tt> and <tt>1000</tt>, and the Arduino guesses it.
numGuess :: LCD -> (Bool -> Arduino ()) -> Arduino (Maybe Key) -> Arduino ()

-- | Entry to the classing number guessing game. Simply initialize the
--   shield and call our game function.
guessGame :: IO ()


-- | Morse code blinker. Original by Antoine R. Dumont, modified to
--   simplify and fit into the existing examples structure.
module System.Hardware.Arduino.SamplePrograms.Morse

-- | A dit or a dah is all we need for Morse: A <tt>dit</tt> is a dot; and
--   a <tt>dah</tt> is a dash in the Morsian world. We use <a>LBreak</a>
--   and <a>WBreak</a> to indicate a letter and a word break so we can
--   insert some delay between letters and words as we transmit.
data Morse
Dit :: Morse
Dah :: Morse
LBreak :: Morse
WBreak :: Morse

-- | Morse code dictionary
dict :: [(Char, [Morse])]

-- | Given a sentence, decode it. We simply drop any letters that we do not
--   have a mapping for.
decode :: String -> [Morse]

-- | Given a morsified sentence, compute the delay times. A <a>Left</a>
--   value means turn the led on that long, a <a>Right</a> value means turn
--   it off that long.
morsify :: [Morse] -> [Either Int Int]

-- | Finally, turn a full sentence into a sequence of blink on/off codes
transmit :: Pin -> String -> Arduino ()

-- | A simple demo driver. To run this example, you only need the Arduino
--   connected to your computer, no other hardware is needed. We use the
--   internal led on pin 13. Of course, you can attach a led to pin 13 as
--   well, for artistic effect.
--   
morseDemo :: IO ()
instance GHC.Show.Show System.Hardware.Arduino.SamplePrograms.Morse.Morse


-- | Basic demo of an Hitachi HD44780 LCD
module System.Hardware.Arduino.SamplePrograms.LCD

-- | Connections for a basic hitachi controller. See
--   <a>http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller</a> for
--   pin layout. For this demo, simply connect the LCD pins to the Arduino
--   as follows:
--   
--   <ul>
--   <li>LCD pin <tt>01</tt> to GND</li>
--   <li>LCD pin <tt>02</tt> to +5V</li>
--   <li>LCD pin <tt>03</tt> to a 10K potentiometer's viper</li>
--   <li>LCD pin <tt>04</tt> to Arduino pin <tt>12</tt></li>
--   <li>LCD pin <tt>05</tt> to GND</li>
--   <li>LCD pin <tt>06</tt> to Arduino pin <tt>11</tt></li>
--   <li>LCD pin <tt>11</tt> to Arduino pin <tt>5</tt></li>
--   <li>LCD pin <tt>12</tt> to Arduino pin <tt>4</tt></li>
--   <li>LCD pin <tt>13</tt> to Arduino pin <tt>3</tt></li>
--   <li>LCD pin <tt>14</tt> to Arduino pin <tt>2</tt></li>
--   <li>[If backlight is needed] LCD pin <tt>15</tt> to +5V</li>
--   <li>[If backlight is needed] LCD pin <tt>16</tt> to GND via 220ohm
--   resistor</li>
--   </ul>
--   
hitachi :: LCDController

-- | The happy glyph. See <a>lcdCreateSymbol</a> for details on how to
--   create new ones.
happy :: [String]

-- | The sad glyph. See <a>lcdCreateSymbol</a> for details on how to create
--   new ones.
sad :: [String]

-- | Access the LCD connected to Arduino, making it show messages we read
--   from the user and demonstrate other LCD control features offered by
--   hArduino.
lcdDemo :: IO ()


-- | Measuring distance using a HC-SR04 sensor. (Data sheet:
--   <a>http://www.micropik.com/PDF/HCSR04.pdf</a>.)
--   
--   NB. As of March 2 2013; StandardFirmata that's distributed with the
--   Arduino-App does <i>not</i> support the high accuracy pulse-in
--   command, which is needed for this sketch. However, there is a patch to
--   add this command; see:
--   <a>http://github.com/rwldrn/johnny-five/issues/18</a> for details on
--   how to install it. You <i>should</i> have this patched version of
--   Firmata running on your board for this sketch to function properly.
--   
--   Accuracy: Keep in mind that measurements on a platform like Arduino is
--   always subject to various errors. Relying on this program for precise
--   distance measurements would be a mistake. The results here should be
--   accurate to within about half-a-centimeter, provided you stay within
--   the range of HC-SR04, which is between 2 to 400 cm. For anything more
--   precise than this, you'll need to use a much more sensitive sensor.
module System.Hardware.Arduino.SamplePrograms.Distance

-- | Sound travels 343.2 meters per second
--   (<a>http://en.wikipedia.org/wiki/Speed_of_sound</a>). The echo time is
--   round-trip, from the sensor to the object and back. Thus, if echo is
--   high for <tt>d</tt> microseconds, then the distance in centimeters is:
--   
--   <pre>
--     d * 10^-6 * 343.2 * 10^2 / 2
--   = 1.716e-2 * d
--   
--   </pre>
microSecondsToCentimeters :: Int -> Float

-- | Measure and display the distance continuously, as reported by an
--   HC-SR04 sensor.
--   
--   Wiring: Simply connect VCC and GND of HC-SR04 to Arduino as usual. The
--   <tt>Echo</tt> line on the sensor is connected to Arduino pin 2. The
--   <tt>Trig</tt> line is connected on the board to the <tt>Echo</tt>
--   line, i.e., they both connect to the same pin on the Arduino. We also
--   have a led on pin 13 that we will light-up if the distance detected is
--   less than 5 centimeters, indicating an impending crash!
--   
distance :: IO ()


-- | Demonstrates using two push-buttons to count up and down.
module System.Hardware.Arduino.SamplePrograms.Counter

-- | Two push-button switches, controlling a counter value. We will
--   increment the counter if the first one (<tt>bUp</tt>) is pressed, and
--   decrement the value if the second one (<tt>bDown</tt>) is pressed. We
--   also have a led connected to pin 13 (either use the internal or
--   connect an external one), that we light up when the counter value is
--   0.
--   
--   Wiring is very simple: Up-button connected to pin 4, Down-button
--   connected to pin 2, and a led on pin 13.
--   
counter :: IO ()


-- | Reads the value of a push-button and displays it's status continuously
--   on the computer screen and by lighting a led on the Arduino as long as
--   the button is pressed.
module System.Hardware.Arduino.SamplePrograms.Button

-- | Read the value of a push-button (NO - normally open) connected to
--   input pin 2 on the Arduino. We will continuously monitor and print the
--   value as it changes. Also, we'll turn the led on pin 13 on when the
--   switch is pressed.
--   
--   The wiring is straightforward: Simply put a push-button between
--   digital input 2 and +5V, guarded by a 10K resistor:
--   
button :: IO ()


-- | The <i>hello world</i> of the arduino world, blinking the led.
module System.Hardware.Arduino.SamplePrograms.Blink

-- | Blink the led connected to port 13 on the Arduino UNO board.
--   
--   Note that you do not need any other components to run this example:
--   Just hook up your Arduino to the computer and make sure
--   StandardFirmata is running on it. However, you can connect a LED
--   between Pin13 and GND if you want to blink an external led as well, as
--   depicted below:
--   
blink :: IO ()


-- | Reads the value of an analog input, controlled by a 10K potentiometer.
module System.Hardware.Arduino.SamplePrograms.Analog

-- | Read the value of an analog input line. We will print the value on the
--   screen, and also blink a led on the Arduino based on the value. The
--   smaller the value, the faster the blink.
--   
--   The circuit simply has a 10K potentiometer between 5V and GND, with
--   the wiper line connected to analog input 3. We also have a led between
--   pin 13 and GND.
--   
analogVal :: IO ()


-- | Abstractions for shift-register IC parts.
module System.Hardware.Arduino.Parts.ShiftRegisters

-- | A shift-register class as supported by the hArduino library.
class ShiftRegister a

-- | Capacity
size :: ShiftRegister a => a -> Int

-- | Display name
name :: ShiftRegister a => a -> String

-- | Data sheet (typically a URL)
dataSheet :: ShiftRegister a => a -> String

-- | Initialize the shift-register
initialize :: ShiftRegister a => a -> Arduino ()

-- | Disable the output, putting it into high-impedance state
disable :: ShiftRegister a => a -> Arduino ()

-- | Enable the output, getting it out of the high-impedance state
enable :: ShiftRegister a => a -> Arduino ()

-- | Clear the contents
clear :: ShiftRegister a => a -> Arduino ()

-- | Push a single bit down the shift-register
push :: ShiftRegister a => a -> Bool -> Arduino ()

-- | Store the pushed-in values in the storage register
store :: ShiftRegister a => a -> Arduino ()

-- | Read the current value stored
read :: ShiftRegister a => a -> Arduino [Bool]

-- | The Texas-Instruments 74HC595 8-bit shift register with 3-state
--   outputs. Data sheet:
--   <a>http://www.ti.com/lit/ds/symlink/sn74hc595.pdf</a>.
--   
--   This is a versatile 8-bit shift-register with separate serial and
--   register clocks, allowing shifting to be done while the output remains
--   untouched. We model all control pins provided. Note that the enable
--   and clear lines are negated.
data SR_74HC595
SR_74HC595 :: Pin -> Pin -> Pin -> Pin -> Pin -> Maybe [Pin] -> SR_74HC595

-- | Chip Pin: 14: Serial input
[serial] :: SR_74HC595 -> Pin

-- | Chip Pin: 13: Negated output-enable
[nEnable] :: SR_74HC595 -> Pin

-- | Chip Pin: 12: Register clock, positive triggered
[rClock] :: SR_74HC595 -> Pin

-- | Chip Pin: 11: Serial clock, positive triggered
[sClock] :: SR_74HC595 -> Pin

-- | Chip Pin: 10: Negated clear-data
[nClear] :: SR_74HC595 -> Pin

-- | Chip Pins: 15, 1-7, and 8: Sequence of output bits, connect only if
--   reading is necessary
[mbBits] :: SR_74HC595 -> Maybe [Pin]
instance System.Hardware.Arduino.Parts.ShiftRegisters.ShiftRegister System.Hardware.Arduino.Parts.ShiftRegisters.SR_74HC595


-- | Control a single seven-segment display, echoing user's key presses on
--   it verbatim. We use a shift-register to reduce the number of pins we
--   need on the Arduino to control the display.
module System.Hardware.Arduino.SamplePrograms.SevenSegment

-- | Connections for the Texas Instruments 74HC595 shift-register.
--   Datasheet: <a>http://www.ti.com/lit/ds/symlink/sn74hc595.pdf</a>. In
--   our circuit, we merely use pins 8 thru 12 on the Arduino to control
--   the <a>serial</a>, <a>enable</a>, <a>rClock</a>, <a>sClock</a>, and
--   <a>nClear</a> lines, respectively. Since we do not need to read the
--   output of the shift-register, we leave the <a>mbBits</a> field
--   unconnected.
sr :: SR_74HC595

-- | Seven-segment display demo. For each key-press, we display an
--   equivalent pattern on the connected 7-segment-display. Note that most
--   characters are not-mappable, so we use approximations if available. We
--   use a shift-register to reduce the pin requirements on the Arduino,
--   setting the bits serially.
--   
--   Parts:
--   
--   <ul>
--   <li>The seven-segment digit we use is a common-cathode single-digit
--   display, such as TDSG5150
--   (<a>http://www.vishay.com/docs/83126/83126.pdf</a>), or Microvity's
--   IS121, but almost any such digit would do. Just pay attention to the
--   line-connections, and do not forget the limiting resistors: 220 ohm's
--   should do nicely.</li>
--   <li>The shift-register is Texas-Instruments 74HC595:
--   <a>http://www.ti.com/lit/ds/symlink/sn74hc595.pdf</a>. Make sure to
--   connect the register output lines to the seven-segment displays with
--   the corresponding letters. That is, shift-registers <tt>Q_A</tt>
--   (Chip-pin 15) should connect to segment <tt>A</tt>; <tt>Q_B</tt>
--   (Chip-pin 1) to segment <tt>B</tt>, and so on. We do not use the
--   shift-register <tt>Q_H'</tt> (Chip-pin 9) in this design.</li>
--   </ul>
--   
sevenSegment :: IO ()


-- | Abstractions for servo motors. See
--   <a>System.Hardware.Arduino.SamplePrograms.Servo</a> for example uses.
module System.Hardware.Arduino.Parts.Servo

-- | A servo motor. Note that this type is abstract, use <a>attach</a> to
--   create an instance.
data Servo

-- | Create a servo motor instance. The default values for the min/max
--   angle pulse-widths, while typical, may need to be adjusted based on
--   the specs of the actual servo motor. Check the data-sheet for your
--   servo to find the proper values. The default values of <tt>544</tt>
--   and <tt>2400</tt> microseconds are typical, so you might want to start
--   by passing <a>Nothing</a> for both parameters and adjusting as
--   necessary.
attach :: Pin -> Maybe Int -> Maybe Int -> Arduino Servo

-- | Set the angle of the servo. The argument should be a number between 0
--   and 180, indicating the desired angle setting in degrees.
setAngle :: Servo -> Int -> Arduino ()


-- | Demonstrates basic Servo motor control
module System.Hardware.Arduino.SamplePrograms.Servo

-- | Control a servo, by executing user requests of blade movement. We
--   allow 3 user commands:
--   
--   <ul>
--   <li><tt>l</tt> to swipe from angle-0 to 180;</li>
--   <li><tt>r</tt> to swipe from angle-180 to 0;</li>
--   <li>Or any number between <tt>0</tt> to <tt>180</tt>, which puts the
--   servo to the desired position.</li>
--   </ul>
--   
--   Almost any servo motor would work with this example, though you should
--   make sure to adjust min/max pulse durations in the <a>attach</a>
--   command to match the datasheet of the servo you have. In this example,
--   we have used the HS-55 feather servo
--   (<a>http://www.servocity.com/html/hs-55_sub-micro.html</a>), which has
--   the values 600 to 2400 micro-seconds.
--   
--   To connect the servo to the Arduino, simply connect the VCC (red) and
--   the GND (black) appropriately, and the signal line (white) to any
--   SERVO capable pin, in this example we're using pin number 9:
--   
servo :: IO ()

-- | Control a servo, as guided by the input read from a potentiometer. The
--   set-up is similar to the <a>servo</a> example above, except instead of
--   querying the user for the angle, we use the readings from a
--   potentiometer connected to analog input number 2. We used a 10 KOhm
--   potentiometer, but other pots would work just as well too:
--   
servoAnalog :: IO ()


-- | Abstractions for piezo speakers.
module System.Hardware.Arduino.Parts.Piezo

-- | A piezo speaker. Note that this type is abstract, use <a>speaker</a>
--   to create an instance.
data Piezo

-- | Create a piezo speaker instance.
speaker :: Int -> Pin -> Arduino Piezo

-- | Musical notes, notes around middle-C
data Note
A :: Note
B :: Note
C :: Note
D :: Note
E :: Note
F :: Note
G :: Note
R :: Note

-- | Beat counts
data Duration
Whole :: Duration
Half :: Duration
Quarter :: Duration
Eight :: Duration

-- | Play the given note for the duration
playNote :: Piezo -> (Note, Duration) -> Arduino ()

-- | Rest for a given duration:
rest :: Piezo -> Duration -> Arduino ()

-- | Turn the speaker off
silence :: Piezo -> Arduino ()

-- | Play a sequence of notes with given durations:
playNotes :: Piezo -> [(Note, Duration)] -> Arduino ()
instance GHC.Classes.Eq System.Hardware.Arduino.Parts.Piezo.Duration
instance GHC.Classes.Eq System.Hardware.Arduino.Parts.Piezo.Note
instance GHC.Show.Show System.Hardware.Arduino.Parts.Piezo.Duration
instance GHC.Show.Show System.Hardware.Arduino.Parts.Piezo.Note


-- | A (pretty bad!) rendering of Jingle Bells on a piezo speaker
module System.Hardware.Arduino.SamplePrograms.JingleBells

-- | Notes for jingle-bells. Expecting a nice rendering from this encoding
--   on a piezo speaker would be naive.. However, it's still recognizable!
jingleBells :: [(Note, Duration)]

-- | Play the jingle-bells on a PWM line, attached to pin 3. We use a tempo
--   of <tt>75</tt>; which is fairly fast. For a slower rendring try
--   <tt>150</tt> or higher values.
--   
--   The circuit simple has a piezo speaker attached to pin 3.
--   
main :: IO ()


-- | Models of various Hardware components
module System.Hardware.Arduino.Parts
