找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2084|回复: 28
打印 上一主题 下一主题
收起左侧

EC11编码器的最佳转速是多少?

  [复制链接]
跳转到指定楼层
楼主
利用假期时间调试了新到的EC11编码器。用了论坛里一个大佬的函数,在此表示感谢!正常手速下(看说明书应该是每秒一转)测试基本成功,但是暴力手速下(最快速旋转)编码器好像就反应不过来了,转很大角度就变化几个数值。为实现消抖,我在AC、BC上也并联了100nf电容。

我想请教各位的是:EC11的最佳转速是多少?像这种机械编码器暴力转速下反应不过来是正常的吗,是不是我并联的消抖电容大了?这个函数里对EC11的扫描时间是几毫秒呢?我用的是89C52+EC11,是不是扫描速度也有点慢了?

下面贴出函数代码,请大佬看看还有优化的地方吗?程序功能是旋转EC11对步进电机调速,每转一格频率变化100Hz,频率范围(100~9900Hz)。


sbit EC11_A=P3^2;           //加速

sbit EC11_B=P3^3;           //减速


u16 freq;              //脉冲频率
float fosc=12000000;  //系统时钟频率12MHz
float TEMP_T;   
u8 TIMER0_L,TIMER0_H;



/*********************************

* @函数名:EC11_Scan

* @描  述:判断方向,计算旋转的值

* @参  数:无

* @返回值:无

*********************************/

void EC11_Scan()

{

      static bit EC11_Flag=0,Left_Flag=0,Right_Flag=0;

    if((EC11_A)&&(EC11_B))  //两个都是1,表示开始第一个脉冲

    {

  EC11_Flag =1 ;//标记为第一个信号收到,可以进行下一个信号

    }

    if(EC11_A!=EC11_B)//第二个信号

    {

   Left_Flag = EC11_A ; //记录AB的信号状态

   Right_Flag = EC11_B ;

    }

    if(EC11_Flag)  

    {

   if((EC11_A==0)&&(EC11_B==0))  // 第三个信号,处理第二个信号的值

           {

      if(Left_Flag)  //左转

              {
   
            if(freq<=100) freq=100;

             else

                 freq-=100;               //脉冲频率 1格减100Hz

              }

    else if(Right_Flag)

              {
   
               if(freq>=9900)freq=9900;

               else
           
            freq+=100;                //脉冲频率 1格加100Hz
      
              }

            TEMP_T=(65536-fosc/(24.0*freq));  //定时器重装初值   

  
            TIMER0_H=(u16)TEMP_T/256;

            TIMER0_L=(u16)TEMP_T%256;   

  EC11_Flag = 0; //把标志位清零,等待下一个周期

           }

    }

}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2022-10-7 05:54 | 只看该作者
反应不过来第一步应该看你的代码。
回复

使用道具 举报

板凳
ID:276663 发表于 2022-10-7 07:29 | 只看该作者
支持---反应不过来第一步应该看你的代码。
回复

使用道具 举报

地板
ID:1044091 发表于 2022-10-7 11:55 | 只看该作者
在网上找了半天,我认为EC11最佳转速应该就是1圈/秒。实际使用中不推荐高于这个速度,以下截图为证。这还是有型号的大厂产品,我买的这个EC11实际性能如何只有天知道了。




https://wenku.baidu.com/view/f61 ... 11cc7931b7783d.html






无标题2.png (10.07 KB, 下载次数: 26)

无标题2.png
回复

使用道具 举报

5#
ID:888148 发表于 2022-10-7 12:10 | 只看该作者
你这还好了,我转太快就抓到错的数据.
比如正转时候识别成反转.

想快,用外部中断,一步一脉冲的用下降沿中断
回复

使用道具 举报

6#
ID:1044091 发表于 2022-10-7 12:25 | 只看该作者
yanjian 发表于 2022-10-7 12:10
你这还好了,我转太快就抓到错的数据.
比如正转时候识别成反转.

那您可以试试我发这个驱动函数。

您有外部中断的例程吗?我找了一段外部中断的代码,可是不能用,可能是有一句代码有问题,编译就过不了;注释掉编译过了,可旋转编码器没反应
回复

使用道具 举报

7#
ID:161164 发表于 2022-10-7 13:13 | 只看该作者
回复

使用道具 举报

8#
ID:384109 发表于 2022-10-7 14:24 | 只看该作者
怎么感觉这代码做复杂了,EC11没这么复杂
回复

使用道具 举报

9#
ID:401564 发表于 2022-10-7 15:07 | 只看该作者
ningsy 发表于 2022-10-7 11:55
在网上找了半天,我认为EC11最佳转速应该就是1圈/秒。实际使用中不推荐高于这个速度,以下截图为证。这还是 ...

