/ ET-CETERA

Arduino

Arduino 개요

아두이노(Arduino)는 이탈리아에서 개발한 오픈소스 보드로 이탈리아어로 강한 친구라는 뜻을 가지고 있습니다.

아두이노는 우리가 흔히 얘기하는 컴퓨터가 아닙니다. 라즈베리파이와는 다르게 아두이노는 우리가 사용하는 컴퓨터처럼 OS를 설치하고 응용프로그램을 설치하는 등의 일을 할 수 없습니다. 참고로 라즈베리파이는 OS설치와 여러 응용프로그램 설치가 가능한 싱글보드 컴퓨터입니다. 우리과정에서는 라즈베리파이대신에 라떼판다(Latte panda)를 이용할 예정입니다. 라떼판다는 아두이노 레오나르도 칩이 코프로세서로 설치되어 있습니다.

아두이노는 Micro-Controller 입니다. 즉, 코드를 돌리는 단순한 기계입니다.

아마도 아두이노란 용어는 많이 들어봤을텐데 이런 아두이노가 왜 이렇게 각광을 받고 있을까요? 그 이유는 사물인터넷(IoT, Internet of things)과 맞물려 있기 때문입니다.

사물인터넷(IoT)은 일반적인 물건처럼 보이지만 1)통신장비를 결합하고 2)고도화된 통신기술을 이용하여 3)특별한 작업을 수행하는 장비를 지칭합니다.

간단한 예를 들자면 사용자의 음성을 인식하는 스피커라든지, 거울에 그날의 날씨나 뉴스와 같은 내용을 띄워주는 스마트 미러와 같은 것이 있습니다.

이러한 사물인터넷을 구현하기 위해 그 안에 들어가는 Controller는 다음과 같은 특징을 가져야 합니다.

  • 가격이 저렴해야 한다.
  • 프로그램 실행코드를 기판에 주입(upload)하는 과정이 간편해야 한다.
  • 센서의 사용이 간편해야 한다.

Arduino는 이러한 특징을 가지고 있는 Micro Controller입니다.

아두이노는 제품의 이름이 아니라 브랜드명입니다. 아두이노라는 브랜드 안에 여러개의 모델이 존재하고 있습니다. 마치 갤럭시라는 브랜드안에 S9,S10,S20와 같은 모델이 있는것처럼 말이죠. 아두이노의 가장 대표적인 모델(가장 기본적인 모델)은 Uno 입니다.

굉장히 많은 아두이노 모델(버전)들이 있고 각 버전들은 나름대로의 특징을 가지고 있습니다. 아주 작은 크기로 소형화된 버전, 크기가 크지만 상대적으로 고사양인 버전, wifi기능에 특화된 버전같은 여러 버전들이 있습니다.

일반적으로 많이 사용하는 버전은 다음과 같은 3가지라고 볼 수 있습니다.

  • Arduino Uno : 가장 일반적인 모델
  • Arduino Mega ADK : 크기가 크지만 꽤나 복잡한 연산을 수행.
  • Arduino Pro Mini : 크기가 작아 저전력으로 사용가능.

아두이노에 대해서 또 알아두어야 할 점은 오픈소스 하드웨어란 점입니다. 즉, 설계와 활용법이 모두 대중적으로 공개되어 있습니다. 따라서 아두이노 호환보드라고 불리는 유사제품들이 굉장히 많이 존재합니다. 하지만 정품제품과 이런 호환제품간에 성능이나 기타 능력면에서 차이는 거의 없다고 보면 됩니다. (가격차이는 좀 있습니다.)


전류,전압,저항

아두이노를 사용하기 위해서는 기본적인 전기에 대한 지식이 필요합니다.

전기는 전압전류로 설명할 수 있는데 전압은 물의 수압과 같은 개념으로 두 점 사이의 전기적인 전위 차이를 의미합니다. 이 전위차에 의해서 전압이 높은 곳에서 낮으곳으로 전자가 흐르게 됩니다. 건전지의 경우 플러스(+)가 높은 전압, 마이너스(-)가 낮은 전압입니다.

