0

I am doing serial communication using termios in C++.

#include <stdio.h>
#include <string.h>

// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()

#include <thread>

using std::thread;

int serial_port;
struct termios tty;

unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\n' };

char read_buf [256];
int num_bytes;

void setport()
{
  serial_port = open("/dev/ttyUSB0", O_RDWR);
}

void setup()
{
  if(tcgetattr(serial_port, &tty) != 0) 
  {
      printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
  }

  tty.c_cflag &= ~PARENB; 
  tty.c_cflag &= ~CSTOPB; 
  tty.c_cflag &= ~CSIZE; 
  tty.c_cflag |= CS8; 
  tty.c_cflag &= ~CRTSCTS; 
  tty.c_cflag |= CREAD | CLOCAL; 

  tty.c_lflag &= ~ICANON;
  tty.c_lflag &= ~ECHO; 
  tty.c_lflag &= ~ECHOE; 
  tty.c_lflag &= ~ECHONL; 
  tty.c_lflag &= ~ISIG; 
  tty.c_iflag &= ~(IXON | IXOFF | IXANY); 
  tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);

  tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
  tty.c_oflag &= ~ONLCR; 

  tty.c_cc[VTIME] = 0;    
  tty.c_cc[VMIN] = 1;

  cfsetispeed(&tty, B9600);
  cfsetospeed(&tty, B9600);

  if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
      printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
      //return 1;
  }
}

void send()
{
  while(true)
    {
      write(serial_port, msg, sizeof(msg));
      printf("%d\n",serial_port);
      sleep(1);
    }
}

void receive()
{
  int num_bytes;
  char read_buf [256];
  while (true)
    {
      num_bytes = read(serial_port, &read_buf, sizeof(read_buf));
      std::string
      printf("%s",read_buf);
      memset(&read_buf, '\0', sizeof(read_buf));
    }
}


int main()
{
  setport();
  setup();
  thread _send(send);
  thread _read(receive);
  _send.join();
  _read.join();
  return 0;
}

My C++ script is shown above. I am sending and receiving serial data at a same time. What is bothering me is the receiver part.

I am using another computer using pyserial and this computer just replies back what it receives. Therefore, I should receive message 'Hello\n' as soon as I send it.

However, I am receiving a 1 or 2 byte every time and this is really annoying. It seems like when I set tty.c_cc[VTIME] = 0; and tty.c_cc[VMIN] = 1; The receiver returns back as soon as it receives 1 or 2 bytes of memory. I want to make this return not by certain of byte but return by chunk. If returning with chunk is not possible, is there I can return it with certain character like '\n'?

Pablo
  • 13,271
  • 4
  • 39
  • 59
임성래
  • 43
  • 4
  • 1
    If you put it in cooked mode, it reads whole lines, so it will wait for the newline character. – Barmar Apr 20 '22 at 00:53
  • 임성래, How long do you want to wait for a `'\n'` to arrive? Forever? – chux - Reinstate Monica Apr 20 '22 at 00:54
  • @ Barmar What is cooked mode? @ chux - Reinstate MonicaYes. I can wait it forever. – 임성래 Apr 20 '22 at 01:02
  • https://en.wikipedia.org/wiki/Terminal_mode – Joseph Larson Apr 20 '22 at 01:40
  • "*What is cooked mode?*" -- The opposite of raw mode. See [Canonical Mode Linux Serial Port](https://stackoverflow.com/questions/57152937/canonical-mode-linux-serial-port) and https://stackoverflow.com/questions/25996171/linux-blocking-vs-non-blocking-serial-read/26006680#26006680 – sawdust Apr 20 '22 at 08:02

0 Answers0