AndroidThings & Raspberry Pi3로 고양이용 선풍기 만들기 (6)

2017년 11월 18일, 19일에 실시된 「 도호쿠 Tech 도장 고리야마 도장 제8회 」의 작업 내용의 계속을 정리합니다.

L 치카 프로그램을 CatFans에 이식했기 때문에 이번에 이를 사용하여 선풍기 팬을 돌립니다. 그렇다면 서보 모터를 돌리는 처리를 추가합니다.

1. 선풍기의 팬을 돌린다



지난번 프로그램의 핀 이름String pinName = "BCM6";에서String pinName = "BCM23";로 변경하면 선풍기의 팬이 돌아갑니다. 또, 메소드명을 다음과 같이 바꾸어, 코멘트도 재기입했습니다.
BlinkRunnable → turnFan
이런 식으로 팬들이 돌고 있습니다. 그건 그렇고, 사진 고양이는 우리 집의 빛입니다. (^^)


2. 서보를 돌린다



서보 모터를 움직여보십시오. L치카의 샘플 프로그램에는 서보 모터를 움직이는 프로그램(PWM sample)도 들어 있으므로, 이번에는 그것을 사용하기로 했습니다. 선풍기의 팬과는 반대로 고양이가 없으면 서보를 돌리고 고양이가 있으면 서보를 멈춥니다.

(1) L치카 프로그램의 이식



(i) mChangePWMRunnable 및 PWM 방법 추가



「Simple PIO」의 com.example.androidthings.simplepio 안의 onCreate 메소드와 mChangePWMRunnable 메소드를 참고로 다음과 같은 메소드를 추가한다.

CatFansActivity.java
    private Pwm mPwm;
    private boolean mIsPulseIncreasing = true;
    private double mActivePulseDuration;

    // Parameters of the servo PWM
    private static final double MIN_ACTIVE_PULSE_DURATION_MS = 0.8;
    private static final double MAX_ACTIVE_PULSE_DURATION_MS = 2.3;
    private static final double PULSE_PERIOD_MS = 20;  // Frequency of 50Hz (1000/20)

    // Parameters for the servo movement over time
    private static final double PULSE_CHANGE_PER_STEP_MS = 0.08;
    :
    :
    //サーボモータの処理
    private void mChangePWMRunnable(boolean onoff){
            // Exit Runnable if the port is already closed
            if (mPwm == null) {
                Log.w(TAG, "Stopping runnable since mPwm is null");
                return;
            }

            // Change the duration of the active PWM pulse, but keep it between the minimum and
            // maximum limits.
            // The direction of the change depends on the mIsPulseIncreasing variable, so the pulse
            // will bounce from MIN to MAX.
            if (mIsPulseIncreasing) {
                mActivePulseDuration += PULSE_CHANGE_PER_STEP_MS;
            } else {
                mActivePulseDuration -= PULSE_CHANGE_PER_STEP_MS;
            }

            // Bounce mActivePulseDuration back from the limits
            if (mActivePulseDuration > MAX_ACTIVE_PULSE_DURATION_MS) {
                mActivePulseDuration = MAX_ACTIVE_PULSE_DURATION_MS;
                mIsPulseIncreasing = !mIsPulseIncreasing;
            } else if (mActivePulseDuration < MIN_ACTIVE_PULSE_DURATION_MS) {
                mActivePulseDuration = MIN_ACTIVE_PULSE_DURATION_MS;
                mIsPulseIncreasing = !mIsPulseIncreasing;
            }

            Log.d(TAG, "Changing PWM active pulse duration to " + mActivePulseDuration + " ms");

            try {

                // Duty cycle is the percentage of active (on) pulse over the total duration of the
                // PWM pulse
                if(onoff){
                    mPwm.setPwmDutyCycle(100 * mActivePulseDuration / PULSE_PERIOD_MS);
                }

            } catch (IOException e) {
                Log.e(TAG, "Error on PeripheralIO API", e);
            }
        }


    private void PWM(){
        //サーボモータの処理
        PeripheralManagerService service = new PeripheralManagerService();
        try {
            String pinName = "PWM0";
            mActivePulseDuration = MIN_ACTIVE_PULSE_DURATION_MS;

            mPwm = service.openPwm(pinName);

            // Always set frequency and initial duty cycle before enabling PWM
            mPwm.setPwmFrequencyHz(1000 / PULSE_PERIOD_MS);
            mPwm.setEnabled(true);

            // Post a Runnable that continuously change PWM pulse width, effectively changing the
            // servo position
            Log.d(TAG, "Start changing PWM pulse");
            mChangePWMRunnable(false);
        } catch (IOException e) {
            Log.e(TAG, "Error on PeripheralIO API", e);
        }
    }


L치카와 같이 핀은 고정으로 하므로,String pinName = "PWM0";한다.
라즈파이의 핀명은 기본 BCM~이 되지만, 서보 모터만 PWM0, PWM1이 된다. 또한, 서보 모터는 펄스 폭으로 회전하는 위치가 결정되고, 펄스 폭은 펄스 파의주기와 듀티 비로 결정된다.

(ii) onCreate 메소드 수정



OnCreate 메서드의 끝에PWM();추가.

(iii) onDestroy 메소드 수정



onDestroy 메소드를 다음과 같이 수정.

CatFansActivity.java
    protected void onDestroy() {
        :
        :
        //サーボ
        // Remove pending Runnable from the handler.
        mChangePWMRunnable(false);
        // Close the PWM port.
        Log.i(TAG, "Closing port");
        try {
            mPwm.close();
        } catch (IOException e) {
            Log.e(TAG, "Error on PeripheralIO API", e);
        } finally {
            mPwm = null;
        }
    }

(iv) onPictureTaken 수정



onPictureTaken 메소드를 다음과 같이 수정한다.

CatFansActivity.java
    private void onPictureTaken(final byte[] imageBytes) {
                :
                :
                        if (annotations != null) {
                            //猫画像なら
                            if (annotations.containsKey("cat") == true) {
                                if (annotations.get("cat") >= 0.8F) {
                                    // イメージをfirebaseにアップロードする
                                    log.child("timestamp").setValue(ServerValue.TIMESTAMP);
                                    log.child("image").setValue(imageStr);
                                    log.child("annotations").setValue(annotations);

                                    mChangePWMRunnable(false);
                                    turnFan(true);
                                    Log.d(TAG, "Turn the fan");
                                } else {
                                    mChangePWMRunnable(true);
                                    turnFan(false);
                                    Log.d(TAG, "Stop the fan");
                                }
                            }
                            else {
                                mChangePWMRunnable(true);
                                turnFan(false);
                                Log.d(TAG, "Stop the fan");
                            }
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Cloud Vison API error: ", e);
                    }
                }
            });
        }
    }

(v) 실행 확인



다음과 같이 선풍기의 팬 아래에 붙인 서보가 고양이가 없으면 돌고 고양이가 있으면 멈춘다.



제8회는 아직 계속됩니다.

좋은 웹페이지 즐겨찾기