Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@tomato_sugar

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

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

12月2日に東北Tech道場全体の発表会が行われたのですが、その直前の回です。前回までの作業で、5秒おきに写真を撮って、Cloud Vision APIで解析して、解析結果とともにFirebaseにアップロードし、スマホからそれを確認するところまでできました。そろそろハードと合わせないと間に合いません。それと、当初予定していた、

  • 画像をAIで判別し、猫が写っていて、設定温度と湿度を超えていれば扇風機のモータを回す。このとき、距離センサで猫との距離を測り、離れすぎている場合には扇風機は回さない。

という仕様ですが、これはもう時間的に全部は完成させられそうにないので、

  • 画像をAIで判別し、猫が写っていれば扇風機のモータを回す。
  • サーボモータで扇風機そのものを回転させ、猫を探す。

に限定して開発することになりました。なお、下の方の仕様は、距離センサの代替案です。

1. ハードウェアの状態

この時点でのハードウェアは次のような状態です。市販の扇風機から取り外したファンと別途購入したサーボモータをRaspberry Pi3で制御します。
29.jpg

2. Lチカを試す

まず、Raspberry Pi3のPIOの使い方を覚えるためにLEDを点灯させるプログラムLチカを作成しました。参考にしたのは、「電子工作、プログラミングのメモ的なブログ」です。

(1) 配線

サイトに載っている通りにブレッドボードにLEDと抵抗の配線をした。抵抗は1kΩを使用した。

(2) サンプルプログラムのインポート

サイトに載っている「Simple PIO」をダウロード・解凍し、Android Studioにインポートした。インポートしたとき、バージョンが異なっていたらしく、アップデートを促すポップアップがでたので指示に従いアップデートした。

(3) 実行

サイトの説明の通り、「RUN」の隣にあるプルダウンから「blink」を選択して実行した。すると、ちゃんと1秒ごとにLEDが点滅した。

3. CatFansへLチカを移植

CatFansにLチカのプログラムをいれます。画像を解析して、猫がいたらLEDをOn、猫がいなかったらLEDをOffにするプログラムにします。実際にはLEDのOn/OffをファンのOn/Offに使えるようにすることになります。

(1) mBlinkRunnableメソッドの追加

Lチカのプログラム、BlinkActivityの79行目から97行目にあるLEDの処理、「mBlinkRunnable」メソッドをコピーして、以下のように書き換える。これで、LEDを1秒おきではなく、引数でon/offできるようになる。

CatFansActivity.java
    //LEDの処理
    private void mBlinkRunnable(boolean onoff) {
        // Exit Runnable if the GPIO is already closed
        if (mLedGpio == null) {
            return;
        }
        try {
            mLedGpio.setValue(onoff);
            Log.d(TAG, "State set to " + onoff);

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

(2) GPIO()メソッドの追加

CatFansのCatFansActivityに新しいメソッド「GPIO()」を作り、その中にLチカのプログラムのBlinkActivityの49行目から60行目までをコピーする。このとき、ピン名は「String pinName = "BCM6"」の様にCantFansの中で固定する。

CatFansActivity.java
import com.google.android.things.pio.PeripheralManagerService;
    :
    private Gpio mLedGpio;  //LED
    :
    private void GPIO(){
        // GPIOの処理
        PeripheralManagerService service = new PeripheralManagerService();
        try {
            String pinName = "BCM6";
            mLedGpio = service.openGpio(pinName);
            mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            Log.i(TAG, "Start blinking LED GPIO pin");
            // Post a Runnable that continuously switch the state of the GPIO, blinking the
            // corresponding LED
            mBlinkRunnable(false);
        } catch (IOException e) {
            Log.e(TAG, "Error on PeripheralIO API", e);
        }
    }

GPIO()の呼び出し部分をonCreateメソッドに追加する。

CatFansActivity.java
public void onCreate(Bundle savedInstanceState) {
    :
    :
    GPIO();
}

(3) onDestroyメソッドの修正

CatFansのonDestroyの中にLチカのプログラムのonDestroyを追記する。Lチカのプログラム、BlinkActivityの66行目から76行目をコピーする。

CatFansActivity.java
    protected void onDestroy() {
        :
        :
        //LED
        // Remove pending blink Runnable from the handler.
        mBlinkRunnable(false);
        // Close the Gpio pin.
        Log.i(TAG, "Closing LED GPIO pin");
        try {
            mLedGpio.close();
        } catch (IOException e) {
            Log.e(TAG, "Error on PeripheralIO API", e);
        } finally {
            mLedGpio = null;
        }
    }

(4) onCreateメソッドの修正

OnCreateメソッドの最後に
GPIO();
を追加。

4. 猫がいたらLEDをOn、猫がいなかったらLEDをOffにする処理

猫がいたらLEDをOnにし、猫がいなかったらLEDをOffにする処理を追加します。

(1) onPictureTakenメソッドの修正

onPictureTakenメソッドの中に、画像解析の結果、Catが80%以上だったらLEDをつける、そうでなかったのならば、LEDを消す処理を追加する。そして、今まで画像を先にFirebaseに投げてそのあと解析していたが、if文の中でFirebaseに投げるようにする。

CatFansActivity.java
    String imageStr;
    private void onPictureTaken(final byte[] imageBytes) {
        if (imageBytes != null) {
            final DatabaseReference log = mDatabase.getReference("logs").push();

            //画像を画面サイズに合わせて縮小する
            Bitmap b = createScaleBitmap(imageBytes, 1.0F, 1.0F);
            byte[] temp = bmp2byteArray(b, Bitmap.CompressFormat.JPEG, 100);
            final byte[] imageB = temp;

            imageStr = Base64.encodeToString(imageB, Base64.NO_WRAP | Base64.URL_SAFE);

            mCloudHandler.post(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "sending image to cloud vision");
                    // Cloud Vision APIにアップロードして画像に注釈を付ける
                    try {
                        Map<String, Float> annotations = CloudVisionUtils.annotateImage(imageB);
                        Log.d(TAG, "cloud vision annotations:" + annotations);
                        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);

                                    mBlinkRunnable(true);
                                    Log.d(TAG, "LED ON");
                                    log.child("annotations").setValue(annotations);
                                } else {
                                    mBlinkRunnable(false);
                                    Log.d(TAG, "LED OFF");
                                }
                            }
                            else {
                                mBlinkRunnable(false);
                                Log.d(TAG, "LED OFF");
                            }
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Cloud Vison API error: ", e);
                    }
                }
            });
        }
    }

(2) 実行

実行して、猫の画像にカメラを向けるとLEDが点灯し、そうでないときにはLEDが消灯するように動いた。

第8回はまだ続きます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?