LoginSignup
0
0

More than 5 years have passed since last update.

AndroidThings & Raspberry Pi3 で猫用扇風機を作る(6)

Posted at

2017年11月18日、19日に実施された「東北Tech道場 郡山道場 第8回」の作業内容の続きをまとめます。

LチカのプログラムをCatFansに移植したので、今度はこれを使って扇風機のファンを回します。それからができたら、サーボモータを回す処理を追加します。

1. 扇風機のファンを回す

前回のプログラムのピン名を
String pinName = "BCM6";
から
String pinName = "BCM23";
に変更するだけで、扇風機のファンが回ります。また、メソッド名を次のように変え、コメントも書き換えました。

BlinkRunnable → turnFan

こんな感じでファンが回っています。ちなみに写真の猫は我が家のライトです。(^^)
30.jpg

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) 実行確認

以下のように扇風機のファンの下につけたサーボが、猫がいなければ回り、猫がいたら止まる。

31.jpg

第8回はまだ続きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0