Последовательная запись в Linux C ++: написан только один символ

0

Я пытаюсь изменить код, написанный здесь: Чтение/запись в последовательном порту Linux C, чтобы я мог управлять светодиодной вспышкой через последовательный (с адаптером USB-адаптер). Однако, когда я пытаюсь записать команду 12 на устройство, а затем я проверяю состояние светодиода с помощью GTKterm и осциллографа, кажется, что устройство получает только первый член, то есть получает команду ( "10000000000"). Я считаю, что настройки порта верны (хотя я мог быть совершенно не прав) и правильно подключили следующий образ команд, запущенных в GTKterm! http://oi59.tinypic.com/27wrexx.jpg. Кто-нибудь может понять, почему это может произойти? Большое спасибо Сэму

Мой код:

int flasher::allon(){
  int USB = open( "/dev/ttyUSB0", O_RDWR| O_NOCTTY );
  struct termios tty;
  struct termios tty_old;
  memset (&tty, 0, sizeof tty);

  /* Error Handling */
  if ( tcgetattr ( USB, &tty ) != 0 )
    {
      cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
    }

  /* Save old tty parameters */
  tty_old = tty;

  /* Set Baud Rate */
  cfsetospeed (&tty, (speed_t)B9600);
  cfsetispeed (&tty, (speed_t)B9600);

  /* Setting other Port Stuff */
  tty.c_cflag     &=  ~PARENB;        // Make 8n1
  tty.c_cflag     &=  ~CSTOPB;
  tty.c_cflag     &=  ~CSIZE;
  tty.c_cflag     |=  CS8;  
  tty.c_cflag     &=  ~CRTSCTS;       // no flow control
  tty.c_cc[VMIN]      =   1;                  // read doesn't block
  tty.c_cc[VTIME]     =   5;                  // 0.5 seconds read timeout
  tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

  /* Make raw */
  cfmakeraw(&tty);

  /* Flush Port, then applies attributes */
  tcflush( USB, TCIFLUSH );
  if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
     {
       cout << "Error " << errno << " from tcsetattr" << endl;
     }

  unsigned char cmd[] = "111111111111 \r\n";
  int n_written = 0;

  do {
    n_written += write( USB, &cmd[n_written], 1 );
  }
  while (cmd[n_written-1] != '\r' && n_written > 0);
  int n = 0;
  char buf = '\0';

  /* Whole response*/
  std::string response;

  do
    {
      n = read( USB, &buf, 1 );
      response.append( &buf );
    }
  while( buf != '\r' && n > 0);

  if (n < 0)
    {
      cout << "Error reading: " << strerror(errno) << endl;
    }
  else if (n == 0)
    {
      cout << "Read nothing!" << endl;
    }
  else
    {
      cout << "Response: " << response<<endl;
    }
  return 0;
}
  • 0
    Почему вы сделали буфер только одним символом?
  • 0
    Это было то, как ОП в ссылочной ветке делал это, и он / она утверждал, что это работает. Установка буфера записи на 12 и буфера чтения на 25 не помогает.
Показать ещё 6 комментариев
Теги:
serial-port
usb

1 ответ

0

По этой причине ваш код не будет работать наверняка

string имеет функцию append, которая принимает char *, но ожидает строку с нулевым завершением. Ваш buf - это всего лишь один символ, поэтому, если read() помещает в него символ, нет гарантии, что следует за ним в памяти, поэтому у вас нет нулевой строки с завершающим нулем, но неопределенного поведения.

Вероятно, вы должны предоставить буфер с более чем 1 символом, а затем использовать версию append которая занимает длину, передавая n.

В противном случае замените

response.append( &buf );

с

response.push_back( buf );

который может работать, но, вероятно, менее эффективен, чем использование многосимвольного буфера. Вероятно, вы должны проверить результат read прежде чем добавлять его. Поскольку код стоит, если read не выполняется, вы добавите его в любом случае.

Это утверждение, если оно вообще действует, должно переключать порядок предложений while

while (cmd[n_written-1] != '\r' && n_written > 0);

если n_written не> 0, то LHS является неопределенным поведением. Так

while ( n_written > 0 && cmd[n_written-1] != '\r');

Вы уверены, что это правильное условие для завершения цикла? Я предполагаю, что \r - это своего рода символ "сообщение поверх".

Если write() возвратил -1, это не обязательно будет нажимать n_written до или ниже 0.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню