2014-11-08 73 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中打开(并保持)端口允许有足够的时间在第二次打开和读取之间流逝。

解决的办法是在打开端口后延迟几秒 - 现在“它正常工作”!