编码器(Encoder)是将一种信息转换为另外一种可以进行传输、通信或者可以采用计算机进行处理的设备。编码器分很多中,本文关注旋转编码器(Rotary Encoder)是用来测量马达旋转速度和角度的装置。
旋转编码器可以分为单相,两相和三相三种,其中AB两相编码器比较常见,它可以做到正反向检测,计数和测速。
其原理比较简单就是旋转的时候A,B产生两路脉冲,不过两路脉冲错开1/4周期,这样根据AB两相检测到的高低脉冲值就可以判断方向和旋转速度。
其基本的计算方法:首先知道编码器转一圈产生r个脉冲,然后得知电机的减速比是s(减速比顾名思义就是为了减速,为了加大电机的扭矩也就是能够输出更大的力量,需要在电机转轴上安装小齿轮带动外面的大齿轮,可以电机转轴旋转s圈外面才输出一圈),所以单位时间t内产生了n个脉冲的话转速等于。
贴一段别人的示例代码,代码的基本意思是AM1与BM1就是两相的输入引脚,通过最后两者的脉冲数之和除以脉冲数*减速比*时间毫秒数/1000获得每秒的转速单位应该是round per second,代码中的rad/s应该是写错了,如果是角速度应该需要再乘以2Pi。另外代码没有判断正转或者反转的逻辑,具体可以参考本文后arduino官网的说明页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 /** * 日期: 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)<d_time) { 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); }
有了测速编码器就可以做到测量电机的转速,这样就可以使用PID控制器来将编码器的测量结果作为输入来控制电机的转速,下面的代码使用了官方的PID库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 /******************************************************** * PID Basic Example * Reading analog input 0 to control analog PWM output 3 ********************************************************/ #include <PID_v1.h> //Define Variables we'll be connecting to double Setpoint, Input, Output; //Specify the links and initial tuning parameters PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT); void setup() { //initialize the variables we're linked to Input = analogRead(0); Setpoint = 100; //turn the PID on myPID.SetMode(AUTOMATIC); } void loop() { Input = analogRead(0); myPID.Compute(); analogWrite(3,Output); }
其中Input是测量输入,Setpoint是设定的目标,Output是控制的输出。
参考