它其实就是通过检测哪个引脚先出现电平的变化来区分转动方向的
只要你程序合理,不可能只是1秒一圈的


51hei截图20221007145958.png (28.98 KB, 下载次数: 27)

51hei截图20221007145958.png
回复

使用道具 举报

10#
ID:401564 发表于 2022-10-7 15:20 | 只看该作者
这个是我自己用的,你参考一下,速度不是很快,但正常使用是可以的,定时器扫描速度提高一点,可以读取得快一点




/*──────────────────────────────────────────────────────────────────────────────────────────────────
EC11_T0.c
编写:YGG
完成日期:20211118
功能:通过T0定时器来完成EC11编码开关的检测
适用于STC8051单片机T0定时器编码开关函数

完成状态:已经完成
──────────────────────────────────────────────────────────────────────────────────────────────────*/
#include "Stc8a.h"
#include "EC11_T0.h"
sbit sa=P2^2;                                                        //编码开关的两个端口
sbit sb=P2^1;                                                        //编码开关的两个端口
sbit over=P3^2;                                                        //过流检测IO
sbit                buzz=P4^0;                                        //用于蜂鸣器控制
bit fa;                                                                        //用于标记编码开关两个端口状态
bit fb;                                                                        //  0 为没有记录,1 为已经记录
unsigned char turn_f=0x00,turn_r=0x00;        //用于存放旋转变量的,一个是正反两个方向
//──────────────────────────────────────────────────────────────────────────────────────────────────
void Timer0Init(void)        //T0定时器初始化,1毫秒@11.0592MHz
{
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0x66;                        //设置定时初始值
        TH0 = 0xEA;                        //设置定时初始值
        TF0 = 0;                        //清除TF0标志
        ET0 = 1;                        //T0定时器中断开启
        TR0 = 1;                        //定时器0开始计时       
        P_SW2=0x80;                        //
           P2PU|=0x06;               //P2.1,P2.2上拉电阻启用
    P_SW2=0x00;                        //
}
//──────────────────────────────────────────────────────────────────────────────────────────────────
//──────────────────────────────────────────────────────────────────────────────────────────────────
void timer0() interrupt 1                                 //T0定时器中断
{               
        static        unsigned  char bm_data;         //用于保存两个端口读取到的数据                
        TL0 = 0x66;                                                        //设置定时初始值
        TH0 = 0xEA;                                                        //设置定时初始值
        if(!over)buzz=!buzz;                                //检测到低电平,蜂鸣器响
        else buzz=0;
        //──────────────────────────────────────────────────────────────────────────────────────────────
        if(sa&&sb)                                                         //如果两个端口都是1,就表示编码开关位于"静止"
                {
                  if(bm_data==0x12)
                        {       
                                turn_f++;       
                        }       
                        else if(bm_data==0x21)
                                {                                       
                                        turn_r++;       
                                }                                                         
                        bm_data=0;                                           //长期静止状态,端口数据要清除
                        fa=1;
                        fb=1;                                 
                }
        //──────────────────────────────────────────────────────────────────────────────────────────────────
           else         if((fa!=sa)||(fb!=sb))                //如果标志位的上次的一样,就不记录端口数据
                           {
                                           bm_data=(bm_data<<1)|sa;
                                        bm_data=(bm_data<<1)|sb;
                                        fa=sa;
                                        fb=sb;
                           }
}               
//──────────────────────────────────────────────────────────────────────────────────────────────────


回复

使用道具 举报

11#
ID:624769 发表于 2022-10-7 15:27 来自手机 | 只看该作者
即便,不接电容,1秒两圈的速度也是没啥问题的,关键看代码,还有焊接问题了,虚焊能让你转了不动,不转乱动。
回复

使用道具 举报

12#
ID:1034262 发表于 2022-10-7 15:34 | 只看该作者
EC11质量好的1秒至少能5圈,即100脉冲一秒,没有任何问题。
回复

使用道具 举报

13#
ID:1044091 发表于 2022-10-7 15:53 | 只看该作者
coody_sz 发表于 2022-10-7 15:34
EC11质量好的1秒至少能5圈,即100脉冲一秒,没有任何问题。

大侠,你说的是“光电编码器”吧,一个大几十元,用在医疗监控,高端精密设备上那种?那种用不起,我这是一个才2块多包邮的机械编码器。
回复

使用道具 举报

14#
ID:8222 发表于 2022-10-7 16:02 | 只看该作者
从自己的代码找问题,最快的是中断处理。查询处理,如果主程序执行的代码比较长,速度肯定跟不上。
回复

