2009-10-20 7 views
2

문제 : 모든 포장의 그래픽 컬러 바코드를 스캔하는 휴대형 장치가 있습니다. 장치를 자동으로 밀기 위해 사용할 수있는 트랙 장치가 있습니다. 이 트랙 장치는 직렬 포트를 통해 ASCII 코드를 가져와 작동합니다. Mac에서 FileMaker에서이 작업을 수행해야합니다. 따라서 터미널 프로그램 등은 없습니다 ...C++ 직렬 포트 질문

내가 지금까지 가지고있는 것 : Keyspan USB/Serial 어댑터를 구입했습니다. ZTerm이라는 프로그램을 사용하여 장치에 명령을 보내는데 성공했습니다. 예 : "C 7^M^J"는

난이 명령을 사용하여 터미널에서 동일한 작업을 수행 할 수 있었다 : 화면 다음 /dev/tty.KeySerial1 57600 및 (위와 같은 명령을 입력 하지만 입력 할 때 나는 캐리지 리턴과 줄 바꿈을 위해 Control-M과 Control-J을 누르기 만했다.)

이제 C++의 FileMaker 용 플러그인을 작성하고있다. 위에서 수행 한 작업을 C++에서 수행하려고합니다. FileMaker에서 해당 플러그인을 설치하면 해당 함수 중 하나만 호출하고 전체 프로세스를 바로 수행 할 수 있습니다.

기기에 연결할 수는 있지만 통화 할 수 없습니다. 아무것도 응답하지 않습니다.

나는이 사용 (성공적으로) 장치에 연결 시도했다 :

FILE *comport; 
if ((comport = fopen("/dev/tty.KeySerial1", "w")) == NULL){...} 

int fd; 
fd = open("/dev/tty.KeySerial1", O_RDWR | O_NOCTTY | O_NDELAY); 

내가 장치에 대화의 방법으로 지금까지 시도한 것입니다 :

fputs ("C,7^M^J",comport); 

또는

,
fprintf(comport,"C,7^M^J"); 

또는

char buffer[] = { 'C' , ',' , '7' , '^' , 'M' , '^' , 'J' }; 
fwrite (buffer , 1 , sizeof(buffer) , comport); 

또는

fwrite('C,7^M^J', 1, 1, comport); 

질문 : 나는 터미널에서 장치와 ZTerm과를 사용하여 연결하면 , 내 보드를 설정 할 수 있었다 나는 그것이 그것이 여기에서 응답하지 않는 이유일지도 모른다라고 생각한다. 하지만 여기서 어떻게해야할지 모르겠다. 아무도 그 일을하는 방법을 알고 있는가? 나는이 시도했지만 작동하지 않았다

comport->BaudRate = 57600; 

가 밖으로 수준의 솔루션이 많이있다하지만 그들은 모두는 이러한 termios.h 및 STDIO.H 같은 파일을 포함 호출합니다. 나는 이것들을 가지고 있지 않으며 어떤 이유로 든 나는 그것들을 다운로드 할 수 없다. 몇 가지 예제를 다운로드했지만 20 개의 파일이 있고 다른 파일을 찾을 수 없습니다 (위에 나열된 파일과 비슷 함). 이걸 찾을 필요가 있습니까? 난 단지 C++에 대해 충분히 모른다. 라이브러리를 다운로드 할 수있는 웹 사이트가 있는가?

또 다른 해결책은 터미널 명령을 C++에 넣는 것입니다. 그렇게 할 수있는 방법이 있습니까?

이렇게 나에게 미치고 있습니다. 저는 C++이 아니기 때문에 기본적인 프로그래밍 개념 만 알고 있습니다. C++ 전문가가 누구입니까? 필자는 이상적인 fput, fputs stuff처럼 이미 가지고있는 함수를 사용하여 작업하고 싶습니다. 감사합니다.

답변

5

보내는 중^다음 M은 제어 -M을 전송하지 않습니다. 바로 문자를 쓰는 방법입니다. 제어 문자를 보내는 가장 쉬운 방법은 ascii control 코드를 사용하는 것입니다.

ps.^M은 캐리지 리턴입니다. "\ r"이고^J는 라인 피드입니다. "\ n"

편집 : 아마 더 이상 알 필요가 없을 것입니다. 그러나 더 이상 진행하기 전에 The Serial Port Howto을 읽으십시오.

0

모든 컴파일러 도구를 올바르게 설치 했습니까? 내 OS X 10.5.8 Mac에서 termios.h 및 stdio.h가/usr/include 아래에 있습니다. 예상대로입니다. 다른 유닉스 변종에서 직렬 포트 프로그래밍을 위해 이미 발견 한 코드는 으로 변경해야합니다 (있는 경우). 에 대해 더 자세히 알려주십시오. 무엇이 잘못 되었습니까?

