아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo

서보모터는 일정한 속도로 연속회전하는 일반모터와 달리 원하는 각도만큼 회전하게 하는 모터로 로봇이나 기타 위치제어에 많이 사용됩니다. 서보모터에도 토크, 최대각도, 사용전압 등에 따라 종류가 다양합니다. 여기서는 소형 서보모터에 속하는 9g 서보모터를 사용하여 아두이노로 각도를 제어하는 실험을 합니다.

이번 실험에서 사용하는 서보모터는 소형의 서보모터로서 가장 많이 사용하는 9g서보모터 입니다. 연결케이블은 아래 사진과 같이 3핀 케이블로 되어 있으며 두 선은 전원공급선이고 나머지 하나는 신호선입니다. 신호선에 PWM 신호를 보내줌으로서 원하는 각도로 회전하도록 할 수 있으며 아두이노를 사용하면 기본 제공되는 라이브러리를 사용하므로서 제어를 쉽게 할 수 있습니다.

아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo

아래와 같이 결선합니다. 서보모터의 전원은 5V와 GND에 연결하고 신호선은 아두이노 보드의 4번선에 연결하십시요.

아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo

아래는 실제 결선하여 실험한 모습입니다.

아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo

소스코드

아래는 소스코드입니다. 아두이노 IDE에 붙여넣기 하여 컴파일하고 업로드해봅니다.

// 아두이노 서보모터 각도제어 실험

int i,val;
char a[3];
boolean display;
#include <Servo.h>
Servo servo1;

void setup()
{
  Serial.begin(9600);
  servo1.attach(4);//서보모터를 핀4에 연결
}

void loop()
{
  if (Serial.available()){        //시리얼입력이 있으면
    delay(30);          //시리얼입력이 모두 전송되는 시간을 벌기위해 30ms 딜레이
    if (Serial.available() <= 3){ //입력된 데이터가 <=3 인경우
      while (Serial.available()){ //입력된 데이터를 모두 읽어온다
        a[i++] = Serial.read();   //a[]버퍼에 모두 저장
      }
      display = 1;                 //데이터를 모두 읽은 후 표시 플래그를 ON
    }
    else {                         //입력된 데이터가 >3 인 경우
      Serial.flush();             //시리얼버퍼 클리어
    }
  }
  
  if (a[0] == 43 && display){
    val++;
    servo1.write(val);
    Serial.println(val);
    display = 0;                  //표시 플래그 OFF
    Serial.flush();              //시리얼버퍼 클리어
    for (i = 0; i <= 3; i++)      //A[]버퍼 클리어
    {
      a[i] = 0;
    }
    i = 0;                        //i 변수 초기화
  }
  if (a[0] == 45 && display){
    val--;
    servo1.write(val);
    Serial.println(val);
    display = 0;                  //표시 플래그 OFF
    Serial.flush();              //시리얼버퍼 클리어
    for (i = 0; i <= 3; i++)      //A[]버퍼 클리어
    {
      a[i] = 0;
    }
    i = 0;                        //i 변수 초기화
}

//======================== 데이터 검증 ======================
  if (display)    //표시 플래그가 ON 이면 a[]어레이의 값을 표시
  {
    if (!a[2]){   //입력된 값이 두자리이면
      if (!a[1]){ //입력된 값이 한자리이면
         a[2] = a[0];
         a[1] = 48; //48은 ASCII 코드에서 0 에 해당
         a[0] = 48;
      }
      else {   //두자리인 경우
         a[2] = a[1];
         a[1] = a[0];
         a[0] = 48;
      }
    }
//== A[]버퍼의 값을 각도로 변환한 후 서보모터로 전송하고 화면출력 ==
    for (i=0;i<=3;i++){ //char 변수를 int 변수로 변환
      a[i] -= 48;
    }
    val = 100*a[0] + 10*a[1] + a[2];
    servo1.write(val);
    Serial.println(val);
    
    display = 0;                  //표시 플래그 초기화
    Serial.flush();              //시리얼버퍼 초기화
    for (i = 0; i <= 3; i++)      //a[]버퍼 초기화
    {
      a[i] = 0;
    }
    i = 0;                        //i변수 초기화
  }
}

아두이노 IDE에서 시리얼 모니터 창을 열어서 아래와 같이 0~180도의 각도를 입력하면 입력한 위치로 회전함을 알 수 있습니다.

아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo

Servo

Servo 모터는 움직임을 만들어 내는데 아주 중요한 부품이다. 이러한 서보 모터는 Servo 라이브러리를 이용하여 제어한다.

서보 함수

servo.attach(pin); servo: 서보 모터에 사용할 객체 변수. 서보 라이브러리를 할당한 변수라고 생각하면 쉽다.
pin: 서보 모터를 사용할 핀 번호.
servo.write(angle); angle: 서보 모터에 쓸 각도값(0~180도)

서보 모터의 파형 이해하기

서보 모터의 파형의 주기는 일반적으로 20ms이며, 주파수는 50Hz이다. 입력 파형의 HIGH값은 1~2ms 사이의 값을 갖는다.

서보 모터는 이러한 입력 파형의 값에 따라 움직이는 각도가 다르다.

서보 모터 사용하기

아두이노 시리얼 모니터 서보모터 - adu-ino silieol moniteo seobomoteo
서보 모터 회로도

서보 모터 사용 코드

#include<Servo.h>
Servo ms;
void setup(){
    Serial.begin(9600);
    ms.attach(9);
    ms.write(0);
}
void loop(){
    if(Serial.available()>0){
        char u = Serial.read();
        if(u!= '\n'){
            if(u == '1') ms.write(0);
            else if(u == '2') ms.write(30);
            else if(u == '3') ms.write(60);
            else if(u == '4') ms.write(90);
            else if(u == '5') ms.write(120);
            else if(u == '6') ms.write(180);

            delay(100);
        }
    }
}

코드 해석

#include<Servo.h>
Servo ms;
  • #include 함수를 통해 서보 라이브러리를 가져옴.
  • Servo ms: 서보 모터의 객체 변수 ms를 선언함.
void setup(){
    Serial.begin(9600);//출력 속도 설정
    ms.attach(9);//서보 모터의 핀 설정
    ms.write(0);//서보 모터의 각 설정
}
  • 시리얼 모니터의 통신 속도를 9600으로 설정한다.
  • 서보 모터의 핀을 9로 설정한다.
  • 서보 모터의 각도를 0으로 초기화한다.
void loop(){
    if(Serial.available()>0){
        char u = Serial.read();
        if(u!= '\n'){
            if(u == '1') ms.write(0);
            else if(u == '2') ms.write(30);
            else if(u == '3') ms.write(60);
            else if(u == '4') ms.write(90);
            else if(u == '5') ms.write(120);
            else if(u == '6') ms.write(180);

            delay(100);
        }
    }
}

만약 시리얼 모니터에 입력이 있다면, 문자형 변수 u에 입력된 값을 저장한다.

이후 입력값에 따라 모터의 각을 변경하고 0.1초 기다린다.

입력값 모터의 각 제어
1 0
2 30
3 60
4 90
5 120
6 180