실제 실생활에서 모터는 여러 용도로 사용되고 있다. 아두이노를 통해 모터를 제어하는 방법을 다룬다.

모터의 종류에는 크게 DC 모터와 서보 모터가 있다.

DC 모터는 제어가 매우 쉽고, 저 전압의 직류 전원으로 구동이 가능하며 쉽게 구할 수 있어 많은 기계장치, 전자, 전기 분야에 폭 넓게 사용되고 있다.
또한 구동력이 크며, 회전 제어와 속도제어가 쉬우며, 제어용 모터로서 아주 우수한 특성을 가지고 있다. 로봇에 사용되는 DC 모터는 이동에 적정한 속도와 토크(torque)를 얻기 위하여 모터에 감속 기어를 장착한 기어드 모터를 사용한다.

소형 DC 모터는 대부분 고정자로 영구자석과 전기자(회전자) 코일로 구성되어 있다. 정류자를 통하여 전기자에 전류를 공급하면 자기력의 반발, 흡인력으로 회전력이 발생하여 회전한다.
로봇을 비롯한 산업의 여러 방면에서 가장 널리 사용되고 있는 모터이다.

  1. 기동 토크가 크며, 인가전압에 대하여 회전특성이 직선적으로 비례한다.
  2. 입력 전류에 대하여 출력 토크가 직선적으로 비례하며, 또한 출력 효율이 양호하다.
  3. 쉽게 구할 수 있고, 가격이 저렴하다.
  1. 구조상 브러시(brush)와 정류자(commutator)에 의한 기계식 접점이 있어, 전기 불꽃(spark)에 의한 노이즈가 발생한다.
  2. DC 모터의 각 단자와 케이스 사이에 0.01uF ~ 0.1uF 정도의 세라믹 콘덴서를 부착하면 전기불꽃을 흡수하여 노이즈를 억제할 수 있다.

DC 모터는 전원 입력 단자에 전압을 걸어주면 모터가 돌아가며 전원을 제거하면 정지한다.
DC 모터의 속도는 전기자 코일의 전류에 비례하여 회전한다. 따라서 모터의 회전속도는 전류를 제어함으로써 제어 가능하다. 그러나 전기자 코일의 저항이 일정하므로 전압에 비례하여 전류가 증가하게 되므로 모터에 공급되는 전압을 조절해주면 모터 속도가 제어된다.
모터의 속도 제어는 아날로그 제어와 디지털 제어인 PWM(Pulse Width Modulation)제어가 있다.

서보 모터는 작고 컴팩트하며, 크기에 비해 힘이 좋아 작은 로봇 실험에 매우 유용하게 사용되고 있다. 또한 모터, 기어박스, 위치 궤환 메커니즘과 제어회로까지 모든 것들이 모터 내부에 포함되어 있다.
간단한 PWM 제어에 의해 위치를 제어할 수 있어, 최근 로봇의 제어에 많이 사용되고 있으며, 또한 간단한 개조로 별도의 제어회로 없이 정회전, 역회전 제어를 할 수 있어 라인트레이서나 소형 로봇의 구동장치로 사용되고 있다.

서보모터는 제어회로와 기어 박스 및 모터 출력축과 연결된 포텐셔미터(가변저항)를 가지고 있다. 이 포텐셔미터는 서보모터의 현재 각도를 제어회로에 제공하여 모터가 정확한 위치에 멈추도록 한다.
서보모터의 작동범위는 대부분 180도를 회전할 수 있고, 회전 범위를 넘어서 회전하지 못하도록 기어에 기계적 제동장치가 만들어져 있다.

서보모터에 공급되는 전력량은 모터가 움직여야할 거리에 비례하는데 회전각도가 크면 모터는 높은 속도로 돌며 회전각도가 작으면 모터속도는 느려지는 비례제어를 행한다.
서보모터에는 3가닥의 선이 나와 있으며 3색 선의 기능은 색깔로 구분된다.

빨간색 Vcc(+5V)
검은색 GND
노란색(흰색) 제어선

전원은 서보모터 기동 시 전압강하를 고려하여 4.8 ~ 6.0V 독립전원이 필요하지만 많은 프로세서들이 저전압 동작기능이 있기 때문에 CPU 와 같은 전원을 사용한다.

제어신호는 PWM 으로 공급해야 하는데 펄스의 주기는 18 ~ 25ms 정도로 하고, ON 되는 시간 Ton(Duty rate)을 변화시켜 PWM 펄스를 만드는데 Ton 이 1500usec에서 서보모터는 중앙 각도에서 정지하고 700usec - 0도, 2300usec 에서 180도의 각도로 움직인다.

