众为兴SCARA四轴机械臂编程——基于硬接线替代Modbus通讯

Posted 杀智勇双全杀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了众为兴SCARA四轴机械臂编程——基于硬接线替代Modbus通讯相关的知识,希望对你有一定的参考价值。

众为兴SCARA四轴机械臂编程(二)——基于硬接线替代Modbus通讯

众为兴SCARA四轴机械臂编程(一)——基于ModbusTCP协议

概述

由于Siemens S7-200SMART ST20是小型PLC,使用通讯功能时导致扫描周期变长,实时性、稳定性、可靠性极差。。。控制逻辑繁琐时尤甚。。。换用稍微不那么低端的PLC如S7-1200系列的1214C成本偏高,且本体IO点数不太够。。。接IO模块的成本高。。。倒不如工控机写上位机直连SCARA。。。原理上讲PLC完全没用。。。但是其中有些不可告人的秘密,又不能不用。。。本着能省则省的原则,使用硬接线的方式替代ModbusTCP,解决PLC性能过差的问题。。。

原理

SCARA驱控一体机自身就可以做中位机,但是为了用上PLC【这种情况用PLC就像SuperMan把大裤衩子穿外边】,只好屈尊做类似电机驱动板的下位机,让PLC做中位机。

嵌入式单片机能够实现通讯是因为有串口通讯协议,不管是UART的异步串口通讯(如RS485、RS232、RS422)还是网口,底层都是利用高低电平实现的逻辑01。TTL电平是5v为+,当然也有5v为0负电平为1的情况,RS232还有±12V构成电压差24V的做法。。。从数电的角度考虑,只需要知道电势差即可,PNP和NPN大不了反着用。。。大不了最后给读到的电平高低Inv取反。。。

通讯协议一般有起始帧、数据帧、校验帧、结束帧,好多位,也可以自己写一个协议。还有波特率决定传输速率。SCARA每次执行需要超过1s,传输速率并没有太高要求。那么,只需要每次执行结束后读取一次输入状态即可,没有刷新就死等,即可稳定通讯。死等的方式可以使扫描周期内只扫描接头电平而不扫描后续代码段,减少了CPU负载,防止出现跑飞的情况。。。

众所周知,1条线有10高低电平可以表达2种情况,2条线就是4种,3条线就是8种。。。考虑到可以读写分离,4条线就是16种命令,其实够用了。。。

代码实现

--************虎彩印艺股份有限公司************
--2021年1月24日 xx机械臂程序		Dai→He→Zhiyong

--********************PLC到机器人的信号定义开始**********************
local IN_Run   = 1				--PLC1 Q1.0 机器人启动
local IN_Stop  = 2				--PLC1 Q1.1 机器人停止
local IN_Pause = 3				--PLC1 Q1.2 机器人暂停
local IN_Reset = 4				--PLC1 Q1.3 机器人复位
local IN_Sucker = 9				--PLC1 Q0.7 机器人吸嘴状态 (0 == 打开, 1 == 关闭)

--*****************************PLC输出****去原点***去取料点*去正上点*去反上点***去正放点**去反放点**去NG点*去取料***去正搬***去反搬*去压配*
local IN_5 = 5				--PLC1 Q1.4		0		0		0		0		0		0		0		1		1		1		1
local IN_6 = 6				--PLC1 Q1.5		0		0		0		1		1		1		1		0		0		0		0
local IN_7 = 7				--PLC1 Q1.6		0		1		1		0		0		1		1		0		0		1		1
local IN_8 = 8				--PLC1 Q1.7		1		0		1		0		1		0		1		0		1		0		1
--*****************************PLC输出****去原点***去取料点*去正上点*去反上点***去正放点**去反放点**去NG点*去取料***去正搬***去反搬*去压配*
--*****************************IN 5~8	  0001	   0010		0011	0100	0101	0110	0111	1000  1001	  1010     1011	
--****************************Command		1		2		  3		 4		 5		 6		 7		 8		9	    10	    11	  

--********************PLC到机器人的信号定义结束**********************


--********************机器人到PLC的信号定义开始**********************
local Alarm = 1				--PLC1 I1.0 机器人报警
--*****************************PLC输入****去原点***去取料点*去正上点*去反上点***去正放点**去反放点**去NG点*去取料***去正搬***去反搬*去压配****收到命令**
--*****************************PLC In***P_Ready***P_Get***P_p1***P_n1*****P_p2****P_n2*****P_Ng****Get*****M_p*****M_n****Push***Received**
local OUT_2 = 2				--PLC1 I1.1		0		0		0		0		0		0		0		1		1		1		1		1 
local OUT_3 = 3				--PLC1 I1.2		0		0		0		1		1		1		1		0		0       0       0       1 
local OUT_4 = 4				--PLC1 I1.3		0		1		1		0		0		1		1		0		0       1       1       1 
local OUT_5 = 5				--PLC1 I1.4		1		0		1		0		1		0		1		0		1       0       1       1  
--****************************机器人输出****去原点***去取料点*去正上点*去反上点***去正放点**去反放点**去NG点*去取料***去正搬***去反搬*去压配****收到命令**
--*****************************OUT 2~5	  0001	   0010	  0011	  0100	  0101	   0110	   0111	   1000	   1001		1010	1011	111
--****************************Response		1		2		3	    4		5		 6		 7	    8		9		10		11		15

