RS232 and termios Problem

Hi all,

i simply want to send data to an device, which is connected to my RS232-Port (/dev/ttyUSB0) to get an response from it. It shoulden't be that difficult but i dont get it running with Linux.
I have an working application in Windows 7 and I'm trying to port it to Linux (Ubuntu 32bit in my case).
Here is a log, made with portmon that shows the correct communication init-routine:

Link to pastebin due to an lack of space: hxxp://pastebin.com/eGWh1dV4

As you may see the Windows-application sends just a simple hex-String to the device and gets an response. Now here is my Log-file:



143 0.00000081 Virtual PC.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial2 SUCCESS StopBits: 1 Parity: ODD WordLength: 8
144 0.00297025 Virtual PC.exe IOCTL_SERIAL_SET_CHAR Serial2 SUCCESS EOF:1a ERR:3f BRK:3f EVT:1a XON:11 XOFF:13
145 0.00000081 Virtual PC.exe IOCTL_SERIAL_SET_HANDFLOW Serial2 SUCCESS Shake:1 Replace:44 XonLimit:2048 XoffLimit:512
146 0.00000122 Virtual PC.exe IOCTL_SERIAL_PURGE Serial2 SUCCESS Purge: TXABORT RXABORT TXCLEAR RXCLEAR
147 0.00000041 Virtual PC.exe IOCTL_SERIAL_SET_BREAK_OFF Serial2 SUCCESS
148 0.00000081 Virtual PC.exe IOCTL_SERIAL_PURGE Serial2 SUCCESS Purge: TXABORT TXCLEAR
149 0.00092228 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: FF
150 0.00023786 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: FF
151 0.00024516 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: FF
152 0.00025083 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: FF
153 0.00024273 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: FF
154 0.00024597 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: 02
155 0.00024880 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: 80
156 0.00024475 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: 00
157 0.00025164 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: 00
158 0.00024597 Virtual PC.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: 82
159 0.00000243 Virtual PC.exe IOCTL_SERIAL_GET_MODEMSTATUS Serial2 SUCCESS
160 0.00000284 Virtual PC.exe IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
161 0.00000081 Virtual PC.exe IOCTL_SERIAL_GET_MODEMSTATUS Serial2 SUCCESS
162 0.79521655 Virtual PC.exe IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
163 0.00234905 Virtual PC.exe IOCTL_SERIAL_CLR_DTR Serial2 SUCCESS

Full logfile at pastebin: hxxp://pastebin.com/7WtEvbRn

It's obvious that there is an difference between sending "Length 10: FF FF FF FF FF 02 80 00 00 82 " and "Length 1: FF, Length 1: FF ..." but I dont know how to fix that. Another difference I found here was the "XonLimit:2048".

My code-Snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>


int openPort(void)  {
        int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
        if (fd == -1)
        {
                perror("Failed to open /dev/ttyUSB0");
                exit(1);
        }
        return fd;
}

void setupPort(int &fd, termios &options) {
        tcgetattr(fd, &options); // get current settings

        // Set Bautrate to 1200 for input and output
        cfsetispeed(&options, B1200);
        cfsetospeed(&options, B1200);

        // setting up Odd Parity
        options.c_cflag |= PARENB;
        options.c_cflag |= PARODD;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;

        // Timeout Settings
        options.c_cc[VMIN]  = 1;
        options.c_cc[VTIME] = 0;

        // choosing Raw input
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

        // enable parity check
        options.c_iflag |= (INPCK | ISTRIP);
        //options.c_iflag |= (IGNPAR | ISTRIP); //test with disabled parity check


        options.c_cflag |= CRTSCTS;

        // choosing Raw output
        options.c_oflag &= ~OPOST;

        // enabling Software flow control
        options.c_cflag |= (CLOCAL | CREAD); // enable receiver
        tcsetattr(fd, TCSAFLUSH, &options); // Flush input/output buffer and apply changes
}


void writePort(int &fd) {
        unsigned char send_bytes[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x80, 0x00, 0x00, 0x82 };
        int wroteN = write(fd, send_bytes, 10);
        if (wroteN < 10) {
                perror("Write to RS232 failed");
        }
}

void readPort(int &fd, int s) {
        char buf[21];
        int res=0;
        printf("Settings:%i\n",s);
        for(int i=0; i<20; i++) {
                res = read(fd,buf,20);
                buf[res]=0;
                printf("[%i|%i]\n",i, res);
        }
        printf("\n\n");
}


void setRTS(int &fd, int level) {
        int status;
        if (ioctl(fd, TIOCMGET, &status) == -1) {
                perror("setRTS to 1 failed");
                exit(-1);
        }
        if (level)      status |= TIOCM_RTS;
        else            status &= ~TIOCM_RTS;

        if (ioctl(fd, TIOCMSET, &status) == -1) {
                perror("setRTS to 0 failed");
                exit(-1);
        }
}


void msleep(int ms) {
        usleep(ms*1000); //convert to microseconds
}


unsigned long getTime() {
        struct timeval detail_time;
        gettimeofday(&detail_time,NULL);
        return (detail_time.tv_usec);
}

void setDTR(int &fd) {
  // sets the SC8in1 in command mode
  int lineData;
  ioctl(fd, TIOCMGET, &lineData);
  lineData |= TIOCM_DTR;
  ioctl(fd, TIOCMSET, &lineData);
}


int main(void) {
        // general Setup
        int fd = openPort();
        struct termios options;
        setupPort(fd, options);

        // start sending data
        setDTR(fd);
        // Different timing between send and receive data
        for(int var=80; var<200; var++) {
                setRTS(fd, 1); // enabling RTS
                msleep(2);
                int start,diff;
                start = getTime();
                writePort(fd);
                // Different timing
                do{
                        diff = getTime() - start;
                }while(diff<var);

                setRTS(fd, 0);
                readPort(fd, var);
                sleep(1);
        }


        tcsetattr(fd, TCSAFLUSH, &options); // Flush input/output buffer and apply changes
        return 0;

}


It would be great if anyone could tell me how to fix my code to get it right formated.

Last edited on
Topic archived. No new replies allowed.