마우스를 만들기 위해서는 DC 모터 2개를 제어해야 한다.
이때 모터의 회전 속도/회전 각도를 측정해야하므로 엔코더를 사용해야 하는데 일반적으로 외부 인터럽트를 사용한다.
그러나 아두이노 나노는 외부 인터럽트가 2핀 뿐이므로 PCINT (Pin Change Interrupt)를 사용하기로 했다.
PCINT 는 특정 핀의 상태 변화를 체크하는 것으로 외부 인터럽트와 유사하다.
다만, 외부 인터럽트는 핀의 상태 변화 (Edge : Low -> High or High -> Low) 혹은 상태를 지정할 수 있는데 반해서 PCINT 는 상태가 변할때만 인터럽트가 발생한다.
또한 한 핀당 하나의 ISR(인터럽트 서비스 루틴 : 인터럽트 발생시 수행되는 함수)이 있는 것이 아니라, 여러 개의 핀의 변화가 하나의 ISR을 동작시키게 된다.
따라서, ISR안에서 어떤 핀의 PCINT 인지 판단하고 처리해야 한다.
1. 하드웨어 연결 및 기본 변수 설정
엔코더가 부착된 DC 기어드 모터를 사용하고 엔코더의 출력을 아두이노 나노의 9~12 핀에 연결한다.
9~12번 핀이 PCINT 1~4이다.
volatile은 왠지 모르지만 어딘가에서 썼길래 따라 써봄...
#define LEFT_ENCODER_A 10 volatile long leftMotorEncoder = 0; //엔코더의 증감값 |
2. 인터럽트 설정
아두이노의 PCINT 를 따로 설정하는 함수가 있는지 모르겠지만 레지스터를 직접 제어해서 설정함
PCICR은 PCINT 0번을 사용한다는 뜻이고, PCMSK는 PCINT 핀중 어떤 것을 사용할지 결정하는 것이다.
나 같은 경우는 DC 모터 엔코더로 1~4번 PCINT, 로봇의 출발과 정지를 위한 택트 스위치를 위해 PCINT 5를 사용함
setup(){ noInterrupts(); } |
3. 인터럽트 함수 (ISR)
외부 인터럽트였다면 외부 인터럽트 한 핀당 ISR이 하나겠지만, PCINT 는 PCINT ISR 하나에 핀이 여러개이므로
핀의 상태를 저장했다가, 실제로 변경된 핀이 무엇인지 보고 어떤 핀인지 결정하고 엔코더 값을 계산해야 한다.
코드를 보면 아래와 같이 진행된다.
현재 핀 상태를 읽음 -> 각 핀의 이전 상태와 비교하여 변화가 있는 핀에 따라 엔코더값을 계산 -> 변경된 엔코더 값을 업데이트
ISR(PCINT0_vect) { // 엔코더 제어 int leftEncoderATemp = digitalRead(LEFT_ENCODER_A); int leftEncoderBTemp = digitalRead(LEFT_ENCODER_B); if (leftEncoderA != leftEncoderATemp) { leftMotorEncoder += (leftEncoderATemp == leftEncoderBTemp)?1:-1; leftEncoderA = leftEncoderATemp; } if (leftEncoderB != leftEncoderBTemp) { leftMotorEncoder += (leftEncoderATemp == leftEncoderBTemp)?-1:1; leftEncoderB = leftEncoderBTemp; } int rightEncoderATemp = digitalRead(RIGHT_ENCODER_A); int rightEncoderBTemp = digitalRead(RIGHT_ENCODER_B); if (rightEncoderA != rightEncoderATemp) { rightMotorEncoder += (rightEncoderATemp == rightEncoderBTemp)?1:-1; rightEncoderA = rightEncoderATemp; } if (rightEncoderB != rightEncoderBTemp) { rightMotorEncoder += (rightEncoderATemp == rightEncoderBTemp)?-1:1; rightEncoderB = rightEncoderBTemp; } } |
이렇게 했을때 PCINT를 이용하여 DC 모터의 엔코더를 측정하는데 문제가 없었고,
기본적인 P 제어를 이용한 각도 제어가 가능했음 (모터를 손으로 돌리면 원래 위치로 돌아감!!)
첨부 소스 코드 참조...
'로봇 만들기 - AVR > 마이크로 마우스' 카테고리의 다른 글
DC Mouse 4. 거리 측정 센서 설치 주의사항 (0) | 2020.01.06 |
---|---|
DC Mouse 3. 아두이노 DC 모터 PID 제어 (0) | 2019.12.22 |
DC Mouse 1. DC Motor 를 이용한 마이크로 마우스 제작 (0) | 2019.12.05 |
5. Mouse PCB 주문 (Fritzing) (0) | 2019.11.26 |
Mouse 4. 몸체 조립하기 (0) | 2019.11.22 |