[아두이노 강좌] 14. 아두이노로 서보모터 제어하기

http://wiki.vctec.co.kr/opensource/arduino/servocontrol

본 게시글에서는 아두이노를 이용하여 서보모터를 어떻게 제어하는지 살펴보도록 하겠습니다. 서보를 자동으로 앞뒤로 움직이게 만들어보고, 포텐셔미터를 추가하여 서보의 포지션을 제어하도록 하겠습니다.

knob.jpg

브레드보드 레이아웃1

아래의 브레드보드에서는 서보 모터만이 아두이노에 연결되어 있습니다. 아래와 같이 브레드보드를 셋업합니다.

fritzing_sweep.jpg

서보모터는 3개의 리드선을 가지고 있는데 보통 빨강이 5V, GND는 검정이나 갈색입니다. 나머지 리드선은 제어 리드선으로 보통 오렌지색이나 노랑색을 띄고 있습니다. 제어 리드선을 디지털 핀 9번에 연결합니다.

서보 리드선 끝의 소켓에 점퍼를 연결하여 아래와 같이 브레드보드에 셋업합니다.

sweep.jpg

만약 서보가 오동작을 한다면,

위와 같이 셋업을 하였는데 만약 서보가 이상하게 동작을 한다면, 그것은 서보가 너무 많은 전력을 끌어다 쓰기 때문일 수 있습니다. USB로 아두이노에 전원을 공급하기 때에만 이러한 현상이 발생할 수 있습니다. 보통 모터가 움직이기 시작할때 전력을 많이 쓰기 때문에 이는 아두이노 보드의 전압을 떨어 뜨릴 수 있으며, 이는 다시 아두이노 보드를 리셋하게 만듭니다.

만약 이러한 현상이 발생한다면, 캐페이시터(470uF이상)를 GND와 5V 사이에 추가함으로써 해결할 수 있습니다.

fritzing_with_cap.jpg

캐패에시터는 모터가 사용하는 전력 저장소와 같은 역활을 하여 모터가 시작할때 아두이노 전원뿐아니라 캐패이시터에서 전기를 끌어다 쓸수 있습니다.

캐패이시터의 긴 다리가 양극이며 이 리드선이 5V에 연결되어야 합니다. 음극 리드선은 보통 '-' 심볼로 표시됩니다.

아두이노 코드 1

아래의 스케치 코드를 아두이노에 업로드하면 서보가 한방향으로 돌다가 다른 방향으로 다시 도는 것을 확인 할 수 있습니다.

본 스케치 코드는 아두이노 servo 예제 폴더에 있는 sweep 코드를 기반으로 작성된 코드입니다.

  1. #include <Servo.h>
  2. int servoPin = 9;
  3. Servo servo;
  4. int angle = 0; // servo position in degrees
  5. void setup()
  6. {
  7. servo.attach(servoPin);
  8. }
  9. void loop()
  10. {
  11. // scan from 0 to 180 degrees
  12. for(angle = 0; angle < 180; angle++)
  13. {
  14. servo.write(angle);
  15. delay(15);
  16. }
  17. // now scan back from 180 to 0 degrees
  18. for(angle = 180; angle > 0; angle--)
  19. {
  20. servo.write(angle);
  21. delay(15);
  22. }
  23. }

서보 모터는 펄스에 의해 제어되어 사용하기 쉽습니다. 서보용 아두이노 라이브러리가 있어 서보에게 단지 동작할 각도를 알려주기만 하면 됩니다.

이러한 서보 라이브러리를 사용하기 위해서는 아래와 같은 코드로 아두이노 IDE에게 서보 라이블러리를 사용할 것임을 알려주어야 합니다.

  • #include <Servo.h>

그리고, 서보를 제어하기 위해 servoPin이라는 이름의 변수를 정의하였습니다.

    1. Servo servo;

위의 코드에서 보면 Servo 타입 servo변수를 정의한 것을 볼 수 있습니다. Servo는 라이브러리에서 제공하는 변수 타입으로 서보사용시 사용합니다. 8개까지의 서보를 정의할 수 있습니다. 만약 두개의 서보를 가지고 있다면, 아래와 같이 정의 할 수 있을 것입니다.

    1. Servo servo1;
    2. Servo servo2;

