紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
怎样愉快的使用串口发送16进制数据并读取串口内容
-
像雷达 imu 陀螺仪一类的传感器,一般都是用的usb转串口和主机连接,然后通过串口读取传感器数据,串口是我们绕不过的一道坎,那我们今天就来手撕串口。
串口连接主机问题参考:
https://blog.csdn.net/m0_73694897/article/details/131526937?spm=1001.2014.3001.5502
安装serial库参考:
https://blog.csdn.net/slampai/article/details/127876015
现在我们假装已经连接好了串口,并且串口的端口名: /dev/ttyUSB0
串口测试程序,硬件用JY_95T IMU加速度计 陀螺仪,这款imu在工作前需要发送一段代码命令设置imu的工作方式 {0xA4,0x03,0x08,0x23,0xD2}
创建文件目录mkdir serial_test_cpp cd serial_test_cpp mkdir build touch serial_test.cpp touch CMakeLists.txt
目录结构
serial_test.cpp//serial_test.cpp #include <serial/serial.h> //导入串口库,这个串口库需要安装 int main(void) { std::string port_name="/dev/ttyUSB0"; //根据自己的硬件端口号调整 int baud_rate_=115200; //这里可以查看使用手册 serial::Serial ser; //创建串口对象 /**打开设备**/ try { ser.setPort(port_name); ser.setBaudrate(baud_rate_); serial::Timeout to = serial::Timeout::simpleTimeout(100); ser.setTimeout(to); ser.open(); } catch (serial::IOException &e) { printf("串口打开失败!\n"); } if (ser.isOpen()) { printf("串口已经打开\n"); } //----------------------------发送数据---------------------------------- //unsigned char cmd_buffer[5] ={'a','b','c','d','e'}; //发送字符 c风格字符需加单引号 unsigned char cmd_buffer[5] ={0xA4,0x03,0x08,0x23,0xD2}; //发送16进制数 0x开头是16进制数字写法 //unsigned char cmd_buffer[5] ={2,15,55,120,255}; //发送10进制数,无符号char取值范围0-255 //unsigned char cmd_buffer[5] ={'a','b',0x03,120,255}; //混合发送字符 16进制数 10进制数 /* 上面的不同组合可以分别打开屏蔽发送试试,串口应该是只能发送unsigned char类型,取值范围0-255,字符,16进制, 10进制在ASCII码里面是同一种东西 */ ser.write(cmd_buffer,5); //向串口发送数据 //%x是16进制占位符 printf("发出命令: %x %x %x %x %x\n",cmd_buffer[0],cmd_buffer[1],cmd_buffer[2],cmd_buffer[3],cmd_buffer[4]); //----------------------------接收数据---------------------------------- int count = ser.available(); // count读取到缓存区数据的字节数,不等于0说明缓存里面有数据可以读取 while (count != 0) //无限循环接收数据 { printf("从串口接收数据\n"); //int num; std::vector<unsigned char> read_buf(count);//开辟数据缓冲区,串口read读出的内容是无符号char类型 ser.read(&read_buf[0], count); // 读出缓存区缓存的数据,返回值为读到的数据字节数 for(int i = 0;i < count;i++) { printf("%x ",read_buf[i]); //%x 以16进制的方式打印收到的每一位数据 } printf("\n"); } return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(serial_test) #Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(serial REQUIRED) add_executable(${PROJECT_NAME} serial_test.cpp) target_link_libraries(${PROJECT_NAME} serial)
编译
cd ~/serial_test_cpp/build cmake .. make ./serial_test //运行测试程序
测试结果
至此通过串口已经成功发送数据,并且在循环接收串口发送来的数据了。不同的串口传感器在发送和接收数据层面功能是相同的,收到的数据存在了read_buf动态数组里面,通过解析数组里面的数据造就了不同的硬件功能,比如陀螺仪输出的是角速度, 雷达输出的是距离信息。