Serial Communications in Haskell

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Serial Communications in Haskell

Ronald Guida
I'm on a Windows box and I'm looking for a way to talk to a serial
port (for example, RS-232) from Haskell.  I couldn't find a library to
do this, so I am wondering how to create one.

I have a fairly thorough understanding of how to open and use a serial
port with the Windows API.  In particular, to open a serial port, I
have to use CreateFile, which is the same API call that opens files.
In fact, if I call openFile from GHC, and pass "COM1:" as the
filename, then I can get a writable serial port.

 > module Serial
 >     where
 > import System.IO
 >
 > main = do
 >   h <- openFile "COM1:" ReadWriteMode
 >   hPutStrLn h "Hello World"

I can't read from the port (I always get an immediate EOF), and I have
no way of configuring things like the baud rate or the parity
settings.  Nevertheless, this demonstrates that openFile can at least
open the serial port.

What I would like to do is create some functions that would allow me
to open and configure a serial port, and get a Handle back so that I
can use the existing IO functions like hGetChar and hPutChar.  I am
assuming that hGetChar eventually calls win32::ReadFile and hPutChar
eventually calls win32::WriteFile.  These same two API calls would
work for serial ports.

In Windows, there are 23 API functions that apply specifically to
serial ports.  Out of these 23 functions, only a few of them are
actually necessary if I just want to send and receive data.

Of course, I don't know how to call Windows API functions from Haskell,
and I have no idea how to hook things to the IO library so that I can
use a Handle for a serial port.  I'm looking for some advice on how to
proceed.

-- Ron

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Mitar
Hi!

> Of course, I don't know how to call Windows API functions from Haskell,
> and I have no idea how to hook things to the IO library so that I can
> use a Handle for a serial port.  I'm looking for some advice on how to
> proceed.

You can check how I did this in my Lego Mindstorms NXT interface,
pre-beta version:

http://www.forzanka.si/files/NXT.tgz

It is for UNIX (POSIX?) systems but I had similar problems so I had to
use FFI (foreign function interface) to setup a link. You will
probably just have to replace that with Windows API calls. I hope.


Mitar
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Esa Ilari Vuokko
In reply to this post by Ronald Guida
On 8/29/07, Ronald Guida <[hidden email]> wrote:
> I'm on a Windows box and I'm looking for a way to talk to a serial
> port (for example, RS-232) from Haskell.  I couldn't find a library to
> do this, so I am wondering how to create one.
>
> I have a fairly thorough understanding of how to open and use a serial
> port with the Windows API.  In particular, to open a serial port, I

At the moment, I think it is easier to just use the same Windows API directly,
rather than try to bend GHC's IO system to do it "right".

> have to use CreateFile, which is the same API call that opens files.
> In fact, if I call openFile from GHC, and pass "COM1:" as the
> filename, then I can get a writable serial port.
>
>  > module Serial
>  >     where
>  > import System.IO
>  >
>  > main = do
>  >   h <- openFile "COM1:" ReadWriteMode
>  >   hPutStrLn h "Hello World"
>
> I can't read from the port (I always get an immediate EOF), and I have
> no way of configuring things like the baud rate or the parity
> settings.  Nevertheless, this demonstrates that openFile can at least
> open the serial port.
>
> What I would like to do is create some functions that would allow me
> to open and configure a serial port, and get a Handle back so that I
> can use the existing IO functions like hGetChar and hPutChar.  I am
> assuming that hGetChar eventually calls win32::ReadFile and hPutChar
> eventually calls win32::WriteFile.  These same two API calls would
> work for serial ports.

Unfortunately, it goes via extra hoops and uses c runtime instead of
Windows API directly.  This extra layer makes sure it's hard to predict
exactly what gets done (and with what options) sometimes.

And even if it did, it'd probably use overlapping io, does that work with
COM ports?

> In Windows, there are 23 API functions that apply specifically to
> serial ports.  Out of these 23 functions, only a few of them are
> actually necessary if I just want to send and receive data.
>
> Of course, I don't know how to call Windows API functions from Haskell,
> and I have no idea how to hook things to the IO library so that I can
> use a Handle for a serial port.  I'm looking for some advice on how to
> proceed.

I haven't done much work on COM ports, but the little I did, I used bindings
in Win32 and probably some of my own, and didn't use System.IO/Handle
at all.  Maybe problems with GHC's IO system are easy to solve, but I have
no idea and wasn't inclined to find out.

Best regards,
Esa
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Bas van Dijk-2
On 8/29/07, Esa Ilari Vuokko <[hidden email]> wrote:

