编码电机的使用方法(ESP32--Arduino)

目录

一、种类介绍

1、光电编码器

2.霍尔编码器 

3.优缺点

二、测速方法

1.M法( 高速测量准确)

2.T法(低速测量准确)

四、判断正反转

五、代码

M法测速


一、种类介绍

编码器主要分为光电编码器和磁编码器(霍尔编码器)。

1、光电编码器

      通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。码盘可以包含AB相,相位差相差90度。

2.霍尔编码器 

       通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。

3.优缺点

       优缺点: 光电编码器相对于霍尔编码器来说,多数在恶劣环境下无法使用,而且体积也比较大。此外,光电编码器精度不高,主要是由于码盘(光栅)无法划分的太细。但是,在磁场环境下,光电编码器不受磁场的影响。如果磁场不是很强的话,霍尔编码器可以采用磁屏蔽的方法(顺磁性材料:铁、坡莫合金。抗磁材料:热解石墨)。

二、测速方法

根据脉冲计数来测量转速的方法有以下三种:
(1)在规定时间内测量所产生的脉冲个数来获得被测速度,称为M法测速;
(2)测量相邻两个脉冲的时间来测量速度,称为T法测速;
(3)同时测量检测时间和在此时间内脉冲发生器发出的脉冲个数来测量速度,称为M/T法测速。

