C++로 Linux(Ubuntu)환경에서 시리얼 통신으로 센서 값을 읽어보자!

코드


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <termios.h>                   // B115200, CS8 등 상수 정의
#include <fcntl.h> 

class IMU_Receiver
{
public:
  IMU_Receiver()
  {
    
  }
  ~IMU_Receiver()
  {
  }

  bool init()
  {
    // Open the device
    fd_ = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);

    if (fd_ < 0)
    {
      std::cerr << "Cannot open the port" << std::endl;
      return false;
    }

    // Port environment configuration
    memset(&newtio_, 0, sizeof(newtio_));
    newtio_.c_cflag     =   B115200 | CS8 | CLOCAL | CREAD;
    newtio_.c_oflag       = 0;
    newtio_.c_lflag       = 0;
    newtio_.c_cc[VTIME]   = 0;
    newtio_.c_cc[VMIN]    = 1;

    tcflush(fd_, TCIFLUSH);
    tcsetattr(fd_, TCSANOW, &newtio_);
    fcntl(fd_, F_SETFL, FNDELAY); 

    // Ready to poll event
    poll_events_.fd        = fd_;
    poll_events_.events    = POLLIN | POLLERR;          // 수신된 자료가 있는지, 에러가 있는지
    poll_events_.revents   = 0;

    return true;
  }

  void communicate()
  {
    while(1)
    {
      /**
       * @brief poll()을 호출하여 event 발생 여부 확인 
       * event 등록 변수
       * 체크할 pollfd 개수
       * time out 시간
       */
      poll_state_ = poll( (struct pollfd*)&poll_events_, 1, 1000);

       // 발생한 event 가 있음
      if (poll_state_ > 0)
      {
        // event 가 자료 수신?
        if ( poll_events_.revents & POLLIN)
        {
          cnt_ = read( fd_, buf_, 1024);

          // serial write test
          write( fd_, buf_, cnt_); 
          std::cout << "data received [" << cnt_ << "] bytes: " << buf_ << std::endl;
        }

        // event 가 에러?
        if ( poll_events_.revents & POLLERR)
        {
          std::cout << "Error on communication line, process died" << std::endl;
          break;
        }
      }
      else if(poll_state_ < 0)
      {
        std::cerr << "critical error !!! " << std::endl;
        break;
      }
      else if(poll_state_ == 0)
      {
        std::cout << "wait...." << std::endl;
      }
    }
  }

private:
  int fd_;
  int ndx_;
  int cnt_;
  char buf_[1024];
  struct termios newtio_;
  struct pollfd poll_events_;
  int poll_state_;
};

int main()
{
  IMU_Receiver IR;

  if (!IR.init()) std::cerr << "[main.cpp] cannot create IMU_Recevier object... " << std::endl;
  IR.communicate();

  return 0;
}

Reference


Leave a comment