ROS与STM32通信的实现

ROS功能包与STM32工程文件:
蓝奏云:https://huffie.lanzouw.com/iN7w602ti37a

1 通信协议

STM32和ROS端各有一个数据发送函数和数据接收函数,发送和接受的数据以数据包的形式发送。

数据包的内容:

数据头55aa + 数据字节数size + 数据共用体 + 校验crc8 + 数据尾0d0a

2 原理

2.1 收发数据方法简述

首先,串口收发数据是一个字节一个字节的传输的。一个字节最大表示数据是255,而往往我们需要传递的传感器数据都是int/float类型的。

传统的串口通信方法是将int/float数据分解成一个个字节发送出去。

而这里使用共用体,将数据通过共用体转换为数组发送。

2.2 数据共用体的使用

共用体的规则

  • 共用体是结构体内不同成员共享内存的机制,各成员内存地址一致
  • 同一时刻只能访问其中的一个成员
  • 不同成员按照成员类型的性质进行内存访问。

共用体的创建

#include <stdio.h>
#include <string.h>

union Data
{
    
    
	int i;
	float f;
	char str[20];
};

int main()
{
    
    
	union Data data;
	data.i = 10;
	data.f = 220.5;
	strcpy( data.str, "C Programming");
	printf( "data.i : %d\n", data.i);
	printf( "data.f : %f\n", data.f);
	printf( "data.str : %s\n", data.str);
	return 0;
}

最后赋给变量的值占用了内存位置,因此同一时间只能用到一个成员。

如何使用共用体

在通信两端都定义同样数据结构的共用体,该共用体包含一个short/int/float类型的变量和一个unsigned char类型的数组,数组大小与变量字节大小对应。这样发送和接收数据时,只发送或接收共用体中unsigned char数组的元素。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2H37g76m-1657014428833)(https://gitee.com/huffiema/pictures/raw/master/image/202203251701027-stm32-ros-1.png)]

3 准备工作

3.1 硬件准备

使用STM32串口+TTL转USB模块(CH340)+Linux设备。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PNRHaaBv-1657014428835)(https://gitee.com/huffiema/pictures/raw/master/image/202203251702390-stm32-ros-2.png)]

注意事项

  • STM32和ROS的串口波特率必须一致
  • STM32串口和USB转TTL模块连接正确,RX-TX,TX-RX
  • Linux设备安装好CH340/CH341驱动
  • 确保串口在Linux系统上有超级用户权限
  • 将ROS功能包中mbot_linux_serial.cpp文件中的串口设备名字改为自己的设备名

3.2 串口设置

查看串口设备

Linux设备插上USB转TTL模块后,打开终端,输入命令:

ls -l /dev/ttyUSB*

如果终端出现类似下面的输出结果,说明串口设备已经被识别

crw-rw---- 1 root dialout 188, 0 325 17:07 /dev/ttyUSB0

设置串口权限

在终端中输入下面命令:(注意自己的串口设备名)

sudo chmod 777 /dev/ttyUSB0 
source devel/setup.bash

如果没有任何输出,说明串口设备设置权限成功。(每次重新启动或重新插入串口设备后都需要进行这样的操作)

4 程序设计

4.1 STM32程序设计

工程文件中提供的是STM32F103的程序,也可以在自己板子的串口收发例程的基础上进行修改,添加mbotLinuxUsart.c和mbotLinuxUsart.h到工程中即可。

函数调用方式如下:

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "mbotLinuxUsart.h"//引用该头文件是使用,通信协议的前提

//测试发送变量
short testSend1   =5000;
short testSend2   =2000;
short testSend3   =1000;
unsigned char testSend4 = 0x05;

//测试接收变量
int testRece1     =0;
int testRece2     =0;
unsigned char testRece3 = 0x00;

int main(void)
{
    
       
/*************** 硬件初始化 ***************/
    delay_init();                                   //延时函数初始化   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组2
    uart_init(115200);                              //串口初始化为115200

/***************循环程序 ***************/
    while(1)
    {
    
    
        //将需要发送到ROS的数据,从该函数发出,前三个数据范围(-32768 - +32767),第四个数据的范围(0 - 255)
        usartSendData(testSend1,testSend2,testSend3,testSend4);
        //必须的延时
        delay_ms(13);
    } 
}

/*************** 串口中断服务程序 ***************/
void USART1_IRQHandler()
{
    
    
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
     {
    
    
         USART_ClearITPendingBit(USART1,USART_IT_RXNE);//首先清除中断标志位
         //从ROS接收到的数据,存放到下面三个变量中
         usartReceiveOneData(&testRece1,&testRece2,&testRece3);
     }
}

4.2 ROS程序设计

[[01_Ubuntu20.04安装ROS Noetic|ROS安装]]过程不再介绍

第一步

首先[[13_ROS系统基本功能的使用详解(基本指令、节点、服务、启动文件、动态参数)]](如果没创建的话)

mkdir -p ~/catkin_ws/src
cd catkin_ws/src
catkin_init_workspace

第二步

将topic_example功能包复制到src目录下,然后回到工作空间目录进行编译

cd ..
catkin_make

5 测试

添加串口设备权限

sudo chmod 777 /dev/ttyUSB0
source devel/setup.bash

打开新终端,启动`ros master

roscore

打开新终端,启动测试功能包

rosrun topic_example publish_node

可以看到从STM32接收到的数据。

本博客文章首先发布于个人博客:https://www.mahaofei.com/,欢迎大家访问。

猜你喜欢

转载自blog.csdn.net/weixin_44543463/article/details/125624913