I have a USB to serial adapter attached to /dev/ttyUSB0
which connects to a rotation stage. I can communicate to that rotation stage by simply sending ASCII commands over the serial port. i.e. to request the current position of that rotation stage just:
- in window 1:
echo -e "1tp\r" > /dev/ttyUSB
- in window 2:
cat /dev/ttyUSB
which returns the current position: "1TP-0.00000"
Now I want to be able to do exactly this at a certain trigger inside a C program.
I've browsed this amazing archive and found a few examples of how it can be done. For example
- how to open, read, and write from serial port in C
- Linux C Serial Port Reading/Writing
- Serial port loopback/duplex test, in Bash or C? (process substitution)
So based on those, I wrote this very ugly code to simply try writing "1tp\r" to the serial port and then reading the returned value ( the rotation stage position) back. Here is the code below.
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int main(int argc, char *argv[])
{
char line[1024];
int chkin;
int chkout;
char input[1024];
char msg[1024];
char serport[24];
// argv[1] - serial port
sprintf(serport, "%s", argv[1]);
int file= open(serport, O_RDWR | O_NOCTTY | O_NDELAY);
printf("file descriptor: %d\n",file);
if (file == 0)
{
sprintf(msg, "open_port: Unable to open %s.\n", serport);
perror(msg);
}
else
fcntl(file, F_SETFL, FNDELAY); //fcntl(file, F_SETFL, 0);
while (1)
{
usleep (1000000);
// printf("enter input data:\n");
//scanf("%s",&input[0]);
// printf("You entered %s\n",&input);
//input= "1tp\r";
chkin = write(file,"1tp\r",5);
printf("chkin: %d\n",chkin);
if (chkin<0)
{
printf("cannot write to port\n");
}
fcntl(file, F_SETFL, FNDELAY);
//chkin=read(file,line,sizeof line);
usleep (100000);
//while ((chkin=read(file,line,sizeof line))>=0)
//printf("chkin: %d\n",chkin);
chkout = read(file, line ,sizeof line);
//{
if (chkout<0)
{
printf("cannot read from port\n");
}
else
{
printf("bytes: %d, line=%s\n",chkout, line);
}
//}
/*CODE TO EXIT THE LOOP GOES HERE*/
if (input[0] == 'q') break;
}
close(file);
return 0;
}
Well, it doesn't work. When I run it as: ./sertest /dev/ttyUSB0
, I just get the error "cannot read from port"
. In reality, the problem seems to be that the "1tp\r"
string does not seem to get written to the serial port. In addition, once I am done with this, the serial port settings seem to be all messed up because I can't communicate at all with the stage via simple terminal commands and need to reset the serial port using minicom.
I should also note that I know I can successfully read something from the serial port with the second part of that code because I have managed to send the "1tp\r"
string with a terminal command and just read the output of the stage with the relevant snippet of code in the example below.
So, I would appreciate some input on how to successfully write this simple string "1tp\r"
( or a similar one) to the serial port and alternate to reading the serial port.
I am not a programmer so I apologize in advance for the poor style of the piece of code here.