[아두이노 강좌] 05. PC상에서 Serial Monitor로 LED 제어하기


본 게시글에서는 아두이노의 시리얼 모니터 프로그램을 이용하여 컴퓨터에서 LED를 제어하는 방법에 대해 설명하겠습니다. 시리얼 모니터는 아두이노와 컴퓨터사이에서 메세지를 주고 받을 수 있게 하여 줍니다. 디버깅하기 쉽고 아두이노를 컴퓨터에서 제어 할 수 있게 하여 줍니다.
summary.png
예를 들어 컴퓨터에서 LED를 켜거나 끄라는 명령을 보낼 수 있습니다. 본 게시글은 강좌4에서 사용하였던 아두이노와 브레드보드 레이아웃 셋팅을 다시 사용합니다.

Serial Monitor 프로그램

아래는 이번 게시글에 다룰 스케치 코드입니다. 아두이노에 업로드하여 먼저 한번 시험하여 보십시오.
  1. int latchPin = 5;
  2. int clockPin = 6;
  3. int dataPin = 4;
  4. byte leds = 0;
  5. void setup()
  6. {
  7. pinMode(latchPin, OUTPUT);
  8. pinMode(dataPin, OUTPUT);
  9. pinMode(clockPin, OUTPUT);
  10. updateShiftRegister();
  11. Serial.begin(9600);
  12. while (! Serial); // Wait untilSerial is ready - Leonardo
  13. Serial.println("Enter LED Number 0 to 7 or 'x' to clear");
  14. }
  15. void loop()
  16. {
  17. if (Serial.available())
  18. {
  19. char ch = Serial.read();
  20. if (ch >= '0' && ch <= '7')
  21. {
  22. int led = ch - '0';
  23. bitSet(leds, led);
  24. updateShiftRegister();
  25. Serial.print("Turned on LED ");
  26. Serial.println(led);
  27. }
  28. if (ch == 'x')
  29. {
  30. leds = 0;
  31. updateShiftRegister();
  32. Serial.println("Cleared");
  33. }
  34. }
  35. }
  36. void updateShiftRegister()
  37. {
  38. digitalWrite(latchPin, LOW);
  39. shiftOut(dataPin, clockPin, LSBFIRST, leds);
  40. digitalWrite(latchPin, HIGH);
  41. }

스케치를 아두이노에 업로드한 이후에 IDE 오른쪽의 버튼을 눌러 시리얼 모니터를 실행합니다.

아래와 같은 창이 열립니다.
serial_monitor_0.jpg

이 윈도우를 시리얼 모니터라고 부르며 아두이노 IDE의 한 부분입니다. 이 프로그램은 사용자가 컴퓨터에서 아두이노로 메세지를 보낼수 있게 만들어주며, 반대로 아두이노로부터 오는 메세지를 PC로 받을 수 있게 하여 줍니다.

창에 나오는 "Enter LED Number 0 to 9 or 'x' to clear" 메세지는 아두이노가 PC로 보낸 메세지로 x는 모든 LED를 끄며, 숫자를 입력하면 해당 LED를 켜게 됩니다. LED는 0번부터 7번까지 8개 숫자입니다.

예를 들어 x 0 3 5라는 명령을 입력하면 0, 3, 5번 LED가 켜지게 되고 시리얼 모니터창에는 아래와 같이 결과가 표시됩니다.

serial_monitor.jpg
x를 다시 입력하면 모든 LED가 꺼지게 됩니다.

아두이노 코드

아래의 스케치 코드는 이전 강좌에서 사용되었던 코드이기 때문에 여기서는 이전 강좌에서 설명된 부분을 제외한 부분을 설명하도록 하겠습니다.

먼저 setup함수를 보면 새로운 세줄의 코드가 들어갔습니다.

    <span style="COLOR: rgb(30,52,123)" class="kwd">
    1. void setup()
    2. {
    3. pinMode(latchPin, OUTPUT);
    4. pinMode(dataPin, OUTPUT);
    5. pinMode(clockPin, OUTPUT);
    6. updateShiftRegister();
    7. Serial.begin(9600);
    8. while (! Serial); // Wait until Serial is ready - Leonardo
    9. Serial.println("Enter LED Number 0 to 9 or 'x' to clear");
    10. }
    <p> </p> <p> </p></span>

Serial.begin(9600) 명령은 시리얼통신을 시작하게 합니다. 아두이노는 USB연결을 통해 명령어를 보낼수 있게 됩니다. 9600은 시리얼통신 속도로써 숫자가 높을 수록 빠르게 통신합니다. 이 숫자를 변경하려면 시리얼모니터 역시 같은 값을 가지도록 변경하여야 어야 니다.

