標(biāo)題: EC11編碼器的最佳轉(zhuǎn)速是多少? [打印本頁]

作者: ningsy    時間: 2022-10-6 23:32
標(biāo)題: EC11編碼器的最佳轉(zhuǎn)速是多少?
利用假期時間調(diào)試了新到的EC11編碼器。用了論壇里一個大佬的函數(shù),在此表示感謝!正常手速下(看說明書應(yīng)該是每秒一轉(zhuǎn))測試基本成功,但是暴力手速下(最快速旋轉(zhuǎn))編碼器好像就反應(yīng)不過來了,轉(zhuǎn)很大角度就變化幾個數(shù)值。為實現(xiàn)消抖,我在AC、BC上也并聯(lián)了100nf電容。

我想請教各位的是:EC11的最佳轉(zhuǎn)速是多少?像這種機械編碼器暴力轉(zhuǎn)速下反應(yīng)不過來是正常的嗎,是不是我并聯(lián)的消抖電容大了?這個函數(shù)里對EC11的掃描時間是幾毫秒呢?我用的是89C52+EC11,是不是掃描速度也有點慢了?

下面貼出函數(shù)代碼,請大佬看看還有優(yōu)化的地方嗎?程序功能是旋轉(zhuǎn)EC11對步進電機調(diào)速,每轉(zhuǎn)一格頻率變化100Hz,頻率范圍(100~9900Hz)。


sbit EC11_A=P3^2;           //加速

sbit EC11_B=P3^3;           //減速


u16 freq;              //脈沖頻率
float fosc=12000000;  //系統(tǒng)時鐘頻率12MHz
float TEMP_T;   
u8 TIMER0_L,TIMER0_H;



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

* @函數(shù)名:EC11_Scan

* @描  述:判斷方向,計算旋轉(zhuǎn)的值

* @參  數(shù):無

* @返回值:無

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

void EC11_Scan()

