RS232 (Serial port, C++, Linux, Disable RTS)

L

Thread Starter

Leandro

I'm coding a little application in C++ that reads from Extech 380801 power meter. But to be able to that in need to do this configuration explained below.

-------------------------------------------------
Default RS-232 Communications Settings
Baud Rate: 9600; Stop bit: 1; Data bits: 8; Parity: None
NOTE: Software developers must ensure that DTR provides 10V (or higher) and RTS
provides -10V (or lower). Voltage (10V, -10V) from DTR and RTS is used to generate
the RS-232 signal. DTR is usually enabled (10V) but RTS must be disabled in order to
provide -10V. To accomplish this in BASIC, add RS in the OPEN command:

OPEN "COM1: 9600, N, 8, 1, CS, DS, CD, RS" as #1
-------------------------------------------------

Any idea how I can do this in C++? How can I disable the RTS? I'm using the "termios.h"
 
C

Curt Wuollet

There is a very good HOWTO on Linux serial matters and the Linux Programmers Guide helps too. Both can be found at the Linux Documentation Project at ibiblio.org or on hundreds of mirrors. If that fails, post again and I'll dig up some source code.

Regards
cww
 
M

Michael Griffin

The following is from the message "Re: ENGR: Help with Serial Com (Original in
QBASIC)" on the 11th of April last year. (http://www.control.com/thread/1026221083) It includes a small demo program
in 'C' which I wrote to answer a question on the serial control lines. What
follows is reproduced from that earlier message:

"the following 'C' code seems to work for setting and resetting the RTS line.
The demo code sets the RTS pin, checks the pin status, waits for the user to
press the return key, resets the RTS pin, and checks the pin status again. It
does not show how to read the serial port"

"Most of what is below is just test code to demonstrate the pin being set and
reset. The essential bits are opening the port, and the "ioctl" function call
which sets the RTS pin. You would also need to check the return value from
the "ioctl" call to check for errors."

/***********************************************************/
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>

main() {
int fd, sercmd, serstat;

sercmd = TIOCM_RTS;
fd = open("/dev/ttyS0", O_RDONLY); // Open the serial port.

printf("Setting the RTS pin.\n");
ioctl(fd, TIOCMBIS, &sercmd); // Set the RTS pin.

// Read the RTS pin status.
ioctl(fd, TIOCMGET, &serstat);
if (serstat & TIOCM_RTS)
printf("RTS pin is set.\n");
else
printf("RTS pin is reset.\n");

getchar(); // Wait for the return key before continuing.

printf("Resetting the RTS pin.\n");
ioctl(fd, TIOCMBIC, &sercmd); // Reset the RTS pin.

// Read the RTS pin status.
ioctl(fd, TIOCMGET, &serstat);
if (serstat & TIOCM_RTS)
printf("RTS pin is set.\n");
else
printf("RTS pin is reset.\n");

close(fd);
}

/***********************************************************/
 
I just took a good look and i dont think termios lets you change bit values in registers for DTR and RTS.

Prob will have to write to the ports directly.

#include <asm/io.h>
#define serport 0x3f8 // for "/dev/ttyS0"

iopl(3); // need this for access to ports

outb( 0x02, serport+4); //modem control register


then use termios



/*MCR BIT 0:
0 = force DTR (Data Terminal Ready) to high.
1 = force DTR to low.

MCR BIT 1:
0 = force RTS (Request to Send) to high.
1 = force RTS to low. */

The serial port transmits a '1' as -3 to -25 volts and a '0' as +3 to +25 volts so you have to write a 1 to bit 1 and a 0 to bit 1 therefore the 0x02 written to serport+4

2 problems

1 termios might rewrite the MCR
2 Your RS-232 Driver/Receiver might not output 10 to -10. verify the line voltage for RTS and DTS
 
N

Nelson Castillo

<p>I could change them in Linux
(you could save a syscall here. I think
it is OK to save status).
<pre>
void
start_tx(int fd)
{
int status;

ioctl(fd, TIOCMGET, &status);
status |= TIOCM_RTS;

if (ioctl(fd, TIOCMSET, &status))
{
perror("ioctl");
exit(1);
}
}

void
end_tx(int fd)
{
int status;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &status);
}
</pre>
 
Top