그 다음의 while문은 시리얼 연결이 준비될때까지 기다립니다. 이 라인은 아두이노 레오나르도를 사용하고 있을 경우에만 필요합니다. 우노는 시리얼 모니터프로그램을 열면 자동으로 아두이노를 리셋합니다.

아래는 핵심이 되는 loop문입니다.

  1. void loop()
  2. {
  3. if (Serial.available())
  4. {
  5. char ch = Serial.read();
  6. if (ch >= '0' && ch <= '7')
  7. {
  8. int led = ch - '0';
  9. bitSet(leds, led);
  10. updateShiftRegister();
  11. Serial.print("Turned on LED ");
  12. Serial.println(led);
  13. }
  14. if (ch == 'x')
  15. {
  16. leds = 0;
  17. updateShiftRegister();
  18. Serial.println("Cleared");
  19. }
  20. }
  21. }

Serial.available()함수는 아두이노가 시리얼 데이터를 수신하면 true를 리턴합니다. 들어오는 메세지는 버퍼에 보관하고 이 버퍼가 비어있지않으면 Serial.available()은 true를 리턴합니다.

  1. char ch = Serial.read();

Serial.read()는 버퍼에서 다음 문자를 읽어 ch변수에 할당하고 읽은 문자를 버퍼에서 제거합니다. 시리얼 모니터상에서 알려주는 명령 설명대로 명령을 입력하였으면 읽은 문자는 0~7의 숫자중 나이거나 x 문자일것입니다.

다음 if 문에서는 읽은 문자가 숫자인지를 확인합니다. 각 문자는 ASCII 코드로 표시되는데 그렇기 때문에 문자를 <=나 >=와 같은 연산자로 비교를 할 수 있습니다.

  1. int led = ch '0';

이 코드는 문자에 대해 산술연산을 수행하는 라인입니다. 만약 사용자가 시리얼 모니터에 0을 입력했으면 '0' -'0' = 0이 되어 숫자 0을 계산해 낼수 있고 만약 7을 입력했으면 '7' -'0' = 7이되어 7을 계산할 수 있습니다. 실제적으로는 아스키 코드값이 연산되는 것입니다.

이제 켜고자 하는 LED의 번호를 알았으니 아래의 코드와 같이 leds변수에 비트를 셋팅하고 쉬프트 레지스터를 업데이트 합니다.

  1. bitSet(leds, led);
  2. updateShiftRegister();
다음 두개의 라인은 확인 메세지를 시리얼 모니터에 보내는 내용입니다.
  1. Serial.print("Turned on LED ");
  2. Serial.println(led);

첫번째 줄은 Serial.println대신 Serial.print를 이용하였습니다. 이 두함수의 차이는 Serial.print는 문자열을 출력하고 새 라인을 시작하지 않는 다는 점이며 Serial.println은 문자열을 출력하고 다음주에 새 라인을 시작하는다는 점입니다.먼저 Serial.print를 이용하여 Turned on LED를 프린트 한후 LED번호를 찍게 됩니다.

그 다음 if문에서는 들어온 문자가 x인지 확인을 합니다.

    <span style="COLOR: teal" class="typ">
    1. if (ch == 'x')
    2. {
    3. leds = 0;
    4. updateShiftRegister();
      1. Serial.println("Cleared");
    5. }
  1. </span>
만약 x가 맞다면 모든 LED를 끄고 확인 메세지를 보냅니다.

시도해볼 다른 것들

위의 예제에서 시리얼 모니터상에 문자를 입력할때 문자를 분리하여 입력을 하였지만 아래와 같이 다 붙여서 명령을 주어도 잘 동작합니다. 아래의 명령을 넣고 send버튼을 눌러보십시오.

x0246

다음으로는 스케치에서 통신속도를 9600이 아닌 115200으로 변경하고 업로드 후에 시리얼 모니터 프로그램에서 아래와 같이 속도를 변경하여 테스트를 하여 봅니다. 아두이노와 PC가 더 빠른 속도로 통신을 하게 됩니다.

baud.jpg

속도를 높여도 잘 동작하는 것을 확인 할 수 있을 겁니다. 만약 스케치와 시리얼 모니터의 속도가 맞지 않는다면 화면에는 이상한 문자들이 표시될 것입니다.

시리얼 모니터 프로그램은 스케치 코드를 디버깅하는데도 아주 유용합니다. 스케치 코드가 원하는대로 동작하지 않는다면 Serial.println() 명령을 이용하여 디버깅 메세지를 넣고 프로그램이 어떻게 동작하는지 시리얼 모니터 프로그램으로 살펴볼 수 있을 것입니다.  

Comments