Previously, you (Sharriff Aina) wrote:

> Sounds like the direction that I´m trying to get into, I would 
> appreciate it , naturally if you´ve got the time, if you could
>  explain the  basic steps I would need to take in controlling 
> devices over the serial port on a 80x86 processor( hardware and 
> software)

REBOL makes serial port control pretty easy. You open a serial port and get a port 
which you can read, write and wait on. There are some funny design decisions, but I 
think that they make sense.

Here's some code snippits:

  path: serial-path-to/options lcd 19200

  path ==       serial://port2/19200/none/8/1

  fp: open/mode path [ direct write read binary no-wait ]

serial-path-to is:

serial-path-to: func [
        'name           ; port name ser1, com1, ...
        /options opts   ; baud setting options in REBOL open fmt
        /loc number
    ] [
    either number: find system/ports/serial name [
        number: index? number
    ][  append  system/ports/serial name
        number: length? system/ports/serial
    ]
    ; Append opts or default (redundant)
    either options [opts: join "/" opts] [ opts: "/9600/none/8/1" ]

    ; this was the hard statement for me to figure out
    join serial://port rejoin [ number opts ]
]

REBOL (still exp versions) puts the port names in: system/ports/serial

The defaults are [ ser0 ser1 ] which will be useless in most cases. In QNX, ports are 
in /dev and are typically names ser1, ser2 ... In the MS world they are com1 and so 
on. So the first thing that one needs to do is replace system/ports/serial with valid 
OS names without the /dev prefix. In my box, I make symbolic links to ser1 and ser2 to 
lcd and cbr - hence the lcd in the first code line above.

Although striping the /dev prefix is somewhat handy it at first seemed limiting in QNX 
where a serial port on another node has a node number or name in front of /dev. ie: 
//4/dev/ser5 refers to serial port 5 on node 4 and can be opened accross the net just 
like /dev/ser1 on whatever the local node is. Fortunately, QNX allow one to symbolic 
link (prefix) a remote node into the local namespace. One could thus prefix 
//4/dev/ser5 -> /dev/ser4.5 and open ser4.5 using REBOL - so REBOL does not to be QNX 
net aware to benefit.

The crazy thing that REBOL does is make you open the port with a path name 
serial://port[N] where N is the index? of the port name in system/ports/serial. Thus 
in serial-path-to above, I find the index? or append the passed name and use the 
length? to get port[N]. Of course, REBOL then has to change this back into an open( 
"/dev/serX", ..) so to me it would make sense to use the port name instead of index. 

To set baud, parity, stop bits one just appends resonable values to the port path so 
an open could look like:

        fp: serial://port3/2400/odd/7/2

and REBOL would figure out that you want 2400 baud, 7 data bits, even parity and 2 
stop bits. I don't think that REBOL provides a mechanisim to change the option after 
an open. 

This does bring up a buglett in QNX4 and QNX RTP - the open parameters are not 
correctly set. To solve this, I call the stty command after the open so that the baud 
and so on are correct. At least the port has internal attributes of speed, parity, 
data-bits and stop-bits which make the stty command trivial to build. I currently 
execute stty in core by writing the command "stty baud=xxx ..." to a fifo (named pipe) 
which has a shell script on the other end. This scriptsimply executes whatever command 
is fed to it.

OK, you have a port, now what? Well it behaves pretty much like a socket so you can 
read, write and wait on it.

I have an event loop that looks like this:

loop: func [ /loc ok pd ] [
  ok: 1
  while [ ok ][
    pd: eval-rules              ; do something on every pass
    wait [ pd lcd/fp ]          ; wait for a timeout or lcd key press
    ok: not-equal? 'A pick lcd/fp 1   ; get pressed key.
 ]
]

OK, I don't have the keypad doing anything cool yet.

If your device returns lines of data, then you'd probably open the port with something 
like:

   cbr/fp: open/mode/with serial://port4/9600/none [ direct write read
                no-wait lines ] "^M"

The cbr port device returns strings of data terminated with ^M in response to a 
command. I have a function which sends a command, waits for a response and returns 
whatever the device sent back minus some prefix. The read removes the ^M. It's all 
pretty slick and with any luck would work on a MS OS if I used com[N} type names.

read-check: func [ cmd prefix /loc data] [
    insert fp cmd           ; write command to the serial port
    wait timeout            ; wait for a response
    data: first fp          ; get line of data
    return find/match data prefix ; return stuff after prefix
]


> >I'm working on a prototype home data acquisition/control device. It
> currently runs on a 486 class SBC onder QNX but only because I don't 

> Previously, you ([EMAIL PROTECTED]) wrote:
> > 
> > Hi guys!
> > 
> > Anyone with experience in robotics or microcontrollers in REBOL?
> > 
> 
> --
> David L. Hawley       D.L. Hawley and Associates    1.503.274.2242
> Software Engineer                      [EMAIL PROTECTED]
> 
> -- 
> To unsubscribe from this list, please send an email to
> [EMAIL PROTECTED] with "unsubscribe" in the 
> subject, without the quotes.<
> 
> -- 
> To unsubscribe from this list, please send an email to
> [EMAIL PROTECTED] with "unsubscribe" in the 
> subject, without the quotes.
> 
> 

--
David L. Hawley       D.L. Hawley and Associates    1.503.274.2242
Software Engineer                      [EMAIL PROTECTED]

-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to