电机编码器测速

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

电机编码器测速

下面这篇文章将会告诉你怎么使用Arduino读取外界的数字信号,编码器的一些介绍,还有听起来比较唬人的4倍频的揭秘。

1编码器的介绍

1.1编码器概述

编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。(对于电机测速来说应该需要将角位移转变为电信号,所以应该是码盘。)按照工作原理编码器可分为增量式和绝对式两类。增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。(淘宝上搜“带编码器的电机”大多是这种类型的编码器)绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。(From 百度百科)

1.2旋转编码器

旋转编码器是一种光电式旋转测量装置,它将被测的角位移直接转换成数字信号(高速脉冲信号)。编码器如以信号原理来分,有增量型编码器,绝对型编码器。我们通常用的是增量型编码器,不同型号的旋转编码器,其输出脉冲的相数也不同,有的旋转编码器输出A、B、Z三相脉冲,有的只有A、B相两相,最简单的只有A相。

单相联接,用于单方向计数,单方向测速。

A.B两相联接,用于正反向计数、判断正反向和测速。

A、B、Z三相联接,用于带参考位修正的位置测量。

1.3测速原理

当电机转一圈之后就会输出相应的脉冲设为a,所以我们如果能计算单位时间里的总脉冲数设为x,那么x/a就是单位时间内转的圈数,即转速。所以我们如果我们想测电机的速度,只需要计算单位时间内的脉冲数,就可以计算转速了。

例如带霍尔编码器的直流电机25GA370的部分参数如下:

编码器如果转一圈呢是11个脉冲。但是电机外有个减速器,而且减速比是34:1,那么就是电机输出轴转1圈,输入轴就要转34圈。即电机输出轴转1圈,编码器就要输出11x34=374个脉冲。至于下面的四倍频我等会介绍。那么就是如果我们在单位时间t内测出一相有n个脉冲,那么转速=n/(374xt)。

其实上面的计算只用了一相,如果我们要利用上两相的话那该怎么办呢?

这是AB两相的时序图,我们可以看到AB两相相位上相差了90度,本来一个脉冲是4个phase,而且用arduino计算是读取的某一个状态的变化。所以4个phase用一相的话我们只能读取1个脉冲。但是如果我们把两相结合起来的话在4个phase中就有4个状态的变化,也就是说如果结合两相我们读取的数值就是一相得4倍。转速=脉冲数/(4x374xt)。这就是所谓的软件4倍频功能。通过读取更多的数值来减少误差。

2相关代码

/** * 日期: 2017/02/28 * 作者: 呆萌阿宝* 描述: 电机测速*/

const int d_time=100;//设定单位时间

int flagA=0;

int flagB=0;//标志位设定

int AM1=2;

int BM1=3;//A相B相输入引脚的定义

int AIN1=7;

int AIN2=8;

int PWMA=9;//AIN1、2和PWMA是电机输出引脚的定义

int valA=0;

int valB=0;//用来储存A相B相记录的脉冲数

double n;//存储转速的变量

unsigned long times;

unsigned long newtime;//时间变量

void go(int g);

void back(int b);

void stay();//电机子函数申明

void setup()

{

Serial.begin(9600);//串口初始化

pinMode(AIN1,OUTPUT);

pinMode(AIN2,OUTPUT);

pinMode(PWMA,OUTPUT);//AIN1、2和PWMA引脚的输出方式 pinMode(AM1,INPUT);

pinMode(BM1,INPUT);//AM1、BM2引脚的输入方式

}

void loop()

{

go(255);//调用go()子函数

newtime=times=millis();

while((newtime-times)

{

if(digitalRead(AM1)==HIGH && flagA==0)

{

valA++;

flagA=1;

}

if(digitalRead(AM1)==LOW && flagA==1)

{

valA++;

flagA=0;

}

if(digitalRead(BM1)==HIGH && flagB==0)

{

valB++;

flagB=1;

}

if(digitalRead(BM1)==LOW && flagB==1)

{

valB++;

flagB=0;

}

newtime=millis();

}//计算AB两相的脉冲数

n=(valA+valB)/(1.496*d_time);//计算转速

Serial.print(n);

Serial.println("rad/s");//输出转速数值

valA=valB=0;//清零储存脉冲数的变量

}

/***********************************子函数程序**********************************/ void go(int a)

{

digitalWrite(AIN1,HIGH);

digitalWrite(AIN2,LOW);

analogWrite(PWMA,a);

}

void back(int b)

{

digitalWrite(AIN1,LOW);

digitalWrite(AIN2,HIGH);

analogWrite(PWMA,b);

}

void stay()

{

digitalWrite(AIN1,HIGH);

digitalWrite(AIN2,HIGH);

} [/kenrobot_code]

[kenrobot_code]/**

* 日期: 2017/02/28

* 作者: 呆萌阿宝

* 描述: 我觉得loop那应该可以改一下但是我没办法实验希望大家帮我看看行不行

*/

void loop()

{

go(255);//调用go()子函数

newtime=times=millis();

while((newtime-times)

{

if(digitalRead(AM1)==HIGH)

{

valA++;

}

if(digitalRead(BM1)==HIGH )

{

valB++;

}

newtime=millis();

}//计算AB两相的脉冲数

n=(valA+valB)/(1.496*d_time);//计算转速

Serial.print(n);

相关文档
最新文档