servo변수에게는 실제로 제어할 서보의 제어핀이 어떤 핀인지를 알려주어야 니다. 아래의 코드로 servo변수에게 제어핀을 알려줍니다.

servo.attach(servoPin);

변수 angle은 서보의 현재각도를 저장하기 위해 사용됩니다. loop함수에서 우리는 두개의 for loop를 사용하는 것을 볼 수 있는데, 첫번째로 각도를 한방향으로 180도까지 증가 시키고, 다음 for 루프에서는 반대방향으로 욺직이게 합니다.

servo.write(angle);

위의 코드는 서보에게 파라메터로 들어온 각도로 위치를 업데이트 하는 명령입니다.

브레드보드 레이아웃2

그럼 두번째 브레드보드 레이아웃을 살펴보겠습니다. 이 레이아웃에는 포텐셔미터가 포함되어 포텐셔미터를 돌려 서보의 위치를 조절할 수 있습니다. 포텐셔미터의 슬라이더 리드를 아두이노의 A0에 연결합니다.

fritzing_knob.jpg

아두이노 코드

  1. #include <Servo.h>
  2. int potPin = 0;
  3. int servoPin = 9;
  4. Servo servo;
  5. void setup()
  6. {
  7. servo.attach(servoPin);
  8. }
  9. void loop()
  10. {
  11. int reading = analogRead(potPin); // 0 to 1023
  12. int angle = reading / 6; // 0 to 180-ish
  13. servo.write(angle);
  14. }

두번째 코드도 첫번째 코드와 비슷한데 potPin이라는 변수가 추가되었습니다. 서보의 위치를 셋팅하기 위해 포텐셔미터로부터 나오는 아날로그 값을 A0핀으로부터 analogRead함수를 통하여 읽어 드리면, 0에서 1023의 값이 읽히게 됩니다.

서보는 오직 180도만 회전할 수 있기 때문에 180도에 맞게 0~1023까지의 값을 스케일 하여야 합니다. 0-1023을 6으로 나누면 0~170이 되어 알맞게 스케일 되었습니다

서보 모터

서보 모터의 위치는 펄스의 길이에 따라서 설정됩니다. 서보는 대략 매 20ms마다 펄스를 받게되는데, 만약 이 펄스가 1ms동안 high이면 각은 0 이며, 1.5ms동안 high이면 중간위치에 위치하게 되고 2ms인 경우는 180도가 되게 됩니다..

servos.png

서버가 움직일 수 있는 끝부분은 제품에 따라 차이가 있는데 많은 서보가 170도까지만 회전을 합니다. 360도까지 회전하는 서보도 있으니 필요하다면 제품을 찾아보는 것도 좋습니다.

 


Posted by 샌츠
,

[아두이노 강좌] 07. 버튼을 이용하여 RGB LED 색상 제어하기

http://wiki.vctec.co.kr/opensource/arduino/rgbledcolorcontrol

이번 게시글에서는 6번 강좌에서 셋업하였던 세개의 푸쉬버튼을 이용하여 RGB LED의 색깔을 제어하는 실험을 진행하도록 하겠습니다.

overview.jpg

브레드보드 레이아웃

브레드보드 레이아웃은 아래와 같습니다. RGB LED의 가장 긴다리는 2번째 줄에 연결하여 GND에 연결되어 있는 것을 주의하십시오

본 레이아웃은 RGB LED가 공통 음극을 가진 타입을 기준으로 작성되었습니다. 만약 공통 양극을 가진 RGB LED를 가지고 있다면 가장 긴 다리를 +5V에 GND대신 연결하십시오.

fritzing.jpg

아두이노 코드

아래의 코드를 아두이노에 로드합니다.

시작할때, 모든 LED는 꺼져 있게 되며 버튼을 누르고 있으면 LED는 점점 밝게 빛나게 됩니다. 브레드보드상의 제일 상단에 있는 버튼은 빨강, 중간은 초록, 제일 밑의 버튼은 파랑색을 조절하는 버튼입니다.