아두이노 보드 부분에 POWER라고 적힌 부분 밑에 3V3, 5V라고 적힌 전원 헤더소켓이 있습니다. 각각 전압이 3.3V, 5V라는 것을 의미하고 이렇게 전압이 표시된 곳이 건전지의 +부분과 같고 전기가 흘러나오는 곳이라고 생각하면 됩니다.

헤더소켓은 핀을 꼽을 수 있는 소켓을 의미하며 점퍼와이어를 연결할 수 있습니다. 점퍼와이어의 수컷은 핀으로 암컷은 구멍으로 되어 있습니다.

아두이노 보드 POWER

전원 헤더 소켓의 오른쪽에 GND라고 적힌 헤더 소켓이 2개 있습니다. 그리고 DIGITAL이라고 적힌 곳에도 GND 헤더 소켓이 존재합니다.

GND는 그라운드라는 의미로 전압이 0V인 곳을 의미합니다. 즉, 건전지의 마이너스(-)부분과 같고 전기가 빠져나가는 배수로 개념이라고 생각하면 됩니다.

전자부품을 연결할 때 전자제품의 플러스 부분을 3V3, 5V 헤더소켓에 연결하고 마이너스 부분을 GND 헤더 소켓에 연결하면 됩니다. 아두이노는 일반적으로 5V를 이용합니다.

전류는 전위가 높은 곳에서 낮은곳으로 전하가 연속적으로 이동하는 형상을 의미합니다. 물로 비유하면 수압이 높은곳에서 낮은곳으로 물이 흐르며 이 물의 흐름에 의해서 물레방아가 돌아가게 됩니다. 전자의 흐름을 전류라고 하고 이 전류에 의해서 전자기기가 동작하게 됩니다.

저항은 물체가 전류의 흐름을 제어하는 것을 의미하며 저항이 높은 물체일수록 전류가 적게 흐르고 저항이 낮은 물체일수록 전류가 많이 흐르게됩니다. 수도꼭지를 생각하시면 됩니다.

물리학의 기본법칙 중 하나로 옴의 법칙이라는 것이 있습니다. 전압, 전류, 저항사이의 관계를 나타내는 법칙으로 전류의 세기는 전압에 비례하고 저항에 반비례한다는 공식입니다. 기본공식이기 때문에 잘 알아두어야 합니다.

  • 전압은 기호로는 V(Voltage)를 이용하고 단위는 V(볼트)를 이용한다.
  • 전류는 기호로는 I(Intensity)를 이용하고 단위는 A(암페어)를 이용한다.
  • 저항은 기호로는 R(Resistance)을 이용하고 단위는 을 이용한다.

전류(I) = 전압(V) / 저항(R)


Sensor(센서), Actuator(액추에이터), 기타

아두이노는 센서를 이용하여 주위환경에 대한 정보를 수집할 수 있습니다. 밝기 센서, 거리 센서등 여러 종류의 센서를 이용하여 아두이노는 데이터를 수집할 수 있습니다. 또한 아두이노가 어떤 활동을 할 수 있도록 만들어주는 전자부품이 있을 수 있는데 이를 액추에이터라고 합니다. 모터, LED 같은 것들이 대표적인 액추에이터입니다.

저항은 전기를 열로 바꾸어주는 전자부품입니다. 저항에는 4개 혹은 그 이상의 띠가 표시되어 있는데 이 띠의 색이 저항값을 의미합니다. 당연히 저항이 높을 수록 더 많은 전기를 열로 바꾸게 됩니다. 각 저항이 가지는 값은 저항에 둘려져있는 띠의 색상으로 알 수 있습니다. 교재를 이용해서 각 저항의 값을 알아내는 방법을 알아둘 필요도 있어보입니다. 또는 저항 제품들마다 해당 저항은 몇 옴인지를 표시해 놓고 있는 경우도 있습니다.

