Напишите, а затем прочитайте в последовательный порт в C

У меня есть USB-последовательный адаптер, подключенный к /dev/ttyUSB0, который подключается к этапу вращения. Я могу связаться с этой стадией вращения, просто отправив команды ASCII через последовательный порт. то есть запросить текущую позицию этой стадии вращения просто:

  1. в окне 1: echo -e "1tp\r" > /dev/ttyUSB
  2. в окне 2: cat /dev/ttyUSB, которое возвращает текущую позицию: "1TP-0.00000"

Теперь я хочу иметь возможность делать именно это при определенном триггере внутри программы на C.

Я просмотрел этот удивительный архив и нашел несколько примеров того, как это можно сделать. Например

Поэтому, основываясь на них, я написал этот очень уродливый код, чтобы просто попытаться записать «1tp\r» в последовательный порт, а затем прочитать возвращаемое значение (положение этапа вращения) обратно. Вот код ниже.

#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;
}

Ну, это не работает. Когда я запускаю его как: ./sertest /dev/ttyUSB0, я просто получаю сообщение об ошибке "cannot read from port". На самом деле проблема заключается в том, что строка "1tp\r" не записывается в последовательный порт. Кроме того, как только я закончу с этим, настройки последовательного порта, похоже, будут перепутаны, потому что я вообще не могу общаться со сценой с помощью простых команд терминала и мне нужно сбросить последовательный порт с помощью minicom.

Я также должен отметить, что я знаю, что могу успешно прочитать что-то из последовательного порта со второй частью этого кода, потому что мне удалось отправить строку "1tp\r" с помощью команды терминала и просто прочитать вывод этапа с соответствующим фрагментом кода в примере ниже.

Итак, я был бы признателен за некоторые советы о том, как успешно записать эту простую строку "1tp\r" (или аналогичную) в последовательный порт и чередовать чтение последовательного порта.

Я не программист, поэтому заранее извиняюсь за плохой стиль кода здесь.


person Denis Barkats    schedule 21.07.2015    source источник
comment
Всего нужно написать 4 символа. \r — это один символ, хотя он выглядит как два. В частности, \r — это возврат каретки, шестнадцатеричное значение 0x0D.   -  person user3386109    schedule 22.07.2015
comment
Кроме того, команда echo может добавлять символ перевода строки в конец сообщения. В этом случае код должен отправлять "1tp\r\n", что на самом деле составляет 5 символов.   -  person user3386109    schedule 22.07.2015
comment
Вызовите perror сразу после вызова write, чтобы получить более точное представление об ошибке.   -  person kaylum    schedule 22.07.2015
comment
Или используйте errno. Вы проверили, что у вас есть права на запись?   -  person Iharob Al Asimi    schedule 22.07.2015
comment
правильно. Я исправил строку для записи в 1tp\r\n, и ее размер правильно равен 5. Какой аргумент должен быть в perror? Я забыл сказать, что делаю это как root, так что да, у меня есть права на запись в /dev/ttyUSB0 (либо в командной строке, либо в коде C.   -  person Denis Barkats    schedule 22.07.2015
comment
Не используйте perror(), попробуйте fprintf(stderr, "error(%d): %s\n", errno, strerror(errno));. вместо этого вы должны включить errno.h   -  person Iharob Al Asimi    schedule 22.07.2015
comment
Ваш тест командной строки пишет в /dev/ttyUSB, но ваш тест кода пишет в /dev/ttyUSB0. Возможно, вам следует попробовать свой код с /dev/ttyUSB   -  person cup    schedule 22.07.2015