Unix Technical Forum

RS232 programming, helps needed...

This is a discussion on RS232 programming, helps needed... within the HP-UX Operating System forums, part of the Unix Operating Systems category; --> linda <plinda77@yahoo.com> wrote: > Hi All > I am doing a project recently requires RS232 communication between a > ...


Go Back   Unix Technical Forum > Unix Operating Systems > HP-UX Operating System

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #11 (permalink)  
Old 01-16-2008, 06:28 PM
jimp@specsol-spam-sux.com
 
Posts: n/a
Default Re: RS232 programming, helps needed...

linda <plinda77@yahoo.com> wrote:
> Hi All


> I am doing a project recently requires RS232 communication between a
> hpux workstation and a robot. This machine has its own RS232
> communication protocol which can accept commands and return result
> from queries. The RS232 connection requirement is very simple.


> the workstation the machine
> 9 pins connector 25 pins connector


> Pin 2(Rx) connected to Pin 2(Tx)
> Pin 3(Tx) connected to Pin 3(Rx)
> Pin 5(Gnd) connected to Pin 7(Gnd)


> Ive wrote a C code to control the machine. Apparently, the machine is
> accepting the commands from the C program and performed its tasks, but
> wouldnt response to the queries that Ive sent from the program.
> Therefore Ive probe(pin2 - Tx) from the 25 pins Dsub connector and
> found that the machine is actually returning the expected result but
> the serial port is not set to read the result. The read result return
> -1.


> I am not a RS232 programmer and this is the first time I am doing so.
> But I think it must something to do with the RS232 options that I
> should set in my hpux box.
> All kinds of RS232 related helps are appreciated. Thanks in advance.
> ~


For a direct connection, i.e. no flow control, you should be using the
device file that has 00 as the last 2 digits of the minor device number.

As in:

crw--w--w- 1 bin bin 78 0x023800 Sep 23 07:11 tty2d9
^^ These digits.

The termio man page should explain these bits.

--
Jim Pennino

Remove -spam-sux to reply.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #12 (permalink)  
Old 01-16-2008, 06:28 PM
Stefaan A Eeckels
 
Posts: n/a
Default Re: RS232 programming, helps needed...

On 23 Sep 2004 09:22:39 -0700
plinda77@yahoo.com (linda) wrote:

> #define ENQ 5
> #define ACK 6
> #define NAK 15
> #define STX 2
> #define ETX 3
>
> #define QUERY "XX" /* XX, something to represent an query, say 2
> bytes */
>
> int main()
> {
> int fd;
> int io_status;
> int write_status;
> int close_status;
> struct termio t;


Don't use termio, it has been superseded by termios.

> char *device = "/dev/devicefile";
> char query[10];
> char recvbuf[10];
>
> sprintf(query, "%c%s%c\n", STX, QUERY, ETX);


Always use snprintf, it avoids buffer overflows.

> /* need to encapsulate QUERY between the STX and ETX, to be recognize
> by the robot */
>
> if((fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY))==-1)
> fprintf(stderr, "Open RS232 Fail%d!\n", fd);
>
> if((io_status = ioctl(fd, TCGETA, &t))==-1)
> fprintf(stderr, "IOCTL TCGETA Fail!\n");


Use tcgetattr() and tcsetattr().
>
> t.c_cflag=B9600|CS8|HUPCL|CREAD;
>
> if((io_status = ioctl(fd, TCSETA, &t))==-1)
> fprintf(stderr, "IOCTL TCSETA Fail!%d\n", io_status);


You could try to print errno (it's helpful :-).

> if((write_status = write(fd, &query, 5))==-1)
> fprintf(stderr, "Write RS232 Fail!%d\n", write_status);


You should output the bytes in a loop, and check for
the number of bytes written.

> /* let say the query returns 2 bytes, YY */
> /* actual data return from robot and received will be "2YY3" but ascii
> character 2 and 3 is not printable(is this the problem?) therefore it
> will be YY, as STX, "YY", ETX */
>
> if((read_status = read(fd, &recvbuf, 5))==-1)
> fprintf(stderr, "read RS232 Fail!%d\n", read_status);


This is not the way to go about it. You should switch to
raw mode, and read character by character.

Once you've got your tty in raw mode, with the proper number
of characters and timer set, you can start reading the characters.
You'll need to know the robot's protocol to make reasonable
vmin/vtime settings.

> /* read_status received but is 0*/
>
> close(fd);
>
> }
> /* End of code */
>
> Is there any settings that are capable of filter away the STX and ETX
> during read? or it that needed?