다이오드는 전류가 한 방향으로만 흐를 수 있도록 해주는 전자부품입니다. 즉, 전류의 역류를 방지하는 반도체 소자입니다. 띠가 있는 부분이 -를 의미하고 띠가 없는 부분이 +를 의미하는데 전기는 띠가 없는 부분에서 있는 부분으로만 흘러갈 수 있습니다. 즉, 양극(+)에서 음극(-)의 방향으로 전류를 흐르게 합니다. 우리가 회로도를 구성한다고 가정했을 때 그 안에 저항도 넣고, 센서도 넣고, 모터도 넣어서 구성할 수 있습니다. 이렇게 회로를 다 구성한 후 회로에 전원을 반대로 연결하면 어떻게 될까요?

센서는 고장날테고, 모터는 반대로 돌게되며 스파크나 화재까지 발생할 수 있습니다. 즉, 안전을 위해 다이오드를 사용해야 합니다. 모터와 같은 전자부품을 사용하는 경우 다이오드가 필수적으로 들어가야 합니다. 모터가 회전하고 있는 동안에 모터안의 코일에 에너지가 축적됩니다. 그러다가 모터가 OFF된다면 전원은 끊기지만 코일에 에너지가 남아있는 상태가 되며 모터는 에너지를 방출하려 합니다. 이때 높은 전압을 가진 역방향의 기전력이 발생하게 되고 아두이노 보드나 센서등이 파괴될 수 있습니다. 이를 막기위해서 다이오드를 이용하여 역방향으로 오는 기전력을 차단하여 다른 제품을 안전하게 보호해야 합니다. 다이오드는 안전을 위해서 꼭 사용해 주어야 하며 특히 모터와 같은 코일을 사용하는 회로에서는 반드시 사용해야 하는 부품입니다.

브레드보드(일명 빵판)은 전자부품을 쉽게 연결할 수 있도록 도와줍니다. 브레드보드안에 가로와 세로방향에 따라 철심이 박혀있기 때문에 전자부품을 연결할 수 있습니다. 아래의 브레드보드에서 가로로 파진 홈(notch)인 중앙선의 위아래에 위치한 수직방향의 단자띠(terminal strip)와 수평방향의 버스띠(bus strip)로 구성됩니다. 단자띠는 부품들간의 연결을 위한것이고 버스띠는 전원공급을 위한 것입니다.(적색선이 +이고, 청색선이 -입니다.)

브레드보드 형식


디지털과 아날로그

아두이노를 제어하는 방법은 크게 디지털아날로그 두가지가 있습니다. 아두이노 보드에서 점퍼 와이어 핀을 꼽을 수 있는 부분을 헤더소켓 이라고 하는데 그냥 짧게 핀(pin)이라고 부르기도 합니다. 아두이노에서 디지털 신호를 제어할 수 있는 핀을 디지털 핀이라고 부릅니다.

아두이노 UNO의 경우 DIGITAL이라고 표시된 곳에 숫자 0부터 13까지 적혀있는 핀들을 볼 수 있습니다. 이 핀들이 바로 디지털 핀입니다. 그리고 이 디지털 핀을 통해서 디지털 신호를 제어할 수 있습니다. 즉, 디지털 핀에 전기를 연결하거나 끊어줄 수 있다는 말입니다. 이렇게 전기를 연결하거나 끊는 방식이 디지털 출력입니다. 반면 디지털 입력은 디지털 핀으로부터 전기가 들어오는지 들어오지 않는지를 체크하는 것입니다. 디지털 핀의 0과 1번은 컴퓨터와 통신을 담당하는 부분이기 때문에 일반적으로 사용하지 않고 나머지 번호의 핀을 이용합니다.

아두이노 보드 POWER

디지털 핀을 이용할때는 디지털 핀을 입력 용도로 쓸 것인지 출력 용도로 쓸 것인지를 설정해야 합니다. 이때 사용하는 함수 pinMode() 함수로 사용방법은 다음과 같습니다.

// 13번 핀을 입력으로 설정합니다.
// INPUT은 0을 가지는 상수값입니다.

pinMode(13,INPUT);

// 13번 핀을 출력으로 설정합니다.
// OUTPUT은 1을 가지는 상수값입니다.

pinMode(13,OUTPUT);

