Stability | experimental |
---|---|
Maintainer | erkokl@gmail.com |
Safe Haskell | None |
(The hArduino library is hosted at http://leventerkok.github.com/hArduino/. Comments, bug reports, and patches are always welcome.)
hArduino: Control Arduino from Haskell, using the Firmata protocol.
The hArduino library allows construction of Haskell programs that control Arduino boards that are running the (freely available) Firmata program. Note that hArduino does not allow you to run arbitrary Haskell code on the Arduino! It simply allows you to control a board from Haskell, where you can exchange information with the board, send/receive commands from other peripherals connected, etc.
See http://www.youtube.com/watch?v=PPa3im44t2g for a short video (4m29s) of the blink example.
- withArduino :: Bool -> FilePath -> Arduino () -> IO ()
- data Arduino a
- queryFirmware :: Arduino (Word8, Word8, String)
- pin :: Word8 -> Pin
- data Pin
- data PinMode
- setPinMode :: Pin -> PinMode -> Arduino ()
- digitalWrite :: Pin -> Bool -> Arduino ()
- digitalRead :: Pin -> Arduino Bool
- pullUpResistor :: Pin -> Bool -> Arduino ()
- waitFor :: Pin -> Arduino Bool
- waitAny :: [Pin] -> Arduino [Bool]
- waitAnyHigh :: [Pin] -> Arduino [Bool]
- waitAnyLow :: [Pin] -> Arduino [Bool]
- setAnalogSamplingInterval :: Int -> Arduino ()
- analogRead :: Pin -> Arduino Int
- delay :: Int -> Arduino ()
Running the controller
:: Bool | If |
-> FilePath | Path to the USB port |
-> Arduino () | The Haskell controller program to run |
-> IO () |
Run the Haskell program to control the board:
- The file path argument should point to the device file that is
associated with the board. (
COM1
on Windows, '/dev/cu.usbmodemfd131' on Mac, etc.) - The boolean argument controls verbosity. It should remain
False
unless you have communication issues. The print-out is typically less-than-useful, but it might point to the root cause of the problem.
See System.Hardware.Arduino.Examples.Blink for a simple example.
The Arduino monad.
Programming the Arduino
Basic handshake with the board
queryFirmware :: Arduino (Word8, Word8, String)Source
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.
Accessing pins
The mode for a pin.
setPinMode :: Pin -> PinMode -> Arduino ()Source
Set the mode on a particular pin on the board
Digital I/O
Writing digital values
digitalWrite :: Pin -> Bool -> Arduino ()Source
Set or clear a digital pin on the board
Reading digital values
digitalRead :: Pin -> Arduino BoolSource
Read the value of a pin in digital mode; this is a non-blocking call, returning
the current value immediately. See waitFor
for a version that waits for a change
in the pin first.
pullUpResistor :: Pin -> Bool -> Arduino ()Source
Turn on/off internal pull-up resistor on an input pin
waitFor :: Pin -> Arduino BoolSource
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 digitalRead
, which returns the current
value of a pin immediately.
waitAny :: [Pin] -> Arduino [Bool]Source
Wait for a change in any of the given pins. Once a change is detected, all the new values are
returned. Similar to waitFor
, but is useful when we are watching multiple digital inputs.
waitAnyHigh :: [Pin] -> Arduino [Bool]Source
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.
waitAnyLow :: [Pin] -> Arduino [Bool]Source
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.
Analog Communication
Setting up sampling interval
setAnalogSamplingInterval :: Int -> Arduino ()Source
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 10
and 16384
; 10
being the minumum sampling interval supported by Arduino
and 16383
being the largest value we can represent in 14 bits that this message can handle. (Note that
the largest value is just about 16
seconds, which is plenty infrequent for all practical needs.)
Reading analog values
analogRead :: Pin -> Arduino IntSource
Read the value of a pin in analog mode; this is a non-blocking call, immediately
returning the last sampled value. It returns 0
if the voltage on the pin
is 0V, and 1023
if it is 5V, properly scaled. (See setAnalogSamplingInterval
for
sampling frequency.)