버튼들을 서로 눌러서 색이 어떻게 섞이는 지 확인하여 보십시오. 다시 시작하고 싶으시면 아두이노의 리셋버튼을 눌러 초기화 시키십시오. USB커넥터 옆에 있는 버튼입니다.

  1. int redLEDPin = 11;
  2. int greenLEDPin = 10;
  3. int blueLEDPin = 9;
  4. int redSwitchPin = 7;
  5. int greenSwitchPin = 6;
  6. int blueSwitchPin = 5;
  7. int red = 0;
  8. int blue = 0;
  9. int green = 0;
  10. void setup()
  11. {
  12. pinMode(redLEDPin, OUTPUT);
  13. pinMode(greenLEDPin, OUTPUT);
  14. pinMode(blueLEDPin, OUTPUT);
  15. pinMode(redSwitchPin, INPUT_PULLUP);
  16. pinMode(greenSwitchPin, INPUT_PULLUP);
  17. pinMode(blueSwitchPin, INPUT_PULLUP);
  18. }
  19. void loop()
  20. {
  21. if (digitalRead(redSwitchPin) == LOW)
  22. {
  23. red ++;
  24. if (red > 255) red = 0;
  25. }
  26. if (digitalRead(greenSwitchPin) == LOW)
  27. {
  28. green ++;
  29. if (green > 255) green = 0;
  30. }
  31. if (digitalRead(blueSwitchPin) == LOW)
  32. {
  33. blue ++;
  34. if (blue > 255) blue = 0;
  35. }
  36. analogWrite(redLEDPin, red);
  37. analogWrite(greenLEDPin, green);
  38. analogWrite(blueLEDPin, blue);
  39. delay(10);
  40. }

스케치를 보면 LED를 제어하기 위한 세개의 출력 핀이 있고, 이 출력 핀은 PWM핀으로 LED의 각 컬러로 들어가는 전력을 제어할 있습니다.

또 다른 세개의 핀이 필요한데 이 핀들은 버튼을 위하여 사용이 됩니다. setup함수에서 입력으로 설정되었으며 HIGH상태로 풀업되어, 만약 버튼이 눌리게 된다면 LOW상태로 변화하게 됩니다.

핀이 정의된 다음에는 red, green, blue라는 변수들이 나오게 됩니다.

  1. int red = 0;
  2. int blue = 0;
  3. int green = 0;

이 변수들은 LED의 각 RGB 채널의 빛의 세기를 저장하는 값입니다. 만약 red가 0이라면 LED의 빨강색부분은 꺼지게 되며, 255라면 최고치의 빨강색을 밝게 표현합니다.

loop함수는 두 부분으로 나뉘어 있는데 첫번째 부분은 버튼을 체크해서 red, green, blue변수에 버튼의 상태에 따라 필요한 변화를 주는 부분입니다. 예를 들어 빨강색용 버튼을 체크하는 부분은 아래와 같습니다.

  1. if (digitalRead(redSwitchPin) == LOW)
  2. {
  3. red ++;
  4. if (red > 255) red = 0;
  5. }

digitalRead함수를 실행하게 되고 red 핀이 LOW상태인것을 발견하게 되면 이것은 버튼이 눌렸다는 것을 의미합니다. 그래서 red변수에 1을 더하게 됩니다.

PWM용으로 쓸수 있는 최대 값은 255이기 때문에 다음 라인에서 red가 255를 넘는지를 확인 한 후 넘었다면 0으로 다시 설정합니다.

두번째 부분은 analogWrite함수를 수행하는 부분으로 각각의 LED의 색을 설정하게 됩니다.

  1. analogWrite(redLEDPin, red);
  2. analogWrite(greenLEDPin, green);
  3. analogWrite(blueLEDPin, blue);

마지막으로 loop의 마지막에는 짧은 딜레이를 주어 색의 변화를 조금 늦추어 줍니다. 이 딜레이가 다다면 푸쉬버튼의 물리적인 노이즈로 색이 랜덤하게 변할 수 있습니다.


Posted by 샌츠
,

[아두이노 강좌] 06. 푸쉬버튼을 이용한 디지털 입력하기

http://wiki.vctec.co.kr/opensource/arduino/pushbutton