使用道具 举报

15#
ID:151348 发表于 2022-10-7 16:11 | 只看该作者
一直用外部中断做的,硬件部分上拉加电容滤波,没见到有什么异常
回复

使用道具 举报

16#
ID:1044091 发表于 2022-10-8 10:52 | 只看该作者
Y_G_G 发表于 2022-10-7 15:20
这个是我自己用的,你参考一下,速度不是很快,但正常使用是可以的,定时器扫描速度提高一点,可以读取得快一点
...

您发的代码我测试了,初步可用,但感觉速度还不够,不知是不是我没调好。

我手里有一个成品步进电机控制器,可连续调速,那旋钮真的灵敏,不管手速多快,就是没误码(也许有,但我感觉不到)。不知是怎么做到的。

我这个也可以连续调速,但手速一快就反应不过来了。
回复

使用道具 举报

17#
ID:401564 发表于 2022-10-8 11:03 | 只看该作者
ningsy 发表于 2022-10-8 10:52
您发的代码我测试了,初步可用,但感觉速度还不够,不知是不是我没调好。

我手里有一个成品步进电机控 ...

IO不需要电容
定时器扫描时间改成500uS或者更短时间的话,反应可以快一点
因为用的是中断,如果其它中断打断的话,可能会慢点
反正,在我这基本是没有出过问题的
回复

使用道具 举报

18#
ID:1044091 发表于 2022-10-8 15:31 | 只看该作者
Y_G_G 发表于 2022-10-8 11:03
IO不需要电容
定时器扫描时间改成500uS或者更短时间的话,反应可以快一点
因为用的是中断,如果其它中断 ...

首先说明:我现在用的MCU是89C52,跟您用的Stc8差远了,也没有1T模式,只能12T(6T 也可能行,我没用)。我做这个是步进电机控制器,一上电定时器0中断就不停产生脉冲,频率100~9900Hz连续可调。