디지털 핀을 설정한 후 디지털 신호를 출력할 수 있습니다. 디지털 신호를 출력하는 함수는 digitalWrite() 함수로 다음과 같이 사용한다.

// 13번 핀에 디지털 신호를 내보내지 않는다.
// LOW : 0

digitalWrite(13,LOW);

// 13번 핀에 디지털 신호를 내보낸다.
// HIGH : 1
digitalWrite(13,HIGH);

HIGH로 설정하면 전압이 5V가 되면서 전기가 흘러가게 됩니다.

아날로그의 제어 역시 디지털 제어처럼 간단합니다.

디지털핀은 하나의 핀에서 입력과 출력을 둘 다 제어할 수 있지만 아날로그 핀은 입력용과 출력용이 따로 분리되어 있습니다. 아두이노 UNO의 경우 ANALOG IN이라고 표시된 곳에 A0부터 A5까지 적혀있는 핀이 있는데 이 핀들이 바로 아날로그 입력 핀 입니다.

디지털에서의 입력은 LOW,HIGH와 같이 단순히 전기가 끊겼는지 연결됐는지를 확인하는거에 비해 아날로그 입력은 전압이 0V와 5V사이에서 어떤 크기로 들어오는지 확인합니다.

아두이노 UNO의 디지털 핀들이 있는 곳에 보면 틸트(~) 표시가 붙은 핀들을 볼 수 있는데 이 핀들이 바로 아날로그 출력 핀입니다. 당연히 이 핀들은 전압을 0V에서 5V사이에서 원하는 크기로 설정하는 것입니다.

아두이노 보드 POWER

아날로그 신호를 출력할 때 사용하는 함수는 analogWrite()인데 신호를 출력할 핀번호와 설정할 전압의 값을 인자로 사용합니다. 아날로그 신호 출력의 경우 0V부터 5V사이를 256개로 쪼개서 원하는 값을 사용할 수 있습니다. 즉, 0V는 0의 값을 가지며 5V는 255의 값을 가집니다.

LED를 이용하게 되면 당연히 전압의 크기에 따라서 LED의 밝기가 달라지게 됩니다.


Arduino IDE 설치

Arduino는 코드를 돌리는 기계이기 때문에 아두이노에게 우리가 작성한 code를 upload해 주어야 합니다. 우리가 코드를 작성한 후 Arduino에게 code를 이식하는 작업을 도와주는 것이 Arduino IDE입니다.

Arduino 홈페이지를 방문한 후 자신에게 맞는 (windows installer 버전) 버전을 선택하여 다운로드 후 설치를 진행합니다.

Arduino IDE를 실행하면 아두이노 개발환경에서 작성한 코드를 볼 수 있는데 이를 Sketch(스케치)라고 부릅니다. 그리고 이 스케치를 아두이노 보드에 이식하는 것을 Upload라고 합니다.

Arduino는 USB Type-A 단자를 이용하여 컴퓨터와 연결합니다. IDE에서 보드종류를 선택하고 포트를 선택한 후 업로드 버튼을 누르면 Arduino에 코드가 이식되고 수행되게 됩니다.

아두이노 보드에 기본으로 부착된 LED를 이용하여 블링크 예제를 실습해보도록 하겠습니다.

기본 LED는 별도의 하드웨어 연결없이 제어할 수 있습니다. DIGITAL 13번 핀을 이용하고 다음의 코드로 실행합니다. 프로그램을 아두이노에 Upload하게 되면 초기에 setup()함수가 한번 실행되게 됩니다. 일반적으로 초기설정과 관련된 코드가 setup()함수에 나오게 됩니다.

setup()함수가 호출되고 난 후 loop()함수가 자동으로 반복실행되게 됩니다.

void setup() {
    pinMode(13,OUTPUT);
}

void loop() {
    digitalWrite(13,HIGH);
    delay(1000);    // 1초간 아두이노 보드를 멈추는 함수
    digitalWrite(13,LOW);
    delay(1000);
}

analog입력을 이용하여 LED 밝기를 조절하도록 코드를 작성할 수 있습니다. 아래와 같이 아두이노 회로를 구현합니다. (analog입력은 9번을 사용합니다.)

