2014-11-08 42 views
3

我想在Haskell(Haskell中的第一個嚴肅的程序)中編寫一個命令行實用程序來查詢通過串行端口連接到arduino的傳感器。代碼的相關部分如下:神祕的串行端口行爲

-- Read a single reading from the serial port 
recursiveread :: SerialPort -> B.ByteString -> IO B.ByteString 
recursiveread s acc sent = do 
    recd <- recv s 1000 
    if ((B.pack "Done\r\n") `B.isSuffixOf` acc) 
     then return acc 
     else recursiveread s $ B.append acc recd 

-- Read a single reading from the serial port 
getSingleRead :: FilePath -> IO [String] 
getSingleRead path = do 
    s <- openSerial path defaultSerialSettings 
    send s $ B.pack "1" 
    acc <- recursiveread s B.empty 
    closeSerial s 
    return $ (lines . B.unpack) acc 


-- Checks if the filepath exists, and prints a single reading 
readspr :: [FilePath] -> IO() 
readspr [path] = do 
    exists <- doesFileExist path 
    case exists of 
     False -> putStrLn "No device found" 
     True -> getSingleRead path >>= (mapM_ putStrLn) 

調度功能(未示出)調用readspr並使用"/dev/cu.modem1421"作爲參數。 我懷疑的問題與評估順序有關。預期的行爲是爲接收這樣的數據,這是我檢查「完成」的幀作爲終止子:

T: 33697 
Data 
0:3.2967772483 
1:3.2967772483 
2:3.2967772483 
... 
126:3.2967772483 
127:3.2967772483 
Done 

這裏的問題是:

1)當我本身後運行該代碼編譯,從Bash - 該程序計算一秒鐘並掛起 - 沒有輸出。 2)但是,當我進入ghci並與openSerial :: FilePath -> SerialPort命令打開一個串行端口,然後在Bash運行程序我看到預期的輸出。 (我不應該得到資源忙不過來了什麼如果我使用screen打開連接我得到這個錯誤?)

此行爲是重複的 - 我可以在ghcicloseSerial,並返回到在Bash中沒有輸出。

此前的研究/其他背景:

我使用System.Hardware.SerialPort庫(的SerialPort-0.4.7:在陰謀跨平臺的串行端口庫)的OS X的機器上。有一個與OS X上的串口阻塞/非阻塞性質有關的問題,與UNIX標準-Issue 13 on Github for serialport-0.4.7不一致。但是,我無法理解這一點。高度讚賞任何幫助理解這個問題。這是我對哈斯克爾懶惰的誤讀問題,還是我在評估的順序上錯過了一些東西,在我完全閱讀之前或者在圖書館閱讀之前,端口被關閉了? (在這種情況下,我應該張貼在Github的頁面上?)

進一步的研究:(案件告破)

這裏的問題 - 串行連接打開時Arduino的復位(可以被禁用)。當我打開與程序的連接時,它會在啓動之前從主機接收通信。在兩個獨立的案例中觀察Arduino上的LED時我注意到了這一點 - 打開(並保持)端口ghc允許在第二次讀取和讀取之間有足夠的時間。

解決的辦法是在打開端口後延遲幾秒 - 現在「它正常工作」!

+0

'defaultSerialSettings'是否完全符合您的設備需求? (速度,數據位,停止位,奇偶校驗等) [對於我的Minitel項目,我使用隊列設置了兩個線程](https://github.com/Zigazou/HaMinitel/blob/master/src/Minitel/Minitel.hs),超時時間爲10,而不是0.1。這允許我進行阻塞和非阻塞讀/寫(它在源代碼的末尾)。 – zigazou 2014-11-08 05:34:06

+1

這是一個黑暗的鏡頭,但它可能是串行端口庫需要線程運行時?你有沒有嘗試編譯與螺紋? – gspr 2014-11-08 10:22:23

+0

您是否介意將您的解決方案作爲答案發布?這樣它可以記錄在適合後代的地方。 – sclv 2016-03-13 21:37:32

回答

1

回答更新的後人: 進一步研究:(案件告破)

這裏的問題 - 串行連接打開時Arduino的復位(可以被禁用)。當我打開與程序的連接時,它會在啓動之前從主機接收通信。我注意到,在兩種不同的情況下觀察Arduino上的LED時 - 在ghc中打開(並保持)端口允許有足夠的時間在第二次打開和讀取之間流逝。

解決的辦法是在打開端口後延遲幾秒 - 現在「它正常工作」!