mgb에는 제어 문자를 나타내는 방법에 대한 좋은 점도 있습니다.

1

이것은 C++ 문제가 아닙니다. TTY 드라이버를 사용하여 통신 속도를 설정하는 방법을 묻습니다./dev 밑에 파일을 열었다는 사실은 당신이 유닉스 파생물을 사용하고 있다는 것을 말해 주므로 리눅스 시스템에서 읽을 수있는 man 페이지는 "man 3 termios"입니다.

기본적으로 위의 open() 변형을 사용하고 파일 설명자를 tcsetattr/tcgetattr에 전달합니다.

0

전송 속도는 ioctl으로 설정할 수 있습니다. 여기에 link to an example이 있습니다.

+0

불행히도 휴대용 TTY ioctl API는 없습니다. 대신 POSIX API를 사용하는 것이 훨씬 좋습니다. c.f. termios, tcsetattr, et. al. –

0

사용중인 유닉스를 지정하지 않으므로 아래에서 제가 사용하는 일부 Linux 프로덕션 코드를 게시하고 있습니다.

아래 코드는 클래스 메서드이므로 외부 (즉, 선언되지 않은) 참조는 무시됩니다. 다음과 같이

단계는 -. 당신이 필요한 모든 플래그를 설정할 경우

당신의 TERMIO 구조를 구성,이는 등 (즉, 당신이 ZTerm과를 사용하여 아래의 TERMIO 설정은 8 데이터 비트, 1 stopbit로 포트를 구성 수행 단계 및 패리티 없음 (8-n-1). 또한 포트는 "raw"(cooked와 반대) 모드로되어 문자 스트림, 텍스트는 라인 등에 프레임되지 않습니다. 보오 상수는 실제 값과 일치합니다. 56,700 전송 당신은 "57600"를 사용합니다.

타이밍 파라미터는 문자가 즉시 사용할 수 있습니다로 장치에서 반환되는 것을 의미한다.

termainal 매개 변수가 설정되면 POSIX open()을 사용하여 장치를 연 다음 tcgetattr/tcsetattr을 사용하여 fd를 통해 장치를 구성 할 수 있습니다.

이 시점에서 read()/write() 시스템 호출을 사용하여 장치를 읽고 쓸 수 있습니다.

아래 예제에서 read()는 데이터가 없으면 차단되므로 차단이 바람직하지 않은 경우 select()/poll()을 사용하는 것이 좋습니다.

희망이 있습니다.

termios termio  
tcflag_t baud_specifier; 

    //reset device state... 
    memset (&termio, 0, sizeof (termios)); 
    read_buffer.clear(); 

    //get our boad rate... 
    if (!(baud_specifier = baud_constant (baud))) { 
     ostringstream txt; 
     txt << "invalid baud - " << baud; 
     device_status_msg = txt.str(); 
     status = false; 

     return (true); 
    } 


    //configure device state... 
    termio.c_cflag = baud_specifier | CS8 | CLOCAL | CREAD; 

    //do we want handshaking? 
    if (rtscts) { 
     termio.c_cflag |= CRTSCTS; 
    } 

    termio.c_iflag = IGNPAR; 
    termio.c_oflag = 0; 
    termio.c_lflag = 0; 

    //com port timing, no wait between characters and read unblocks as soon as there is a character 
    termio.c_cc[VTIME] = 0; 
    termio.c_cc[VMIN]  = 0; 

    //open device... 
    if ((fd = open (device.c_str(), O_RDWR | O_NOCTTY)) == -1) { 

     ostringstream txt; 
     txt << "open(\"" << device << "\") failed with " << errno << " - " 
      << std_error_msg (errno); 
     device_status_msg = txt.str(); 
     status = false; 

     return (true); 
    } 

    //keep a copy of curret device state... 
    if (tcgetattr (fd, &old_termio) == -1) { 

     ostringstream txt; 
     txt << "tcgetattr() failed with " << errno << " - " << std_error_msg (errno); 
     device_status_msg = txt.str(); 
     status = false; 

     return (true); 
    } 

    //flush any unwanted bytes 
    if (tcflush (fd, TCIOFLUSH) == -1) { 

     ostringstream txt; 
     txt << "tcflush() failed with " << errno << " - " << std_error_msg (errno); 
     device_status_msg = txt.str(); 
     status = false; 

     return (true); 
    } 

    //apply our device config... 
    if (tcsetattr (fd, TCSANOW, &termio) == -1) { 

     ostringstream txt; 
     txt << "tcsetattr() failed with " << errno << " - " << std_error_msg (errno); 
     device_status_msg = txt.str(); 
     status = false; 

     return (true); 
    } 

    node_log_f ("successfully initialised device %s at %i baud", "open_device()", 
       device.c_str(), baud); 

    status = true; 
    return (true); 
}