[아두이노] 스위치버턴+Servo Motor 제어

IOT/아두이노|2019. 4. 21. 09:00

[아두이노] 스위치버턴+Servo Motor 제어



어제 조이스틱으로 Servo Motor를 실험을 했는데 포스트를 본신 분들이 그냥 글을 보는거로만 끝내는 것이 좀 그런 것 같아서 조이스틱의 느낌을 스위치 버턴으로 최대한 살려서 비슷하게 가상시뮬레이터에서 테스트를 해 볼 수 있도록 변경을 해 봤습니다. 원리는 동일하고 스위치 버턴 2개로 조이스틱의 좌/우측의 회전 값으로 표현을 했고 스위치 버턴 1개로 조이스틱의 스위치 버턴으로 표현을 해서 총 3개의 스위치 버턴으로 조이스틱의 느낌을 담아 회로도와 코딩을 수정했네요. 위에 공개회로도를 클릭하시면 바로 가상시뮬레이터를 실행 할 수 있는 창이 나오니깐 가상시뮬레이터로 직접 스위치를 눌러 Servo Motor를 회전 시켜보세요. 대충 어떤 느낌으로 회전이 이루어지는지 체험을 하실 수 있습니다. 이제 본격으로 어떻게 표현 했는지 살펴보도록 하죠.

1. 회로도 구성


  • 준비물 : 스위치 버턴 3개, Red LED 1개, 저항 220옴 1개, Servo Motor 1개, 아두이노우노
  • 내용 : Servo Motor핀은 7번에 연결, 스위치 버턴은 3,4,5 번핀에 연결, Red LED은 12번 핀으로 연결


어제 포스팅한 조이스틱 + Servo Motor 회로에서 조이스틱 부분만 스위치 3개로 대신 표현한 회로도 입니다. 나머지는 동일하고 스위치 버턴 3개만 변경 했네요.

3. 코딩


  • 사용함수 : pinMode(), digitalRead(), delay(), servo.attach(), servo.write(), map()
  • 내용 : 스위치 버턴 2개로 Servo Motor를 회전 시키고 나머지 한개로 Red LED를 제어 깜박이게 해보자.

함수

  • pinMode(사용핀, 입/출력모드) : 해당 사용핀을 어떤 모드로 사용할지 결정한다. INPUT_PULLUP모드로 설정(내부저항을 사용할 예정)
  • digitalRead(디지털핀) : 디지털 신호를 읽음(0 or 1)
  • digitalWrite(출력핀, HIGH/LOW) : 출력핀에 HIGH(5V) or LOW(0)를 출력
  • delay(시간값) : 시간값만큼 대기한다.

Servo Motor 함수

#include <Servo.h> 
  • Servo servo : 서보모터 객체 선언
  • servo.attach(서보핀) : 서보 모터에 출력을 담당할 핀 선언
  • servo.write(회전각) : 회전각 만큰 서보모터를 회전 시킴

[ 조이스틱 소스 ]

#include <Servo.h> 

Servo servo;

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 3; 

const int servoPin = 7;
const int redLed = 12;

int m_Angle = 0;
 
void setup() {
  servo.attach(servoPin);
  pinMode(redLed, OUTPUT);
  pinMode(SW_P,INPUT_PULLUP);
}
 
void loop() {
  m_Angle = map(analogRead(AXIS_X),0,1023,0,180);
  digitalWrite(redLed,digitalRead(SW_P));
  servo.write(m_Angle); 
  delay(100); 
  
}

변경 후, 어떻게 코딩이 되었는지 볼까요.

[스위치 버턴 소스]

#include <Servo.h> 

Servo servo;

const int AXIS_X1 = 5;
const int AXIS_X2 = 4;
const int SW_P = 3; 

const int servoPin = 7;
const int redLed = 12;

int m_Angle = 0;

void setup()
{
  servo.attach(servoPin);
  pinMode(redLed, OUTPUT);
  pinMode(AXIS_X1, INPUT_PULLUP);
  pinMode(AXIS_X2, INPUT_PULLUP);
  pinMode(SW_P, INPUT_PULLUP);
}

void loop()
{    
  if(digitalRead(AXIS_X1) == 0){  
    if(m_Angle<180){
      m_Angle=m_Angle+10; 
    }          
  }
  else if(digitalRead(AXIS_X2) == 0){ 
    if(m_Angle>0){
      m_Angle=m_Angle-10; 
    }      
  }
  else{
    digitalWrite(redLed,digitalRead(SW_P));
  }
  servo.write(m_Angle);
  delay(100);
}