void setup() {
}

void loop() {
    for(int i=0; i<256; i++) {
        analogWrite(9,i);
        delay(10);
    }

    for(int i=255; i>=0; i--) {
        analogWrite(9,i);
        delay(10);
    }      
}

PC와의 통신

아두이노 보드는 PC와 Serial 모니터를 이용해서 통신할 수 있습니다. 이 Serial 모니터는 아두이노 보드의 센서값을 확인하거나 아두이노 보드로 명령을 보낼 때 주로 사용합니다.

아래의 코드를 컴파일 한 후 upload하고 Serial 모니터를 이용하여 확인


void setup() {
    Serial.begin(9600);
    // 보드레이트 설정 : 시리얼 통신할 때의 통신속도를 의미. PC쪽에서 보드레이터를 동일하게
    // 설정해야 통신이 가능. 다른 보드레이트를 이용할 경우 데이터가 잘못 전송될 수 있음.
}

void loop() {
    Serial.println("Hello World");   // Serial 모니터로 데이터 전송
    delay(1000);
}

반대로 PC에서 아두이노 보드로 메시지를 전송할 수 있습니다. Serial 모니터의 상단에서 글자를 입력하고 전송버튼을 누르면 아두이노 보드로 메시지가 전송됩니다.

void setup() {
    Serial.begin(9600);
}

void loop() {
    if(Serial.available()) {     // Serial통신으로 받은 데이터가 있는지를 확인
        char c = Serial.read();  // Serial통신으로 들어온 데이터 중 1바이트를 잘라내어 읽는다.
                                 // 만약 문자열형태로 읽고 싶다면 readString()이용
        Serial.print(c);
    }
}

LED 사용

LED는 전류가 흐르면 빛이 나는 액추에이터입니다. LED는 LED 렌즈의 지름이 5mm인 것을 많이 사용합니다. LED는 플러스와 마이너스로 극성이 나누어져있는데 LED의 다리 길이가 긴쪽이 플러스, 짧은 쪽이 마이너스 극성을 가집니다.

LED가 버틸 수 있는 전류보다 많은 전류가 연결되면 당연히 LED가 탈 수 있습니다. 반대로 너무 작은 전류가 흐를경우 LED의 빛이 거의 나지 않게됩니다. 따라서 전류의 양을 조절하기 위해 저항을 LED의 앞이나 뒤에 연결해 주어야 합니다. 그러면 얼마만큼의 전류가 적당한지를 알아야 하는데 이는 전자부품의 데이터시트를 보고 확인해야 합니다.

일반적으로 5mm LED의 필요 전류는 15mA이고 강하전압이 2V정도 된다고 알려져 있습니다. 그렇다면 아두이노 보드에서 전류가 15mA 정도 흐르게 하기 위해서는 저항을 어떤값을 이용해야 할까요?

전압 = 전류 * 저항

아두이노의 전압은 5V이고 LED의 강하전압은 2V이기때문에 5-2=3 즉, 3V로 계산하면 됩니다. LED에서 필요한 전류는 15mA이기 때문에 0.015A입니다. 따라서

3 = 0.015 * 저항

저항을 구해보면 200이라는 값을 구할 수 있고 우리는 200옴짜리 저항을 이용해서 사용해야 LED가 타지 않고 사용할 수 있게될 것입니다. 좀 더 안전하게 사용하기 위해서는 220옴과 같은 약간 더 큰 옴값을 이용하는 것이 좋습니다.

아두이노 Blink

int ledPin = 13;

void setup() {
  pinMode(ledPin,OUTPUT);
}

void loop() {
  digitalWrite(ledPin,HIGH);
  delay(1000);
  digitalWrite(ledPin,LOW);
  delay(1000);
}

버튼 사용

버튼을 누르면 LED가 켜지고 버튼을 떼면 LED가 꺼지게끔 만들어보겠습니다.

