코드 작성하기 코드를 작성하기에 앞서서 먼저 생성된 프로젝트의 기본 코드를 살펴보겠습니다.아래 그림과 같이 화면 좌측의 Project를 누른 다음. app - java - <Company Domain>.<Project Name> - <Activity Name>.java 파일을 엽니다.
엑티비티 파일을 열면 아래와 같은 코드가 뜹니다.
우선은 LED를 켜보는 것이 집중하여 코드를 살펴보도록 하겠습니다. 관련 지식이 없으신 분들은 지금 당장은 이해하기 어려울 수 있으니 이해가 안되면 고생하지 마시고 편하게 쭉쭉 넘기면서 읽으세요. 6번 줄부터 살펴보도록 하겠습니다. 먼저 public이라고 되어있는데, 이는 말그대로 공용 즉 누구나 접근 및 사용할 수 있음을 의미합니다. 안드로이드는 객체를 기본으로 구성됩니다. 객체 지향 프로그래밍(Object Oriented Programming)의 개념을 잘 모르시는 분들은 객체(Object)란 단순하게 변수와 함수 등을 묶어 놓은 개념이라고 생각하시면 됩니다. 이런 객체를 선언(Declaration)할 때 클래스(Class)를 씁니다. 모든 안드로이드의 기초가 되는 것이 Activity 클래스(AppCompatActivity는 안드로이드 4.0 이하 버전과의 호환성을 위한 것으로 Activity로 바꾸어도 무방합니다.)입니다. 그래서 안드로이드 SDK에서 기본적인 Activity 클래스를 정의해놓고, 각각의 개발자들이 자신들의 프로젝트를 생성할 때 이 Activity 클래스를 상속(extends) 받아 사용하도록 하고 있습니다. 여기서 상속이란 객체를 확장할 때 사용하는 말로 자식 객체가 부모 객체의 모든 변수와 함수 등을 모두 그대로 가져오고, 여기서 확장하여 자신 만의 변수와 함수를 추가하는 것을 말합니다. 여기서 자식 객체는 MainActivity, 부모 객체는 AppCompatActivity입니다. 6번 줄을 다시 해석하자면 객체 MainActivity를 선언하는데, AppCompatActivity를 부모 삼아 확장(extends)하여 사용한다는 의미입니다. 8번 줄부터 보시면, Override라는 말이 나오는데 이는 onCreate함수가 부모 객체에 있는 함수인데, 이를 상속/확장하여 사용한다는 의미입니다. 함수 내부를 보면 10번 줄에 super.onCreate(...);이 부모 객체에서 구현된 부분을 실행하는 함수입니다. 11번 줄의 setContentView 함수는 화면을 그려주는 함수입니다.
먼저 처음하시는 분들이 접근하기 쉽도록, 코드는 다소 어렵고 복잡하더라도 아두이노와 비슷한 형태가 되도록 만들어보겠습니다. 다음 코드를 아래 사진과 같은 위치에 붙여 넣으세요. 첫번째 코드 :
Thread mThread; Runnable mRunnable = new Runnable() { public void run() { while (true) { // put your main code here, to run repeatedly: } } };
그리고 두번째 코드 :
mThread = new Thread(mRunnable); mThread.start();
첫번째 함수의 While 문 내부를 아두이노의 loop으로 생각하시면 되고, 두번째 함수 onCreate 중간에 빈 줄을 아두이노의 setup으로 생각하시면 됩니다. 7번줄에 나오는 쓰레드(Thread)란 하나의 작업을 의미합니다. 아두이노의 loop를 하나의 쓰레드라고 생각하시면 됩니다. 아두이노는 단 하나의 쓰레드만 가지고 실행할 수 있는 반면, 안드로이드나 일반 컴퓨터에서는 여러 개의 쓰레드를 실행, 즉 한번에 여러가지 작업을 병행할 수 있습니다. 하지만 쓰레드가 하나도 없는 경우도 있기 때문에 지금처럼 주기적으로 LED를 켰다 껐다하는 작업을 위해서는 하나의 쓰레드를 작성해줘야 하기 때문에, 이렇게 복잡한 코드를 필요로 하게 되는 것입니다. 러너블(Runnable)은 쓰레드의 인터페이스인데, 당장은 쓰레드만 이해해도 충분하니 나중에로 넘기도록 하겠습니다. 먼저 LED를 컨트롤하고, 그 상태를 기억해놓기 위한 변수를 하나씩 만들어보겠습니다. 맨 위의 Main Activity와 Thread 사이에 넣어주시면 됩니다.
public class MainActivity extends Activity { private Gpio mLedGpio = null; private boolean mLedVal = true;
Thread mThread; ...
Gpio 클래스는 Gpio 핀들을 입출력으로 이용하는데 필요한 클래스입니다. 아두이노의 Digital 핀과 같다고 생각하시면 됩니다. 그 다음으로는 아래와 같이 핀들의 초기 설정을 해줍니다.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
PeripheralManagerService pioService = new PeripheralManagerService();
try { mLedGpio = pioService.openGpio("BCM6"); mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW); mLedGpio.setValue(true); } catch (IOException e) {}
mThread = new Thread(mRunnable); mThread.start(); }
PeripheralManagerService 클래스는 GPIO 클래스에 지정된 핀 BCM6를 담당하는 객체를 생성해주는 역할을 합니다. try 문은 예외사항이 발생할 가능성, 즉 실행하는 과정에서 에러가 날 가능성이 있는 함수를 사용할 때 필수적으로 사용해야 하는 함수입니다. 만약 에러가 나면 뒤의 catch문 안에 있는 명령을 실행하게 됩니다만 현재는 비어있습니다. 예외사항의 예로는 이 프로그램이 라즈베리파이가 아닌 다른 보드에 설치되었을 경우를 들 수 있습니다. BMC6는 라즈베리파이의 GPIO핀의 이름이기 때문에 다른 보드에서는 에러가 나게 됩니다. try문 내부는 아두이노에서 pinMode처럼 생각하시면 됩니다. 핀을 출력으로 초기값은 LOW로 설정해줍니다. 아두이노와 다른 점은 GPIO핀을 초기화하는데 별개의 클래스, PeripheralManagerService,가 필요하다는 부분입니다. 이게 초기 설정을 마쳤으니 Loop 문으로 가보겠습니다.
Thread mThread; Runnable mRunnable = new Runnable() { public void run() { while (true) { try { if (mLedVal) { mLedGpio.setValue(false); mLedVal = false; } else { mLedGpio.setValue(true); mLedVal = true; } } catch (IOException e) {}
try { Thread.sleep(1000); } catch (InterruptedException e) {} } } };
마찬가지로 try 문을 사용합니다. LED가 켜져 있으면 끄도록, 꺼져있으면 켜도록 코드를 작성했습니다. 마지막으로 Thread.sleep에서 1초(1000ms)를 기다리도록 했습니다. 아두이노의 delay함수가 같다고 생각하시면 됩니다. 전체 코드는 다음과 같습니다.
import android.app.Activity; import android.os.Bundle;
import com.google.android.things.pio.Gpio; import com.google.android.things.pio.PeripheralManagerService;
import java.io.IOException;
public class MainActivity extends Activity { private Gpio mLedGpio = null; private boolean mLedVal = true;
Thread mThread; Runnable mRunnable = new Runnable() { public void run() { while (true) {
try { if (mLedVal) { mLedGpio.setValue(false); mLedVal = false; } else { mLedGpio.setValue(true); mLedVal = true; } } catch (IOException e) {}
try { Thread.sleep(1000); } catch (InterruptedException e) {} } } };
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
PeripheralManagerService pioService = new PeripheralManagerService();
try { mLedGpio = pioService.openGpio("BCM6"); mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW); mLedGpio.setValue(true); } catch (IOException e) {}
mThread = new Thread(mRunnable); mThread.start(); } }
이제 프로그램을 업로드하면 LED가 1초 간격으로 깜빡거리는 것을 확인하실 수 있습니다. 업로드 방법이 기억나지 않으시는 분들은 다음 포스트 내용을 참고하세요.
[라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 2. Hello World |