'전기, 전자/Sensor 와 응용'에 해당되는 글 1건

  1. 2019.11.30 엔코더의 회전방향 검출방법
2019. 11. 30. 15:16

인크리멘탈엔코더(Incremental encoder)

인크리멘탈 엔코더는 일정한 회전 각도에 대하여 1개의 펄스(pulse)를 얻도록 되어있으며 슬릿원반에 다수의 슬릿을 배치하고 발광소자에서 발생한 빛을 고정슬릿을 통하여 수광소자에서 검출하여 전기 신호로 변환한다. A상과 B상이 90도 위상차를 가지고 있고, 회전의 원점을 검출하기 위해 1회전 당 하나의 펄스가 얻어지는 원점 위상 결정용의 Z상이 있다.

 

인크리멘탈엔코더는 회전 범위에 대한 각도 상의 출력 전압은 그림2-16과 같이 A위상과 B위상의 출력전압이 90도 위상차가 나도록 되어있고 A상의 출력전압이 B상의 출력전압 보다 90도 앞서게 되면 엔코더는 정방향 회전을 하는 것이고, 위상이 90도 뒤지게 되면 엔코더가 역방향으로 회전하게 되는 것을 감지할 수가 있다.

 

 0 → 0
 0 → 1
 0 → 2
 0 → 3

 1 → 0
 1 → 1
 1 → 2
 1 → 3

 2 → 0
 2 → 1
 2 → 2
 2 → 3

 3 → 0
 3 → 1
 3 → 2
 3 → 3

 정지
 + 1
  - 1
 무효

  - 1
 정지
 무효
 + 1

 + 1
 무효
 정지
  - 1

 무효
  - 1
 + 1
 정지

 

위의 그림과 같이 A상과 B상을 바이너리 코드로 보면 그 값은 회전에 수반해 0 → 1 → 3 → 2 → 0(정회전의 경우 )을 반복하는 것을 압니다. 따라서 정기적으로 출력을 샘플링 해 이전 회의 값과 비교하는 것으로 어디로 회전했는지 알 수 있습니다. 변화의 패턴은 16방법이 되어, 각각의 대응은 왼쪽과 같습니다.

무효 코드는 회전 속도(카운트 레이트)가 샘플링 주파수 이상이 되면 발생합니다. 이 경우, 회전 방향의 정보가 없어지므로, 에러가됩니다. 통상, 이 에러는 위치 정보 상실로서 시스템 오류가 됩니다. 다이얼(유저 인터페이스)이라면 무시해도 특히 문제는 없을 것 입니다. 또, 무효 코드에 대해서 특별한 처리(이전 회와 같은 방향으로 2 카운트로 한다)를 하는 것에 의해, 샘플링 주파수의 2배 미만까지의 오버 스피드 내성을 갖게 할 수도 있습니다.

엔코더 출력 변화의 패턴으로부터 회전 방향을 판정하려면 다음과 같은 방법이 생각됩니다.

 

테이블 변환으로 요구한다.

이전 회치 * 2 + 이번 값」으로 모든 조건을 나타내는 4 bit의 인덱스로 테이블 변환한다. 이 방법은 데이터 테이블을 참조할 수 있는 경우에만 사용할 수 있습니다.

 

연산에 의해 요구한다. (1)

인덱스치의 패리티가 짝수라면 변화 없음이나 무효, 홀수라면 변화 있어.변화 없음의 경우 0 b0101로 AND를 취해 패리티 짝수로 정지, 홀수로 무효.변화 있는 경우 0 b0110로 AND를 취해 패리티 짝수로+방향, 홀수로-방향.이 방법은 2회의 판정으로 끝납니다만, 파티플레그가 있는 프로세서일 필요가 있습니다.

 

연산에 의해 요구한다. (2)

엔코더 출력은(바이너리로) 0→1→3→2로 변화하므로 그대로는 사용하기 어려운 것입니다.이것은 2비트의 그레이 코드라고 말할 수 있습니다만, 이것을 바이너리코드로 변환하면 0→1→2→3의 차례로 되어, 전회와의 차이를 취하는 것으로 회전 방향을 검출할 수 있습니다.바이너리 변환하려면 , 샘플링 한 값의 bit0에 bit1로 XOR를 취하는 것으로 2로 3이 바뀌어, 시퀀셜인 바이너리코드가 됩니다.2 bit치이므로, 결과는―2~+1의 범위에서 얻을 수 있어-2는 에러입니다.많은 프로세서에서는 이 방법이 제일 간단하겠지요.

 

로터리 엔코더의 코딩예 (1)

동작판정에 테이블 변환을 사용한 예로

sample_encoder()는, 타이머 세치기등의 배경 프로세스로 일정시간마다 호출합니다.(최대 카운트율<호출율)

로터리 엔코더의 회전량은 ENCODER 구조체의 POSITION에 리얼타임에 반영되어 움직임을 검출할 때마다 MOVED를 세웁니다.

 

volatile struct
{
    long POSITION;         /* 축위치 */
    u_char MOVED;         /* 이동 플래그 */
}

ENCODER;

void sample_encoder()
{
    const static char dir[ ] = { 0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0 };      /* 회전 방향 테이블 */
    static u_char i;                                                               /* 인덱스 */
    i = (i << 2) + (PA.PIN.BYTE & 3);                    /* 전회치와 이번 값으로 인덱스로 한다 */
    i &= 15;


    if (dir[i])
    {                                                             /* 움직임이 있으면 위치 갱신 */
        ENCODER.POSITION += (long) dir[i];
        ENCODER.MOVED = 1;
    }

}

 

로터리 엔코더의 코딩예 (2)

유저 I/F에 잘 사용되는 슬쩍밀기 다이얼의 카운트 처리의 예입니다.

1 클릭 움직임이 있을 때마다 커멘드 코드를 발생합니다.

데텐트형 슬쩍밀기 다이얼의 경우, 데텐트 위치가 2또는 4 카운트비의 위치에 있는 것이 있습니다. 즉, 1 스텝 당 2또는 4 카운트가 되므로, 취급하기 어려울지도 모릅니다. 이 경우는, 불필요한 천이분을 변환 테이블에서 제외해 주면 OK입니다.카운트 조건이 줄어들므로, 테이블 변환보다 비교·분기 명령으로 처리하는 편이 좋을 것입니다. 슬쩍밀기 다이얼 상대라면 수백~1 kHz 정도의 샘플링 레이트가 적당합니다.

 

u_char CMD; /* 키 커멘드 */

void sample_encoder()
{
    static u_char i;                             /* 인덱스 */
    i = (i << 2) + (PA.PIN.BYTE & 3);     /* 전회치와 이번 값으로 인덱스로 한다 */
    i &= 15;


    switch (i)
    {                                                /* 데텐트 위치는"0"을 상정 */
        case 0x7:                                 /* 13 */
        CMD = FORWARD;
        break;
        case 0xd:                                 /* 31 */
        CMD = BACKWARD;
        break;
    }                                                /* End of switch */

}                                                    /* End of sample_encoder */

Posted by Paul Hwang