부품을 여러개 사용하다보면 전원과 그라운드가 모자르게 되는경우가 있는데 이때 브레드보드를 이용하면 이 문제를 해결할 수 있습니다.

  1. 아두이노의 그라운드 핀에 점퍼와이어를 연결한 후 브레드보드의 긴 파란색 부분에 연결합니다. 일반적으로 그라운드는 검은색 점퍼와이어를 이용하는게 좋습니다. (구별을 위해서)

  2. LED를 디지털 핀 13번에 연결합니다. 저항(220옴)도 같이 연결해서 기존에 LED 켜기할 때 사용했던 구조로 연결합니다.

  3. 버튼을 중앙선을 기준으로 놓습니다. 버튼을 눌러야 전류가 통하도록 연결합니다. 저항은 10k옴을 이용합니다. 그리고 디지털 핀 8번을 입력으로 사용합니다. (버튼을 누르면 전류가 흐르고 디지털 핀 8번에서 digitalRead()하면 HIGH값이 리턴됩니다.)

  4. 아래의 코드를 이용하여 버튼을 누르면 전원이 연결되고 디지털 핀 8번으로부터 입력이 HIGH가 됩니다. 이를 조건문으로 활용하여 디지털 핀 13번에 연결한 LED에 불이 들어오게끔 코드를 작성합니다.

아두이노 Button Blink

void setup() {
  pinMode(13,OUTPUT);
  pinMode(8,INPUT);
}

void loop() {
    int value = digitalRead(8);

    if(value==HIGH) {
      digitalWrite(13,HIGH);
    } else {
      digitalWrite(13,LOW);
    }
}

자바프로그램과의 연동(Event기반)

통신에서의 시리얼 통신이란 패러럴 통신(병렬 통신)에 반대되는 말로써 한번의 통신의 한 비트의 데이터를 보내는 방식을 말합니다.

이런 Serial통신을 이용하여 Java와 아두이노간의 데이터 통신을 할 수 있습니다.

간단하게 아두이노에서 버튼을 누르면 자바프로그램(javaFX)에서 “아두이노에서 버튼부품 클릭해서 LED 켜기”이라는 메시지를 javaFX의 TextArea에 출력하고 javaFX의 “LED 켜기” 버튼을 누르면 아두이노의 LED를 켜고 “LED 끄기” 버튼을 누르면 아두이노의 LED를 끄게 구현하겠습니다.

  • 아두이노 회로 구현(위에서 설명한 버튼과 LED구현을 그대로 이용)

아두이노 JavaFX Blink

  • 아두이노 스케치 프로그램 작성 및 업로드
int btnInputPin = 8;

void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);
  pinMode(btnInputPin,INPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()) {   // Serial통신을 사용할 때 데이터 수신시 사용
                             // 리턴값 : 시리얼 통신으로 수신한 데이터의 길이(bytes)
                             // Serial 통신으로 아두이노에 데이터가 들어오면 이 데이터는
                             // 일단 Serial Buffer라고 불리는 작은 메모리에 저장되고
                             // Serial.read() 계열의 함수를 통해서 버퍼의 데이터를 읽어옵니다.
    String inString = Serial.readString();
    if(inString == "LED_ON") {
      digitalWrite(13,HIGH);  
    } else if(inString == "LED_OFF"){
      digitalWrite(13,LOW);
    }
  }

  int value = digitalRead(btnInputPin);
  if(value == HIGH) {
    digitalWrite(13,HIGH);
    Serial.print("O"); 
    delay(1000);   // 1초간 정지(메시지가 계속 전달되는것을 피하기 위해)
  }
}
  • 자바프로그램 작성 및 실행

아두이노 JavaFX Window

class Exam03_ArduinoSerialListener implements SerialPortEventListener {

	InputStream in;
	Exam03_ArduinoJavaFXSerial window;

	Exam03_ArduinoSerialListener(InputStream in,Exam03_ArduinoJavaFXSerial window) {
		this.in = in;
		this.window = window;
	}

	@Override
	public void serialEvent(SerialPortEvent oEvent) {
		if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
			try {

				int available = in.available();
				System.out.println("받은 바이트수 : " + available);
				byte chunk[] = new byte[available];
				in.read(chunk, 0, available);

				String result = new String(chunk);
				System.out.println("아두이노에서 받은 메시지 : " + result);

				if(result.equals("O")) {
					window.printMessage("아두이노에서 버튼부품 클릭해서 LED 켜기");	
				}

			} catch (Exception e) {
				System.err.println(e.toString());
			}
		}		

	}	
}