본 게시물에서는 푸시 버튼을 이용하여 LED를 켜고 끄는 방법에 대해 살펴보도록 하겠습니다.

overview.jpg

맨위에 있는 푸쉬 버튼을 누르면 LED가 켜지고 다른 버튼을 누르면 LED가 꺼지게 될 것입니다.

브레드보드 레이아웃

스위치 버튼의 핀은 스위치 반대편에 위치하여 있습니다.

fritzing.jpg

LED를 연결할 때는 극성을 주의하여 연결하십시오. 짧은 쪽이 음극이며 오른쪽에 위치 시켜야 합니다.

아두이노 코드

아래의 스케치를 아두이노에 로드시키고 맨 위에 위치한 푸쉬버튼을 눌러보십시오. LED가 켜지는것을 확인한 후 다른 버튼을 눌러 LED를 끄십시오.

  1. int ledPin = 5;
  2. int buttonApin = 9;
  3. int buttonBpin = 8;
  4. byte leds = 0;
  5. void setup()
  6. {
  7. pinMode(ledPin, OUTPUT);
  8. pinMode(buttonApin, INPUT_PULLUP);
  9. pinMode(buttonBpin, INPUT_PULLUP);
  10. }
  11. void loop()
  12. {
  13. if (digitalRead(buttonApin) == LOW)
  14. {
  15. digitalWrite(ledPin, HIGH);
  16. }
  17. if (digitalRead(buttonBpin) == LOW)
  18. {
  19. digitalWrite(ledPin, LOW);
  20. }
  21. }

코드의 첫부분에서는 세개의 핀을 위한 변수를 정의하였습니다. ledPin은 출력 핀이며 buttonApin은 제일 위에 있는 버튼, buttonBpin은 다른 스위치를 의미합니다.

setup함수에서 ledPin을 디지털 출력모드로 설정하였습니다. buttonApin, buttonBpin은 입력으로 설정되었는데 INPUT_PULLUP이 파라메터로 쓰였습니다.

  1. pinMode(buttonApin, INPUT_PULLUP);
  2. pinMode(buttonBpin, INPUT_PULLUP);

INPUT_PULLUP 핀모드는 핀이 입력으로 사용될 것이지만 아무것도 연결되지 않았다면 HIGH 상태로 pullup 시켜두라는 것을 의미합니다. 다시 말하면 입력핀의 기본 상태는 HIGH입니다. 그리고 버튼을 눌르면 상태는 LOW가 되어야 합니다.

그래서 스위치들이 GND에 연결되어 있습니다. 스위치가 눌리면 스위치는 입력핀을 그라운드와 연결시키게 되고 입력핀은 더이상 HIGH상태가 될수 없게 됩니다.

입력은 보통 HIGH이고 버튼이 눌리면 LOW로 되는 로직을 loop 함수에서 처리합니다.

  1. void loop()
  2. {
  3. if (digitalRead(buttonApin) == LOW)
  4. {
  5. digitalWrite(ledPin, HIGH);
  6. }
  7. if (digitalRead(buttonBpin) == LOW)

{

  1. digitalWrite(ledPin, LOW);
  2. }
  3. }

루프 함수 안에는 두개의 if문이 있고 각각 버튼 두개의 상태를 검사합니다.

버튼이 눌린다면 눌린쪽에 연결된 입력핀은 LOW가 되므로 버튼A가 눌려 LOW상태가 된다면 digitalWrite 함수가 ledpin을 HIGH로 만들어 LED를 켜게 됩니다.

비슷하게 버튼 B가 눌린다면 LED를 끄게 됩니다.

푸쉬 스위치

스위치는 간단한 부품으로 버튼을 누르면 두개의 접촉부분을 연결시켜 전기를 흐르게 만드는 부품입니다.

여기서 사용되는 택틀 스위치는 4개의 다리를 가지고 있어 무엇이 무엇인지 약간 헷갈립니다.

sw.png

실제로 버튼에는 두개의 전기적 연결만이 있습니다. 스위치 케이스 안에는 핀B와 핀C가 서로 연결되어 있고 핀A와 핀D가 서로 연결되어 있습니다.

 


Posted by 샌츠
,