Raspberry Pi 2Bでディスプレイ無しセットアップからGPIOでLチカとボタン入力まで


似たような情報が沢山ありますが、アウトプットさせて下さい。
いろいろ自信のない部分もあるのでおかしい所あれば突っ込み頂ければと思います。
作業環境はWindowsです。

# セットアップ

## RPiのモデル検討

現時点では A+/B+/2B が候補になります。
消費電力は A+＜＜B+＜2B で性能が A+≦B+＜2B という感じのようです。
(参考：http://denshikousaku.net/raspberry-pi-models)

どれにするか悩んだので全部買って無事解決しましたが、ここではRPi2Bで進めます。

1つのSDカードを使い回して各ラズパイがブートできるようなので、予備という扱いもできそうです。


## 準備

* 本体
* MicroSDカード 4GB以上(8GBあれば余裕)
* 電源供給用MicroUSBケーブル
* GPIOピン引き出す用のメス⇔オスのケーブル
* ブレッドボード、抵抗とかLEDとかスイッチとか

## OSインストール

https://www.raspberrypi.org/downloads/ から RASPBIAN を選択。

SDカードへのイメージ書き込みツールはWin32DiskImagerがボタン少なくて簡単でした。
http://sourceforge.net/projects/win32diskimager/

Win32DiskImager で 2015-05-05-raspbian-wheezy.img を選択して書き込みます。

書き込みが終わったら本体に挿して、LANケーブル挿して、最後にMicroUSBで給電して起動します。

## SSH接続

起動して点滅が落ち着いたらDHCPで割り当てられたIPアドレスを探すんですが、このときMacアドレスに対応するメーカー名を出してくれるFingを使うのがオススメです。
(http://www.overlooksoft.com/)

* iOS版
![](https://qiita-image-store.s3.amazonaws.com/0/67857/446933ab-1df5-e1b2-61a2-52c3a3f2eb81.png)

* Windows版
![](https://qiita-image-store.s3.amazonaws.com/0/67857/a7ca2876-a67d-32b2-c20c-98a256375641.png)

iOS版の方が強力なようです。

Windows版はコマンドラインツールですが、対話型で特に悩むことはありませんでした。
ただ、都度入力するのは面倒なので以下の様なショートカットを用意しています。
`-n`部分は適宜変更します。

```
cmd /k "C:\Program Files (x86)\Overlook Fing 2.2\bin\fing.exe" -n 192.168.0.103/24 -r 1 -d false -o table,text,console
```

「Raspberry Pi Foundation」を探してIPアドレスが分かったら、該当ホストにユーザ名 `pi` パスワード `raspberry` でログインします。



ちなみに写っているPINONは8年くらい稼働しているSizka BASICです。
(参考：http://pinon-pc.co.jp/pc/index.html)

## 初期設定

`df`するとデフォルトではSDカードの容量問わず2.9GB程度しかパーティションに使われていません。
`sudo raspi-config`から「1 Expand Filesystem」を選んで拡張します。
その後rebootで反映されます。

後は `sudo apt-get update`、`sudo apt-get upgrade` なども行っておきます。


## ハマった点

* ダウンロードしたRASPBIANのzipを解凍する時エラーが出た
→MSのFCIVというツールを使ってSHA-1 Checksum算出したところZIPが壊れてました。再DLで解決。

* SSHでログインしようとするとPermission Denied
→SDカードへの書き込みに失敗してたようです。再び書き込んだらログインできるようになりました。



# Lチカ

分かりやすいよう端っこのピンのGPIO21(白ケーブル)とGND(黒ケーブル)を使い、1kΩの抵抗を挟んでLEDを接続します。

![](https://qiita-image-store.s3.amazonaws.com/0/67857/8ba70e6e-a9cf-2b88-1978-abdd11ab5d8f.png)


そして次のようなコマンドでLEDを点灯させることができます。

```bash
sudo echo 21 > /sys/class/gpio/export
sudo echo out > /sys/class/gpio/gpio21/direction
sudo echo 1 > /sys/class/gpio/gpio21/value
```

![](https://qiita-image-store.s3.amazonaws.com/0/67857/f6213180-ce37-4195-8ed3-0499577041d0.jpeg)
![](https://qiita-image-store.s3.amazonaws.com/0/67857/38b4c1da-6689-46de-dd9f-a9ceaeb575f5.jpeg)
![](https://qiita-image-store.s3.amazonaws.com/0/67857/da8d11df-8ed9-1d8b-8268-cba91c51b872.jpeg)




# ボタン入力

ここからPythonとRPi.GPIOライブラリを使用します。
どちらも既に入ってますのでスクリプトを書くだけで使えます。

接続はGPIO19(赤ケーブル)、GPIO26(緑ケーブル)、GND(黒ケーブル)で以下のように行いました。

![](https://qiita-image-store.s3.amazonaws.com/0/67857/7bf1d565-2000-7a9c-9062-c4df6798cad1.png)


監視方法について、必要に応じてピンのレベルを読み取る方法もありますが、`GPIO.wait_for_edge()` という便利なものが用意されているためこれを使います。

スクリプト全体としてはこのような形になりました。
ボタンが押された時に引数で与えられた文字列をprintするだけです。

```python:interrupt.py
#!/usr/bin/env python2.7
import RPi.GPIO as GPIO
import sys

pin = int(sys.argv[1])
message = sys.argv[2]

GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
    while True:
        GPIO.wait_for_edge(pin, GPIO.FALLING)
        print message
except KeyboardInterrupt:
    GPIO.cleanup()
GPIO.cleanup()
```

スクリプトに実行権限を与えたのち、以下のように起動してボタン入力の待機をします。

```bash
sudo ./interrupt.py 26 'green' &
sudo ./interrupt.py 19 'red' &
```

ボタンを押すと無事反応しました。

![](https://qiita-image-store.s3.amazonaws.com/0/67857/579656db-bfe3-7ee7-af0b-86d837b6971f.jpeg)


## スイッチ2個について

1個も2個も同じだろうと安易にスイッチ2個付けたのですが、2つのピンの同時監視が簡単ではなさそうな事が発覚しました。
`while True`ループで両方を読み取るとCPU利用率が増大し、かなり無駄っぽいので、上記のように2プロセスという形にしました。
`wait_for_edge` は内部でepollが使われているようで、低レイヤで割り込み処理しているため電力消費や発熱は最小限になっていると思います。


## プルアップ/プルダウンについて

スイッチを繋げる2つのピンの間が導通しているかどうか、つまりスイッチがONかどうかを安定して検知するためには、スイッチがOFFの場合でもピンの間に電位差を作っておく必要があります。
`VCC⇔SW⇔GPIO` と繋ぐ時はGPIOをLOWに、`GND⇔SW⇔GPIO` と繋ぐ時はGPIOをHIGHにします。

このままだとスイッチを入れた時に電池の＋と－を直結させた時のような大電流が発生してしまいます。
そのために適当な抵抗(プルアップ抵抗/プルダウン抵抗)を挟む必要があります。
抵抗値を高くすると電力消費が抑えられるのですが、高くし過ぎると不安定になったりするようです。
（この抵抗には他にも反射防止などいくつかの目的があるようです）

Raspberry Piでは内部に50kΩ(GPIO2と3は異なる)のプルアップ抵抗/プルダウン抵抗を持っており、
上記のスクリプトの中では `GPIO.setup()` の `pull_up_down=GPIO.PUD_UP` でソフトウェア的にプルアップ抵抗を有効化しています。