아두이노의 PWM 출력은 약 50Hz 구형파이므로 제어 선을 출력에 연결하여, 50Hz 구형파의 듀티 비(Duty rate)를 변경시키면 서보모터가 좌우로 회전하는 것을 확인할 수 있을 것이다.

준비운동하기

모터 제어를 하기 위해 필요한 것 중 하나가 전류이다. 모터의 경우 대개 큰 전류를 필요로 하기 때문에 USB 전원으로 공급되는 전류(500mA)로는 동작시킬 수 없다.
그래서 필요한 전류를 얻기위해 외장 추가 배터리와 이를 제어할 수 있는 모터 모듈이 필요하다. 모터 모듈에서는 기본적으로 2개의 모터를 연결해서 사용할 수 있도록 지원한다.
이들 각각의 연결 방법은 다음과 같다.

============================================================================
 
[아두이노]              [ 모터 드라이버 보드]          [ 3.7V 리튬 폴리머 배터리를 ]         
 
5V      ----------------        5V    
 
GND   ----------------       GND  ---------------------   배터리(-)
 
                                        VMS  ---------------------   배터리(+)
 
============================================================================

모터 모듈에는 4개의 핀(IN1, IN2, IN3, IN4)이 있는데, 이를 통해 연결된 각각의 모터를 제어할 수 있다. 이중 모터 A 는 IN1, IN2 를 사용하고, 모터 B는 IN3, IN4 를 사용한다.
모터 A 의 경우, 아래 표와 같이 신호 레벨을 제어함으로서, 구동 방향과 동작 여부를 조정할 수 있다.

ENA 핀 상태 IN1, IN2 핀 상태 모터A 상태
ENA = High IN1 = High, IN2 = Low 정방향 구동
ENA = High IN1 = Low, IN2 = High 역방향 구동
ENA = High IN1 == IN2 구동 정지
ENA = Low IN1, IN2 상관없음 구동정지

DC 모터 사용하기(정회전/역회전)

int IN1 = 10;
int IN2 = 8;
 
void setup()
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
}
 
void loop()
{
  digitalWrite(IN1, HIGH);       // 정방향 구동
  digitalWrite(IN2, LOW);
 
  delay(2000);
 
  digitalWrite(IN1, LOW);      // 정지
  digitalWrite(IN2, LOW);
 
  delay(2000);
 
  digitalWrite(IN1, LOW);       // 역방향 구동
  digitalWrite(IN2, HIGH);
 
  delay(2000);
}

DC 모터 사용하기(PWM 속도 제어)

이번에는 속도를 제어해보자. 방법은 간단하다. analogWrite 함수를 사용해서 인자값에 변화를 주면 속도가 조절된다.

스위치 3개를 사용해서 첫번째 스위치를 누르면 속도가 빨라지고, 두번째 스위치를 누르면 속도가 느려지고, 마지막 스위치를 누르면 정지하도록 만들었다.
dc-motor-pwm.fzz

int IN1 = 10;
int IN2 = 8;
int SENSOR_HIGH = 11;
int SENSOR_LOW = 12;
int SENSOR_STOP = 7;
 
int val_high;
int val_low;
int val_stop;
 
unsigned char motorPWM = 0;
 
void setup()
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(SENSOR_HIGH, INPUT);
  pinMode(SENSOR_LOW, INPUT);
  pinMode(SENSOR_STOP, INPUT);
 
  Serial.begin(9600);
 
}
 
void loop()
{
  val_high = digitalRead(SENSOR_HIGH);
  val_low = digitalRead(SENSOR_LOW);
  val_stop = digitalRead(SENSOR_STOP);
 
  if(val_high == HIGH)
  {    
    motorPWM += 5;                                    // 스위치를 누르고 있는 동안 값이 증가한다
    if(motorPWM >= 255) motorPWM = 255;        // 최대값 255
 
    digitalWrite(IN2, LOW);
    analogWrite(IN1, motorPWM);                
 
    Serial.println("push high");
 
    delay(100);  
  }
  else if(val_low == HIGH)
  {
    motorPWM = motorPWM - 5;              // 스위치를 누르고 있는 동안 값이 감소한다
    if(motorPWM <= 0) motorPWM = 0;
 
    digitalWrite(IN2, LOW);
    analogWrite(IN1, motorPWM);
 
    Serial.println("push low");
 
    delay(100);
  }
  else if(val_stop == HIGH)
  {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
 
    Serial.println("push stop");
 
    delay(100);
  }
 
  delay(250);
 
}

서보모터 사용하기