{

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

    if((EC11_A)&&(EC11_B))  //兩個都是1,表示開始第一個脈沖

    {

  EC11_Flag =1 ;//標(biāo)記為第一個信號收到,可以進行下一個信號

    }

    if(EC11_A!=EC11_B)//第二個信號

    {

   Left_Flag = EC11_A ; //記錄AB的信號狀態(tài)

   Right_Flag = EC11_B ;

    }

    if(EC11_Flag)  

    {

   if((EC11_A==0)&&(EC11_B==0))  // 第三個信號,處理第二個信號的值

           {

      if(Left_Flag)  //左轉(zhuǎn)

              {
   
            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; //把標(biāo)志位清零,等待下一個周期

           }

    }

}



作者: Hephaestus    時間: 2022-10-7 05:54
反應(yīng)不過來第一步應(yīng)該看你的代碼。
作者: IdeaMing    時間: 2022-10-7 07:29
支持---反應(yīng)不過來第一步應(yīng)該看你的代碼。
作者: ningsy    時間: 2022-10-7 11:55
在網(wǎng)上找了半天,我認為EC11最佳轉(zhuǎn)速應(yīng)該就是1圈/秒。實際使用中不推薦高于這個速度,以下截圖為證。這還是有型號的大廠產(chǎn)品,我買的這個EC11實際性能如何只有天知道了。




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






無標(biāo)題2.png (10.07 KB, 下載次數(shù): 44)

無標(biāo)題2.png

作者: yanjian    時間: 2022-10-7 12:10
你這還好了,我轉(zhuǎn)太快就抓到錯的數(shù)據(jù).
比如正轉(zhuǎn)時候識別成反轉(zhuǎn).

想快,用外部中斷,一步一脈沖的用下降沿中斷
作者: ningsy    時間: 2022-10-7 12:25
yanjian 發(fā)表于 2022-10-7 12:10
你這還好了,我轉(zhuǎn)太快就抓到錯的數(shù)據(jù).
比如正轉(zhuǎn)時候識別成反轉(zhuǎn).

那您可以試試我發(fā)這個驅(qū)動函數(shù)。

您有外部中斷的例程嗎?我找了一段外部中斷的代碼,可是不能用,可能是有一句代碼有問題,編譯就過不了;注釋掉編譯過了,可旋轉(zhuǎn)編碼器沒反應(yīng)

作者: lkc8210    時間: 2022-10-7 13:13
看我的分析一定位一脈沖的EC11旋轉(zhuǎn)編碼器最簡潔的單片機驅(qū)動代碼


作者: 人中狼    時間: 2022-10-7 14:24
怎么感覺這代碼做復(fù)雜了,EC11沒這么復(fù)雜

作者: Y_G_G    時間: 2022-10-7 15:07
ningsy 發(fā)表于 2022-10-7 11:55
在網(wǎng)上找了半天,我認為EC11最佳轉(zhuǎn)速應(yīng)該就是1圈/秒。實際使用中不推薦高于這個速度,以下截圖為證。這還是 ...

它其實就是通過檢測哪個引腳先出現(xiàn)電平的變化來區(qū)分轉(zhuǎn)動方向的
只要你程序合理,不可能只是1秒一圈的


51hei截圖20221007145958.png (28.98 KB, 下載次數(shù): 44)

51hei截圖20221007145958.png

作者: Y_G_G    時間: 2022-10-7 15:20
這個是我自己用的,你參考一下,速度不是很快,但正常使用是可以的,定時器掃描速度提高一點,可以讀取得快一點




/*──────────────────────────────────────────────────────────────────────────────────────────────────
EC11_T0.c
編寫:YGG
完成日期:20211118
功能:通過T0定時器來完成EC11編碼開關(guān)的檢測
適用于STC8051單片機T0定時器編碼開關(guān)函數(shù)

完成狀態(tài):已經(jīng)完成
──────────────────────────────────────────────────────────────────────────────────────────────────*/
#include "Stc8a.h"
#include "EC11_T0.h"
sbit sa=P2^2;                                                        //編碼開關(guān)的兩個端口
sbit sb=P2^1;                                                        //編碼開關(guān)的兩個端口
sbit over=P3^2;                                                        //過流檢測IO
sbit                buzz=P4^0;                                        //用于蜂鳴器控制
bit fa;                                                                        //用于標(biāo)記編碼開關(guān)兩個端口狀態(tài)
bit fb;                                                                        //  0 為沒有記錄,1 為已經(jīng)記錄
unsigned char turn_f=0x00,turn_r=0x00;        //用于存放旋轉(zhuǎn)變量的,一個是正反兩個方向
//──────────────────────────────────────────────────────────────────────────────────────────────────
void Timer0Init(void)        //T0定時器初始化,1毫秒@11.0592MHz
{
        AUXR |= 0x80;                //定時器時鐘1T模式
        TMOD &= 0xF0;                //設(shè)置定時器模式
        TL0 = 0x66;                        //設(shè)置定時初始值
        TH0 = 0xEA;                        //設(shè)置定時初始值
        TF0 = 0;                        //清除TF0標(biāo)志
        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;         //用于保存兩個端口讀取到的數(shù)據(jù)                
        TL0 = 0x66;                                                        //設(shè)置定時初始值
        TH0 = 0xEA;                                                        //設(shè)置定時初始值
        if(!over)buzz=!buzz;                                //檢測到低電平,蜂鳴器響
        else buzz=0;
        //──────────────────────────────────────────────────────────────────────────────────────────────
        if(sa&&sb)                                                         //如果兩個端口都是1,就表示編碼開關(guān)位于"靜止"
                {
                  if(bm_data==0x12)
                        {       
                                turn_f++;       
                        }       
                        else if(bm_data==0x21)
                                {                                       
                                        turn_r++;       
                                }                                                         
                        bm_data=0;                                           //長期靜止?fàn)顟B(tài),端口數(shù)據(jù)要清除
                        fa=1;
                        fb=1;                                 
                }
        //──────────────────────────────────────────────────────────────────────────────────────────────────
           else         if((fa!=sa)||(fb!=sb))                //如果標(biāo)志位的上次的一樣,就不記錄端口數(shù)據(jù)
                           {
                                           bm_data=(bm_data<<1)|sa;
                                        bm_data=(bm_data<<1)|sb;
                                        fa=sa;
                                        fb=sb;
                           }
}               
//──────────────────────────────────────────────────────────────────────────────────────────────────



作者: 188610329    時間: 2022-10-7 15:27
即便,不接電容,1秒兩圈的速度也是沒啥問題的,關(guān)鍵看代碼,還有焊接問題了,虛焊能讓你轉(zhuǎn)了不動,不轉(zhuǎn)亂動。
作者: coody_sz    時間: 2022-10-7 15:34
EC11質(zhì)量好的1秒至少能5圈,即100脈沖一秒,沒有任何問題。
作者: ningsy    時間: 2022-10-7 15:53
coody_sz 發(fā)表于 2022-10-7 15:34
EC11質(zhì)量好的1秒至少能5圈,即100脈沖一秒,沒有任何問題。

大俠,你說的是“光電編碼器”吧,一個大幾十元,用在醫(yī)療監(jiān)控,高端精密設(shè)備上那種?那種用不起,我這是一個才2塊多包郵的機械編碼器。
作者: 溫xyz    時間: 2022-10-7 16:02
從自己的代碼找問題,最快的是中斷處理。查詢處理,如果主程序執(zhí)行的代碼比較長,速度肯定跟不上。
作者: imxuheng    時間: 2022-10-7 16:11
一直用外部中斷做的,硬件部分上拉加電容濾波,沒見到有什么異常
作者: ningsy    時間: 2022-10-8 10:52
Y_G_G 發(fā)表于 2022-10-7 15:20
這個是我自己用的,你參考一下,速度不是很快,但正常使用是可以的,定時器掃描速度提高一點,可以讀取得快一點
...

您發(fā)的代碼我測試了,初步可用,但感覺速度還不夠,不知是不是我沒調(diào)好。

我手里有一個成品步進電機控制器,可連續(xù)調(diào)速,那旋鈕真的靈敏,不管手速多快,就是沒誤碼(也許有,但我感覺不到)。不知是怎么做到的。

我這個也可以連續(xù)調(diào)速,但手速一快就反應(yīng)不過來了。
作者: Y_G_G    時間: 2022-10-8 11:03
ningsy 發(fā)表于 2022-10-8 10:52
您發(fā)的代碼我測試了,初步可用,但感覺速度還不夠,不知是不是我沒調(diào)好。

我手里有一個成品步進電機控 ...

IO不需要電容
定時器掃描時間改成500uS或者更短時間的話,反應(yīng)可以快一點
因為用的是中斷,如果其它中斷打斷的話,可能會慢點
反正,在我這基本是沒有出過問題的
作者: ningsy    時間: 2022-10-8 15:31
Y_G_G 發(fā)表于 2022-10-8 11:03
IO不需要電容
定時器掃描時間改成500uS或者更短時間的話,反應(yīng)可以快一點
因為用的是中斷,如果其它中斷 ...

首先說明:我現(xiàn)在用的MCU是89C52,跟您用的Stc8差遠了,也沒有1T模式,只能12T(6T 也可能行,我沒用)。我做這個是步進電機控制器,一上電定時器0中斷就不停產(chǎn)生脈沖,頻率100~9900Hz連續(xù)可調(diào)。

我想達到的效果:
1、電機運轉(zhuǎn)中轉(zhuǎn)速連續(xù)可調(diào),調(diào)速要絲滑無頓挫(操作者感覺好就行,這條基本沒問題了);
2、快速轉(zhuǎn)動EC11調(diào)速旋鈕反應(yīng)要靈敏無跳碼。(現(xiàn)在是每秒1圈沒問題,手速特別快就跟不上,這也是我想解決的問題。

用您的代碼時,89C52沒有的寄存器我全都注釋掉了,用的是定時器1中斷。運行時結(jié)果是可以調(diào)速,但調(diào)速時電機轉(zhuǎn)速不均,時快時慢;手速快時也反應(yīng)不過來。

所以我這種情況是不是不能同時用兩個定時器中斷來控制呢?畢竟控制電機是主要任務(wù),兩個中斷是不是互相影響?感覺想用好這個EC11編碼器好難,也不知是我用的U太差,還是代碼、電路哪里有問題,我都想給它安排個芯片單獨控制(如果可以的話),不要再占用MCU了。


作者: 人人學(xué)會單片機    時間: 2022-10-8 23:57
//************************************************************************************ 祁緒電子 2021年9月
//        //編碼器掃描旋轉(zhuǎn)
//************************************************************************************ 祁緒電子 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、標(biāo)志置一
        }
        if(Rotary_Flag==1)                                                                //如果標(biāo)志是1
        {
                if((ROTARY_A==0)&&(ROTARY_B==0))                        //C、等待兩個IO口都是低電平        
                {
                        if(Turn_Right==1)                                                //如果右標(biāo)志是1說明是順時針                                       
                        {
                                Rotary_Flag=0;                                                //標(biāo)志清0
                                Rotary_Read_Data_Rotary++;                        //編碼器增加
                        }
                        if(Turn_Left==1)                                                //如果左標(biāo)志是1說明是逆時針
                        {
                                Rotary_Flag=0;                                                //標(biāo)志清0
                                Rotary_Read_Data_Rotary--;                        //編碼器減少
                        }
                }
        }
        Turn_Left=ROTARY_A;                                                                //B、首先保存2個IO口的電平狀態(tài)
        Turn_Right=ROTARY_B;                                                        //B、首先保存2個IO口的電平狀態(tài)        
}//*/
作者: Y_G_G    時間: 2022-10-9 08:10
ningsy 發(fā)表于 2022-10-8 15:31
首先說明:我現(xiàn)在用的MCU是89C52,跟您用的Stc8差遠了,也沒有1T模式,只能12T(6T 也可能行,我沒用)。我 ...

