stm32与ros进行串口通信

163
0
2021年1月4日 09时11分

最近老师定做了一个气动手抓,手抓的原理简单,主要是通过气泵充气后,通过24v电压控制,进而以通电和放电的方式来使手抓闭合和张开,此时可以用一个继电器来自动控制手抓电源。

 

首先分析一下继电器大致原理:如图所示,可以简化理解成通过给线圈通电后,然后产生电磁效应,使衔铁向下移动,从而使回路导通。当断电后,使衔铁向上移动,从而使回路断开

 

微信图片_20210103190600

 

针对于淘宝上购买的继电器模块

 

微信图片_20210103190626

 

可以通过上面的黑色跳线选择高低电平触发,

左边的电源与信号触发端包括三个端口:
DC+,DC-是决定高低电平的范围,如果两者连接的是5V,GND,则高电平认定为5V左右的小范围内,低电平认定为0V左右的小范围内。
IN 链接stm32 IO口,作为控制信号输入端

 

右边的继电器输出控制端包括三个端口:
NO,COM,NC,只需要连接其中两个端口
可以选择 NO,COM作为常开或NC,COM作为常闭,由于为开关所以没有正负输入端口之分,这里连接电压就是被控电压部分,常用的是5V,12V, 24V

 

在继电器内部,IO端口输出电流小,所以用三极管或ULN2003构成驱动电路,产生大电流,从而使电磁铁通电吸合。

 

首先用stm32在与pc进行串口通信,代码如下:

主程序:

 

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "led.h"   //包含对IO初始化
#include "usart.h"


int main (void){
	u8 a;
	//初始化
	RCC_Configuration(); //时钟设置
	LED_Init();//LED初始化
	USART1_Init(115200); //串口初始化(参数波特率)

	//主循环
	while(1){

		/查询方式
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){  //查询串口待处理标志位
			a =USART_ReceiveData(USART1);//读取接受到的数据
			switch (a){
				case '0':
					GPIO_WriteBit(GPIOB,GPIO_Pin_0,(BitAction)(0)); //控制PB0口,作为信号输入0
					printf("%c:PB0 OFF ",a); 
					break;
				case '1':
					GPIO_WriteBit(GPIOB,GPIO_Pin_0,(BitAction)(1)); //控制PB0口,作为信号输入1
					printf("%c:PB0 ON ",a); 
					break;
				default:
					break;
			}		  
		}
	}
}

 

github链接:https://github.com/harrycomeon/stm32-and-ros/tree/master/USART%E4%B8%B2%E5%8F%A3%E6%8E%A7%E5%88%B6%E7%BB%A7%E7%94%B5%E5%99%A8

 

然后是jlink下载器配置参考网址:https://blog.csdn.net/penglijiang/article/details/21653979
这里我采用的J-Link SWD接口,可以在线给stm32下载程序
需要进行以下修改:

 

1,更换Use

 

微信图片_20210103190650

 

单击Settings,更换port,确定

 

微信图片_20210103190704

 

2,更换Use Target Driver for Flash Programming

 

微信图片_20210103190716

 

单击Settings ,选择下面的芯片型号

 

微信图片_20210103190731

 

最后实际连线图,点击load下载程序

 

微信图片_20210103190747

 

微信图片_20210103190758

 

解决问题:串口驱动出现安装不上情况,出现黄色警告
解决网址:https://jingyan.baidu.com/article/27fa73268e06e046f9271f41.html

 

然后点击可以在线下载程序

然后通过串口发送0,1可以控制继电器导通和断开

 

已经在stm32上实现了和PC的串口通信,下一步我们要做的就是在ros上编写节点代替PC上串口调试器,把发送0.1的任务放在节点里。

这里我们参照网址下程序:参考网址:https://blog.csdn.net/weifengdq/article/details/84374690

github代码:https://github.com/harrycomeon/stm32-and-ros/tree/master/serial_communication

 

建立两个串口通信节点,一个发送0.一个发送1

修改后的主要程序如下:

这里我写入的1,也可以写入0,从而控制继电器断开和闭合,转换过程继电器会发出声音,serial_port sp(iosev, “/dev/ttyUSB0”); 是我们插入串口线后,电脑识别的设备号,可以在/dev文件夹下,看传入串口线后多出的设备号。

 

#include <string>
#include <ros/ros.h> // 包含ROS的头文件
#include <boost/asio.hpp> //包含boost库函数
#include <boost/bind.hpp>
#include "std_msgs/String.h" //ros定义的String数据类型

using namespace std;
using namespace boost::asio; //定义一个命名空间,用于后面的读写操作

unsigned char buf[1]; //定义字符串长度

int main(int argc, char **argv)
{

  ros::init(argc, argv, "serial_communication"); //初始化节点
  ros::NodeHandle n;

  //ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); //定义发布消息的名称及sulv

  ros::Rate loop_rate(10);

  io_service iosev;
  serial_port sp(iosev, "/dev/ttyUSB0"); //定义传输的串口
  sp.set_option(serial_port::baud_rate(115200));
  sp.set_option(serial_port::flow_control());
  sp.set_option(serial_port::parity());
  sp.set_option(serial_port::stop_bits());
  sp.set_option(serial_port::character_size(8));

  while (ros::ok())
  {
    write(sp, buffer(buf, 1));  //write the speed for cmd_val
    write(sp, buffer("1", 1));
    ros::spinOnce();
    loop_rate.sleep();

  }

  iosev.run();
  return 0;
}

 

整个系统的搭建图,这里我们未连接24v电源控制机械手抓,但是后来实验可以实现

**注意:**串口线部分(红色)连接的是stm32的3.3v电源,黑色连接stm32的地线,绿色连接stm32的RXD,白色连接的stm32的TXD。

 

微信图片_20210103190900

 

节点图

 

微信图片_20210103190918

 

遇到下面问题的解决办法:

 

微信图片_20210103190932

 

sudo chmod 777 /dev/ttyUSB0
给端口加权限
//这是一次性操作,重启之后就会失效,可设置永久操作如下:
sudo usermod -aG dialout dzu
// –dzu 是你Ubuntu使用者的名字

 

运行指令:

 

roscore
(连线连接到常开状态)
rosrun serial_commucation serial_handoff(手抓张开)
rosrun serial_commucation serial_handon (手抓闭合)

 

发表评论

后才能评论