Help with Serial Com (Original in QBASIC)


Thread Starter


I am trying to interface with a sensor that communicates over RS-232. The vendor provides very little information regarding the interface...except for a exe that lets you open a COM port, engage the sensor, and returns the value. In the "example code source" they provide is the following QBASIC which is supposed to engage the sensor (it is refered to as the "Action" call by the manufacturer):

FOR I = 1 TO 30000 STEP 1
OUT &H3FC, 10
OUT &H3FC, 0

So once this runs, the sensor engages and then returns a numerical value over the serial port. Any suggestions on the best way to implement this. I need a small app that will:

-Open com interface
-engage sensor
-return value


Michael Griffin

Your program writes "10" to port "3FC" 30,000 times, then clears this port. I assume the 30,000 iterations are a crude timing loop. I also assume that since the sample program is written in QBasic, the computer hardware in question is an IBM compatible PC.

Port "3FC" (hex) is a register in the first serial port (assuming a typical IBM PC compatible architecture - this wasn't true for all "PCs" from that era however). The first serial port had an address range from 3F8 to 3FF, so for an 8250 UART, 3FC would be register 4, the "modem control register" (MCR).

Writing a decimal "10" (binary 1010) to this register sets RTS (bit 1), and "general purpose output 2" (bit 3), which is connected to the PC's interupt control circuitry.

So essentially, the program turns on the RTS line and gets ready to receive data at the serial port. The code fragment you've shown doesn't actually read the port though.

You would not be able to easily duplicate this on a computer running a modern operating system. A modern operating system would install a serial port driver that controls the hardware. What is more, the hardware addresses used are not guaranteed to be the same as the older hardware the original program was written for.

I believe however, that you may be able to achieve the same thing by opening a serial port for reading while enabling RTS handshaking. I'm not sure why this approach wasn't taken in the original example.

As for how to implement it, that depends upon what you are trying to interface *to*. What are you going to do with the return value; print it to the console?

Michael Griffin

<p>As a clarification and correction to my previous reply on this topic, 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. This is more or less equivalent to the original QBasic program, but adds the feature of reporting on the pin status.

<p>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");
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");
printf("RTS pin is reset.\n");



<p>Michael Griffin
Thanks so much. This is a good start.
What do you make of this....

The original QBASIC i posted is supposed to invoke an "action" in the sensor...and this is to engage it so it produces a reading. Another snippet of code they include is the following:

FOR I = 1 TO 30000 STEP 1
OUT &H3FC, 1
OUT &H3FC, 0

This is supposed to invoke the "mode" functionality on the sensor to change its mode.

This is very confusing if the "action" snipped just sets the RTS line to accept data.



Michael Griffin

The original code example you provided set the RTS line. The one in your
second sample (below) seems to control the DTR line. The Modem Control
Register (MCR) register in an 8250 UART (and other compatible ones) is as

Bit Description
7 Reserved
6 Reserved
5 Autoflow Control Enabled (16750)
4 Loopback Mode
3 Auxiliary Output 2
2 Auxiliary Output 1
1 Request To Send
0 Data Terminal Ready

So, setting bit 0 in the MCR register enables DTR. Setting bit 1 enables RTS.
As I mentioned in a previous message, "output 2" (bit 3), is connected to the
PC's interupt control circuitry, and I strongly suspect this enables
interupts when receiving data.

It appears from your examples that the sensor may be controlled using the RTS
and DTR signals, where DTR controls the "mode" (whatever this is) and RTS
causes it to output data. If this is the case, then while using the serial
handshake lines in this manner is not "normal", it is not without precedent.
Many simple PC UPS systems will interface with a PC serial port over the
handshake lines while engaging in *no* serial communications at all. The
serial port simply provides a few convenient digital I/O lines.

There is another UART register called the "Modem Status Register" (MSR)
located 2 ports above the MCR register (base address + 6 rather than base
address + 4) which provides inputs including the DSR and CTS signals. If your
sensor sets some handshaking lines of its own, these can be monitored using
this register. If your documentation shows any Basic examples reading the
address &H3FE using the "INP" instruction, then I would suspect it is
examining the DSR or CTS signals.

MSR Register.
Bit Description
7 Carrier Detect
6 Ring Indicator
5 Data Set Ready
4 Clear To Send
3 Delta Data Carrier Detect
2 Trailing Edge Ring Indicator
1 Delta Data Set Ready
0 Delta Clear To Send

Many simple devices don't even use a hardware UART. Instead they emulate one
in software (something which isn't practical on a PC), which means they can
do pretty much anything they want with the serial lines.
I am trying to do the same thing in VB 6. Please guide me regarding this. I want to Read the Value from the Com port and displays it in my Vb textbox. I attach the Indicator (weight machine) with my PC.

If you help me regarding this then i will very thankful to you.