Reputation: 450
I wish to make software PLC on raspberry pi. I did reserve one core just for PLC task and I got latency under 100 micro seconds. But the PLC need RS485 communication at 1 Megabit. It works, but the serial read take a lot of time. I use builtin serial of raspbbery to avoid additional latency of USB converters.
Transmitting to RS485 with
write (SerialId, buf, len);
take up to 85 microseconds.
but the receiving part with
int bytes = read (SerialId, RxBuf, sizeof RxBuf);
is really bad as it can take over 10 miliseconds.
I setup serial to be nonblocking and buffer big enough so every read will be timeouted. I measure how much read take and it can be anything from few micros to over 10 millis. How to achive better response time?
And this is setup routine:
void SetupSerial(){
char *portname = "/dev/ttyAMA0";
int speed=B1000000;
SerialId = open (portname, O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK);
if (SerialId < 0){
printf ("FastPLC: Error %d opening %s: %s\n", errno, portname, strerror (errno));
exit(errno);
}
printf ("FastPLC: %s is open\n", portname);
struct termios tty;
if (tcgetattr (SerialId, &tty) != 0) {
printf ("FastPLC: Error %d from tcgetattr", errno);
exit(errno);
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
cfmakeraw(&tty);
tty.c_cc[VTIME] = 0; //nonblocking
tty.c_cc[VMIN] = 0;
if (tcsetattr (SerialId, TCSANOW, &tty) != 0) {
printf ("FastPLC: Error %d from tcsetattr", errno);
exit(errno);
}
}
Upvotes: 1
Views: 51
Reputation: 450
Finally got working code. The issue is that I was read with timeout (and timeout is set to 0) So it should work, and it does, but introduce some delay (up to 10ms).
The proper solution seems to be to check how many bytes are in buffer with ioctl and if there are some bytes and not more than buffer ten then read it. something like this:
int bytes;
ioctl(SerialId, FIONREAD, &bytes);
if (bytes>sizeof(RxBuf)) bytes=sizeof(RxBuf);
if (bytes) bytes = read (SerialId, RxBuf, bytes); //read characters from input queue
with this I have latency around 150 us.
Upvotes: 1