我這代碼用的也是中斷
步進電機也用中斷的話,兩個之間是有沖突的
而且,我的代碼是1KHZ的掃描頻率,而你的是最高9.9KHZ的,占用的資源比EC11的還多,自然就慢下來了
就算你用別的EC11代碼,結(jié)果也是一樣的
問題出現(xiàn)在你的代碼上,跟什么1T/12T的沒有關(guān)系
如果要用PWM驅(qū)動,你應(yīng)該用單片機自帶的PWM功能,而不是用定時器中斷來產(chǎn)生PWM
如果你用的單片機沒有PWM功能,那就換一個有PWM功能的單片機,STC89C52早跟這個時代脫節(jié)了
作者: ningsy    時間: 2022-10-9 10:21
對。

我今天把74HC245+138驅(qū)動數(shù)碼管方案換成了TM1650驅(qū)動,已經(jīng)正常顯示了,但感覺又進一步拖累了EC11的反應(yīng)。以前有誤區(qū),總想著優(yōu)化某一部分的代碼就行,現(xiàn)在看來要整體考慮了。您說的那個PWM驅(qū)動我去了解一下,后續(xù)這個項目也準(zhǔn)備轉(zhuǎn)移到STC8上來搞。

這個小控制器的事真是越做越多啊。
作者: coody_sz    時間: 2022-10-9 12:14
ningsy 發(fā)表于 2022-10-7 15:53
大俠,你說的是“光電編碼器”吧,一個大幾十元,用在醫(yī)療監(jiān)控,高端精密設(shè)備上那種?那種用不起,我這是 ...