pinMode()함수로 두개의 스위치 버턴의 모드를 풀업저항모드로 설정을 했고 loop()함수 내부의 코드가 좀 바뀌었네요.

조이스틱보다 코딩이 좀 길어졌죠. if~else if 문을 사용했습니다. AXIS_X1과 AXIS_X2 로 두개의 변수를 설정해서 방향 스위치를 만들었습니다. AXIS_X1 방향이 정방향이면 AXIS_X2은 역방향이 됩니다.

이제 회전 시킬려면 스위치를 눌렀을 때 상황을 만들어 줘야 합니다. 정방향 스위치를 눌렀는지 역방향 스위치를 눌렀는지를 IF문으로 표현 하면 됩니다. 참고로 내부풀업저항을 이용 했기 때문에 초기 상태는 '1'의 상태입니다. 여기서 스위치를 누르면 '0'의 상태가 됨으로 스위치가 눌렀을 때 '0'인가 라고 IF문에서 체크하면 됩니다.

다음과 같은 코딩으로 표현이 되겠죠.

if(digitalRead(AXIS_X1) == 0) {
    정방향 10도 회전;
}
else if(digitalRead(AXIS_X2) == 0){  
    역방향 10도 회전;
}

이제 두 개의 방향스위치로 해당 스위치를 누르면 10도씩 회전하게 만들려면 m_Angle(각) 변수를 하나 만들어 놓고 이 변수값을 10씩 변화를 주면 됩니다.

  • 정방향 => m_Angle=m_Angle+10;
  • 역방향 => m_Angle=m_Angle-10;

간단하게 이 표현으로 스위치를 눌렀을 때 정방향은 +10이 되고 역방향은 -10이 되도록 위 문장을 코딩을 하면 간단하게 회전 시킬 각을 만들 수 있습니다.

그런데 Servo Motor은 0~180도 회전만 할 수 있습니다. 아무리 스위치 버턴을 눌러도 180도 이상 증가하면 안되고 0도이하로 감소해도 안됩니다.

if(m_Angle<180)  m_Angle=m_Angle+10; 

if(m_Angle>0)  m_Angle=m_Angle-10; 

이렇게 if문으로 각에 대해 제한을 두면 아무리 스위치를 눌러도 180이상 0이하로 m_Angle 값은 더이상 변하지 않게 됩니다.

종합해보면,

  if(digitalRead(AXIS_X1) == 0){  
    if(m_Angle<180) m_Angle=m_Angle+10; 
  }
  else if(digitalRead(AXIS_X2) == 0){ 
    if(m_Angle>0) m_Angle=m_Angle-10;     
  }
    else{
    digitalWrite(redLed,digitalRead(SW_P));
  }

이렇게 방향 스위치를 누르지 않았다면 else 문을 수행하는데 SW_P핀의 스위치가 상태값에 따른 redLed핀의 출력을 만들어 내면 마무리가 됩니다. 그냥 else에서 SW_P핀의 스위치가 눌러졌는지 체크하고 그냥 넘어가는 표현이라고 생각하시면 될 듯 싶네요.
이 부분을 else if()문으로 눌러졌는지 물어 보는 코딩을 해도 되지만 그냥 스위치 상태값으로 LED를 상태를 결정하기 때문에 묻는 조건식은 생략 했네요.

4. 결과


가상시뮬레이터 결과 영상입니다.


이것도 실제로 표현을 해서 어떻게 돌아가는지 돌려봤네요.


마무리


어제는 조이스틱으로 Servo Motor를 제어 했고 오늘은 스위치 버턴으로 같은 느낌으로 Servo Motor를 제어를 해 보았습니다. 뭔가를 표현학 그게 동작하는 모습을 봐야 어떤 느낌인지 이해가 빠를 꺼에요. 원래 Servo Motor 회전 제어를 예전 포스트에서 리모콘으로 조정했던 포스트였습니다. 아마도 Bluetooth 통신 포스트를 할 때도 LED나 Servo Motor를 가지고 제어를 하지 않을까 싶네요. 가장 시각적으로 표현하기 쉬운 부품이니깐요.

아무튼 어제 배운 조이스틱의 내용이 중요하니깐 꼭 조이스틱의 동작 원리를 이해하셨으면 합니다. 그리고 오늘 다룬 내용은 같은 의미로 스위치 버턴이 대신한 응용편으로 복습이라고 생각하시면 될 듯 싶네요.

여러분들도 다른 것을 이용하여 비슷한 동작을 수행하시고 싶으시다면 어떤 부품으로 비슷한 느낌을 표현할 수 있을지 상상의 나래를 펼쳐 보세요.


댓글()