중급 예제

약간은 익숙하시거나 익숙해지셨나요? 그렇다면 조금더 깊이 다뤄볼까요?

로터리 인코더 모듈-신호제어기

2014-08-08 09:17:26

개요


로터리 인코더
는 전기모터나 엔진의 회전각도 또는 회전속도를 측정할 때 사용되는 대표적인 센서입니다.

인크리멘털식 로터리 인코더는 축이 일정량의 각도를 회전할 때마다 펄스를 발생하며 
펄스 수를 셈으로써 축의 각도를 검출할 수 있습니다.



사진 : 로터리 인코더의 내부 회로도 

그럼 이 로터리 인코더가 어디에 적용되고 있는지 알아 봅시다.


출처 : 로터리 엔코더 키패드 - ponoko.com

푸시버튼을 내장하고 있는 로터러 엔코더를 이용하여 다양한 기계,전자 장비의 회전식 컨트롤러로 사용되거나


출처 : 광학식 로터리 엔코더 - joshuavasquez.com

광학식 로터리 엔코더를 이용하여 모터의 회전 속도와 회전 방향을 검측할 수 있습니다.

이번 실습에서는 로터리 엔코더를 이용하여,
LED의 점등 속도를 제어해보고, 이를 이용하여 신호제어기의 원리를 구현해 보겠습니다.

 

미리보기 동영상


 

 

부품 목록

본 학습에는 총 6종류의 부품이 필요합니다.
 
NO 부품명 수량 상세설명
1 아두이노 1 레오나르도 보드
2 로터리 인코더 모듈 (푸시버튼 내장형)  1 로터리 인코더
3 브레드보드 1 브레드보드
4 220Ω 저항 3 저항
5 점퍼 케이블 9 점퍼 케이블
6 LED 3 빨강:1 노랑:1 초록:1
 
부품명 아두이노 우노 R3 (오렌지보드) 220Ω 저항 브레드보드 점퍼케이블 Red LED
파트 x1 x3 x1 x9  x1
부품명 Yellow LED Green LED 로터리 인코더
파트 x1 x1 x1

하드웨어 Making

회로도

 

 


 

 

브레드보드 레이아웃



 

 

로터리 엔코더 모듈

 

 

센서 핀 아두이노 핀
GND GND
+ 5V
SW(푸시버튼) D2
DT(pinA) D3
CLK(pinB) D4

 

 

소프트웨어 Coding

// 출처 : 33가지 프로젝트로 배우는 아두이노 

// 13번핀에 빨간색 LED를 연결합니다.
int redPin = 13; 
// 12번핀에 노란색 LED를 연결합니다.
int yellowPin = 12;
// 11번핀에 초록색 LED를 연결합니다.
int greenPin = 11; 
// 로터리 엔코더의 aPin을 4번핀에 연결합니다.
int aPin = 4; 
// 로터리 엔코더의 bPIn을 3번핀에 연결합니다.
int bPin = 3; 
// 로터리 엔코더의 푸시버튼을 2번핀에 연결합니다.
int buttonPin = 2;

// 현재 상태를 저장합니다.
int state = 0; 
// 초록색이나 빨간색일 때 불이 들어오는 시간을 설정합니다.
int longPeriod = 5000; 
// 신호가 바뀔때의 시간을 설정합니다.
int shortPeriod = 700; 
int targetCount = shortPeriod;
int count = 0;

void setup() {
	pinMode(aPin, INPUT_PULLUP);
	pinMode(bPin, INPUT_PULLUP);
	pinMode(buttonPin, INPUT_PULLUP);
	pinMode(redPin, OUTPUT);
	pinMode(yellowPin, OUTPUT);
	pinMode(greenPin, OUTPUT);
}

void loop() {
	count++;
	// 푸시버튼이 LOW일때
	if (digitalRead(buttonPin) == LOW) {
		// 모든 LED를 켭니다.
		setLights(HIGH, HIGH, HIGH);
	}
	else {
		int change = getEncoderTurn();
		int newPeriod = longPeriod + (change * 1000);   
		if (newPeriod >= 1000 && newPeriod <= 10000) {
			longPeriod = newPeriod; 
		}
		if (count > targetCount) {
			//현재상태를 저장합니다.
			setState();
			count = 0;
		}
	}
	delay(1);
}

int getEncoderTurn() {
	// -1,0,+1의 값중 하나를 반환합니다.
	static int oldA = LOW;
	static int oldB = LOW;
	int result = 0;
	int newA = digitalRead(aPin);
	int newB = digitalRead(bPin);
	if (newA != oldA || newB != oldB) {
		// 바뀐 값이 있을 때
		if (oldA == LOW && newA == HIGH) {
			result = -(oldB * 2 - 1);
		}
	}
	oldA = newA;
	oldB = newB;
	
	return result;
} 

int setState() {
	if (state == 0) {
		setLights(HIGH, LOW, LOW);
		targetCount = longPeriod;
		state = 1;
	}
	else if (state == 1) {
		setLights(HIGH, HIGH, LOW);
		targetCount = shortPeriod;
		state = 2;
	}
	else if (state == 2) {
		setLights(LOW, LOW, HIGH);
		targetCount = longPeriod;
		state = 3;
	}
	else if (state == 3) {
		setLights(LOW, HIGH, LOW);
		targetCount = shortPeriod;
		state = 0;
	}
}

void setLights(int red, int yellow, int green) {
	digitalWrite(redPin, red);
	digitalWrite(yellowPin, yellow);
	digitalWrite(greenPin, green);
}

 

 

소프트웨어 & 하드웨어 설명

 

// 초록색이나 빨간색일 때 불이 들어오는 시간을 설정합니다.
int longPeriod = 5000; 
// 신호가 바뀔때의 시간을 설정합니다.
int shortPeriod = 700; 

shortPeriod 는 스케치 중간에 바뀌지 않고, 신호등의 색을 바꿀 때 적용됩니다.
longPeriod 는  신호가 초록색이나 빨간색일경우 그 신호를 유지할 시간을 정하는 변수입니다.
따라서 로터리 엔코더를 회전하면 longPeriod의 값이 변화하게 됩니다.

 


int getEncoderTurn() {
	// -1,0,+1의 값중 하나를 반환합니다.
	static int oldA = LOW;
	static int oldB = LOW;
	int result = 0;
	int newA = digitalRead(aPin);
	int newB = digitalRead(bPin);
	if (newA != oldA || newB != oldB) {
		// 바뀐 값이 있을 때
		if (oldA == LOW && newA == HIGH) {
			result = -(oldB * 2 - 1);
		}
	}
	oldA = newA;
	oldB = newB;
	
	return result;
} 

로터리 엔코더를 다룰때 중요한 getEncoderTurn()함수 는 호출될 때 마다 A와 B의 현재 상태를 이전 상태와 비교하고,

그 값이 변하였다면, -1과 1을 반환하여 시계방향과 반시계방향 중 어느쪽으로 회전했는지를 알아냅니다.(회전하지 않을때는 0을 반환합니다.)

oldA 와 oldB 변수 static 한정자를 사용했는데 이는 함수를 한 번 호출하고 다음 호출을 하기 전까지 사용한 값을 유지하고 싶을때 유용하게 쓰입니다.
 

 

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

로터리 인코더, 아두이노