【電子工作】水があるかないかを簡単にスイッチングで検知する

## １．はじめに

> 水は電気を通すことができる（＝ 導電性がある）

　みなさんは上の事柄が本当だと思いますか？非理系である私は、水は電気を通すもの、つまり導電性があるものであるとずっと思ってきました。
　ある日大学の研究室で、水があるかどうかを検知できるようなシステムを突然考えることになったのですが、その際に電子工作の知識を使ってこれを解決しようとなったとき、上の事柄と真正面からぶつかることになりました。
　結論から言ってしまえば、**水自体には電気を通す性質はありません。**しかし、この水というのは不純物のない純水のことを指します。私達が普段使う水、水道水には多くの不純物が含まれていて、この不純物が溶け込んだ水には導電性を示します。今回は水を水道水とし、導電性があるものだとして水の検知システムを電子工作で作ってみたいと思います。

## ２．目的
　今回の水の検知システムを作るにあたって、どんな検知システムにするのか？をまず考えてみました。イメージとしては、お風呂に近いでしょうか。一定量の水がお風呂に溜まった時にはTRUE、溜まっていないときはFALSEになっているようなものです。今回は、水の検知を4段階くらいに分けて検知できるようなものにしたいと思います。以下のようなイメージです。
![実験1.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/e4f7969c-bb15-1ffb-3b2b-605c591f3a0a.jpeg)
　このとき、結果に関する配列を`[h1, h2, h3]`とすると、`[TRUE, TRUE, FALSE]`となるように水を検知できるようにします。配列の要素は3つですが、4段階の検知ができます。
　これを電子工作で頑張って作ってみたいと思います。ラズパイをいつも使っているので、今回もラズパイ3です。

## ３．実験
### ３-１．実験概要
　電子工作においてスイッチングというものがあります。これは、スイッチをONまたはOFFにすることによってそれにつながったマイコンが検知し、LEDを光らせたり消したりといったようなものです。簡単な実験だと、このスイッチングをタクトスイッチなどで手動でやるわけですが、これを今回の目的である水の導電性によってONとOFFを行います。この記事の「はじめに」にもあった通り、純水ではない水道水には導電性があります。そしてこの導電性には電気を通すこと、すなわち電子回路における抵抗と同じ役割を担うことができます。
![実験2.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/0c266bbb-cabd-a4a3-94a1-6ec90a20fe28.jpeg)

### ３-２．回路設計
　以前の記事でプルアップ・プルダウン回路について書きましたが、それにはスイッチングによる検知が使われています。ボタンで行なっていたスイッチングを、今回は上記のような水の有無によるスイッチングにします。プルアップ回路で行うつもりでしたが、**想定外の出来事が発生したため、プルダウン回路による設計を目指します。さらに、プルダウン抵抗には51k~100kΩを使います。**これらを踏まえて、以下のような回路設計を考えました。アノードが共通端子になっています。（アノードコモン）


　さらに、これを実際に配線した際のイメージ図です。
![水検知_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/298123/88953fb7-432d-8e5f-ee54-ed70edd35106.png)
＊タクトスイッチが、今回の水の有無スイッチング代わりです。抵抗は1kΩなので変えてください

### ３-３．プログラム作成
　では、次にpythonを使って水を検知できるプルダウン回路のプログラムを簡単に書いてみましょう！GPIOを操作するためのライブラリは複数ありますが、今回は記事も多くて使いやすい**RPi.GPIO**を使ってみようと思います。pythonのバージョンは3なので、実行時に`python3 test.py`となります。

```python:qiita.py
import RPi.GPIO as GPIO # GPIOアクセスライブラリ
import time # 時間を使う(sleepする)ためのライブラリ

GPIO.setmode(GPIO.BCM) # BCM指定
GPIO.setup(17, GPIO.IN) # h1での水検知
GPIO.setup(27, GPIO.IN) # h2での水検知
GPIO.setup(22, GPIO.IN) # h3での水検知

# Control + C でストップするようにする
try:
    while True:
        status = [GPIO.input(17), GPIO.input(27), GPIO.input(22)] # 配列に入れる
        print(status) # 出力
        time.sleep(1) # wait 1000ms
except KeyboardInterrupt:
    print("Fin.")

GPIO.cleanup()
```
　この回路は**プルダウン回路**なので、`GPIO.input(XX)`で出力される値は**正論理（アクティブ・ハイ）**となることに注意してください。

### ３-４．スイッチング実験
　無事になんとかかけたので、試しにここまでの実行テストをしてみたいと思います。ちょっと危険な気がしないでもないですが、ジャンパワイヤーを伸ばして、コップ等に水をいれてスイッチング実験をしてみましょう。
![実験.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/56d10fa5-9622-a7fb-eb05-f19f7249ba46.jpeg)
　見て分かりますが、水が電気分解されていますね。コンソール画面で確認してみましたが、なんとか機能しているようなのでユニバーサル基板に半田付けを固定および、水位計っぽく作成してみます。

### ３-５．水位計っぽく作成
　半田付けをします。下手なので、その様子の写真は割愛します。目的で示した図の通り、h1、h2、h3で少しずつ高さを変えて水位計を作ります。こんな感じ。
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/82d04546-f094-2741-d56f-aeac480cd303.jpeg)


## ４．結論
　では、実際にテストしてみましょう！配列statusを出力して、その時の様子を写真に収めます。
・`status = [1, 1, 1]`が出力されたとき
![111.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/74f92209-e0b2-c6a4-9d2f-a2ecfdced025.jpeg)

・`status = [1, 1, 0]`が出力されたとき
![110.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/f0f00be1-4bc6-63fc-7c32-f3d382763a95.jpeg)

・`status = [1, 0, 0]`が出力されたとき
![100.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/d8c88361-edc9-c989-0d4b-15b7e30054da.jpeg)

・`status = [0, 0, 0]`が出力されたとき
![000.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/468234c9-a5a2-1bd3-4e38-eacae082063a.jpeg)

となりました。これを見る限りしっかりと水の検知はできていますね！まるで水位計のようになっています。ちなみに`status = [1, 0, 1]`のようになることは誤作動以外あり得ません。（のはず）

## ５．プルダウン回路を選択した理由
　近日中に記事を作成します。もう少々お待ちください。(1/25)