我在 Raspberry Pi 上用 Haskell 编写了一个测试程序,它在连接到 GPIO 引脚的蜂鸣器上播放令人愉悦的曲调。
这是我使用的导入:
import qualified Control.Concurrent as C
import qualified Control.Monad as M
import System.IO
import qualified System.Posix.Unistd as P
以下是通过写入 /sys/class/gpio/gpio16/value 文件来切换引脚的函数:
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
最后,这是一个在下一个音符之前暂停播放一个音符的示例:
mapM_ (blinkOn2 h) (replicate 26 1908)
P.usleep 50000
-- C.threadDelay 50000
当我第一次尝试它时,我使用了 threadDelay,它听起来很糟糕。它的音调很低,表明延迟比预期的要长,所有音符听起来都差不多。使用 usleep 功能大大改善了事情。最后,在使用 ghc 编译时添加 -thread 选项使声音更加清晰。
ghc -threaded buzzer1t.hs
我不明白为什么其中任何一个都对其进行了改进,如果有人知道这将有很大帮助。
谷歌搜索似乎表明 usleep 和朋友是操作系统级别的延迟,而 threadDelay 仅与 Haskell 程序本身中的线程有关。threadDelay 似乎也是更推荐的一种,并且被认为是更好的做法,尽管在这种情况下 usleep 显然更好。