我想达到的效果:
1、电机运转中转速连续可调,调速要丝滑无顿挫(操作者感觉好就行,这条基本没问题了);
2、快速转动EC11调速旋钮反应要灵敏无跳码。(现在是每秒1圈没问题,手速特别快就跟不上,这也是我想解决的问题。

用您的代码时,89C52没有的寄存器我全都注释掉了,用的是定时器1中断。运行时结果是可以调速,但调速时电机转速不均,时快时慢;手速快时也反应不过来。

所以我这种情况是不是不能同时用两个定时器中断来控制呢?毕竟控制电机是主要任务,两个中断是不是互相影响?感觉想用好这个EC11编码器好难,也不知是我用的U太差,还是代码、电路哪里有问题,我都想给它安排个芯片单独控制(如果可以的话),不要再占用MCU了。

回复

使用道具 举报

19#
ID:390416 发表于 2022-10-8 23:57 | 只看该作者
//************************************************************************************ 祁绪电子 2021年9月
//        //编码器扫描旋转
//************************************************************************************ 祁绪电子 2021年9月
void ROTARY_ROTARY_Scan_Drive()
{
        static bit Turn_Left=0,Turn_Right=0,Rotary_Flag=0;
        if((ROTARY_A==1)&&(ROTARY_B==1))                                //A、然后等待两个IO口都是高电平        
        {
                Rotary_Flag=1;                                                                //A、标志置一
        }
        if(Rotary_Flag==1)                                                                //如果标志是1
        {
                if((ROTARY_A==0)&&(ROTARY_B==0))                        //C、等待两个IO口都是低电平        
                {
                        if(Turn_Right==1)                                                //如果右标志是1说明是顺时针                                       
                        {
                                Rotary_Flag=0;                                                //标志清0
                                Rotary_Read_Data_Rotary++;                        //编码器增加
                        }
                        if(Turn_Left==1)                                                //如果左标志是1说明是逆时针
                        {
                                Rotary_Flag=0;                                                //标志清0
                                Rotary_Read_Data_Rotary--;                        //编码器减少
                        }
                }
        }
        Turn_Left=ROTARY_A;                                                                //B、首先保存2个IO口的电平状态
        Turn_Right=ROTARY_B;                                                        //B、首先保存2个IO口的电平状态        
}//*/
回复

使用道具 举报

20#
ID:401564 发表于 2022-10-9 08:10 | 只看该作者
ningsy 发表于 2022-10-8 15:31
首先说明:我现在用的MCU是89C52,跟您用的Stc8差远了,也没有1T模式,只能12T(6T 也可能行,我没用)。我 ...

我这代码用的也是中断
步进电机也用中断的话,两个之间是有冲突的
而且,我的代码是1KHZ的扫描频率,而你的是最高9.9KHZ的,占用的资源比EC11的还多,自然就慢下来了
就算你用别的EC11代码,结果也是一样的
问题出现在你的代码上,跟什么1T/12T的没有关系
如果要用PWM驱动,你应该用单片机自带的PWM功能,而不是用定时器中断来产生PWM
如果你用的单片机没有PWM功能,那就换一个有PWM功能的单片机,STC89C52早跟这个时代脱节了
回复

使用道具 举报

21#
ID:1044091 发表于 2022-10-9 10:21 | 只看该作者
对。

我今天把74HC245+138驱动数码管方案换成了TM1650驱动,已经正常显示了,但感觉又进一步拖累了EC11的反应。以前有误区,总想着优化某一部分的代码就行,现在看来要整体考虑了。您说的那个PWM驱动我去了解一下,后续这个项目也准备转移到STC8上来搞。

这个小控制器的事真是越做越多啊。
回复

使用道具 举报

22#
ID:1034262 发表于 2022-10-9 12:14 | 只看该作者
ningsy 发表于 2022-10-7 15:53
大侠,你说的是“光电编码器”吧,一个大几十元,用在医疗监控,高端精密设备上那种?那种用不起,我这是 ...

你以为我不懂什么是EC11?我手上的光电编码器都是400线以上,转速都能超过50圈一秒。
回复

使用道具 举报

23#
ID:401564 发表于 2022-10-9 13:23 | 只看该作者
ningsy 发表于 2022-10-9 10:21
对。

我今天把74HC245+138驱动数码管方案换成了TM1650驱动,已经正常显示了,但感觉又进一步拖累了EC11 ...

你可以先把你现在的代码改一下,试一下效果就知道了
把用作PWM的定时器中断优先级设定为最低,EC11定时器设定为最高,看一下效果就知道了
因为STC89C52的中断优先级默认都是一样等级的
回复

使用道具 举报

24#
ID:384109 发表于 2022-10-9 14:08 | 只看该作者
使用EC11一直都是用外部中断来检测的,不太明白楼主为什么会用到定时器
回复

使用道具 举报

25#
ID:1044091 发表于 2022-10-10 00:39 | 只看该作者
感觉基本是成功了。电机调速如丝般顺滑,比一开始好很多,最快手速也有反应了,估计至少一秒两圈吧。一点心得体会:

1、要想快,去电容。要想稳(防抖),加电容。一开始我有点被百度误导了,直接放了2个104(0.1uF),事实证明EC11要想快就直接裸奔,电容两端电压不能突变么。但以后我可能会加两个PF级的电容求个心理安慰。

2、优化代码也很重要。两个方面:一是主程序各函数的顺序;二是数码管显示函数,一定要用数组缓存数据,能极大提升显示质量。我一开始用的74HC245+138驱动数码管,后来换成TM1650,效果一样的。再就是把显示函数放在EC11扫描函数里面,数据变了马上显示出来,要减少一切显示延迟。

3、中断是个好方法,但不适合我现在的程序。我用定时器0中断产生脉冲给电机驱动器,用定时器1中断扫描EC11,两个中断一叠加,电机就啸叫、抖动,时快时慢,根本没法用。我还是用的一开始发的那个扫描函数。

4、至于为什么MCU是89C52,是因为我现在还不会用别的刚入了一个STC8,电路还没搭起来~下步准备把代码搬过去,再研究下中断+PWM调速......

以上,再次感谢各位大侠的建议和指导!


回复

使用道具 举报

26#
ID:1044091 发表于 2022-10-16 19:10 | 只看该作者
最新进展:
MCU  89C52换成STC8G1K08
数码管驱动TM1650
步进电机驱动模块A4988+两相4线28步进电机
EC11 编码器+102电容去抖

仍沿用原89C52代码按STC8G做了适应性调整(限于学习水平暂未用中断+PWM)


编码器手感完美,反应灵敏,速度跟成品驱动器差不多,已达到目标期望。




回复

使用道具 举报

27#
ID:490458 发表于 2022-10-16 20:41 | 只看该作者
反正工业上的编码器,速度反馈用的,一分钟800转是基本的。4级电机60f/p,减去转差1400转每分钟。
回复

使用道具 举报

28#
ID:702439 发表于 2023-3-15 23:14 | 只看该作者
楼主的代码能分享吗?
回复

使用道具 举报

29#
ID:1034262 发表于 2023-3-16 10:04 | 只看该作者
没有最佳的说法,一秒一个脉冲也很好,1秒几圈也可以。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表