你以為我不懂什么是EC11?我手上的光電編碼器都是400線以上,轉(zhuǎn)速都能超過50圈一秒。
作者: Y_G_G    時間: 2022-10-9 13:23
ningsy 發(fā)表于 2022-10-9 10:21
對。

我今天把74HC245+138驅(qū)動數(shù)碼管方案換成了TM1650驅(qū)動,已經(jīng)正常顯示了,但感覺又進一步拖累了EC11 ...

你可以先把你現(xiàn)在的代碼改一下,試一下效果就知道了
把用作PWM的定時器中斷優(yōu)先級設(shè)定為最低,EC11定時器設(shè)定為最高,看一下效果就知道了
因為STC89C52的中斷優(yōu)先級默認都是一樣等級的
作者: 人中狼    時間: 2022-10-9 14:08
使用EC11一直都是用外部中斷來檢測的,不太明白樓主為什么會用到定時器
作者: ningsy    時間: 2022-10-10 00:39
感覺基本是成功了。電機調(diào)速如絲般順滑,比一開始好很多,最快手速也有反應(yīng)了,估計至少一秒兩圈吧。一點心得體會:

1、要想快,去電容。要想穩(wěn)(防抖),加電容。一開始我有點被百度誤導(dǎo)了,直接放了2個104(0.1uF),事實證明EC11要想快就直接裸奔,電容兩端電壓不能突變么。但以后我可能會加兩個PF級的電容求個心理安慰。

