小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
使用小鱼的串口代码间歇性串口打开失败
-
@小鱼 晚上重新测试了一下小鱼你的库,是可以运行的,大概率是我修改代码有问题了,但是我自己找不到原因了,下面我是修改的地方:
1.删除了UDP部分的代码
2.删除了包装的用来选择serial或udp client和udp service的那一层代码
3.添加了发送uint8_t数组的函数
小鱼麻烦你帮忙看看了 -
@sen 测试了下,一切正常,多次打开和关闭都是正常的,应该是你哪里搞错了。
错误分析
我重新回头仔细看了下你的错误,核心错误是
std::bad_function_call
,这个应该是你调用函数错误造成的,其实串口已经被你打开了,你发送了错误的数据过去可能。查了下:https://www.apiref.com/cpp-zh/cpp/utility/functional/bad_function_call.html
另外在代码中src/fish_protocol/src/serial_protocol.cpp中使用printf打印串口打开标识是打印不出来的,所以被你当作一打开就错误,你可以换成std::cout进行打印,应该就可以正常看到串口已经被打开的打印了。
std::cout << "open with" << protocol_config_.serial_address_ << std::endl; serial_port_.open(protocol_config_.serial_address_, ec); assert(!ec); if(serial_port_.is_open()) printf("串口已打开!");
-
@小鱼 我刚才测试了一下,确实不是串口的问题,是velocity速度话题订阅者的创建导致了std::bad_function_call,但是之前也是这样子使用的,完全不明白为什么突然不行了。
另外,请问小鱼你测试的时候,更改了哪些地方呢? -
@sen 我测试的时候,用你的代码,一句话没有改哈,就是发送数据用的cli发的。
-
@小鱼 在你那边订阅者创建没有问题的话,就很奇怪了,我这边把订阅者创建语句注释掉之后,就能正常了,但是你那边又没问题,是ubuntu环境吗?
-
@小鱼 我这边突然又可以了,我通过git看了一下源码差异,就只改了如下两个不重要的地方:
1.
2.
就真的很玄学啊 -
@sen 结构体之类的最好做一下内存对齐,不然数据出问题可能性很大
-
@小鱼 好的,这个会检查一下,所以小鱼这个问题可能出在哪里呢 现在偶尔还是会出现std::bad_function_call,就很奇怪
-
@sen 问题应该还是在你发送的数据上,仔细检查一下这一块吧,数据转换出来可能存在空之类的情况造成的估计。
-
@小鱼
从上面的订阅者回调来看,应该是不会出现数据包为空的情况,在打包成帧之前,buf中的数据来自于订阅到的信息,打包的函数如下:
返回帧的cnt永远不会为0,所以发送出去的数据也不会为空 ,到现在为止真的不知道分析什么了,并且现在没出现std::bad_function_call了,等再出现的时候看看能不能找到,后续再更新在这个贴子里面,谢谢小鱼这两天的解答了! -
@小鱼 小鱼请问,我想实现类似stm32串口那样子的中断接收,有什么办法吗?或者我想在ros给下位机发送了指令后,获取下位机的反馈,但是你的代码里面的接收是异步接收的,所有没办法在下发指令之后去循环查询标志位获取返回信息,类似如下
因为是异步接收(本以为会跟stm32的串口中断一样),所有返回信息会在循环等待超时之后才会更新,也就是说每次都会超时,然后才更新数据。
请问有什么解决办法吗?谢谢小鱼 -
@sen 串口通信是全双功的,所以一定是收发不是同步的,不过你可以在数据接收那里进行数据标志的检测,然后他通过一个原子变量进行标志,应该可以达到同样的效果。
-
@小鱼 之前我测试的时候就是在串口接收函数的回调里面对数据进行分类处理,然后每一类数据都有一个flag,我在发送指令后while检测了一段时间应该有变化的那个flag,但是每次在while里面都检测不到flag就很奇怪,示例代码如下:
不知道哪里出问题了 -
@sen 这个你把返回的所有数据打印出来瞅瞅就可以给问题定位了,是没收到还是没发过来,都加个时间戳看看
-
@小鱼 小鱼,今天又出现了打开后出错的情况,如下:
最开始怀疑是数据量太大,做了几次测试之后,发现如果在启动串口时,缓存区已有大量数据,则会导致出错。如果启动时,缓存区数据较少,则可以正常使用,请问小鱼有解决办法吗? -
此回复已被删除! -
@sen 感谢反馈,我又仔细去看了下代码,问题是出在了,打开串口和设置回调函数的顺序问题,先打开了串口后设置了回调函数,如果此时有数据就没有办法进入回调.目前猜测最有可能是这里造成的问题,你可以将设置回调函数放在对串口对象的构造中,然后在构造函数里就完成对回调函数的设置,这样应该就没有问题了.
祝好!
-
@小鱼 小鱼你好,你的代码里面定义回调函数使用的是lambda函数体,我不太了解应该怎么将其放在串口对象的构造函数中,之前试过使用普通函数定义回调,但是编译有问题,请问能帮忙修改一下吗?谢谢小鱼了。
-
@sen 最近抽个空我更新一下,更新后再回复
-
@小鱼 好的,麻烦小鱼了!谢谢!