使用beagelebone读取编码Z相信号

      编码器Z相信号,又称零位信号,编码器轴每旋转一圈,A相和B相都发出相同的脉冲个数,但是A相和B相之间 存在一个90°(电气角的一周期为360°)的电气角相位差,可以根据这个相位 差来判断编码器旋转的方向是正转还是反转,正转时,A相超前B相90°先进行 相位输出,反转时,B相超前A相90°先进行相位输出。编码器 每旋转一圈,Z相只在一个固定的位置发一个脉冲,所以可以作为复位相或零位 相来使用。

       关于beaglebone如何使用A B相,请参考https://mp.csdn.net/postedit/88735024

       当需要使用编码器Z相信号做精度控制时,如需要在特定位置停止,仅仅使用限位开关,精度是比较差的,这时候就需要限位开关配合Z相零点来精确控制了。

1.首先在机械安装的时候把 Z 相信号的 零点位置(编码器 每旋转一圈,Z相只在一个固定的位置发一个脉冲,该位置就是零点位置)对准了。 

2.然后你把限位开关安装到零点位置,当检测到限位开关从OFF->ON 跳变时,私服电机需要减速慢行(非常慢的状态),直到再次检测到限位开关从ON->OFF 跳变的过程中,一直循环判断是否接收到编码器Z相脉冲信号 ,一旦检测到Z 相信号,则立即停机。

也就是说:慢速找到一个近点行程开关。行程开关在on的过程包含了一个Z相的脉冲。这个条件只能由安装保证。行程开关的on过程开放允许一个输入中断。当Z脉冲发生的时候,连接一个输入中断,使得电机立即停止。

另外,用Z相脉冲找原点,并非是在Z相脉冲出现时将机器立即停下来并且以此为参考点,而是在Z相脉冲到来时将计数器清零。如果机器停下来的时候冲过头,首先零位的精度是不会收到影响的,因为在零位脉冲到来时将A,B相position清零并开始重新计数,过冲的距离可以通过A,B相的position获取到。

以下程序没有使用光电开关,仅仅使用了编码器的Z相信号,当系统启动的时候,首先让电机以比较快的速度运动,当检测到Z相脉冲的时候,立刻停止电机,这时候由于电机惯性过冲,在让电机以非常慢的速度反相运动并检测Z相脉冲,一旦检测到上升沿,再次立刻停机即可。

#include<iostream>
#include"GPIO.h"
#include"sys/poll.h"
#include"PWM.h" 
using namespace exploringBB;
using namespace std;

int main()
{
    if(getuid()!=0)
	{
		cout << "必须使用root来执行程序" << endl;
		return -1;
	}
    
    GPIO inGPIO_Z(49);
	inGPIO_Z.setDirection(INPUT);    //设置GPIO为输入
	inGPIO_Z.setEdgeType(RISING);    //设置检测上升沿
	
    cout << "即将启动电机,寻找零点" << endl;
 
	/*
    PWM pwm("pwm_test_P9_16.13"); 
	pwm.setPeriod(500000);         
	pwm.setDutyCycle(75.0f);       // 设置周期循环的百分比
	pwm.setPolarity(PWM::ACTIVE_LOW);  //正转
	pwm.run();
    */
	cout << "电机以较快的速度运动寻找零点" << endl;                 
	inGPIO_Z.waitForEdge();         // 轮询检测上升沿
	
    /*
	PWM pwm("pwm_test_P9_16.13"); 
	pwm.setPeriod(500000);         
	pwm.setDutyCycle(100.0f);       // 电机停机
	pwm.setPolarity(PWM::ACTIVE_LOW); 
	pwm.run();
    */

	cout << "电机以非常慢的速度反向运动,寻找Z相零点精确位置" << endl;
    /*	
	PWM pwm("pwm_test_P9_16.13"); 
	pwm.setPeriod(500000);         
	pwm.setDutyCycle(90.0f);       // 电机慢速
	pwm.setPolarity(PWM::ACTIVE_HIGH);  //反转
	pwm.run();
    */

	inGPIO_Z.waitForEdge();         // 继续检测上升沿,判断是否到达零点
    /*	
	PWM pwm("pwm_test_P9_16.13"); 
	pwm.setPeriod(500000);         
	pwm.setDutyCycle(100.0f);       // 电机停止
	pwm.setPolarity(PWM::ACTIVE_HIGH); 
	pwm.run();
    */

    cout << "找到零点了 " << endl;
	cout << "电机停止" << endl;       

	return 0;
}

配合光电开关的话,将光电开关接上板子即可,接线如下:

棕色:电源正极(+24V,或+5V);
蓝色:电源负极(0V或GND);
黑色:开关信号输出(接PLC或其它设备的输入端);
白色(有的是灰色或其它的浅色),这个的接法多种多样,
最好是参照光电开关说明书接线,归纳起来大概有如下三种类型:
1 白色为公共端,开关动作时(感应到有物体)需要输出低电平时白色与蓝色短接,
需要输出高电平时白色与棕色短接.(此种用法较多).
2 白色为反相输出端,即黑色是常开(NO)输出的话,白色为常闭输出(NC),
此时只需接其中之一,另一线悬空..(此种用法较少).
3 白色为反相控制端,白色为高电平时黑色为常开(NO)输出,
白色为低电平时黑色为常闭输出(NC)...(此种用法很少).

猜你喜欢

转载自blog.csdn.net/qq_34935373/article/details/90040781
今日推荐