2、優(yōu)化代碼也很重要。兩個方面:一是主程序各函數(shù)的順序;二是數(shù)碼管顯示函數(shù),一定要用數(shù)組緩存數(shù)據(jù),能極大提升顯示質(zhì)量。我一開始用的74HC245+138驅(qū)動數(shù)碼管,后來換成TM1650,效果一樣的。再就是把顯示函數(shù)放在EC11掃描函數(shù)里面,數(shù)據(jù)變了馬上顯示出來,要減少一切顯示延遲。

3、中斷是個好方法,但不適合我現(xiàn)在的程序。我用定時器0中斷產(chǎn)生脈沖給電機驅(qū)動器,用定時器1中斷掃描EC11,兩個中斷一疊加,電機就嘯叫、抖動,時快時慢,根本沒法用。我還是用的一開始發(fā)的那個掃描函數(shù)。

4、至于為什么MCU是89C52,是因為我現(xiàn)在還不會用別的剛?cè)肓艘粋STC8,電路還沒搭起來~下步準(zhǔn)備把代碼搬過去,再研究下中斷+PWM調(diào)速......

以上,再次感謝各位大俠的建議和指導(dǎo)!



作者: ningsy    時間: 2022-10-16 19:10
最新進展:
MCU  89C52換成STC8G1K08
數(shù)碼管驅(qū)動TM1650
步進電機驅(qū)動模塊A4988+兩相4線28步進電機
EC11 編碼器+102電容去抖

仍沿用原89C52代碼按STC8G做了適應(yīng)性調(diào)整(限于學(xué)習(xí)水平暫未用中斷+PWM)


編碼器手感完美,反應(yīng)靈敏,速度跟成品驅(qū)動器差不多,已達到目標(biāo)期望。





作者: shenchaobiao    時間: 2022-10-16 20:41
反正工業(yè)上的編碼器,速度反饋用的,一分鐘800轉(zhuǎn)是基本的。4級電機60f/p,減去轉(zhuǎn)差1400轉(zhuǎn)每分鐘。
作者: zgjsntww    時間: 2023-3-15 23:14
樓主的代碼能分享嗎?

作者: coody_sz    時間: 2023-3-16 10:04
沒有最佳的說法,一秒一個脈沖也很好,1秒幾圈也可以。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1