public class Exam03_ArduinoJavaFXSerial extends Application {

	TextArea textarea;
	Button ledOnBtn, ledOffBtn;
	InputStream in;
	BufferedWriter bw;

	public void printMessage(String msg) {
		Platform.runLater(()->{
			textarea.appendText(msg + "\n");
		});
	}

	private void connectSerial() throws Exception {
		CommPortIdentifier portIdentifier = null;		
		portIdentifier = 
				CommPortIdentifier.getPortIdentifier("COM14");

		if ( portIdentifier.isCurrentlyOwned() ) {
			System.out.println("현재 포트가 사용되고 있습니다.");
		} else {

			CommPort commPort = 
					portIdentifier.open("PORT_OPEN",2000);

			if ( commPort instanceof SerialPort ) {
				//포트 설정(통신속도 설정. 기본 9600으로 사용)
				SerialPort serialPort = (SerialPort) commPort;
				serialPort.setSerialPortParams(9600,
						SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1,
						SerialPort.PARITY_NONE);

				//Input,OutputStream 버퍼 생성 후 오픈
				in = serialPort.getInputStream();					
				bw = new BufferedWriter(
						new OutputStreamWriter(
								serialPort.getOutputStream()));

				serialPort.addEventListener(
						new Exam03_ArduinoSerialListener(in,this));
				serialPort.notifyOnDataAvailable(true);

			} else {
				System.out.println("Serial 포트만 사용가능합니다.");
			}
		}     

	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		BorderPane root = new BorderPane();
		root.setPrefSize(700, 500);

		textarea = new TextArea();
		root.setCenter(textarea);

		ledOnBtn = new Button("LED 켜기");
		ledOnBtn.setPrefSize(250, 50);
		ledOnBtn.setOnAction((e) -> {
			String line = "LED_ON";
			printMessage("LED 켜기버튼 클릭!!");
			try {
				bw.write(line,0,line.length());
				bw.flush();				
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		});

		ledOffBtn = new Button("LED 끄기");
		ledOffBtn.setPrefSize(250, 50);
		ledOffBtn.setOnAction((e) -> {
			String line = "LED_OFF";
			printMessage("LED 끄기버튼 클릭!!");
			try {
				bw.write(line,0,line.length());
				bw.flush();				
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}			
		});

		FlowPane flowpane = new FlowPane();
		flowpane.setPrefSize(700, 50);
		flowpane.setHgap(10);
		flowpane.getChildren().add(ledOnBtn);
		flowpane.getChildren().add(ledOffBtn);

		root.setBottom(flowpane);

		Scene scene = new Scene(root);
		primaryStage.setScene(scene);
		primaryStage.setTitle("javaFX Arduino Serial 통신");
		primaryStage.setOnCloseRequest(e->{
			System.exit(0);
		});
		primaryStage.show();

		try {
			connectSerial();	
		} catch (Exception e) {
			System.out.println(e);
		}


	}

	public static void main(String[] args) {
		launch();
	}
}

안드로이드와 아두이노 연동 예제

안드로이드의 SeekBar를 이용하여 Mobile Device에서 LED의 불빛을 제어하는 예제를 작성합니다.

Android - Java Network Server - Arduino 형태로 다음의 영상처럼 동작하도록 구현합니다.


피에조 스피커 활용

피에조 스피커는 전기적 신호를 이용해서 소리를 내는 전자부품입니다. 동작하는 전압에 따라 크기가 다양합니다. 여기서는 5V용 피에조 스피커를 활용합니다.

피에조 스피커를 이용한 소리출력 예제를 작성해보도록 하겠습니다.

  • 아두이노 회로 구현

아두이노 피에조 스피커

