我遇到麻烦的编码器,旋转正常工作与AVR微控制器。编码器是一种机械 阿尔卑斯山的编码器, 和我使用 Atmega168.

澄清

我已经尝试采用一个外部中断听到销,但现在看来似乎是过于缓慢。当针变为高中断过程的开始和然后检查,如果销B很高。这个想法是,如果销B是高的那一刻销一个又高,那么它是旋转逆时明智的。如果销B是低的,那么它是旋转的时明智的。但它似乎是AVR的时间太长,检查销B,因此,它始终是读高。

我也想创造一个节目那只是块,直到销B或销一个变化。但它可能是,有太多噪音的时编码器,旋转,因为这并不能工作。我的最后一次尝试是有一个计时器储存的最后8个值在缓冲区和检查,如果它是要从低到高。这个没有工作。

我有试图界定范围的编码器,并且它似乎使用之间的2 4ms从第一个销的改变,直到其他针的改变。

有帮助吗?

解决方案

我有一个网页约 编码器,旋转,以及如何使用它们, 你可能找到有用的。

不幸的是,没有更多的信息,我不能解决特定的问题。

其微控制器销都连接到的编码是什么代码你现在是用于解码的脉冲?

好吧,你正在处理的几个不同的问题,第一个问题是,这是一个机械编码,所以你必须要处理有关噪声(反弹,chatter).的 数据表 表示可能需要3mS的零部件来停止跳动和建立虚假的产出。

你需要创建一个抖的程序。最简单的是连续检查,看是否有进高。如果是这样,开始计时器,并检查它再次在3毫秒。如果它仍然是高的,然后你可以检查的B-如果它是不高的,然后你忽略的寄生脉,并继续寻找一个高。当你入住B,你看看它,开始计时器,用于3毫秒,然后看看在B一次。如果是相同的两倍,然后你可以使用价值-如果它改变在3ms那么你需要再做一次(阅读B,等待3毫秒,然后再读一遍看看它是否匹配).

信号是足够快的,你不应该担心这些检查的要慢慢地,除非你还在运行一个缓慢的时钟的速度。

一旦你处理机械噪音,然后你想看看一个适当的灰色代码常规的算法你们在下面不会工作除非你也减量,如果一个高B去低。一般人储存的最后一个值的两个投入,然后进行比较的新的价值的两个输入和使用一个小的功能增加或减少基于这一点。(检查了标题为"高分辨率阅读"网站上,我在上面提到的表格)。我结合这两个读数到四位数量和使用一个简单的阵告诉我是否我递增或递减计数,但也有解决方案,甚至更先进和优化用于代码尺寸、速度或易代码维护。

其他提示

增加一个模拟低通滤波器,极大地改善了的信号。与低通滤波器,上的代码AVR真的很简单。

       _________
        |         |
        | Encoder |
        |_________|
          |  |  |
          |  |  |
     100n |  O  | 100n  
 GND O-||-+ GND +-||-O GND
          |     | 
          \     /
      3K3 /     \ 3K3
          \     /
          |     |    
VCC O-/\/-+     +-\/\-O VCC
     15K  |     |  15K
          |     |
          O     O
          A     B

嗯,奇迹ASCII:p

这里是程序上的AVR。连A和B输入PORTB avr:

#include <avr/io.h>

#define PIN_A (PINB&1)
#define PIN_B ((PINB>>1)&1)

int main(void){
    uint8_t st0 = 0;
    uint8_t st1 = 0;
    uint8_t dir = 0;
    uint8_t temp = 0;
    uint8_t counter = 0;
    DDRD = 0xFF;
    DDRB = 0;
    while(1){   
    if(dir == 0){
        if(PIN_A & (!PIN_B)){
            dir = 2;
        }else if(PIN_B & (!PIN_A)){
            dir = 4;
        }else{
            dir = 0;
        }
    }else if(dir == 2){
        if(PIN_A & (!PIN_B)){
            dir = 2;
        }else if((!PIN_A) & (!PIN_B)){
            counter--;
            dir = 0;
        }else{
            dir = 0;
        }
    }else if(dir == 4){
        if(PIN_B & (!PIN_A)){
            dir = 4;
        }else if((!PIN_A) & (!PIN_B)){
            counter++;
            dir = 0;
        }else{
            dir = 0;
        }
    }else if(PIN_B & PIN_A){
        dir = 0;
    }
        PORTD = ~counter;
    }
    return 0;
}

这个代码的工作,除非你转动编码器的真快。然后它可能会错过一个或两个步骤,但这不是重要的,因为使用人使用的编码不知道有多少个步骤,他们已经把它。

速度不应该是一个问题。大多是所有机械开关的需要抖的程序。如果你想这样做与中断关闭中断时,它触发器,开始计时器,这将打开它后几毫秒。将保持你的计划询免>:)

究竟是什么你有问题?我假设你已经能够勾销的编码的图片作为每技术规格相联系的泛页你给,所以问题是有阅读的数据?你不会得到任何数据编码器?你不知道如何解释的数据,你们回来吗?

/* into 0 service rutine */
if(CHB)
{
  if(flagB)
   Count++;
  FlagB=0;
}
else
{
  if(FlagB)
   count--:
  FlagB=0:
}

/* into 1 service rutine */
FlagB=1;

/* make this give to you a windows time of 1/4 of T of the encoder resolution
   that is in angle term: 360/ (4*resolution)
 */
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top