--********************机器人到PLC的信号定义结束**********************


--***************定义变量开始****************

local Spd_Init 			= 20		    							--机器人初始化速率,范围 1~100(允许改动)
local command 			= 0											--PLC控制命令
local Run_Speed 		= 95										--机器人运行速度
local Order 			= "{IN5,IN6,IN7,IN8}"						--使用"Order"代替"{IN5,IN6,IN7,IN8}"
local Response 			= "{OUT_2,OUT_3,OUT_4,OUT_5}"				--使用"Response"代替"{OUT_2,OUT_3,OUT_4,OUT_5}"
local P_Ready  			= "{OFF,OFF,OFF,ON}"						--使用"P_Ready"代表到达原点状态
local P_Get				= "{OFF,OFF,ON,OFF}"						--使用"P_Get"代表到达取料点状态
local P_p1				= "{OFF,OFF,ON,ON}"							--使用"P_p1"代表到达正放上方点状态
local P_n1				= "{OFF,ON,OFF,OFF}"						--使用"P_n1"代表到达反放上方点状态
local P_p2  			= "{OFF,ON,OFF,ON}"							--使用"P_p2"代表到达正放点状态
local P_n2   			= "{OFF,ON,ON,OFF}"							--使用"P_n2"代表到达反放点状态
local P_Ng   			= "{OFF,ON,ON,ON}"							--使用"P_Ng"代表到达Ng点状态
local Get   			= "{ON,OFF,OFF,OFF}"						--使用"Get"代表取料动作完毕
local M_p				= "{ON,OFF,OFF,ON}"							--使用"M_p"代表正搬动作完毕
local M_n   			= "{ON,OFF,ON,OFF}"							--使用"M_n"代表反搬动作完毕
local Push				= "{ON,OFF,ON,ON}"							--使用"Push"代表压配动作完毕
local Received 			= "{ON,ON,ON,ON}"							--使用"Received"代表接收到控制信号

--***************定义变量结束****************

--****************机器人点位开始***************************
local Pos_Ready=g1													--等待点(取料点正上方)  
local Pos_Get=g2								                    --取料点          
local Pos_Positive=g3							                    --正放上方点        
local Pos_Negative=g4							                    --反放上方点        
local Pos_Push_Positive=g5						                    --正放点          
local Pos_Push_Negative=g6						                    --反放点          
local Pos_NG=g7									                    --NG点          


local Wait_Time = 20												--等待时间

--****************机器人点位结束***************************


--*******************此处可定义其它点*******************

--*******************此处可定义其它点*******************


--**************主程序开始***************
function main()

	print("机器人进入复位状态")
	Init()															--机器人初始化子函数
	print("初始化或复位完成")
	
	while true do													--主程序需死循环方可连续运行,否则为单步运行
		Run()														--机器人运动控制子函数
	end
	
end

--**************运行程序开始***************
function Run()
	command = DI ( Order )											--刷新PLC的控制指令
	print("Command=",command)

	if sysrate() ~= Run_Speed then
		sysrate( Run_Speed )										--机器人速度设定到运行速度	
		print("运行速度已设定为",Run_Speed,"%")
	end
	
	repeat
		Delay(5)
	until
		command ~= 0												--判断是否接受到PLC的运动指令

	if ( command == 1 ) then 										--Command=1,回原点
		print("接收到回原点信号,开始回原点")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g1)													--去g1点
		print("回原点完成")
		DO ( Response, P_Ready )									--返回到达原点信号							
	end
	
	if ( command == 2 ) then										--Command=2,去取料点g2
		print("开始去取料点g2")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g2)
		print("回取料等待点完成")
		DO ( Response, P_Get )										--返回到达取料点信号		
	end
	
	if(  command == 3 ) then										--Command=3,去正放上方点g3
		print("开始去正放上方点g3")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g3)
		print("到达取料点g3")
		DO ( Response, P_p1 )										--返回到达正放上方点信号		
	end
	
	if( command == 4 ) then											--Command=4,去反放上方点g4
		print("开始去安全点g4")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g4)
		print("到达安全点g4")
		DO ( Response, P_n1 )										--返回到达反放上方点信号		
	end
	
	if( command == 5 ) then											--Command=5.去正放点g5
		print("开始去正放点g5")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g5)
		print("到达压配点g5")
		DO ( Response, P_p2 )										--返回到达正放点信号		
	end
	
	if( command == 6 ) then											--Command=6,去反放点g6
		print("开始去反放点g6")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g6)
		print("到达NG点g6")
		DO ( Response, P_n2 )										--返回到达反放点信号		
	end
	
	if( command == 7 ) then											--Command=7,去NG点g7
		print("收到去NG点命令,准备去NG点")
		DO ( Response, Received )									--返回接收命令成功信号
		MovP(g7)
		DO ( Response, P_Ng )										--返回到达NG点信号		
	end
	
	if( command == 8 ) then											--Command==8,去取料
		print("收到去取料命令,准备取料")
		DO ( Response, Received )									--返回接收命令成功信号
		Action_Get()												--调用取料子函数
		print("取料完成")
		DO ( Response, Get )										--返回取料动作完成信号		
	end
	
	if( command == 9 ) then											--Command==9,去正搬运
		print("收到去正搬运命令,准备正搬运")
		DO ( Response, Received )									--返回接收命令成功信号
		Action_Move_P()												--调用正搬运子函数
		print("正搬运完成")
		DO ( Response, M_p )										--返回正搬运动作完成信号		
	end
	
	if( command == 10 ) then										--Command==10,去反搬运
		print("收到去反搬运命令,准备反搬运")
		DO ( Response, Received )									--返回接收命令成功信号
		Action_Move_N()												--调用反搬运子函数
		print("反搬运完成")
		DO ( Response, M_n )										--返回反搬运动作完成信号		
	end
	
	if( command == 11 ) then										--Command==11,去压配
		print("收到去压配命令,准备压配")
		DO ( Response, Received )									--返回接收命令成功信号
		Action_Push()												--调用压配子函数
		print("取料完成")
		DO ( Response, Push )										--返回压配动作完成信号		
	end
	

