[아두이노] 서보모터를 리모콘(IRremote)으로 제어

IOT/아두이노|2019. 3. 15. 09:00

[아두이노] 서보모터를 리모콘(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에 회전각을 출력시켜보자.


참 쉽죠. 회로도 별거 없지요. 그러면 욕먹겠지요. 지금까지 배운 서보모터 제어, 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도 회전하는 장면 입니다.


동영상으로 제가 실험한 장면을 녹화 했네요. 어떤식으로 진행 했는지 보시면 그리 어렵지 않을꺼에요. 3개의 주제를 다 합치고 또 코딩하는 부분 까지 전부 다 녹화하다보니 꽤 길어졌네요. 동영상이 너무 길기 때문에 결과 이미지만 보시고 대충 이렇게 결과가 나오는 구나 정도로만 이해하시도 됩니다.


마무리


이번 포스팅은 응용편으로 각 하나의 부품을 제어하다 보면은 너무 쉽고 간단해서 이걸로 뭘 할 수 있지 생각하는 분들이 아마 있을거에요. 각 부품 포스팅 마다 예제소스도 너무 단순하게 표현해서 뭘 만들어 볼려는 분들은 부품간 연결이 이미지화 하기가 좀 힘드실꺼에요. 그래서 이번에는 좀 고려하고 코딩해야하는 부분이 있는데 그걸 다 무시하고 읽기 편하게 코딩을 배치했네요. 원래를 코딩을 하실때 이렇게 배치하시면 안되고요. 변수와 객체를 체계적으로 선언하고 코딩도 각 경계의 구분을 명확하게 하고 너무 한곳에 집중 코딩하기 보다는 외부함수로 빼서 분산시켜서 loop()함수 내 코딩은 최소화로 간결하게 가독성을 높이는 코딩을 해야 합니다. 그걸 다 무시하고 우선 초보분들은 가독성 위주로 코딩 했네요.

오늘은 서보모터랑 LCD16x2 모니터를 사용하여 리모콘을 제어했네요. 여러분들오 한번 지금까지 포스팅한 부품 중에 맘에 드는 것을 골라서 한번 만들어 보세요. LED가 맘에 든다면 LED 부품을 사용하여 숫자키 값에 따라서 전원 스위치로 활용하여 LED를 켜고 끄기를 할 수 있습니다. 또는 RGB LED로 리모콘 키값을 이용해서 컬러값을 만들어내서 RGB LED의 색을 다양하게 표현하는 실험을 할 수 있을거에요.

그외도 많지만 한번 상상의 나래를 펼쳐 보세요.


댓글()

[아두이노] 리모콘(IRremote) 제어

IOT/아두이노|2019. 3. 14. 09:00

[아두이노] 리모콘(IRremote) 제어



오늘은 리모콘을 사용하는 법을 배워보도록 하겠습니다. 제가 참고했던 라이브러리 파일이 있는 github의 자료입니다. 링크된 곳에 들어가시면 기본 데모 예제가 있습니다. 그걸 이용해서 실험하시면 됩니다.

1. IRremote 라이브러리 설치


가상시뮬레이터에서 기본적으로 제공됩니다. 라이브러리 소스를 가져올 필요 없이 라이브러리 파일을 인크루드만 하면 됩니다.

#include <IRremote.h>

실제로 한다면 라이브럴리 파일을 추가해야겠죠.


라이브러리 매니저에서 IRremote 치시면 라이브러리가 여러게 보이는데 젤 위에거로 그냥 설치하시면 됩니다.

설치하시면 예제에 들어가시면 IRremote라는 예제가 추가되었고 거기에 IRrecvDemo 예제를 실행 시키면 됩니다.


아래 소스를 보면 대충 예제가 11번 핀을 IR Sensor핀으로 사용했네요. 그리고 두개의 IRrecv, decode_results 클래스가 있는데 소스상으로 대충 보면은 IR Sensor값을 IRrecv 클래스에서 받아서 뭔가 처리를 할꺼고 decode_results 클래스는 변수명을 보면 먼지는 모르지만 센서의 결과값이 여기에 있겠구나 하고 유추가 되실 꺼에요. println()에 results.value 값을 찍은거 봐서는 리모콘를 누른 값이겠군 하고 생각하시면 됩니다.


대충 이런느김으로 라이브러리를 살펴보실때 클래스 객체명이나 또는 함수 등을 통해서 데모 예제들을 통해 유추해보면서 한번 코딩을 해독 해보세요. 데모 예제들은 심풀하게 나와 있어서 어렵지 않게 해독이 될꺼에요.

2. 회로도 구성


  • 준비물 : IR Sensor, 리모콘, 아두이노우노
  • 내용 : 키를 누르면 그 값을 시리얼모니터로 출력


참 쉽죠. 측정하는 센서를 사용할때는 전원(Vcc,Gnd)핀과 Dout핀으로 구성된다고 했죠. 아두이노에 해당 핀에 연결만 하면 도비니다. 가상 리모콘은 따로 할 건 없고요. 아주 간단하게 구성 됩니다.

3. 코딩


  • 사용함수 : irrecv.enableIRIn(), irrecv.decode()
  • 내용 : 리모콘를 누른 값을 아두이노 IDE의 시리얼 모니터로 간단히 출력하자.
  • 참고출처 : http://playground.arduino.cc/Code/Keypad

  • irrecv.enableIRIn() : 리모콘 시작
  • irrecv.decode(results) : 키가 눌러진지 확인
  • irrecv.resume() : 다음값

데모소스를 기반으로 해서 수정해 보자. 우선 위에 링크된 라이브러리 파일이 있는 github로 가보세요. 이 라이브러리를 만드신 분의 라이브러리 IRremot.h 파일을 열어 볼 수 있습니다. 거기에 decode_results 클래스를 열어 보시면 여기에 리모콘의 정보가 어떤것을 저장하는지 잘 나와 있습니다.

보시면, decode_results 클래스에서는 decode_type, address. value, bits, *rawbuf, rawlen, overflow 변수들을 담고 있습니다. 여기서 decod_type, bits, value 값만 찍어보도록 하죠.

#include <IRremote.h>
 
int IRpin = 11;  
IRrecv irrecv(IRpin);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // 리모콘 시작
}