1.M法( 高速测量准确

      优点:固定采样周期测量,实现起来简单易行。在高速测量时,有较好的速度平稳性及较高的测量精度。

      缺点:在低速时会出现速度波动幅度大,平稳性差,且随着采样频率的提高,所测得的低速范围会变窄,测速精度随之下降等问题。  
       设脉冲发生器每转一圈发出的脉冲数为P,且在规定的时间Tg(s)内,测得的脉冲数为m1,则电机每分钟转数:nm=60*m1/(P*Ta)(r/min)
技术指标:
a、分辨率:Q=60*(m1+1)/(P*Tg)-60*m1/(P*Tg)=60/(P*Tg)

b、测量精度:在极端情况下会产生正负1个转速脉冲的检测误差,相对误差为1/m1
c、检测时间:T=PQ

2.T法(低速测量准确)

      测量相邻两个脉冲的时间间隔来确定被测速度的方法。用一已知频率为f。的高频时钟频率向一计时器发送脉冲数,此计时器由测速脉冲的两个相邻脉冲控制其起始和终止。若计数器的读数为m2,则电机每分钟的转数为nm=60*f./(P*m2)(r/min)

式中:fc--时钟脉冲频率
        m2--计数器对时钟脉冲频率f的脉冲计数值技术指标:
a、分辨率:Q=60*fc/(P*m2)-60*fc/((P*(m2+1))=n2..*P/(60*f-+n…*P)。在极端的情况下,时间的检测会产生正负1个高频脉冲周期。因此下法在被测转速
较低时,才有较高的测量精度。
b、测量精度:时钟脉冲m,计数时,总有1个脉冲的误差,由此造成的相对误差为1/mz
c、检测时间:T等于测速脉冲周期,即T=60/(P*nm)
d、时钟脉冲中f,的确定:f.愈高,分辨率愈高,测速精度愈高;但f,过高,又会使m,过大,使计数器字长加长,影响运算速度。确定方法是:根据最低转速nm min和计
算机字长设计出最大计数m2 max。f=nm min*p*m2 max/60

3. M/T法

      为了兼顾高速与低速,实际使用中常常是 M 法和 T 法结合使用,称为 M/T 法测速。

M法、T法结合的 M/T 测速法:低速时测周期、高速时测频率。

四、判断正反转

       针对具有AB两相的编码器。  只需要看QEP_A和QEP_B。AB具有90度的相位差,通过判断两者上升沿或者下降沿的关系即可。

假设QEP_A触发为高电平,QEP_B为低电平时为正转,反之为反转。

五、代码

      编码器返回的数据是一组正交信号,由于Arduino和ESP32都没有正交解码功能,所以要想实现正交解码功能的话就需要用两个io口来同时判断当前是属于状态。

配置对应的io口,一个编码器需要两个io口,一个用来检测外部跳边沿中断,另一个来判断方向。

一个脉冲信号周期完成4次跳变。精度提高

1时刻:TI2为低电平,TI1上升沿跳变,计数器向上计数;

2时刻:TI1为高电平,TI2上升沿跳变,计数器仍然向上计数;

3时刻:TI2为高电平,TI1下降沿跳变,计数器仍然向上计数;

4时刻:TI1为低电平,TI2下降沿跳变,计数器仍然向上计数。
 

M法测速

#include<Ticker.h>

#define PI 3.1415926

/***************** 定时中断参数 *****************/
Ticker timer1;  // 中断函数
int interrupt_time = 10; // 中断时间
int timer_flag=0;               //定时器标志;
 
/***************** 编码器引脚及参数 *****************/
uint8_t R1 = 18, R2=19;    // 右轮编码器引脚
uint8_t L1 = 26, L2=25;    // 左轮编码器引脚   左右轮区分是以锂电池为底部区分
volatile long Rcounter1=0, Rcounter2=0; // 右轮脉冲计数  该变量用于存储编码器的值,所以用类型修饰符volatile;
volatile long Lcounter1=0, Lcounter2=0; // 左轮脉冲计数  该变量用于存储编码器的值,所以用类型修饰符volatile;


// void right_counter_encoder1(); // 右轮1 计数脉冲数
// void right_counter_encoder2(); // 右轮2 计数脉冲数
// void left_counter_encoder1();  // 左轮1 计数脉冲数   
// void left_counter_encoder2();  // 左轮2 计数脉冲数   

void setup()

{

   Serial.begin(115200);

/***************** 编码器初始化 *****************/
  pinMode(L1, INPUT);    pinMode(L2, INPUT);   
  pinMode(R1, INPUT);    pinMode(R2, INPUT);  
  attachInterrupt(R1, right_counter_encoder1, RISING);//设置编码器R1相位上升沿中断
  attachInterrupt(R2, right_counter_encoder2, RISING);//设置编码器R2相位上升沿中断      
  attachInterrupt(L1, left_counter_encoder1, RISING);//设置编码器L1相位上升沿中断
  attachInterrupt(L2, left_counter_encoder2, RISING);//设置编码器L2相位上升沿中断
   
/***************** 定时中断 *****************/   
  timer1.attach_ms(interrupt_time, timerIsr);  // 打开定时器中断
  interrupts();                      //打开外部中断  

}

void loop()

{

if(timer_flag==1)

{        //判断是否发生定时器中断,这里是 interrupt_time ms发生一次
      timer_flag=0;       //清除标记
 }

}

//定时器中断处理函数,其功能主要为了输出编码器得到的数据
void timerIsr(){
   timer_flag=1;  //定时时间达到标志      
   readEncoder();   // 编码器
}

//编码器输出  mm
void readEncoder(){
  float L = Lcounter1/7/238*2*PI;  // 编码器旋转的角度(rad)编码器旋转一圈7个脉冲,减速比为238,
  float R = Rcounter1/7/238*2*PI; // 右轮
  Serial.print("左轮旋转的角度为:  ");  Serial.println(L);

//数值清零,重新计数
  Rcounter1 = 0; Rcounter2 = 0;   
  Lcounter1 = 0; Lcounter2 = 0;
}

 

// 编码器计数
void right_counter_encoder1(){  //右轮计数
    Rcounter1++;
  }
void right_counter_encoder2(){
    Rcounter2++;
  }
void left_counter_encoder1(){  // //左轮计数
    Lcounter1++;
  }
void left_counter_encoder2(){
    Lcounter2++;
  }

验证

———————————————
                        
本文为学习笔记

原文链接:https://blog.csdn.net/ksjz123/article/details/108825534

  https://blog.csdn.net/weixin_45829708/article/details/122374287

  • 18
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Arduino ESP32-C3板(ESP32-C3 DevKitM)有多个硬件定时器,可以用来生成精确定时的信号,例如PWM信号、定时采样等。在这里,我们将介绍如何在Arduino ESP32-C3板上使用硬件定时器来生成PWM信号。 步骤1:引入头文件 首先,需要在Arduino IDE中引入ESP32-C3的头文件,其中包含了定时器相关的函数和常量。 #include <esp32-hal-timer.h> 步骤2:配置定时器 在Arduino ESP32-C3板上,有四个硬件定时器可供使用,分别为TIMER0、TIMER1、TIMER2和TIMER3。在使用定时器之前,需要先进行配置。以下是一个示例代码段,用于配置TIMER0。 void initTimer0() { // 配置TIMER0为PWM模式 timerAttach(TIMER0, 0, true); timerSetMode(TIMER0, TIMER_PWM_MODE, 1); timerSetFrequency(TIMER0, 1000); timerSetDuty(TIMER0, 0, 50); // 开始TIMER0 timerAlarmEnable(TIMER0); } 在上述代码中,我们首先使用timerAttach()函数将TIMER0与GPIO0引脚绑定,然后使用timerSetMode()函数将其设置为PWM模式。接下来,使用timerSetFrequency()函数设置PWM频率为1000Hz,然后使用timerSetDuty()函数设置PWM占空比为50%。最后,使用timerAlarmEnable()函数启动TIMER0。 步骤3:控制PWM输出 完成定时器的配置后,可以使用timerWrite()函数来控制PWM输出。以下是一个示例代码段,用于控制TIMER0输出PWM信号。 void loop() { for (int i = 0; i <= 100; i++) { timerWrite(TIMER0, i); delay(10); } } 在上述代码中,我们使用一个for循环来逐步增加PWM占空比,从0到100。每次循环使用timerWrite()函数来设置PWM占空比,然后使用delay()函数延时10毫秒。 总结 在Arduino ESP32-C3板上使用硬件定时器可以生成精确的PWM信号,用于控制各种设备和传感器。在使用定时器时,需要注意配置定时器的模式、频率和占空比。同时,也需要注意控制PWM输出的时序,以保证信号的稳定性和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值