2015-07-28 2 views
0

Я пытаюсь получить данные от моего Arduino Serial.println("No Format");. Когда я открываю arduino-serial-monitor, я могу видеть результат, как я этого хотел.Haskell: Последовательные принятые данные неверно напечатаны

No Format 
No Format 
... 

Я использую serialport package. Но выход напечатанный на GHCI является:

*Main> main 
"\r\nNo Forma" 
"t\r\nNo Form" 
"at\r\nNo For" 
"mat\r\nNo Fo" 
"rmat\r\nNo F" 
"ormat\r\nNo " 
"Format\r\nNo" 
" Format\r\nN" 
"o Format\r\n" 
... 
... 
"\nNo" 
" For" 
"mat\r" 
"\nNo " 
"Form" 
"at\r\n" 
.... 

Haskell:

import qualified Data.ByteString.Char8 as B 
import System.Hardware.Serialport 
import System.IO 
import Control.Monad 

main :: IO() 
main = forever $ do 
    let port = "/dev/ttyACM0" 
    s <- openSerial port SerialPortSettings { commSpeed = CS9600, 
              bitsPerWord = 8, 
              stopb = One, 
              parity = NoParity, 
              flowControl = NoFlowControl, 
              timeout = 10 } 
    recv s 10 >>= print 
    closeSerial s 

Arduino:

void setup() { 
    Serial.begin(9600); 
} 

void loop() { 
    Serial.println("No Format"); 
} 

Любая помощь будет удивительным. Благодарю.

+2

Попробуйте использовать 'putStr' вместо' print'. Вам также может потребоваться сбросить стандартный вывод или изменить режим буферизации на 'LineBuffering' – pat

+0

Также вы открываете и закрываете последовательный порт для каждых 10 символов. Это действительно то, что вы хотите сделать? – pat

+0

@pat: Ваш второй комментарий правильный. «\ r \ nNo Forma» действительно является байтовой строкой длины 10. Возможно, байтовая строка должна быть проанализирована в строку (возможно, даже с использованием страшного Data.ByteString.Char8, в зависимости от потребности) – Sarah

ответ

0

Использование B.putStr вместо print устранено. Благодаря @pat.

2

Вы можете просто получить символы, пока не получите символ «\ n». Возможно, что-то вроде этого:

import Control.Monad (forever) 
import Control.Applicative ((<$>)) 
import Data.ByteString.Char8 (unpack) 
import System.Hardware.Serialport (SerialPort, openSerial, recv) 

-- Read a character from the serial port. 
receive :: SerialPort -> IO String 
receive sp = fmap unpack (recv sp 1) 

-- Read a line, ending with '\n'. 
readLine :: SerialPort -> IO String 
readLine sp = readLineRec sp [] 

-- Recursive function to read a line from the serial port. 
readLineRec :: SerialPort -> String -> IO String 
readLineRec sp [] = receive sp >>= readLineRec sp 
readLineRec sp chars 
    | last chars == '\n' = return chars 
    | otherwise = (chars ++) <$> receive sp >>= readLineRec sp 

main = do 
    let port = "/dev/ttyACM0" 
    s <- openSerial port SerialPortSettings { commSpeed = CS9600, 
             bitsPerWord = 8, 
             stopb = One, 
             parity = NoParity, 
             flowControl = NoFlowControl, 
             timeout = 10 } 
    forever $ do 
     line <- readLine s 
     print line 

Существует возможность для улучшения, но это работает!

+0

Спасибо Эли. Это, безусловно, очень полезный ответ. –