void loop()
{
  if (irrecv.decode(&results)) //리모콘 누른값이 없다면 패스
    {
     Serial.print("results.decode_type : "); //리모콘 타입
     Serial.println(results.decode_type);
     
     Serial.print("results.bits : "); //키값길이
     Serial.println(results.bits);
     
     Serial.print("results.value : "); //키값
     Serial.println(results.value);
     
     Serial.print("results.value, HEX : "); //키값을 16진수로변환
     Serial.println(results.value, HEX);
   
     irrecv.resume(); // 다음값
    }
}

대충 11번 핀을 IR Sensor 값을 읽는 핀입니다. IRrecv 객체변수를 선언할대 인자값으로 IR핀을 넘겨줍니다. 그리고 우리가 리모콘의 키값을 얻어야 하기때문에 리모콘 키값이 저장되어 있는 decode_results 클래스 객체 변수를 선언합니ㅏㄷ.

시리얼모니터로 출력하기 때문에 지난시간에 배웠듯이 begin(9600)으로 시리얼통신 시작을 선언하고 시리얼출력을 하기 위해서 print(), println()함수를 사용했네요.

리모콘을 사용하기 위해서 enableIRin()함수를 리모콘을 사용을 선언해야겠죠.

loop()함수에서 irrecv.decode(&reults)함수로 리모콘 키가 눌러졌는지 확인 작업을 합니다. 눌러졌다면 results 객체 변수에는 키값이 저장되어 있고 리모콘 decode_type, bits, value 정보를 print(), println()함수로 출력하는 로직입니다.

여기서 중요한 것은 value값입니다. 이 값을 토대로 리모콘을 눌렀을때 누른키값의 동작을 아두이노에서 명령을 내리면 됩니다.

핵심은results.value 이거 입니다.
다른 건 몰라도 대충

  irrecv.enableIRIn(); // 리모콘 시작
    
    if(irrecv.decode(&results)){ //리모콘 눌렀는지 확인
     if(results.value==0xFD48B7) {
       Serial.println(" key : 3"")
     }
     irrecv.resume(); //다음값
 } 

리모콘을 3번키를 누르면 3번키값이 'FD48B7' 16진수 값입니다. 3번키가 눌러졌다면 프린트문장을 수행되겠죠. 만약에 특정 동작을 프린트문장 대신에 모터를 돌린다거나 불을 끈다든가 다른 동작을 수행하도록 할 수 도 있겠죠.

다 빼고 부분만 빼내오니간 별거 없죠. 키값을 미리 알수가 없으니깐 실제로 실험하실때 리모톤의 기본 정보를 출력하시고 각 키값을 누러서 값을들 미리 적어놓고 그 값을 기준으로 제어 하시면 될꺼에요.

어려운 것은 없습니다.

4. 결과


리모콘 3번 키를 눌렀을때 결과입니다.


동영상은 실험과정을 담아 놨습니다. 보시고 따라해보세요. 소스를 복사한 곳은 위에 링크된 라이브러리 Github에 등록된 자료입니다. 위 링크된 곳을 미리 창을 열어 놓고 따라서 해보세요.

마무리


IRremote 라이브러리를 누군가 이미 만들어 놓았습니다. 우리는 단지 실험을 할때 그걸 이용할 뿐이죠. 리모콘을 제어하기 위해서 라이브러리를 개발 해야하는 소모적 시간을 줄일 수 있습니다. 아두이노를 다루는 가장 큰 장점은 이미 많은 라이브러리들이 오픈 되어 있어서 우리들은 창의적인 개발만 신경쓰면 됩니다. 뭘 만들지 그것만 여러분들이 상상의 나래만 펼치면 되고 기본 베이스 소스나 코딩은 오프라인으로 다 공개되어 있기 때문데 가져다가 잘 응용하여 표현만 하시면 됩니다.

처음부터 하나하나 프로그래머로써 코딩을 한다면 리모콘 하나를 다루기 위해서 엄청난 많은 시간을 소비해야 합니다. 전문적 지식도 필요하고요. 짧게는 몇일 길게는 한달이 걸리지 모릅니다.
하지만 IRremote 라이브러리를 이미 오프라인으로 공개되어 있어서 누구나 쉽게 이걸 활용할 수 있습니다. 물론 상업적으로는 저작권의 문제가 있겠지만 단지 실험을 목적으로 우리가 다룬다면 사실 부담없이 실험 할 수 있습니다.

이 라이브러리를 통해서 리모콘 키값을 얻을 수 있게 되었고 그 키값을 통해서 해당 동작만 설계만 우리들이 표현하면 되니깐 개발 시간을 엄청 단축시킬 수 있습니다. 참 좋은 세상에 살고 있는 거지요.
암튼 리모콘의 키값을 읽을 수 있게 되었으니깐 이 키로 뭘 제어할지 상상의 나래를 펼쳐 보세요


댓글()