0
$\begingroup$

Rosanswers logo

I am trying to connect a VOC sensor in ROS via RS485 communication port. I opened the port with serial package downloaded form wjwwood.com now. Then I defined a char array request[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xc4,0x0b} and sent it to the port by the code ser.write(request).As a result, I received an response frame ("01 83 03 01 31") which means my request frame was wrong in Modbus protocol. Is it right to send a char array to the port?How to send hex type data to the serial port? Sorry for my poor English. Here are my codes.

#include <string>
#include <iostream>
#include <cstdio>

// OS Specific sleep
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "serial/serial.h"

using std::string;
using std::exception;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;



void my_sleep(unsigned long milliseconds) {
#ifdef _WIN32
      Sleep(milliseconds); // 100 ms
#else
      usleep(milliseconds*1000); // 100 ms
#endif
}

void enumerate_ports()
{
    vector<serial::PortInfo> devices_found = serial::list_ports();

    vector<serial::PortInfo>::iterator iter = devices_found.begin();

    while( iter != devices_found.end() )
    {
        serial::PortInfo device = *iter++;

        printf( "(%s, %s, %s)\n", device.port.c_str(), device.description.c_str(),
     device.hardware_id.c_str() );
    }
}

void print_usage()
{
    cerr << "Usage: test_serial {-e|<serial port address>} ";
    cerr << "<baudrate> [test string]" << endl;
}

 

int run(int argc, char **argv)
{
  if(argc < 2) {
      print_usage();
    return 0;
  }

  // Argument 1 is the serial port or enumerate flag
  string port(argv[1]);

  if( port == "-e" ) {
      enumerate_ports();
      return 0;
  }
  else if( argc < 3 ) {
      print_usage();
      return 1;
  }

  // Argument 2 is the baudrate
  unsigned long baud = 0;
#if defined(WIN32) && !defined(__MINGW32__)
  sscanf_s(argv[2], "%lu", &baud);
#else
  sscanf(argv[2], "%lu", &baud);
#endif

  // port, baudrate, timeout in milliseconds
  serial::Serial my_serial(port, baud, serial::Timeout::simpleTimeout(1000));

  cout << "Is the serial port open?";
  if(my_serial.isOpen())
    cout << " Yes." << endl;
  else
    cout << " No." << endl;

  // Get the Test string
  char ask[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xc4,0x0b};
  int count = 0;
  int i=0;
  string test_string;
  if (argc == 4) {
    test_string = ask;
  } else {
    test_string = ask;
  }

  // Test the timeout, there should be 1 second between prints
  cout << "Timeout == 1000ms, asking for 1 more byte than written." << endl;
  while (count < 10) {
    size_t bytes_wrote = my_serial.write(test_string);

    string result = my_serial.read(test_string.length()+1);

    cout << "Iteration: " << count << ", Bytes written: ";
    cout << bytes_wrote << ", Bytes read: "<<endl;
    cout << result.length() << ", String read: " << result << endl;
    //for( i=0;i<8;i++) {printf("%x\n",result[i]);}
    count += 1;
  }

  return 0;
}

int main(int argc, char **argv) {
  try {
    return run(argc, argv);
  } catch (exception &e) {
    cerr << "Unhandled Exception: " << e.what() << endl;
  }
}

And here are the results I received.

luc@luc-ThinkPad-T450:~/catkin_ws$ rosrun serial serial_example /dev/ttyUSB0 11
Is the serial port open? Yes.
Timeout == 1000ms, asking for 1 more byte than written.
Iteration: 0, Bytes written: 2, Bytes read: 
3, String read: �
Iteration: 1, Bytes written: 2, Bytes read: 
3, String read: 1
Iteration: 2, Bytes written: 2, Bytes read: 
3, String read: �1
Iteration: 3, Bytes written: 2, Bytes read: 
3, String read: `
Iteration: 4, Bytes written: 2, Bytes read: 
3, String read: ��
Iteration: 5, Bytes written: 2, Bytes read: 
3, String read: 1
Iteration: 6, Bytes written: 2, Bytes read: 
3, String read: �
Iteration: 7, Bytes written: 2, Bytes read: 
3, String read: 1
Iteration: 8, Bytes written: 2, Bytes read: 
3, String read: �(�
Iteration: 9, Bytes written: 2, Bytes read: 
3, String read: 

There are some unreadable codes like �(�, but I don't know why.


Originally posted by LucYang on ROS Answers with karma: 56 on 2017-10-09

Post score: 0


Original comments

Comment by jayess on 2017-10-09:
Should the link be http://wjwwood.io instead of http://wjwwood.com?

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

I sloved the question by just now. I read the documentation of Serial::write and it says the first parameter of Serial::write is a const reference containing the data to be written to the serial port, and it should be uint8_t type. So I changed

char ask[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xc4,0x0b};

to be

uint_8 ask[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xc4,0x0b};

and changed

size_t bytes_wrote = my_serial.write(test_string);

to be

my_serial.write(test_string,8);

Originally posted by LucYang with karma: 56 on 2017-10-09

This answer was ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.