Reputation: 1001
In my program which sends bytes to a serial port, I receive bytes which I send. I don't want to receive bytes which I send, and I don't know how to do this?
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/ioctl.h>
int fd;
struct termios tio, old_tio;
time_t SubTime_mSec(timeval val1, timeval val2)
{
timeval tv;
if (val1.tv_sec > val2.tv_sec) return (0);
if (val1.tv_sec == val2.tv_sec)
if (val1.tv_usec > val2.tv_usec) return (0);
tv.tv_sec = val2.tv_sec - val1.tv_sec;
if (val1.tv_usec < val2.tv_usec) {
tv.tv_usec = val2.tv_usec - val1.tv_usec;
} else {
tv.tv_sec --;
tv.tv_usec = 1000000 + val2.tv_usec - val1.tv_usec;
}
return(tv.tv_sec*1000 + tv.tv_usec/1000);
}
void RTUOutMessage(int cnt1, int cnt2)
{
unsigned char msg[13] = {0x01, 0x10, 0x00, 0x2F, 0x00, 0x02, 0x04, 0x4B, 0x64, 0x3D, 0xD9, 0x36, 0xC6};
int Len = 13;
int status, i, j;
ioctl(fd, TIOCMGET, &status);
status = status | TIOCM_RTS | TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
write(fd, msg, Len);
for (j = 0; j < cnt1; j ++)
for (i = 0; i < cnt2; i ++);
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
timeval start_t, curr_t;
char Buff[80];
int l;
gettimeofday(&start_t, NULL);
curr_t = start_t;
while (SubTime_mSec(start_t, curr_t) < 1000) {
l = read(fd, Buff, 80);
if (l > 0) {
printf("BUFFER=");
for(i = 0; i < l; i++) {
printf(" %x", Buff[i]);
}
//printf("\n");
}
gettimeofday(&curr_t, NULL);
}
}
void InitPort(void)
{
int StopBits = 2;
if ((fd = open("/dev/ttyAM2", O_RDWR | O_NDELAY)) < 0) {
printf("Couldn't open //dev//ttyAM2\n");
}
tcflush(fd, TCIOFLUSH);
int n = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, n & ~O_NDELAY);
tcgetattr(fd, &old_tio);
tcgetattr(fd, &tio);
cfsetospeed(&tio, (speed_t)B9600);
cfsetispeed(&tio, (speed_t)B9600);
tio.c_cflag = (tio.c_cflag & ~CSIZE) | CS8;
tio.c_cflag |= CLOCAL | CREAD ;
tio.c_cflag &= ~OFILL;
//parity
tio.c_cflag &= ~(PARENB | PARODD);
tio.c_cflag &= ~CRTSCTS;
if (StopBits == 2) tio.c_cflag |= CSTOPB;
else tio.c_cflag &= ~CSTOPB;
tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;
tio.c_cc[VTIME]=0;
tio.c_cc[VMIN]=0;
if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 1 failed\n");
int mcs=0;
ioctl(fd, TIOCMGET, &mcs);
mcs |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &mcs);
if (tcgetattr(fd, &tio)!=0) printf("tcgetattr() 4 failed\n");
tio.c_cflag &= ~CRTSCTS;
if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 2 failed\n");
}
int main(int argc, char **argv)
{
InitPort();
int cnt1, cnt2;
cnt1 = 3;
cnt2 = 20000;
cnt1 = atoi(argv[1]);
cnt2 = atoi(argv[2]);
for(;;) {
RTUOutMessage(cnt1, cnt2);
usleep(1000000);
}
tcsetattr(fd, TCSANOW, &old_tio);
close(fd);
printf("End\n");
return 0;
}
Upvotes: 4
Views: 3897
Reputation: 17047
If you are receiving the chars that you sent, then the remote's serial port is apparently echoing its input.
You will either have to disable input echo at the other device, or perform "echo cancellation" in your receive logic. I.E. create an "echo FIFO". Each byte output to the serial port is also written to the "echo FIFO". Set a flag indicating that an echo is expected. As input is received, compare it to the "echo FIFO", and remove chars when it matches, and toss the receive char. If no match, then accept receive char. Clear the echo flag when the "echo FIFO" is empty.
BTW the code appears to set the serial port to raw or non-canonical mode. The preferred method would be to use
cfmakeraw(&tio);
rather than
tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;
Upvotes: 4