시리얼통신에서 select함수 사용에 대한 질문입니다..

cdcmp의 이미지

안녕하세요...

시리얼 통신으로 센서 입력을 받고 있는데요...

pc에서 8개의 데이터를 센서로 보내면 센서에서는 측정한 데이터를 pc로

계속 보내게 되는 겁니다..

센서는 거리측정용 레이져 센서입니다..

그런데 입력 받은 데이터를 확인 하면 잃어버린 데이터가 많습니다..

그래서 select함수를 사용하여 데이터를 받는걸로 수정을 했는데요..

코드는 다음과 같습니다..

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>

#define  SERIALDEVICE "/dev/ttyMP1"
#define  BAUDRATE B9600

#define FALSE 0
#define TRUE 1

volatile int READ_LOOP = TRUE;
volatile int WRITE_LOOP = TRUE; 

unsigned char tx_buf[8];
unsigned char rx_buf[100000];

FILE *fp;

void laser::start()
{
    tx_buf[0] = 0x02;
    tx_buf[1] = 0x00;
    tx_buf[2] = 0x02;
    tx_buf[3] = 0x00;
    tx_buf[4] = 0x20;
    tx_buf[5] = 0x24;
    tx_buf[6] = 0x34;
    tx_buf[7] = 0x08;

	   
    int i,nread;
    struct termios oldtio, newtio;
    
    fd_set readfs;
    
    fd0 = open(SERIALDEVICE,O_RDWR|O_NOCTTY);
    if(fd0<0)
    {
	printf("file open error\n");
	perror(SERIALDEVICE);
	exit(-1); 
    }
			
    tcgetattr(fd0,&oldtio);
    bzero(&newtio, sizeof(newtio));
    newtio.c_cflag= (CS8+BAUDRATE+CREAD+CLOCAL+HUPCL);
    newtio.c_lflag &= ~ICANON;
    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
	
    tcflush(fd0, TCIFLUSH);
    tcsetattr(fd0,TCSANOW,&newtio);
		
    FD_ZERO(&readfs);
    FD_SET(fd0,&readfs);
    
    while(WRITE_LOOP == TRUE)
    {
	for(i=0;i<8;i++)
	{		
	    write(fd0,&tx_buf[i],8);
	}
	
	WRITE_LOOP = FALSE;
	i = 0;
    }
	
    while(READ_LOOP == TRUE)
    {
	fp = fopen("/home/eunsu/serial/select/laser/data.txt","a+");	
	
	select(fd0, &readfs, NULL, NULL, NULL);
			
	if(FD_ISSET(fd0, &readfs))     
	{
	    ioctl(fd0,FIONREAD,&nread);
	        
	    nread = read(fd0,&rx_buf[i],sizeof(rx_buf));
	     
	    fprintf(fp,"%x \n",rx_buf[i]);
	    printf("%x \n",rx_buf[i]);
	    fclose(fp);
	}

	i++ ;
}

이와같이 해서 실행을 시켜 보았는데요...

그런데 read로 아무런 값을 읽어 내지를 못합니다....

select쪽에 코딩이 잘못된거 같은데 어디서 잘못된는지를....

감이 잘 안오네요....

serial howto문서와 프로그래밍 책을 참고 해서 코딩했습니다...

다시한번 여러분들께 부탁드리겠습니다...

오늘도 삽질의 연속입니다....ㅜㅜ[/u]

은영신랑의 이미지

while(WRITE_LOOP == TRUE) 
    { 
   for(i=0;i<8;i++) 
   {       
       write(fd0,&tx_buf[i], 8); 
   }

루프를 돌리고 &tx_buf[i] 를 넣어주신걸 보면 1바이트씩 보내려는 의도가
아니신지요? 그런데 8바이트씩 8번을 보내게 되는 코드 같습니다.
1로 바꾸어야 할것 같은데요.

   select(fd0, &readfs, NULL, NULL, NULL); 
          
   if(FD_ISSET(fd0, &readfs))      
   { 
       ioctl(fd0,FIONREAD,&nread); 
           
       nread = read(fd0,&rx_buf[i],sizeof(rx_buf)); 
         
       fprintf(fp,"%x \n",rx_buf[i]); 
       printf("%x \n",rx_buf[i]); 
       fclose(fp); 
   } 

여기도 위에서와 마찬가지 인것 같네요. 1바이트씩 받는건지, 한꺼번에
받는건지 코드가 에매합니다.
cdcmp의 이미지

은영신랑님 답변 감사합니다..^^

read하는곳에서 한바이트씩 읽어야 하는데...설정을 잘못했었군요...

이거 때문에 몇일 삽질 했는데...

해결 됐습니다...

다시한번 감사합니다..^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.