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.

Programming the Arduino

Pins

Declare an analog pin on the board. For instance, to refer to analog pin no 0
simply use analog0.

Note that analog0 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 pin for pin mappings.)

Declare a pin by its index. For maximum portability, prefer digital
and analog 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.

Analog input

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.)

Programming with triggers

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.

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.

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.

Receiving and sending pulses

Send down a pulse, and measure how long the pin reports a corresponding pulse, with a potential time-out. The call pulse p v duration mbTimeOut
does the following:

Set the pin to value v for duration microseconds.

Waits 2 microseconds

Waits until pin p has value not v.

Returns, in micro-seconds, the duration the pin stayed v, counting from the 2 microsecond wait.

Time-out parameter is used as follows:

If mbTimeOut is Nothing, then pulse 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.

If mbTimeOut is Just t then, pulse will stop if the above procedure does not complete within the given micro-seconds.
In this case, the overall return value is Nothing.

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 not support the Pulse-In command.
However, there is a patch to add this command; see: http://github.com/rwldrn/johnny-five/issues/18 for details.
If you want to use hArduino's pulseIn command, then you have to install the above patch. Also see the function
pulseIn_hostOnly, 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.

A hostOnly 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 not be accurate, and should not
be expected to work uniformly over different boards. Similar comments apply for pulseOut_hostTiming
as well. See the function pulse for a more accurate version.

A hostOnly 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 not be accurate, and should not
be expected to work uniformly over different boards. Similar comments apply for pulseIn_hostTiming
as well. See the function pulse for a more accurate version.

Misc utilities

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.)