Mysterious Serial Port Behavior

I am trying to write a command line utility in Haskell (the first serious program in Haskell) to request a sensor connected to an arduino via a serial port. The relevant part of the code looks like this:

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

      

A send function (not shown) calls readspr

and uses a parameter "/dev/cu.modem1421"

as a parameter. The problem I suspect is related to the order of evaluation. The expected behavior is to get a dataframe like this, which I check for "Done" as a terminator:

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

      

Here's the problem:

1) When I run this code myself after compilation, from Bash - the program calculates the second and hangs - no output. 2) However, when I go to ghci

and open the serial port with a command openSerial :: FilePath -> SerialPort

and then run the program in Bash , I see the expected output. (Shouldn't I be downloading a resource here or something? If I open a connection using screen

, I get this error)

This behavior is repeated - I can closeSerial

in ghci

and back to output without output to Bash.

Previous research / additional information:

I am using the library System.Hardware.SerialPort

(serialport-0.4.7: cross-platform serial port library in cabal) on an OS X machine. There is an issue related to the blocking / non-blocking nature of the serial port on OS X which is contrary to the UNIX standard - Issue 13 in Github for serialport -0.4.7 . However, I cannot figure it out. Any help in understanding this issue is highly appreciated. Is this a problem with my misunderstanding of Haskell lies, or am I missing something in the order of evaluation when the port is closed before I can read it in full or with the library? (in which case should I post it to the Github page?)

Further research: (the issue is being resolved)

Here's the problem - Arduino resets when opening serial connection (can be disconnected). When I opened a connection to the program, it will receive a message from the host before it loads. I noticed this while watching the LEDs on the Arduino on two separate occasions - opening (and holding) the port in ghc

allowed enough time to elapse between the second opening and reading.

The solution was to add a couple of seconds delay after opening the port - now "it just works"!

+3


source to share


1 answer


Answer updated for posterity: Further research: (resolved)

Here's the problem - Arduino resets when opening serial connection (can be disconnected). When I opened a connection to the program, it will receive a message from the host before it loads. I noticed this when observing the LEDs on the Arduino on two separate occasions - opening (and holding) the port in the ghc allowed enough time to elapse between the second open and read.



The solution was to add a couple of seconds delay after opening the port - now "it just works"!

+1


source







All Articles