简体   繁体   中英

Reading HEX values from a serial port (Posix)

I wrote a class to handle data coming from a module to the serial port. The goal is having the port always listening and when it's needed transmit some messages. The module communicates using hexadecimal tokens. Here is my code for the receiving part:

int serial::serial_receive (string &s_buffer, int &rcp)
{
  struct pollfd fds[1];
  fds[0].fd = ptr;
  fds[0].events = POLLIN ;
  int pollrc = poll( fds, 1, 1000);
  if (pollrc < 0)
  {
    perror("poll");
  }
  else if( pollrc > 0)
  {
    if( fds[0].revents & POLLIN )
    {
      char buff[1024];
      ssize_t rc = read(ptr, buff, sizeof(buff) );
      if (rc > 0)
      {
        s_buffer = buff;
        rcp = rc;
       }
        else {cout << "error reading fd";}
    }

}
return pollrc;
}

In my test main:

using namespace std;
char test[] = {0xAA,0x34,0x00,0x22};

int main(void) {
    stringstream ss;
    const char* mybuff;
    string serial_buffer;
    int rcl;

    serial mymodule ("/dev/ttymxc5",115200, 0);  //port configuration

    ss << std::hex << setfill('0');
    mymodule.serial_send(test,4);                //send method
    usleep(2000);

    mymodule.serial_receive(serial_buffer,rcl);  //receive method

    mybuff = serial_buffer.c_str();
        for (int i = 0; i < 8; ++i)
        {
            ss << std::setw(2) << static_cast<unsigned>(mybuff[i]);
        }
    cout << ss.str() << endl;

return 0;
}

My serial port configuration is:

int serial::serial_set()
{
  struct termios options;
  if (tcgetattr (ptr, &options) != 0)
              {
                      return EXIT_FAILURE;
              }
   cfsetospeed (&options, B115200);
   cfsetispeed (&options, B115200);
   options.c_cflag = (options.c_cflag & ~CSIZE) | CS8;
   options.c_iflag &= ~IGNBRK;
   options.c_lflag = 0;
   options.c_oflag = 0;
   options.c_cc[VMIN]  = 0;
   options.c_cc[VTIME] = 5;
   options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |    ICRNL | IXON);
   options.c_cflag |= (CLOCAL | CREAD);
   options.c_cflag &= ~(PARENB | PARODD);
   options.c_cflag |= serial_parity;
   options.c_cflag &= ~CSTOPB;
   options.c_cflag &= ~CRTSCTS;
   if (tcsetattr (ptr, TCSANOW, &options) != 0)
      {
       return EXIT_FAILURE;
      }
return EXIT_SUCCESS;
 }

Please note that ISTRIP bit is set as 0, not to lose the 8th bit.

The resoult i get is "almost" correct. I'm aspecting a AA B4 04 01 00 00 00 94 sequence but instead i get a AA B4 04 01 00 A8 4A F0 sequence. This mistake is repeatable, every time I send given command to the module.

Do you possible have some ints or suggestions ?

After some thinking, I found out that i can't simply cast string = char*.

I used a string method instead to build my string:

std::string check(reinterpret_cast<char*>(buff), 8);

Where buff is the char array to convert and 8 is the number of elements.

Thanks to Neil Butterworth who pointed out the unsafe casting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM