1

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:

  1. in window 1: echo -e "1tp\r" > /dev/ttyUSB
  2. 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

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.

Community
  • 1
  • 1
Denis Barkats
  • 41
  • 1
  • 4
  • 1
    There are only 4 characters to write. The `\r` is a single character, even though it looks like two. Specifically `\r` is a carriage return, hex value 0x0D. – user3386109 Jul 21 '15 at 22:40
  • 1
    Also, the `echo` command may be adding a gratuitous line-feed char to the end of the message. If that's the case, the code should be sending `"1tp\r\n"`, which actually *is* 5 characters. – user3386109 Jul 21 '15 at 22:49
  • 2
    Call `perror` immediately after the `write` call to give you a more precise indication of what the error is. – kaylum Jul 21 '15 at 22:57
  • Or use `errno`. Did you check that you have write permission? – Iharob Al Asimi Jul 21 '15 at 23:17
  • right. I fixed the string to write to "1tp\r\n" and its size is correctly 5. What argument should be in perror though ? I forgot to say I am doing this as root, so yes I have permissions to write to /dev/ttyUSB0 ( either in commandline or in the C code. – Denis Barkats Jul 21 '15 at 23:19
  • Don't use `perror()` try this `fprintf(stderr, "error(%d): %s\n", errno, strerror(errno));`. instead, you have to include `errno.h` – Iharob Al Asimi Jul 21 '15 at 23:20
  • Your command line test writes to **/dev/ttyUSB** but your code test writes to **/dev/ttyUSB0**. Maybe you ought to try your code with **/dev/ttyUSB** – cup Jul 22 '15 at 04:18

0 Answers0