I wrote a test program in Haskell on the Raspberry Pi that plays a delightful tune on a buzzer connected to a GPIO pin.
Here are the imports I used:
import qualified Control.Concurrent as C
import qualified Control.Monad as M
import System.IO
import qualified System.Posix.Unistd as P
Here are the functions that toggle the pin by writing to the /sys/class/gpio/gpio16/value file:
changePin2 :: Handle -> String -> Int -> IO ()
changePin2 handle onOff delay = do
pos <- hGetPosn handle
hPutStr handle (onOff ++ "\n")
hFlush handle
hSetPosn pos
P.usleep delay
--C.threadDelay delay
blinkOn2 :: Handle -> Int -> IO ()
blinkOn2 handle delay = do
changePin2 handle "1" delay
changePin2 handle "0" delay
finally, here is an example of playing one note with a pause before the next one:
mapM_ (blinkOn2 h) (replicate 26 1908)
P.usleep 50000
-- C.threadDelay 50000
When I first tried it, I used threadDelay and it sounded terrible. It was low pitched, suggesting the delay was longer than expected and all notes sounded more or less the same. Using the usleep function improved things considerably. Finally, adding the -threaded option when compiling with ghc made the sound even cleaner.
ghc -threaded buzzer1t.hs
I do not understand why either of these improved it and if anyone knows it would help greatly.
googling seems to reveal that usleep and friends are delays at the OS level whereas threadDelay only pertains to the thread in the Haskell program itself. threadDelay also seems like the more recommended one and considered better practice even though in this case usleep is clearly superior.