서보모터를 리모콘(IRremote)으로 제어 (아두이노)
서보모터를 리모콘(IRremote)으로 제어 (아두이노)
- 온라인 가상시뮬레이터 : AUTODESK CIRCUITS
- 참고자료출처 : https://github.com/z3t0/Arduino-IRremote (라이브러리 제공 사이트)
서보모터 제어(아두이노)
LCD16x2 (LiquidCrystal) 제어(아두이노)
리모콘(IRremote) 제어(아두이노)
이번 내용을 지금까지 복습한 내용들을 종합해서 사용해보는 시간을 갖도록 하겠습니다. 총 3개의 주제를 하나로 묶어서 회로도를 구성할 예정입니다. 다 합쳐진 모습은 좀 복잡해 보일 수 있지만 개별 포스트 내용을 참고하시면 어렵지 않을거라 생각됩니다. 전체 코딩한 내용을 보면 이런걸 어떻게 코딩을 초보분들이 할 수 있냐고 생각 될 수 있지만 따로 각 주제별로 접근하면 단순한 코딩입니다. 그걸 합쳐놓아서 복잡해 보일 뿐입니다. 위에 참고자료 3개의 포스팅한 내용을 한번 다시 읽고 이번 포스팅을 보시면 "그냥 합쳐놓은거네!" 이라고 말할 꺼에요.
1. IRremote + Servo모터 + LCD16x2 소스
IRremot 소스
#include <IRremote.h>
int IRpin = 11;
IRrecv irrecv(IRpin);
decode_results results;
void setup()
{
irrecv.enableIRIn(); // 리모콘 시작
}
void loop()
{
if (irrecv.decode(&results)) //리모콘 누른값이 없다면 패스
{
"results.value의 키값을 사용할 예정";
irrecv.resume(); // 다음값
}
}
Servo모터 소스
#include <Servo.h>
Servo servo;
int SERVO_PIN = 10;
void setup()
{
servo.attach(SERVO_PIN);
}
void loop()
{
"servo.write(180) 함수로 서모모터회전시킬 예정";
}
LCD16x2 소스
#include <LiquidCrystal.h>
//LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(3, 4, 9, 10, 11, 12);
void setup()
{
lcd.begin(16,2);
lcd.setCursor(0, 0);
lcd.print("Servo Angle :");
delay(1000);
}
void loop() {
lcd.setCursor(0, 1);
"lcd.print("각도")함수로 각도값을 출력할 예정";
}
2. 회로도 구성
- 준비물 : IR Sensor, 리모콘, 서보모터 1개, LCD16x2 1개, 저항 220옴 1개, 가변저항 10k옴 1개, 아두이노우노, 뻥판
- 내용 : 리모콘을 눌러서 서보모터를 회전 시키고 LCD16x2에 회전각을 출력시켜보자.
![](https://steemitimages.com/700x700/https://i.imgur.com/RMmsrNo.jpg)
참 쉽죠. 회로도 별거 없지요. 그러면 욕먹겠지요. 지금까지 배운 서보모터 제어, LCD16x2 제어, 리모콘 제어로 총 3편의 포스팅 내용을 토대로 간단히 회로도를 구성해 봤습니다. 개별적으로 포스팅한 내용 보시면 이 회로도 구성은 별거 없다는 것을 아마 아실꺼에요. 다 합쳐놓으니깐 좀 복잡해 보일뿐이죠. 실상은 간단합니다.
만약 LCD16x2 I2C 로 출력한다면 더 간단해 집니다. 해보고 싶은분은 LCD16x2 I2C 제어편을 보시고 실제로 실험을 도전하세요.
3. 코딩
- 사용함수 : 리모콘 함수, 서보모터 함수, LCD16x2 함수
- 내용 : 리모콘를 화살표키를 눌러 10도씩 회전 시키고 그 결과를 LCD 16x2로 출력해보자.
[ 리모콘 함수 ]
- irrecv.enableIRIn() : 리모콘 시작
- irrecv.decode(&results) : 키가 눌러진지 확인
- irrecv.resume() : 다음값
[ 서보모터 함수 ]
- servo.attach(사용핀) : 사용핀을 서보모터 제어로 사용
- servo. write(각도) : 각도로 회전시킨다.
[ LCD16x2 함수 ]
- lcd.begin(가로,세로) : 화면나누기
- lcd.setCursor(0, 0) : LCD16x2 모니터의 커서의 위치
- lcd.print(출력값) : LCD16x2에 값을 출력
설계
1. 리모콘의 화살표 위아래 버턴만 사용한다.
2. 리모콘의 키값을 읽는다.
if (irrecv.decode(&results)) {
키가 눌러졌다면 => results.value 값에 키값이 있겠죠
}
3. 각도변수에 화살표 키값을 위아래 누를때 증가/감소 시켜서 각도값을 만들어 낸다.
if(리모콘키값 == 증가키값){
if(m_Angle<180){ //0~180도로 제한으로180도 이상 증가하면 안되니깐 각도 증가는 180보다 작아야함
m_Angle=m_Angle+10; or m_Angle+=m_Angle; => 같은 표현
}
}
else if(리모콘키값 == 감소키값){ //0~180도 제한으로 0도 이하로 감소하면 안되니간 각도 감소는 0보다 커야함
if(m_Angle>0){
m_Angle=m_Angle-10; or m_Angle-=m_Angle; => 같은 표현
}
}
4. LCD16x2에 각도값을 출력한다.
lcd.setCursor(0, 1); //두번째 줄에 첫칸에 커서 위치
lcd.print(" "); //두전째 줄에 이전 기록된 값을 지우기 공백 16칸
lcd.setCursor(0, 1); //두번째 줄에 첫칸에 커서 위치한 이유 데이터를 기록할 위치를 다시 잡아줘야함
lcd.print(m_Angle); // 두번째 첫칸에 각도값이 출력됨
5. 서보모터에 각도변수에 저장된 값을 출력(회전) 한다.
servo.write(m_Angle);
간단하지요.
전체적으로 코딩을 하면
#include <IRremote.h>
#include <LiquidCrystal.h>
#include <Servo.h>
//1
Servo servo;
int SERVO_PIN =10;
int m_Angle = 0;
//2
//LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
//3
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
servo.attach(SERVO_PIN);
irrecv.enableIRIn();
lcd.begin(16,2);
lcd.setCursor(0, 0);
lcd.print("Servo Angle : ");
}
void loop() {
if (irrecv.decode(&results)) {
// Serial.println(results.value);
if(results.value == 0xFD50AF){ //16601263 or 0xFD50AF
if(m_Angle<180){
m_Angle=m_Angle+10; // m_Angle+=m_Angle;
}
}
else if(results.value == 0xFD10EF){ //16584943 or 0xFD10EF
if(m_Angle>0){
m_Angle=m_Angle-10; // m_Angle-=m_Angle;
}
}
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(m_Angle);
irrecv.resume();
}
servo.write(m_Angle);
delay(100);
}
4. 결과
리모콘 화살 키를 눌렀을때 결과입니다. 각도 0도에서 각도 10도가 증가하고 LCD16x2에 각도 값이 출력되고 서보모터는 10도 회전하는 장면 입니다.
![](https://steemitimages.com/700x700/https://i.imgur.com/lyiFPrC.jpg)
동영상으로 제가 실험한 장면을 녹화 했네요. 어떤식으로 진행 했는지 보시면 그리 어렵지 않을꺼에요. 3개의 주제를 다 합치고 또 코딩하는 부분 까지 전부 다 녹화하다보니 꽤 길어졌네요. 동영상이 너무 길기 때문에 결과 이미지만 보시고 대충 이렇게 결과가 나오는 구나 정도로만 이해하시도 됩니다.
마무리
이번 포스팅은 응용편으로 각 하나의 부품을 제어하다 보면은 너무 쉽고 간단해서 이걸로 뭘 할 수 있지 생각하는 분들이 아마 있을거에요. 각 부품 포스팅 마다 예제소스도 너무 단순하게 표현해서 뭘 만들어 볼려는 분들은 부품간 연결이 이미지화 하기가 좀 힘드실꺼에요. 그래서 이번에는 좀 고려하고 코딩해야하는 부분이 있는데 그걸 다 무시하고 읽기 편하게 코딩을 배치했네요. 원래를 코딩을 하실때 이렇게 배치하시면 안되고요. 변수와 객체를 체계적으로 선언하고 코딩도 각 경계의 구분을 명확하게 하고 너무 한곳에 집중 코딩하기 보다는 외부함수로 빼서 분산시켜서 loop()함수 내 코딩은 최소화로 간결하게 가독성을 높이는 코딩을 해야 합니다. 그걸 다 무시하고 우선 초보분들은 가독성 위주로 코딩 했네요.
오늘은 서보모터랑 LCD16x2 모니터를 사용하여 리모콘을 제어했네요. 여러분들오 한번 지금까지 포스팅한 부품 중에 맘에 드는 것을 골라서 한번 만들어 보세요. LED가 맘에 든다면 LED 부품을 사용하여 숫자키 값에 따라서 전원 스위치로 활용하여 LED를 켜고 끄기를 할 수 있습니다. 또는 RGB LED로 리모콘 키값을 이용해서 컬러값을 만들어내서 RGB LED의 색을 다양하게 표현하는 실험을 할 수 있을거에요.
그외도 많지만 한번 상상의 나래를 펼쳐 보세요.
저는 영상 보면서 만족중입니다.... 오.. 이렇게 이렇게... 이런 원리구나.... 제가 프로그래밍에는 쥐약이라... 이렇게 만들어 가시는것을 보면 신기해요 잘 보고 갑니다. ^^
세 주제를 하나로 묶다 보니깐 동영상이 꽤 기네요.