Serial port access with CLisp and Windows

383 views
Skip to first unread message

Joe Driscoll

unread,
Feb 21, 2004, 8:32:22 PM2/21/04
to
Hello,

Has anyone successfully been able to use the serial (COM) ports of a Windows
machine under CLisp (or some other free Lisp)? I'd need both input and
output modes. Is there sample code available?

Thanks,
Joe


Pascal Bourguignon

unread,
Feb 21, 2004, 10:10:21 PM2/21/04
to
"Joe Driscoll" <drisc...@comcast.net> writes:


Well, under unix I'd do:

(with-open-file (serial "/dev/ttyS0" :direction :inout)
(format serial "ATZ~%")
(format t (read-line serial)))

So I suppose that under MS-Windows you could do:

(with-open-file (serial "COM:" :direction :inout)
(format serial "ATZ~%")
(format t (read-line serial)))


--
__Pascal_Bourguignon__ http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/

Joe Driscoll

unread,
Feb 21, 2004, 11:43:39 PM2/21/04
to
Thanks for the quick reply. I tried this, but it didn't work:

[5]> (with-open-file (serial "COM1" :direction :io)


(format serial "ATZ~%")
(format t (read-line serial)))

*** - EVAL: variable L has no value
The following restarts are available:
STORE-VALUE :R1 You may input a new value for L.
USE-VALUE :R2 You may input a value to be used instead of L.

I don't think "serial" is defined in my CLisp. Any suggestions? Has anyone
done this in Windows?

"Pascal Bourguignon" <sp...@thalassa.informatimago.com> wrote in message
news:87vflz7...@thalassa.informatimago.com...

Greg Menke

unread,
Feb 21, 2004, 11:46:51 PM2/21/04
to
Pascal Bourguignon <sp...@thalassa.informatimago.com> writes:

> "Joe Driscoll" <drisc...@comcast.net> writes:
>
> > Hello,
> >
> > Has anyone successfully been able to use the serial (COM) ports of a Windows
> > machine under CLisp (or some other free Lisp)? I'd need both input and
> > output modes. Is there sample code available?
>
>
> Well, under unix I'd do:
>
> (with-open-file (serial "/dev/ttyS0" :direction :inout)
> (format serial "ATZ~%")
> (format t (read-line serial)))
>
> So I suppose that under MS-Windows you could do:
>
> (with-open-file (serial "COM:" :direction :inout)
> (format serial "ATZ~%")
> (format t (read-line serial)))
>

Probably not, Windows likes to pretend it has a generic I/O interface,
but it doesn't really. I think he's going to be stuck using the Win32
functions just like he would in C or C++. That is, unless Clisp has
done a bunch of work to bury the weirdness.

Gregm

Sam Steingold

unread,
Feb 22, 2004, 12:58:21 AM2/22/04
to Joe Driscoll
> * Joe Driscoll <qevfp...@pbzpnfg.arg> [2004-02-21 22:43:39 -0600]:

>
> Thanks for the quick reply. I tried this, but it didn't work:
>
> [5]> (with-open-file (serial "COM1" :direction :io)
> (format serial "ATZ~%")
> (format t (read-line serial)))
>
> *** - EVAL: variable L has no value
> The following restarts are available:
> STORE-VALUE :R1 You may input a new value for L.
> USE-VALUE :R2 You may input a value to be used instead of L.

this is what you _SOMETIMES_ get when you cut and paste into the
console. try Emacs instead
the form is correct, but you have to edit out the spurious "L" which
was planted there during the cut and paste process.

> I don't think "serial" is defined in my CLisp. Any suggestions? Has
> anyone done this in Windows?

variable `serial' is bound by `with-open-file'
<http://www.lisp.org/HyperSpec/Body/mac_with-open-file.html>.

--
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
There is an exception to every rule, including this one.

Joe Driscoll

unread,
Feb 22, 2004, 9:27:11 AM2/22/04
to
Thanks, I typed it in manually and no longer got that error. However, it
just hangs now.

