아두이노 제어 주기 - adu-ino jeeo jugi

2016-04-16 20:57:35

PWM(Pulse Width Modulation)

 PWM 이란 Pulse Width Modulation의 준말로
펄스의 폭을 컨트롤 하는 주기 제어방법입니다.

출력되는 전압값을
일정한 비율(duty)동안은 High를 유지하고,
나머지는 Low를 출력하여 아래와 같은 사각파의 출력을 만들어 내는데,

PWM을 사용하면 0V와 5V 사이의 아날로그 값을 모사할 수도 있으며,
제어 및 통신에서도 많이 사용됩니다.

아두이노 제어 주기 - adu-ino jeeo jugi

analogWrite

 아두이노에서는 
analogWrite 함수를 통해서 이러한 PWM 출력을 제공하는데, 
analogWrite 함수의 인자로는 0~255까지의 정수가 들어갈 수 있습니다.
이 값에 따라 PWM의 duty가 0~100%로 변하게 됩니다.

아두이노 제어 주기 - adu-ino jeeo jugi

led_gradation.ino 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

int ledPin = 6;

int val = 0;

void setup()

{

pinMode(ledPin, OUTPUT);

}

void loop()

{

analogWrite(ledPin, val);

delay(5);

val += 1;

if(val >= 256)

val = 0;

}

서보 모터 제어하기

서보 모터 또한 PWM으로 각도 제어가 가능합니다.
통상적으로, 서보 모터를 제어하는 PWM은 20ms 정도의 주기를 가지고 있으며,
1ms ~ 2ms의 High 신호에 따라 0도 에서 180도까지 회전합니다.

반면

analogWrite 로 발생되는 PWM은
약 490Hz(핀마다 다름) 정도의 빠른 주기를 가지고 있는데,
따라서 해당 PWM 신호는 서보 모터를 제어하기 부적합 합니다.
해당 예제에서 우리는 미리 만들어진
Servo 라이브러리를 사용하여 서보 모터를 제어 해 볼 것입니다.

아두이노 제어 주기 - adu-ino jeeo jugi

servo.ino

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <Servo.h>

Servo myservo;

int pos = 0;

void setup(){

myservo.attach(6);

}

void loop(){

for(pos=0; pos<=180; pos++){

myservo.write(pos);

delay(15);

}

for(pos=180; pos >=0; pos--){

myservo.write(pos);

delay(15);

}

}

참고자료

  • Arduino - analogWrite() 참고자료 
  • Arduino - Servo 변수 참고자료

[출처] https://opentutorials.org/module/2106/12246

앞선 포스팅에서 digitalRead 함수를 이용한 예제를 풀어보았다. 

https://udangtangtang-cording-oldcast1e.tistory.com/38?category=1019061 

[Arduino] #7. 아두이노 디지털/아날로그 출력하기 & 예제

저번 포스팅에서 입출력 함수를 배웠다면, 이번 포스팅에서는 디지털/ 아날로그 입출력 함수를 통해 직접 아두이노를 구동해보자. 입출력 선언 pinMode(variable,status); //variable(변수)를 status로 입출

udangtangtang-cording-oldcast1e.tistory.com

아두이노 제어 주기 - adu-ino jeeo jugi

위의 예제를 응용하여 우리는 버튼 입력값을 받아 LED의 동작을 제어할 수 있다. 하지만 버튼을 때게 되면 LED의 불이 꺼지게 되는데, 이러한 문제점을 attachInterrupt을 사용하면 해결할 수 있다.

attachInterrupt

attachInterrupt란 특정한 핀에 특정한 조건에 맞는 외부 인터럽트가 발생할 경우 수행할 함수를 등록하는 함수이다.

아두이노 자체적으로 탑제되어 있으므로 따로 include를 하지 않아도 된다.

attachInterrupt(digitalPinToInterrupt(pin),ISR,mode);
pin 핀 번호. 아두이노의 경우 2,3
ISR 인터럽트가 발행하면 하드웨어적으로 호출되는 인터럽트 처리함수.
일반적으로 사용자가 정의하는 함수이다.
mode 인터럽트 발생 조건

mode 조건

RISING LOW -> HIGH
FALLING HIGH -> LOW
CHANGE RISING -> FALLING
LOW pin : LOW 연결

인터럽트로 LED 제어하기

const int LED= 12;
const int BUTTON = 2;

int LED_STATE = LOW;
bool LED_STATE_CHANGE = false;

void BP(){

  LED_STATE_CHANGE = true;
  LED_STATE = (LED_STATE==LOW)?HIGH:LOW;
}

void setup (){

  pinMode(LED,OUTPUT);
  pinMode(BUTTON,INPUT);

  attachInterrupt(digitalPinToInterrupt(BUTTON),BP,RISING);
}

void loop(){

  if(LED_STATE_CHANGE){
    LED_STATE_CHANGE = false;
    digitalWrite(LED,LED_STATE);
  }
}

용어 설명

const int LED= 12;
const int BUTTON = 2;
  • LED 변수에 12번 핀 할당: LED
  • BUTTON 변수에 2번 핀 할당: 버튼
int LED_STATE = LOW;
bool LED_STATE_CHANGE = false;
  • LED의 상태(LED-STATE)를 LOW로 설정
  • bool 함수 이용하여 LED의 상태 변화(LED_STATE_CHANGE)를 불변(false)으로 설정
void BP(){//BUTTON PRESS
  LED_STATE_CHANGE = true;
  LED_STATE = (LED_STATE==LOW)?HIGH:LOW;
}

버튼이 눌렸을 때 실행할 함수 선언

  1. LED의 상태 변화를 true로 설정
  2. LED의 상태(LED_STATE)를 조건 연산자를 이용하여 LOW이면 HIGH, HIGH이면 LOW로 설정

즉, 버튼이 눌리면 LED가 변화할 수 있음을 알리고 LED의 상태(ON/OFF)를 변경한다.

void setup (){

  pinMode(LED,OUTPUT);
  pinMode(BUTTON,INPUT);

  attachInterrupt(digitalPinToInterrupt(BUTTON),BP,RISING);
}
  • LED와 BUTTON의 입출력을 선언한다.
  • attachInterrupt를 정의한다.
void loop(){
  if(LED_STATE_CHANGE){
    LED_STATE_CHANGE = false;
    digitalWrite(LED,LED_STATE);
  }
}

LED의 상태 변화값이 1이면(LED의 변화 여부가 가능하면) LED의 상태 변화 여부를 false로 설정하고 LED의 상태에 맞게 LED를 제어한다.