서보모터를 사용하기 위해서는 관련 라이브러리를 사용해야(include) 한다. '스케치 → 라이브러리 가져오기 → Servo' 를 선택한다.

핀(pin)에 서보 변수(개체)를 연결시킨다.
servo.attach(pin, min, max)

  1. servo : 연결할 서보의 변수
  2. pin : 서보가 연결될 핀 번호
  3. min(옵션) : 최소 각의 펄스 폭(us), 0도 일 때 초기 설정 값은 544
  4. max(옵션) : 최대 각의 펄스 폭(us), 180도 일 때 초기 설정 값은 2400

사용 예)

#include <Servo.h>
 
Servo myservo;     // 연결할 서보 변수 myservo 를 만듬
 
void setup()
{
   myservo.attach(9);     // D9 번에 서보 변수를 연결함
}

서보를 angle 각도만큼 회전시킴. angle(각)은 0 ~ 180 사이의 값을 사용한다.
사용 예)

myservo.write(90);   // 서보가 90도(중간위치)로 이동함

서보제어를 us 값으로 제어한다. 일반적인 서보에서 700~2300 사이의 값을 사용한다 700us → 0도, 1500us→ 90도, 2300us → 180도로 이동한다.
사용 예)

myservo.writeMicroseconds(1500);    // 90도로 회전

현재의 서보의 각도를 읽어옴. 반환 값은 0~180 사이이다.

myservo.read();

서보 변수가 핀에 연결되었는지를 점검한다. 반환 값은 true, false 이다.
사용 예)

myservo.attached();

핀으로부터 연결된 서보변수의 연결을 해제한다.
사용 예)

myservo.detach();

서보모터의 경우, 낮은 전압으로도 충분한 동작이 가능하기 때문에 모터모듈이 필요없다.
subo.fzz

서보모터를 0도 → 90도 → 180도 → 90도로 움직이는 코드다.

int pulseWidth;      // 서보 제어용 펄스 폭(us)
int i;                   // 출력 유지
 
// 지연을 이용한 서보제어 사용자 함수(서보 연결 핀, 각도)
void servoControl(int servoPin, int angle)
{
  // 서보 동작을 위한 일정시간 동안 동일 파형 유지
  for(i=0; i<25; i++)       //  서보가 회전하는 동안 출력 파형을 유지해야 한다. 따라서 파형을 유지하기 위해 25 회 반복시킨다. 펄스폭이 정확히 출력되고 있으나, 
  {                            //   서보모터가 정확한 위치로 회전하지 않을 경우 반복횟수를 늘리면 해결된다.
    pulseWidth = (angle * 9) + 700;      // 펄스 폭 계산. 0~180도를 시간(700us ~ 2300us)으로 만들기 위한 계산식. 0도이면 700 이 되며, 180도이면 2320 이 된다
    digitalWrite(servoPin, HIGH);           // 펄스 ON
    delayMicroseconds(pulseWidth);      // 펄스 폭 만큼 지연
    digitalWrite(servoPin, LOW);          // 펄스 OFF
    delay(20);                            // 약 50Hz 파형을 만들기 위한 지연
 
    // 계산된 Ton 시간 동안 ON 시킨 후, 20ms 동안 OFF 시킨다. 4줄의 명령어로 20ms ~ 22.3ms 주기의 PWM 출력을 만들어낸다. 
    // 더 정밀하게 할 경우는 delay(20 - pulseWidth/1000); 으로 변경하면 정확한 50Hz 의 PWM 이 출력된다.
 
  }
}
 
void setup()
{
  pinMode(10, OUTPUT);
}
 
void loop()
{
  servoControl(10,0);      // 0도로 이동
  servoControl(10,90);     // 90도로 이동
  servoControl(10,180);    // 180도로 이동
  servoControl(10,90);     //  90도로 이동
}

스위치 3개를 사용해서 서보모터의 방향을 제어할 것이다.
subo2.fzz

#include <Servo.h>
 
int sensor1 = 5;
int sensor2 = 6;
int sensor3 = 7;
 
Servo myservo;
 
void setup()
{
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
 
  myservo.attach(10);
 
 
}
 
void loop()
{
  if(digitalRead(sensor1) == HIGH)
  {
    myservo.write(0);            // 0도
  }
 
  if(digitalRead(sensor2) == HIGH)
  {
    myservo.write(90);          // 90도
  }
 
  if(digitalRead(sensor3) == HIGH)
  {
    myservo.write(180);          //180도
  }
}
  • computer/embedded/아두이노_그대로_따라하기_-_8.모터_사용하기.txt
  • Last modified: 3 years ago
  • by likewind