  • 아두이노 스케치 프로그램 작성 및 업로드
int melody[] = { 262, 294, 330, 349, 392, 440, 494, 523 };

void setup() {
  for(int i=0; i<8; i++) {
    tone(8,melody[i],250);
    delay(400);
    noTone(8);
  }
}

void loop() {
  
}

LCD 활용

LCD는 액정 화면에 글자나 숫자를 표시하는 전자부품입니다. 아두이노와 연결해 사용하는 것은 주로 2줄이 있고 한 줄당 16글자를 표시할 수 있는 1602 LCD를 많이 이용합니다. (총 32자 표시)

LCD를 확인해보면 핀이 아주 많은 것을 확인할 수 있습니다.

아두이노 LCD

각 핀들의 의미는 다음과 같습니다.

  • 배경관련 LCD의 가장 오른쪽의 KA는 배경의 밝기와 관련이 있습니다. K는 배경밝기를 제어하기 위해서 GND에 연결하고 A는 전원에 연결합니다. 만약 배경조명이 없거나 배경 밝기가 필요없다면 이 2개의 핀들을 사용하지 않습니다.

  • 데이터관련 오른쪽 3번째부터 10번째까지 핀들은 LCD에 값을 보내거나 LCD로부터 값을 받을 때 사용하는 핀입니다. 각 핀들의 이름은 D7 ~ D0입니다.

  • 설정관련 E핀은 LCD에 값을 쓸 수 있도록 할지 말지를 설정합니다. RW핀은 LCD의 값을 읽을지 쓸지 선택할 때 사용합니다.

  • 기타 VSS핀은 LCD가 동작하기 위해서 GND에 연결하는 핀이고, VDD핀은 전원에 연결합니다. V0핀은 글자 색을 진하게 할지 흐리게 할지 설정할 때 사용합니다.

이렇게 LCD는 핀들이 굉장히 많고 용도도 각기 다릅니다. 상당히 복잡하지만 사실 우리가 LCD를 이용할때는 라이브러리를 이용해서 사용합니다. LCD는 LiquidCrystal이라는 라이브러리를 이용해서 제어합니다.

먼저 아두이노 회로도를 만들어야 합니다. 글로 표현하기에는 너무 복잡하기 때문에 교재를 이용해서 회로도를 완성합니다. (아두이노, 상상을 현실로 만드는 프로젝트-입문편. 영진닷컴)

아두이노 LCD 회로도

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,2,3,4,5);
// LiquidCrystal(RS,E,D4,D5,D6,D7); 핀 연결번호

void setup() {
  lcd.begin(16,2);
}

void loop() {
  lcd.clear();
  lcd.print("Hello World");
  delay(500);
}

LiquidCrystal 라이브러리에서 사용할 수 있는 함수는 다음과 같습니다.

  • LiquidCrystal() : LCD 클래스 생성에 사용. LCD 인터페이스 설정
  • begin() : LCD 화면 초기화(column과 row설정)
  • clear() : LCD 화면을 지우고 커서를 좌상으로 이동
  • home() : 커서를 좌상으로 이동
  • setCursor() : 커서를 특정위치로 이동
  • write() : 현재 커서에 한 문자를 출력
  • print() : 현재 커서부터 출력(Serial.print()와 유사)
  • cursor(), nocursor() : 커서 표시 on/off
  • display(), noDisplay() : LCD 화면에 정보 표시 on/off
  • scrollDisplayLeft(), scrollDisplayRight() : LCD 내용과 커서를 좌/우로 한칸 스크롤
  • autoscroll(), noautoscroll() : 문자 출력 시 이전 내용을 스크롤할 지를 결정
  • leftToright(), rightToLeft() : 문자 출력 후 커서의 이동위치 결정

LCD와 조도센서의 활용

조도센서(Ambient Light Sensor)를 이용하여 측정한 조도를 LCD에 표현하는 예제를 구현합니다.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,2,3,4,5);
// LiquidCrystal(RS,E,D4,D5,D6,D7); 핀 연결번호
int cds = A0;  

void setup() {
  lcd.begin(16,2);
}

void loop() {
  int val= analogRead(cds); 
  // analogRead()로 측정되는 범위(0~1023)
  lcd.clear();
  lcd.print(val);
  delay(100);
}

End.