Here's something I hacked up. Warning: it's not tested as I
don't currently have a serial device to hang off a HP-UX serial
port. It should more or less work - I hope (famous last words).

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <termios.h>
#include <sys/fcntl.h>

#define ENQ 5
#define ACK 6
#define NAK 15
#define STX 2
#define ETX 3

#define QUERY "XX" /* XX, something to represent an query, say 2 bytes */

/* Prototypes */
void fatal(char *);
int tty_raw(int, int, int);

char *device = "/dev/tty0p0";

int main(int argc, char *argv[]) {
int bcount; /* byte counter */
int osize; /* output size */
int fd;
char query[10];
char recvbuf[10];

switch (argc) {
case 0:
case 1:
break;
case 2:
device = argv[1];
break;
default:
fprintf(stderr, "Format: %s: { tty-device (default: %s) }\n",
argv[0], device);
exit(1);
break;
}

/* Open the tty and put in raw mode */
if((fd = open(device, O_RDWR | O_NOCTTY))==-1) {
fatal("Open RS232 Failed");
}
if (!isatty(fd)) {
fatal("Not a tty");
}

if (tty_raw(fd, 0, 10) < 0) { /* one character, 10 secs timeout */
fatal("Cannot set to raw mode");
}

/* Prepare the output query */
osize = snprintf(query, sizeof(query), "%c%s%c\n", STX, QUERY, ETX);

/* Send the message down the tty */
bcount = 0;
while (bcount < osize) {
int w;
if ((w = write(fd, &query[bcount], osize-bcount)) == EOF) {
break;
}
if (w == -1 && errno == EAGAIN) {
continue; /* no data available in non-blocking mode */
}
bcount += w;
}

/* Read the reply from the robot */
bcount = 0;
while (bcount < sizeof(recvbuf)) { /* Stop buffer overflow */
int r;
if ((r = read(fd, &recvbuf[bcount], 1)) == 0) {
fatal("Robot closed connection");
}
if (r == -1 && errno == EAGAIN) {
continue; /* no data available in non-blocking mode */
}
if (bcount == 0 && recvbuf[bcount] != STX) {
fatal("Robot lost its mind");
}
if (recvbuf[bcount] == ETX) {
break;
}
bcount += r;
}

/* Do something with the reply */
recvbuf[bcount] = '\0'; /* Make it printable */
/* skip STX */
fprintf(stdout, "Reply from robot was: <%s>\n", recvbuf+1);
exit(0);
}

/* Switch terminal to raw mode */
int tty_raw(int tty_fd, int vmin, int vtime) {
struct termios cooked;
struct termios raw;

/* Keep a copy so we can go back in case of error */
tcgetattr(tty_fd, &cooked);
tcgetattr(tty_fd, &raw);

/* Set flags */
raw.c_lflag = 0; /* local flags */
/* Alternatively, remove the following flags:
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); */
raw.c_iflag = 0; /* input flags */
/* Alternatively, remove the following flags:
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); */
raw.c_oflag = 0; /* output flags */
/* Alternatively, remove the following flag:
raw.c_oflag &= ~(OPOST); */
raw.c_cflag |= (B9600|CS8); /* control flags - make sure we get 8bits
*/

/* control characters: remove special treatments */
raw.c_cc[VINTR] = '\0';
raw.c_cc[VQUIT] = '\0';
raw.c_cc[VERASE] = '\0';
raw.c_cc[VKILL] = '\0';
raw.c_cc[VSTART] = '\0'; raw.c_cc[VSTOP] = '\0';

/* control characters: minimum number of bytes, timer before return*/
/* eg vmin = 5, vtime = 5 means return after 5 bytes or half a second
after the first byte */
raw.c_cc[VMIN] = vmin;
raw.c_cc[VTIME]= vtime;

/* Now put the tty in raw mode after flushing */
if (tcsetattr(tty_fd, TCSAFLUSH, &raw) < 0) {
tcsetattr(tty_fd, TCSAFLUSH, &cooked);
return -1;
}
return 0;
}

