[라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 3.3 서보모터 예제

알도 2017-11-15 (수) 17:50 7년전 4775  


 

라즈베리파이 강좌

  안드로이드 씽스(Android Things) 시작하기 - 3.3 서보모터 예제






  안녕하세요. 메카솔루션 알도입니다.

  오늘은 안드로이드 씽스(Android Things)로 서보 모터를 제어하는 예제 프로그램을 만들어보겠습니다. 서보 모터는 원래 특정 모터를 지칭하는 것이 아니라, 어떤 모터에 제어 시스템이 갖춰진 것을 마치 모터의 종류인 것처럼 서보 모터라고 부르게 되었습니다. 크게 CNC 등 고속 정밀 제어를 요하는 산업현장에 사용되는 것이 있고, 우리가 일상(?)에서 쉽게 만날 수 있는 RC용 또는 로봇용 서보모터가 있습니다. 이 역시 원래는 RC항공기 계열에서 주로 사용하다가, 로봇이 유행하게 되면서 메이커 쪽에서도 많이 사용하게 되었고, 로봇용 서보 모터도 나오게 되었습니다.



  로봇용 서보 모터는 여러 편리한 기능을 제공하지만, 비교적 고가이므로, 아직까지는 RC 서보모터를 많이 사용하고 있습니다. RC 서보 모터는 PWM 신호를 입력을 받아서 모터의 각도를 제어할 수 있는 서보 모터입니다. PWM은 대부분의 마이크로 컨트롤러에서 지원하고 있고, 그 위에 서보 모터 제어 라이브러리도 흔하게 찾을 수 있습니다.

  지난 포스트에서는 버튼을 이용해서 LED를 껐다 켜기는 반복하는 앱을 만들었었습니다. 이번 포스트에서는 안드로이드 씽스에서 지원하는 서보 라이브러리를 이용해 서보모터를 한쪽 끝에서 다른쪽 끝까지 움직이는 앱을 만들어보도록 하겠습니다.

  이 포스트의 내용은 Servo Driver for Android Things의 내용을 참고하여 작성하였습니다.


 


 

     서보 모터 제어 예제


 준비물

  이번 강좌를 위해서는 다음과 같은 준비물들이 필요합니다.


    - 라즈베리파이 3

    - Micro USB 전원

    - 모니터(필수는 아닙니다.)

    - 다음 셋 중 하나는 반드시 필요합니다.

시리얼 컨버터

공유기 + 랜선

랜카드(이더넷 포트) + 랜선


 

 

 

 

 SG90 서보모터

 M-F(수-암) 점퍼

 


  안드로이스 씽스를 준비하는 방법은 아래 포스트를 참고하세요.


    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 1.1 시리얼로 초기화하기

    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 1.2 공유기를 통해 초기화하기

    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 1.3 직접 연결하여 초기화하기


  초기 연결과 프로젝트 생성/업로드 부분은 아래를 참고하세요.


    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 2. Hello World


  지난 포스트인 LED를 주기적으로 켜고 끄기는 아래를 참고하세요.


    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 3.1 LED & 버튼 예제

    [라즈베리파이 강좌] 안드로이드 씽스(Android Things) 시작하기 - 3.2 LED & 버튼 예제



 회로 연결하기

  아래와 같이 회로를 구성합니다. 우측의 GPIO 핀 배치도와 함께 보면 회로를 이해하시는데 더 도움이 됩니다.


 


 



  브레드 보드의

    빨강선은 전원 입력으로 GPIO의 5V

    갈색선은 접지로 GPIO의 GND

    주황선은 PWM으로 GPIO13

  에 연결됩니다.



 프로젝트 설정

 그래들 설정

  ​dependencies에 다음을 추가합니다. LED 켜고 끄기와 다르게 버튼 드라이버도 필요하게 됩니다.


dependencies {

    ...


    compile 'com.google.android.things.contrib:driver-pwmservo:0.3'

    provided 'com.google.android.things:androidthings:0.5.1-devpreview'

}


 

 매니페스트 설정

  아래와 같이 <application .... >이 끝나는 부분에 아래 코드를 입력합니다.


<application>

    <uses-library android:name="com.google.android.things"/>


    ...

</application>




 코드 작성하기

   코드는 이전 코드와 다소 비슷하며, 주기적으로 서보를 회전시키도록 할 것이기 때문에 3.1 LED & 버튼 예제의 코드와 유사합니다.


 맴버 객체/변수 작성

  서보 모터 제어를 위해 Servo 클래스 객체와 이를 주기적으로 제어하기 위해 쓰레드, 러너블 클래스 객체를 선언해줍니다. While문 내부는 후에 채우도록 하겠습니다.


private Servo mServo;

Thread mThread;

Runnable mRunnable = new Runnable() {

    public void run() {

        while (true) {


        }

    }

};


 


 멤버 객체 초기화

  서보 모터를 초기화 하는 방법은 아래와 같습니다. 먼저 모터의 스펙을 알아야 하므로 데이터 시트를 잠시 참고해보겠습니다.


 


  위 내용을 정리해보면, PWM의 주파수는 50㎐, 주기가 50㎳에 PWM의 폭이 1㎳ 일 때 -90도, 2㎳ 일 때 90도, 1.5㎳ 일 때 0도 입니다. 이것을 서보 클래스를 초기화할 때 펄스폭은 1~2㎳, 각도 폭은 -90~90도로 설정해줍니다. 문제는 펄스폭 부분이 정확히 맞지가 않습니다. 심지어 같은 SG90 서보 모터인데도 서로 조금씩 다릅니다. 아래 코드는 필자가 값을 조금씩 바꿔보면서 맞춘 것으로 펄스폭이 원래 1~2㎳이어야 했던 것을 0.75~2.6㎳로 조정했습니다. 여러분들도 실제 하시려면 값을 조금 조정하셔야 할 것입니다.


try {

    mServo = new Servo("PWM1");

    mServo.setPulseDurationRange(0.75,2.6);

    mServo.setAngleRange(-90, 90);

    mServo.setEnabled(true);

} catch (IOException e) {}


mThread = new Thread(mRunnable);

mThread.start();



 멤버 함수 작성

  처음 멤버 객체/변수 작성 부분에서 비워놓았던 While 문 내부를 여기서 채우도록 하겠습니다. Servo 클래스의 setAngle 함수를 이용해서 서보 모터의 각도값을 입력해줍니다. 첫 루프에서 -90도로 출발한 다음 2초를 대기하고 다시 90도로 출발한 다음 2초 대기하기를 반복하는 코드입니다.


while (true) {

    try {

        mServo.setAngle(-90);

    } catch (IOException e) {}


    try {

        Thread.sleep(2000);

    } catch (InterruptedException e) {}


    try {

        mServo.setAngle(90);

    } catch (IOException e) {}


    try {

        Thread.sleep(2000);

    } catch (InterruptedException e) {}

}


 


 전체 코드

  아래는 MainActivity.java 파일의 전체 내용입니다. 맨 위의 패키지 부분은 혼란의 여유가 있어서 포함시키지 않았습니다.


import android.app.Activity;

import android.os.Bundle;


import com.google.android.things.contrib.driver.pwmservo.Servo;


import java.io.IOException;


public class MainActivity extends Activity {

    private Servo mServo;

    Thread mThread;

    Runnable mRunnable = new Runnable() {

        public void run() {

            while (true) {

                try {

                    mServo.setAngle(-90);

                } catch (IOException e) {}


                try {

                    Thread.sleep(2000);

                } catch (InterruptedException e) {}


                try {

                    mServo.setAngle(90);

                } catch (IOException e) {}


                try {

                    Thread.sleep(2000);

                } catch (InterruptedException e) {}

            }

        }

    };


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        try {

            mServo = new Servo("PWM0");

            mServo.setPulseDurationRange(0.75,2.6);

            mServo.setAngleRange(-90, 90);

            mServo.setEnabled(true);

        } catch (IOException e) {}


        mThread = new Thread(mRunnable);

        mThread.start();

    }

}




 동작 영상


메카리워즈 Image Map


모바일 버전으로 보기