さやまのものづくり日記

電子工作やプログラミングなど趣味で作ったのもを紹介していくブログです。

Raspberry piでものを上下させると増えるカウンターを作ってみた

やったこと

Raspberry pi 3B+に赤外線距離センサをつけて、ものを近づけて遠ざけるとカウントが増えるプログラムを作成しました。Raspberrypiで何か生活を便利にするものを作ろうと思っていますが、いきなり高度なものはモチベーションが続かないので簡単なものから作って積み上げていこうと思います。今回はその第1段です。

環境

python 3.7.3

Raspberry pi 3B+

VL53L0x(赤外線距離センサ)

ジャンパーワイヤ

準備

距離センサの選定

赤外線距離センサは、最小検出距離の短さと小ささからAmazonに売っているVL53L0xを選びました。

VL53L0xをPythonで使えるようにするまで

こちらのサイトのとおりに環境構築を進めていきました。
pythonでいきなり使えるようになるわけではなくて、センサの発売元であるSTmicro Electronicsが配布しているAPI(C言語で書かれている)をダウンロードしてコンパイルしないといけないようです。コンパイルが終わったらAPIpythonで使えるようにするためのオープンソースプロジェクトをGithubからクローンします。
今回は自分でプログラムを作成するので、「Counter」というディレクトリを作成し、VL53L0X.piとbinを「Counter」ディレクトリにコピーしました。

カウントするプログラムを作成する

プログラムの設計としては、以下の図に示すような状態をとり、それぞれの条件判定によって状態を遷移していきます。「inital」はプログラムを起動したときの初期状態、「above」は基準よりものが上にある状態、「down」はものを近づけている(下げている)状態、「below」は基準より下に下がっている状態、「up」はものが上がっている状態になります。

f:id:sayama_engner:20210327165008p:plain
本プログラムの状態遷移図
普通に書こうとするとifとwhileの大量の入れ子が発生して見づらくなるので状態で管理します。 こうして状態で管理すると、次の状態に遷移するときの判定だけを見ていれば良いので、見やすく、機能の追加もしやすいです。
本来は距離データは移動平均などを取る必要がありますが、計測してみたらあまり振れ幅がなかったので、今回の用途ではしきい値を調整することでうまく判定できるようにしました。

書いたコードは以下です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time  # time(sleepを使うためのモジュール)のインポート
import VL53L0X  # VL53L0X(spi通信を行うためのモジュール)のインポート

counter = 0
state_dict = {"inital": 0, "above": 1, "down": 2, "below": 3, "up": 4}
above_dist = 16
below_dist = 4
state = 0


def Counter():
    global state
    global counter
    global above_dist
    global below_dist
    if state == state_dict["inital"]:
        print("inital state")
        if dist > above_dist and dist < above_dist+4:  # この範囲に入ったらスタート
            state = state_dict["above"]
    elif state == state_dict["above"]:
        # print("above state")
        if dist < above_dist:
            state = state_dict["down"]
    elif state == state_dict["down"]:
        # print("down state")
        if dist < below_dist:
            state = state_dict["below"]
    elif state == state_dict["below"]:
        # print("below state")
        if dist > below_dist:
            state = state_dict["up"]
    elif state == state_dict["up"]:
        # print("up state")
        if dist > above_dist:
            state = state_dict["above"]
            counter += 1
            print("%d 回" % counter)



if __name__ == '__main__':
    """VL53L0Xのインスタンスを作成"""
    tof = VL53L0X.VL53L0X(address=0x29)

    # 距離の取得を開始する
    tof.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE)

    while True:
        try:
            dist = tof.get_distance()/float(10)  # VL53L0Xから距離[cm]を取得する
            Counter()
        except KeyboardInterrupt:
            break

完成品

プログラムを実行してものを近づけたり離したりするとカウントが上がります。 f:id:sayama_engner:20210327173232g:plain

参考サイト

5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (44) 距離センサ5 I2C VL53L0X | 電子工作の環境向上

sites.google.com