ENCODER는 전기모터나 엔진의 회전각도 또는 회전속도를 측정할 때 사용되는 대표적인 센서입니다.
회전할 때 마다 펄스가 발생합니다.
즉, 펄스 수를 셈으로써 축의 각도를 검출할 수 있습니다.
앱솔루트식 로터리 인코더는 몇 가닥의 신호선에 의하여 축의 절대위치를 검출할 수 있습니다.
RSI503 엔코더를 동작하여 VIVADO를 통해 회전하는 펄스마다 카운트를 세어주는 테스트를 해보려고 합니다.
ENCODER의 동작을 이해해보겠습니다.
RSI503은 1024PPR(Perse per revolution)
"1ppr"은 "1 pulse per revolution"의 약자입니다. 이는 회전하는 기계 또는 장치에서 한 회전당 발생하는 펄스의 수를 나타냅니다.
"4체배"는 회전당 펄스의 수를 기준으로 펄스의 수를 네 배로 증가시키는 방식을 의미합니다. 따라서 1ppr의 경우에는 한 회전당 하나의 펄스가 생성되지만, 4체배인 경우에는 한 회전당 네 개의 펄스가 생성됩니다.
이것은 회전 각도의 해상도를 높이는 방법 중 하나로 사용됩니다. 4체배 인코더는 같은 회전량을 측정할 때 더 많은 펄스를 생성하여 더 정밀한 회전 위치를 측정할 수 있습니다.
다음과 같이 1,2,3,4 phase가 하나의 ppr 이 되어 1024*4 = 4096pulse
위의 동작을 보면 A가 0,0,1,1 이 될 때 B는 1,0,0,1이 됩니다.
같은 타이밍 에서
phase 1에서 A=0 B=0
phase 2에서 A=0 B=1
phase 3에서 A=1 B=1
phase 4에서 A=1 B=0
이렇게 4번 바뀜을 확인할 수 있습니다.
엔코더는 A,B상, A,B,Z 상 이런식으로 다양한 유형이 있는데 RSI503은 A,B,Z상이 있습니다.
Z는 HIGH가 되면 리셋이 된다고 보시면 됩니다.
한바퀴가 돌면 카운트 값은 리셋이 됩니다.
엔코더는 위의 그림과 같이 2방향으로 CW 시계방향, CCW 반시계반향으로 돌 수 있고
저는 이를 고려하여 시계방향으로 돌 때는 +카운트, 반시계방향으로 돌 때는 -카운트를 해주려고 합니다.
이제 이 ENCODER의 각 신호를 연결하고 수신해줄 수신기를 알아보겠습니다.
수신기의 보드 전면 사진입니다.
수신기는 위의 그림과 같이 차동 신호를 입력으로 받아 밑의 그림과 같이 Y1, Y2, Y3등 단일 신호로 출력하여줍니다.
엔코더의 각 선
S00, S00_N 은 A
S90, S90_N 은 B
Sref, Sref_N 은 Z 로써
수신기의 J1, J2, J3에 각각 연결하여 줍니다.
그리고 제가 쓰는 RSI503은 인가전압 범위가 9V~30V 로써 SPMS로 15.6V를 연결하여 공급해줬습니다.
MAX33076E 의 핀맵입니다.
회로 연결할 때 MAX33076E칩에 VCC를 찍어봤더니 전원이 들어오지않아
위의 커넥터 VCC에는 연결을 했는데
위의 JU1을 3.3V 와 VCC를 연결하여 1,4 연결을 해주니 전원이 들어갑니다.
각 핀에 전압이 들어가는지 확인하고 각 A, B, Z의 엔코더 회전 시 동작파형을 찍어봅니다.
A상을 오실로스코프로 SINGLE SEQ 를 눌러서 REDAY 상태에서 한번 더 눌러서 트리거를 잡아줍니다.
회전을 돌리는 속도에 따라 주기의 차이가 있습니다.
A상이 CH3이고 B상이 CH4입니다.
CW 시계방향으로 돌렸을 때 A상이 먼저 1이 들어옴을 확인할 수 있습니다.
A상이 CH3이고 B상이 CH4입니다.
CCW 반시계방향으로 돌렸을 때 B상이 먼저 1이 들어옴을 확인할 수 있습니다.
Z상은 1024PPR당 한번 동작하므로 파형을 잡아내기가 어려웠습니다.
트리거로는 잡히지않고 파형이 잡혔을 때 STOP을 눌러줬습니다.
동작이 잘 됨을 확인했으니 VIVADO로 테스트를 진행합니다.
module encoder(
input CLK_125_P, // 125 MHz clock positive input
input CLK_125_N, // 125 MHz clock negative input
input A, B, Z,
input rst_n
);
wire clk; // Clock signal
// IBUFDS: Differential Input Buffer
// 7 Series
// Xilinx HDL Language Template, version 2017.4
IBUFDS #(
.DIFF_TERM("FALSE"), // Differential Termination
.IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE"
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_inst (
.O(clk), // Buffer output "clk" in your case
.I(CLK_125_P), // Diff_p buffer input (connect directly to top-level port) "clk_p" in your case
.IB(CLK_125_N) // Diff_n buffer input (connect directly to top-level port) "clk_n" in your case
);
// End of IBUFDS_inst instantiation
(* MARK_DEBUG = "TRUE" *) reg direction;
(* MARK_DEBUG = "TRUE" *) reg [20:0] counter;
reg [2:0] A_mem, B_mem;
reg Z_OX;
(* MARK_DEBUG = "TRUE" *) wire counter_en = A_mem[2] ^ A_mem[1] ^ B_mem[2] ^ B_mem[1];
wire dir = A_mem[1] ^ B_mem[2];
always @(posedge clk)
begin
A_mem <= {A_mem[1:0], A}; // shift left and save new value
B_mem <= {B_mem[1:0], B};
Z_OX <= Z;
if(counter_en) begin
counter <= dir ? (counter + 1) : (counter - 1); // if(direction == 1) +1 else -1
direction <= dir;
end
else if(Z_OX) begin
counter <= 0;
end
end
endmodule
동작은 A의 0,1 과 B의 0,1을 EX-OR 로 묶어줘서 카운터가 가능하게끔 조건을 만들어주고
A의 첫번째와 B의 두번째가 EX-OR 둘 중에 하나가 1이 들어오면 카운터가 1이 증가하고
1이 들어오지않으면 -1이 되게끔 코드를 짜줬습니다.
1바퀴당 Count +4096 리셋
(1024PPR)*4 정방향
1바퀴당 Count -4096 리셋
(1024PPR)*4 역방향
4096의 카운터는 1024PPR에 4체배로 1바퀴당 4096이 올라가고 Z가 동작하여 리셋이 되는 것을 확인할 수 있었습니다.
'VERILOG' 카테고리의 다른 글
Smart ZYNQ보드 PS 측의 EMIO 확장 이더넷(ethernet) 네트워크 포트 기능 구현 (0) | 2024.05.14 |
---|---|
Serial통신, Uart, RS232, RS422, RS485, I2C, SPI, TCP, UDP 통신 방식에 대한 정리 (0) | 2024.04.15 |
DMA(Direct Memory Access) Loop test (1) | 2024.03.06 |
Hook script file 에러 시 해결 방법 (0) | 2024.02.27 |
ZCU102-G + AD7606C18 Simultaneous Sampling ADC 8ch 18Bit -4 parallel (1) | 2024.02.27 |