Android Thingsで7セグメントLEDを制御してみる

# Android Thingsで7セグメントLEDを制御してみる

今回は、Android Thingsで7セグメントLEDを制御してみたいと思います。
7セグメントLEDの制御はArduinoなどのマイコンであればループの処理とかなんとなく想像つきますよね？
しかし、Android Thingsでは普通のAndroidアプリのようにしてループ処理を書かなければいけないため、初めたばかりの人には難しいと思います。そのループの処理を使って解説していきます。

1. 使うもの
2. 回路
3. プログラム
4. まとめ

# 1. 使うもの
- Raspberry Pi 3 Model B
- ７セグメントLED（[2381BS](http://akizukidenshi.com/catalog/g/gI-09084/?customer=z)）
- Android StudioのインストールされたPC

環境構築がまだの場合は、「[Raspberry PiにAndroid Thingsを導入する](https://qiita.com/sasakisan/items/d66ccbc46f8cf56144a8)」を参考にしてください


2. 回路
<img width="1097" alt="7seg.png" src="https://qiita-image-store.s3.amazonaws.com/0/143395/e15b0595-6206-f542-4398-775f12dd7504.png">

|    GPIO     |    7セグメントLED     |
|:-------:|:-------:|
|    BCM17      |    11(A)    |
|    BCM27     |    7(B)    |
|    BCM22      |    4( C )    |
|    BCM23      |    2(D)    |
|    BCM24     |    1(E)    |
|    BCM25      |    10(F)    |
|    BCM5      |    5(G)    |
|    BCM6     |    3(DP)    |
|    BCM16      |     8   |
|    BCM20      |     9   |
|    BCM21      |     12   |


こんな感じで配線していきます。

# 3. プログラム
[github](https://github.com/sasakitomohiro/7seg-sample)にコードをあげています。

それでは、解説に入ります。
まず、GPIOを使うためのパーミッションを設定します。

```AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="自分のパッケージ名">
    <uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO"/> ←ここを追加

    <application>
     ...
</manifest>
```


次にメインのプログラムの説明です。

まず、下記のように使いたいGPIOとその変数、定数をグローバルで宣言します。

```MainActivity.java
    // 7セグメントLEDで使うポート
    private static final String SEG_A = "BCM17";
    private static final String SEG_B = "BCM27";
    private static final String SEG_C = "BCM22";
    private static final String SEG_D = "BCM23";
    private static final String SEG_E = "BCM24";
    private static final String SEG_F = "BCM25";
    private static final String SEG_G = "BCM5";
    private static final String SEG_DP = "BCM6";
    private static final String SEG_FIRST = "BCM21";
    private static final String SEG_SECOND = "BCM20";
    private static final String SEG_THIRD = "BCM16";
    private static final int INTERVAL = 1000;

    private Handler handler;

    // 今回使用するGPIO
    private Gpio segA;
    private Gpio segB;
    private Gpio segC;
    private Gpio segD;
    private Gpio segE;
    private Gpio segF;
    private Gpio segG;
    private Gpio segDp;
    private Gpio segFirst;
    private Gpio segSecond;
    private Gpio segThird;

    private int num;

```

次に、GPIOの初期化メソッドです。

```MainActivity.java
...
    // GPIOの初期化メソッド
    private void initGpio() {
        PeripheralManager manager = PeripheralManager.getInstance();
        try {
            segA = manager.openGpio(SEG_A);
            segB = manager.openGpio(SEG_B);
            segC = manager.openGpio(SEG_C);
            segD = manager.openGpio(SEG_D);
            segE = manager.openGpio(SEG_E);
            segF = manager.openGpio(SEG_F);
            segG = manager.openGpio(SEG_G);
            segDp = manager.openGpio(SEG_DP);
            segFirst = manager.openGpio(SEG_FIRST);
            segSecond = manager.openGpio(SEG_SECOND);
            segThird = manager.openGpio(SEG_THIRD);

            segA.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segB.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segC.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segD.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segE.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segF.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segG.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segDp.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segFirst.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segSecond.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            segThird.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
        } catch (IOException e) {
        }
    }
...
```
ここでは、使うGPIOの指定し、初期化しています。

次は、7セグメントLEDに数字を表示させるためのメソッドです。

```MainActivity.java
    private void showNumber(int num){
        try {
            segA.setValue(true);
            segB.setValue(true);
            segC.setValue(true);
            segD.setValue(true);
            segE.setValue(true);
            segF.setValue(true);
            segG.setValue(true);
            segDp.setValue(true);
            switch(num){
                case 0:
                    segA.setValue(false);
                    segB.setValue(false);
                    segC.setValue(false);
                    segD.setValue(false);
                    segE.setValue(false);
                    segF.setValue(false);
                    segG.setValue(true);
                    segDp.setValue(true);
                    break;
                case 1:
                    segA.setValue(true);
                    segB.setValue(false);
                    segC.setValue(false);
                    segD.setValue(true);
                    segE.setValue(true);
                    segF.setValue(true);
                    segG.setValue(true);
                    segDp.setValue(true);
                    break;
                case 2:
                    segA.setValue(false);
                    segB.setValue(false);
                    segC.setValue(true);
                    segD.setValue(false);
                    segE.setValue(false);
                    segF.setValue(true);
                    segG.setValue(false);
                    segDp.setValue(true);
                    break;
                case 3:
                    ...
                    省略
            }
        } catch (IOException e) {
        }
    }
```

このshowNumberメソッドの引数には、表示させたい0~9までの数字を渡します。

最後にループ処理です。
Android Thingsでは、threadというものを使って別スレッドでループ処理をさせます。


```MainActivity.java
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            handler.postDelayed(runnable, INTERVAL);
        }
    };

    private Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                segFirst.setValue(false);
                segSecond.setValue(false);
                segThird.setValue(false);
            } catch (Exception e) {
            }
            while (true) {
                if (num > 99) {
                    try {
                        segFirst.setValue(false);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        int secondDigit = (num % 1000) / 100;
                        showNumber(secondDigit);
                        segFirst.setValue(true);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        Thread.sleep(1);
                    } catch (Exception e) {
                    }
                } else {
                    try {
                        segFirst.setValue(false);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        showNumber(0);
                        segFirst.setValue(true);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        Thread.sleep(1);
                    } catch (Exception e) {
                    }
                }
                if (num > 9) {
                    try {
                        segFirst.setValue(false);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        int thirdDigit = num % 1000 % 100 / 10;
                        showNumber(thirdDigit);
                        segFirst.setValue(false);
                        segSecond.setValue(true);
                        segThird.setValue(false);
                        Thread.sleep(1);
                    } catch (Exception e) {
                    }
                } else {
                    try {
                        segFirst.setValue(false);
                        segSecond.setValue(false);
                        segThird.setValue(false);
                        showNumber(0);
                        segFirst.setValue(false);
                        segSecond.setValue(true);
                        segThird.setValue(false);
                        Thread.sleep(1);
                    } catch (Exception e) {
                    }
                }
                try {
                    segFirst.setValue(false);
                    segSecond.setValue(false);
                    segThird.setValue(false);
                    int fourthdigit = num % 1000 % 100 % 10;
                    showNumber(fourthdigit);
                    segFirst.setValue(false);
                    segSecond.setValue(false);
                    segThird.setValue(true);
                    Thread.sleep(1);
                } catch (Exception e) {
                }
            }
        }
    });
```
ここでは、3桁あるうちのどの7セグメントLEDを表示するかを指定したりしています。
3桁ある7セグメントLEDは同時に表示しているように見えますが、実は１つ１つ表示しています。
それをthreadでループさせているのですが、細かい説明は長くなってしまうのでまた今度

```MainActivity.java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // GPIOの初期化
        initGpio();
        handler = new Handler();

        // 表示させたい数字で初期化
        num = 123;

        // 別スレッドで表示処理
        handler.post(runnable);
        thread.start();
    }
```

最後に、onCreateで起動した時の初期化などをさせれば7セグメントLEDが使えます。

参考プログラム
http://myandroidthings.com/post/tutorial-19

# 4. まとめ
7セグメントLEDでカウンタを作りたい場合は、threadの中でnumの値を変えることによって作ることができます。
また、threadを使ったループ処理は、7セグメントLEDに限らず様々な場面で使うことができるのでぜひ参考にしてみてください。