Here's a transcript of what I was trying before. I open and close the
stream, just to see if that works. Then I open it again, print a character
to it, then try to read from it. But this also hangs, and I have to ctrl-c
out of it. I'm not certain if the character I sent out is even being sent.
I'm pretty sure that the port is really opened, since a separate terminal
program (hyperterminal) can't access the port until the "close" instruction
is used in CLisp.

[9]> (setf sers (open "COM1" :direction :io))
#<IO UNBUFFERED FILE-STREAM CHARACTER #P"COM1" @1>
[10]> (close sers)
T
[11]> (setf sers (open "COM1" :direction :io))
#<IO UNBUFFERED FILE-STREAM CHARACTER #P"COM1" @1>
[12]> (print 'e sers)
E
[13]> (read sers)

*** - READ: Ctrl-C: User break
Break 1 [14]>


"Sam Steingold" <s...@gnu.org> wrote in message news:uhdxj3...@gnu.org...

Constantine Vetoshev

unread,
Feb 22, 2004, 11:32:04 AM2/22/04
to
"Joe Driscoll" <drisc...@comcast.net> writes:

> Thanks, I typed it in manually and no longer got that error. However, it
> just hangs now.

...

> [11]> (setf sers (open "COM1" :direction :io))
> #<IO UNBUFFERED FILE-STREAM CHARACTER #P"COM1" @1>
> [12]> (print 'e sers)
> E
> [13]> (read sers)
>
> *** - READ: Ctrl-C: User break

Disclaimer: I have never written hardware access code in Lisp or any
other language, so I'm only theorizing here.

Is anything actually writing to the COM port? First, the read function
blocks until it finds input. Second, read gives you access to the Lisp
reader. If the device you connected to the COM port writes arbitrary
data, the data may never terminate in a way the reader understands
(end of line and end of file characters). If the device continually
writes to the port, try using read-char-no-hang to pluck out one
character from the stream. To interact with an arbitrary device, you
probably need to use read-byte or read-sequence.

--
Regards,
Constantine Vetoshev
(reverse (concatenate 'string "m" "o" "c" "." "o" "o" "h" "a" "y" "@"
"v" "c" "d" "r" "a" "p" "e" "g"))

Sam Steingold

unread,
Feb 22, 2004, 12:45:56 PM2/22/04
to Joe Driscoll
> * Joe Driscoll <qevfp...@pbzpnfg.arg> [2004-02-22 08:27:11 -0600]:

>
> [12]> (print 'e sers)
> E
> [13]> (read sers)
>
> *** - READ: Ctrl-C: User break
> Break 1 [14]>

please read PRINT and READ documentation.
<http://www.lisp.org/HyperSpec/Body/fun_readcm_re_g-whitespace.html>
<http://www.lisp.org/HyperSpec/Body/fun_writecm_p_rintcm_princ.html>

These are probably not the functions you want when talking to a
specialized device.

please try

(write-line "ATZ" serial) ; or whatever _command_ the device understands
note that WRITE-LINE will write a Newline - which you probably do need.
(this is why I wrote WRITE-LINE and not WRITE-STRING!)

and then

(let ((v (make-array 10 :fill-pointer 0 :adjustable t
:element-type 'character)))
(loop :while (listen serial)
:do (vector-push-extend (read-char serial) v))
v)

equivalent:

(with-output-to-string (s)
(loop :while (listen serial)
:do (write-char (read-char serial) s)))

or

(with-output-to-string (s)
(loop :for c = (read-char-no-hang serial) :while c
:do (write-char c s)))

please read CLHS on all the functions and macros I mentioned.


alas, I read c.l.l only on weekends (no nntp at work), so if you want a
response from me soon, please use clisp-list (http://clisp.cons.org).

Programming is like sex: one mistake and you have to support it for a lifetime.

Phillip

unread,
Mar 30, 2011, 6:50:14 PM3/30/11
to
This works in allegro-cl (express version, so free) on windows XP.


(defun conn (n)
(with-open-file
(out "COM1" :direction :output)
(princ n out)
))

This discussion is the top of the google list for "opening a serial port in lisp" --> I didn't want anyone to think it was too difficult :-)

Reply all
Reply to author
Forward
0 new messages