ROS节点程序运行过程中需要获取机器人的传感器信息和发送控制指令,因此不可避免要与机器人进行通信,常见的通讯方式有串口、CAN和网口等,其中串口最为普遍。
ROS通过自带的 serial 包连接串口设备,进行串口通信,需要提前安装 serial 包:
sudo apt-get install ros-melodic-serial
串口通信根据数据传输方向可以分为 串口发送 和 串口接收 。
通过串口发送数据时,需要明确发送机制,常见的发送机制有:
定时发送是通过设定定时器,以 固定频率 发送数据包;
触发条件发送是通过条件判断语句,判断某个标志位或某个事件发生后,再发送数据包,特点是 频率不固定 。
发送数据分为两个步骤:
由此可知buffer数据结构需要可同时被这两个步骤访问,buffer需要为全局变量。
首先根据通信协议定义buffer中的帧头、帧尾等固定内容,然后接收别的Topic,获取待发送数据,把获取的数据填入到协议的数据段,最后根据数据段计算校验码。
1 订阅发送数据的Topic
serial_sub = nhsubscribe("/joy", 10, &DecodeFrame::serial_sub_callback,this);
2 根据Topic填入数据段和校验
1 创建定时回调函数
首先需要创建一个定时器,设定发送频率,并指定回调函数名称
write_rs232_timer = nhcreateTimer(ros::Duration(001), &DecodeFrame::CB_write_rs232_Cycle, this);
2 通过 serial 将buffer数据写入串口设备
实例化串口对象,并打开串口
发送数据到串口设备上
注意1:发送数据节点挂掉
若发送数据Topic的节点挂掉后,由于buffer是全局变量,buffer的数据段会一直是上一帧的数据,不会再改变,为避免上述情况,在将数据写入串口设备后, 将数据段清零。
注意2:joystick包发送机制
在使用PS3/PS4、Xbox手柄时,使用ros-melodic-joy包获取摇杆数据,手柄的遥杆或者按键如果一直处于同一位置(初始零位和最大值)只会发送一帧数据,不会连续发送, 只有当摇杆数据变化时,才会发送数据。
因此使用 rostopic hz /joy 会显示没有msg信息传输,所以串口程序不会进回调函数获取发送数据,但是数值确实是一直保持的, 所以就不能将数据段清零。
触发条件发送与定时发送相比的最大不同之处在于发送频率不同,不需要设置定时器,在满足条件后直接将数据写入串口即可。
不同的型号是不同的,一般只能一对一。康海时代(新三板挂牌代码:833422 )秉承“因为用心、所以专业”的经营理念,努力打造工业领域设备联网产业优质品牌。
围绕这一目标,公司形成了以科技创新为引领,以市场应用为导向,以产学研合作为载体,以项目开发为主体的创新机制, 通过掌握高集成度、低功耗、低成本基础嵌入式平台技术,高性能通用嵌入式平台技术,方便统一的设备联网管理软件技术和 基于ARM Cortex M系列平台的协议接口拓展技术,专业从事物联网通信领域串口通讯设备和网络通信产品的研发、生产、销售 及提供物联网通信解决方案。
人类生存于世,少不了沟通。沟通使人类互相认知,传递信息,提升生活品质。但然单片机也需要,不然单单一个机器,无法构成一个系统,发挥更大的力量。只有单片机与外围设备传递信息,互相反馈才会有一个完美的系统。串行口通信就被发明出来,下面来了解串行口通信(uart)。
为了能更好理解串行口通信,在介绍它之前,先来看看几个概念,补充知识,方便深入明白uart工作原理。
串行通信有两种,一位异步串行通信,二为同步串行通信。
异步串行通信 :异步串行通信是指通信双方以一个字符(包括特定附加位)作为数据传输单位且发送方传送字符的间隔时间不一定,具有不规则数据段传送特性的串行数据传输。
同步串行通信 :所谓同步通信是指在约定的通信速率下,发送端和接收端的时钟信号频率和相位始终保持一致(同步),这就保证了通信双方在发送和接收数据时具有完全一致的定时关系。
两种串行通信不同就只有时间,在发送字符时,异步可以是不同时间间隔发送,但同步只能以固定的时间间隔发送。
波特率 :波特率表示每秒钟传送的二进制位数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。
相互通信的甲乙双方必须具有相同的波特率,不然无法成功完成串行通信。
52单片机具有一个全双工串行通信口。一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最佳振荡频率为6M—12M。管脚RXD( P30),TXD(P31)与串口通信有关。波特率可以设置。
串行口通信与三个寄存器有关,分别是:
这个寄存器只有SMOD位与串行口通信有关。系统复位默认为SMOD=0。当为用52单片机的定时器2产生波特率时,波特率不受SMOD影响。用定时器1产生波特率时,不去设置,就默认为0,波特率正常,设置为1时,波特率加倍。
串行口为10位通用异步接口。发送或接收一帧数据信息为10位,包括1位起始位“0”、8位数据位、1位停止位“1”。发送数据:数据从TXD端口输出,当数据写入发送缓冲器SBUF时,就启动发送器发送。发送完一帧数据后,置中断标志TI=1,申请中断,通知CPU可以发送下一个数据了。接收数据:首先使REN=1(允许接收数据),串行口从RXD接收数据,当采样到1至0跳变时,确认是起始位“0”,就开始接收一帧数据,当接收完一帧数据时,置中断标志RI=1,申请中断,通知CPU从SBUF取走接收到的数据 。
溢出速率即溢出频率,只要算出定时器每溢出一次所需要的时间T,那溢出率就是1/T。计算在没有波特率加倍(SMOD=0)的情况下,波特率为9600bps时怎样赋值计数器。这里说明一下,由于波特率是需要很精确的,不然通信会出错。如果采用定时器工作模式1,采用人工重载,会有较大误差,因为进入中断函数也需要时间,累积时间就会出错。所以这里运用工作模式2,8位自动重装。计数器自动重装不需人工干预,减少误差。
对照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六进制为fd。
范例1是将接受的数据原封不动发送出去。采用查询法,故不需要打开串口中断,不用中断函数。只需不断查询TI,RI的值,就知道数据接收发送情况。
与范例1如出一撤,就不详细注释。
在串口通信中,方式1是最常用的,要认真理解方式1。串行数据一位一位的已经不用处理了,52单片机已经有一个模块处理完了。只要知道接收一个数据,产生一次接收中断,要软件置0,发送一个数据会产生一次发送中断,也要软件置0。自行置0,处理好数据就OK。下一篇将介绍其他三种方式,欢迎关注。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)