FTDI を使用して USB ポート経由でデータを送受信しようとしているため、C/C++ を使用してシリアル通信を処理する必要があります。Linux(Ubuntu)で作業しています。
基本的に、着信コマンドをリッスンしているデバイスに接続しています。これらのコマンドを送信し、デバイスの応答を読み取る必要があります。コマンドもレスポンスもASCII文字です。
GtkTerm を使用するとすべて正常に動作しますが、C プログラミングに切り替えると問題が発生します。
これが私のコードです:
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
/* Open File Descriptor */
int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY );
/* Error Handling */
if ( USB < 0 )
{
cout << "Error " << errno << " opening " << "/dev/ttyUSB0" << ": " << strerror (errno) << endl;
}
/* *** Configure Port *** */
struct termios tty;
memset (&tty, 0, sizeof tty);
/* Error Handling */
if ( tcgetattr ( USB, &tty ) != 0 )
{
cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
}
/* Set Baud Rate */
cfsetospeed (&tty, B9600);
cfsetispeed (&tty, 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_lflag = 0; // no signaling chars, no echo, no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // 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
tty.c_iflag &= ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
tty.c_oflag &= ~OPOST; // make raw
/* Flush Port, then applies attributes */
tcflush( USB, TCIFLUSH );
if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
{
cout << "Error " << errno << " from tcsetattr" << endl;
}
/* *** WRITE *** */
unsigned char cmd[] = {'I', 'N', 'I', 'T', ' ', '\r', '\0'};
int n_written = write( USB, cmd, sizeof(cmd) -1 );
/* Allocate memory for read buffer */
char buf [256];
memset (&buf, '\0', sizeof buf);
/* *** READ *** */
int n = read( USB, &buf , sizeof buf );
/* Error Handling */
if (n < 0)
{
cout << "Error reading: " << strerror(errno) << endl;
}
/* Print what I read... */
cout << "Read: " << buf << endl;
close(USB);
何が起こるかというと、read()
0 (バイトがまったく読み取られない) を返すか、タイムアウトになるまでブロックする ( VTIME
) ことです。write()
何も送信しないため、これが発生すると想定しています。その場合、デバイスはコマンドを受信せず、応答を受信できません。実際、プログラムの読み取りがブロックされている間にデバイスの電源を切ると、実際に応答を得ることができました (デバイスはシャットダウン中に何かを送信します)。
奇妙なことは、これを追加することです
cout << "I've written: " << n_written << "bytes" << endl;
write()
電話の直後に、私は受け取ります:
I've written 6 bytes
これはまさに私が期待するものです。私のデバイスが実際にポートに書き込んでいるものを受信できないなど、私のプログラムだけが正常に機能しません。
データ型に関しても、さまざまなことと解決策を試しました(cmd = "INIT \r"
orなどの std::string を使用してみましconst char
た)が、実際には何も機能しませんでした。
誰かが私が間違っている場所を教えてもらえますか?
前もって感謝します。
編集: このコードの以前のバージョンが使用されました
unsigned char cmd[] = "INIT \n"
そしてまたcmd[] = "INIT \r\n"
。デバイスのコマンド sintax が次のように報告されているため、変更しました。
<command><SPACE><CR>
.
また、読み取り時にフラグを回避しようとしましO_NONBLOCK
たが、その後は永遠にブロックするだけです。使用してみましselect()
たが、何も起こりません。試しに、データが利用可能になるまで待機ループを作成しましたが、私のコードはループを終了しません。ところで、待っているか、usleep()
私が避ける必要があるものです。報告されたものは、私のコードの抜粋にすぎません。完全なコードはリアルタイム環境(特に OROCOS) で動作する必要があるため、スリープのような機能はあまり必要ありません。