/* Get out on fatal errors */
void fatal(char *message) {
if (errno) {
fprintf(stderr, "%s: %s\n", message, strerror(errno));
} else {
fprintf(stderr, "%s\n", message);
}
exit (1);
}

It compiles OK with gcc -Wall on HP-UX 11.0, the rest is up to you
(watch out for possible broken lines when copy/pasting the code).

Take care,

--
Stefaan
--
"What is stated clearly conceives easily." -- Inspired sales droid
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #13 (permalink)  
Old 01-16-2008, 06:28 PM
Mike Stroyan
 
Posts: n/a
Default Re: RS232 programming, helps needed...

jimp@specsol-spam-sux.com wrote:

|For a direct connection, i.e. no flow control, you should be using the
|device file that has 00 as the last 2 digits of the minor device number.

|As in:

|crw--w--w- 1 bin bin 78 0x023800 Sep 23 07:11 tty2d9
| ^^ These digits.

|The termio man page should explain these bits.

The device file minor number bits can be decoded and set with the
lssf and mksf commands. Look at the "man lssf" and "man mksf" manuals.
You want the asio0 section of "man mksf" for workstation serial ports.

--
Mike Stroyan, mike.stroyan@hp.com
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #14 (permalink)  
Old 01-16-2008, 06:29 PM
linda
 
Posts: n/a
Default Re: RS232 programming, helps needed...

Stefan.

thanks a lot
linda
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #15 (permalink)  
Old 01-16-2008, 06:29 PM
Stefaan A Eeckels
 
Posts: n/a
Default Re: RS232 programming, helps needed...

On 24 Sep 2004 08:32:42 -0700
plinda77@yahoo.com (linda) wrote:

> thanks a lot


You're welcome. Please be aware I just threw it together
and didn't have the possibility to test it. My last
work on asynchronous communications in Unix was way back
in 1990, plus I tend to make off-by-one errors in my
loops. The basic ideas should be sound though. Please
let me know if it helped.

Take care,

--
Stefaan
--
"What is stated clearly conceives easily." -- Inspired sales droid
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #16 (permalink)  
Old 01-16-2008, 06:29 PM
CBee
 
Posts: n/a
Default Re: RS232 programming, helps needed...

linda wrote:

> Hi All
>
> I am doing a project recently requires RS232 communication between a
> hpux workstation and a robot. This machine has its own RS232
> communication protocol which can accept commands and return result
> from queries. The RS232 connection requirement is very simple.
>
> the workstation the machine
> 9 pins connector 25 pins connector
>
> Pin 2(Rx) connected to Pin 2(Tx)
> Pin 3(Tx) connected to Pin 3(Rx)
> Pin 5(Gnd) connected to Pin 7(Gnd)
>
> Ive wrote a C code to control the machine. Apparently, the machine is
> accepting the commands from the C program and performed its tasks, but
> wouldnt response to the queries that Ive sent from the program.
> Therefore Ive probe(pin2 - Tx) from the 25 pins Dsub connector and
> found that the machine is actually returning the expected result but
> the serial port is not set to read the result. The read result return
> -1.
>
> I am not a RS232 programmer and this is the first time I am doing so.
> But I think it must something to do with the RS232 options that I
> should set in my hpux box.
> All kinds of RS232 related helps are appreciated. Thanks in advance.
> ~


Most problems I see with new RS232 setups are that most unix implementations
give a login-session (getty or such) on each found serial port. If you use the
serial port for other purposses than a terminal-login be sure to disable this
login. See your inittab file ("/etc/inittab" ?) for your situation.


CBee
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:13 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com