end

--*************子函数*********************

function Init()														--初始化及复位至等待位置
	MotOn()
	print("电机已使能,机器人进入复位状态")
	sysrate(Spd_Init)												--机器人速度设定到初始化速度
	print("初始化运行速度为",Spd_Init,"%")
	MovJ(J3,Pos_Ready.z)											--将Z轴提升至和等待点相同的高度确保安全											
	print("Z轴已经移动到安全高度")
	MovP(Pos_Ready)													--移动到等待点	
	print("机械手移动到安全位置")
	DO ( Response, P_Ready )										--返回到达原点信号							
end

function Action_Get()												--取料子函数
	print("开始取料")			
	MovP(Pos_Ready)													--确保从等待点开始动作
	waitrealpos()
	MovJ(J3,Pos_Get.z)												--z轴下降,移动到取料点
	waitrealpos()
	DO ( Response, P_Get )											--返回到达取料点信号		
	
	repeat
		Delay(10)
	until
		( DI(IN_Sucker) == ON )  
	
	Delay(Wait_Time)												--等待真空条件满足
	MovJ(J3,Pos_Ready.z)											--z轴上升
	waitpos()
	print("取料动作完成")
end

function Action_Move_P()											--正搬运子函数
	MovP(Pos_Positive)												--移动到正放上方点
	waitrealpos()
end

function Action_Move_N()											--反搬运子函数
	MovP(Pos_Negative)												--移动到反放上方点
	waitrealpos()
end

function Action_Push()												--压配子函数
	print("开始压配")
	MovJ(J3,Pos_Push_Positive.z)									--Z轴下降
	waitrealpos()
	DO ( Response, P_p2 )											--返回到达正放点信号		

	repeat															--等到负压关闭
		Delay(10)
	until
		( DI(IN_Sucker) == OFF )
	
	Delay(Wait_Time)
	MovJ(J3,Pos_Positive.z)											--z轴上升
	waitpos()
	MovL(Pos_Ready)													--移动到等待点,减少取料准备时间
	print("压配动作完成")
end

电路图

由于要同时绘制机械图、电气图、接线图、气动回路图,选择了Solidworks Electrical绘制,首次肯定比AutoCAD费劲,但是后续就很轻松,也方便管理图纸。时间紧任务重,也就没来得及出3D Routh布线图,计划也是赶不上变化。。。画的像不像倒是没啥大影响。。。毕竟都是现场接线。。。

故意选了个不对应的电路图供有需要的电气攻城狮和工控行业的老哥学习借鉴,帮后人少走弯路少进坑。。。笔者下班时间用自己的笔记本电脑绘制的图纸,当然并木有任何加班费,白嫖就白嫖吧,“锻炼”不叫白嫖,那学习的事更不能叫白嫖。。。当时配图框、设置PLC模板也折腾了好久。。。不干这行,我留着没啥大用。。。留给立志在工业卓有建树的各位神仙。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要的自己去下载,我上传了shenhe慢不是我的锅。。。

谦虚点说我应该是全厂首个机械、电气、液压气动、嵌入式、工控都能搞几下的。。。实事求是地讲,厂是好厂,可惜我稚嫩的小手腕天生不是干体力活的料。。。嵌入式开发后继无人。。。祝贺狮虎“锻炼”4年多机修和电工终于升官了,也祝愿曾经扶助过我的领导平步青云。祝厂子越来越好。

以上是关于众为兴SCARA四轴机械臂编程——基于硬接线替代Modbus通讯的主要内容,如果未能解决你的问题,请参考以下文章

众为兴SCARA四轴机械臂编程——基于ModbusTCP协议

问一个stm32控制伺服电机的问题

SCARA的完整运动学解——代数法求解

stm32控制机械臂抓取的代码

matlab simulink基于BPPID控制的机械臂位置仿真

matlab simulink基于模糊PID控制的机械臂位置仿真