> On 8/29/07, Ronald Guida <[hidden email]> wrote:
> > I'm on a Windows box and I'm looking for a way to talk to a serial
> > port (for example, RS-232) from Haskell.  I couldn't find a library to
> > do this, so I am wondering how to create one.
> >
> > I have a fairly thorough understanding of how to open and use a serial
> > port with the Windows API.  In particular, to open a serial port, I
>
> At the moment, I think it is easier to just use the same Windows API directly,
> rather than try to bend GHC's IO system to do it "right".
>
> > have to use CreateFile, which is the same API call that opens files.
> > In fact, if I call openFile from GHC, and pass "COM1:" as the
> > filename, then I can get a writable serial port.
> >
> >  > module Serial
> >  >     where
> >  > import System.IO
> >  >
> >  > main = do
> >  >   h <- openFile "COM1:" ReadWriteMode
> >  >   hPutStrLn h "Hello World"
> >
> > I can't read from the port (I always get an immediate EOF), and I have
> > no way of configuring things like the baud rate or the parity
> > settings.  Nevertheless, this demonstrates that openFile can at least
> > open the serial port.
> >
> > What I would like to do is create some functions that would allow me
> > to open and configure a serial port, and get a Handle back so that I
> > can use the existing IO functions like hGetChar and hPutChar.  I am
> > assuming that hGetChar eventually calls win32::ReadFile and hPutChar
> > eventually calls win32::WriteFile.  These same two API calls would
> > work for serial ports.
>
> Unfortunately, it goes via extra hoops and uses c runtime instead of
> Windows API directly.  This extra layer makes sure it's hard to predict
> exactly what gets done (and with what options) sometimes.
>
> And even if it did, it'd probably use overlapping io, does that work with
> COM ports?
>
> > In Windows, there are 23 API functions that apply specifically to
> > serial ports.  Out of these 23 functions, only a few of them are
> > actually necessary if I just want to send and receive data.
> >
> > Of course, I don't know how to call Windows API functions from Haskell,
> > and I have no idea how to hook things to the IO library so that I can
> > use a Handle for a serial port.  I'm looking for some advice on how to
> > proceed.
>
> I haven't done much work on COM ports, but the little I did, I used bindings
> in Win32 and probably some of my own, and didn't use System.IO/Handle
> at all.  Maybe problems with GHC's IO system are easy to solve, but I have
> no idea and wasn't inclined to find out.
>
> Best regards,
> Esa
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

Ideally, we would have something like pyserial (
http://pyserial.sourceforge.net ) for Haskell. It provides a nice
portable abstraction over serial communication. See for example the
windows binding:

http://pyserial.cvs.sourceforge.net/pyserial/pyserial/serial/serialwin32.py?view=markup

regards,

Bas van Dijk
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Donald Bruce Stewart
In reply to this post by Mitar
mmitar:

> Hi!
>
> > Of course, I don't know how to call Windows API functions from Haskell,
> > and I have no idea how to hook things to the IO library so that I can
> > use a Handle for a serial port.  I'm looking for some advice on how to
> > proceed.
>
> You can check how I did this in my Lego Mindstorms NXT interface,
> pre-beta version:
>
> http://www.forzanka.si/files/NXT.tgz
>
> It is for UNIX (POSIX?) systems but I had similar problems so I had to
> use FFI (foreign function interface) to setup a link. You will
> probably just have to replace that with Windows API calls. I hope.
>

That's really cool! I hope you can upload this to hackage soon.

-- Don
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Mitar
Hi!

> > You can check how I did this in my Lego Mindstorms NXT interface,
> > pre-beta version:
> >
> > http://www.forzanka.si/files/NXT.tgz
>
> That's really cool! I hope you can upload this to hackage soon.

I do not think it is ready yet. It is working but it is missing
extensive testing (making some bigger programs in practice, to see how
it behaves and to see if the API is sane) and of course documentation
(how to use it, examples, tutorials ...). I will continue with this
project in a few months.

(The main reason is that I do not have any experience with Hackage and
Cabal nor I have time now for this. But if anybody wants to help ...)

I am using it in my AI robot research project where I am using Lego
Mindstorms NXT unit and communicating with it over Bluetooth. And the
AI is made in Haskell. :-)


Mitar
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Serial Communications in Haskell

Ronald Guida
In reply to this post by Ronald Guida
On 8/28/07, Ronald Guida wrote:
 > I'm on a Windows box and I'm looking for a way to talk to a serial
 > port (for example, RS-232) from Haskell.  I couldn't find a library to
 > do this, so I am wondering how to create one.

I figured out FFI and marshaling, and I got my serial port to work in
Haskell.  See http://ronguida.home.mindspring.com/ for a simple
demonstration.  To test this program, I connected my COM1 and COM2
ports with a null-modem cable and I used Hyperterminal to talk to
COM2.

The demo only does a few things: open a serial port, configure it,
write to it, and read from it.

I have some questions regarding this demonstration:

1. In the DCB and COMMTIMEOUTS datatypes and their marshaling code,
   is it better to convert Win32 datatypes to Haskell equivalents
   (e.g. DWORD to Int), like I did with DCB, or is it better to leave
   things in machine types like I did with COMMTIMEOUTS (e.g. DWORD to
   Word32) ?

2. Can anyone tell me whether I am making proper use of
   unsafeInterleaveIO in my implementation of getContentsSerialPort?

I am interested in creating a library for serial ports under Win32,
and I'm wondering, how should I proceed?

-- Ron

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe