churob -12ページ目

churob

ちゅろぶ

ここまでで作った温湿度計は、データを抜き出したり電源を切ったりするのに

いちいちディスプレイ・マウス・キーボードにつながないといけなかった。

シンプルな温湿度計として使うには、単体で動くようにしたい。

そのための方法が、図書館から借りてきた本の付録(web上)に載っていたのでやってみた。

 

参考書籍「Raspberry Piで学ぶ電子工作 超小型コンピュータで電子回路を制御する」

付録ページ https://bluebacks.kodansha.co.jp/books/9784062578912/appendix/

付録 PDF https://bluebacks.kodansha.co.jp/books/9784062578912/appendix/attachments/RaspberryPi-PDF_p01-30.pdf

 

 

 

<目指す流れはこう>

 

①電源ON(ラズパイコンセントIN)

 ↓

②タクトスイッチで電源を切れるプログラム起動

 ↓

③USBにcsvデータを保存

 ↓

④タクトスイッチで電源OFF

 ↓

⑤USBを抜いて、自分のパソコンでデータチェック

 

 

④タクトスイッチで電源OFF

まずこれから作った。

付録PDF 5.8章を参考に作業した。サンプルコードはそのまま拝借。

前回LED点灯のためにタクトスイッチを配線しておいてあったので

そのまま流用できた。

 

import RPi.GPIO as GPIO
from time import sleep
import subprocess

def my_callback(channel):
    if channel==24:                 #ここは実際にタクトスイッチをつなげていたピン7に変更した
        args = ['sudo', 'poweroff']
        subprocess.Popen(args)

GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(24, GPIO.RISING, callback=my_callback, bouncetime=200)  #これもピン24→7に変更

try:
    while True:
        sleep(0.01)

except KeyboardInterrupt:
    pass

GPIO.cleanup()
 

 

実際試したらちゃんとタクトスイッチで電源が切れるようになった!

 

②タクトスイッチで電源を切れるプログラム起動

次は、上で作ったプログラムが、ディプレイやキーボード操作なしで実行される=OS起動と同時に実行されるようにした。

付録PDFのp.14「●タクトスイッチによるRaspberry Piのシャットダウン」を参考にした。

起動プログラムを操作できるrc.localを、Ternimalから管理者権限で開く。

(なぜかLeafpadだが起動しなかったのでnanoにした)

 

sudo nano /etc/rc.local

 

末尾にあるexit 0のまえに、先ほど保存した、タクトスイッチで電源を切る

プログラムを起動させる指示を追加。

(ファイル名、パスは適宜修正)

 

sudo python /home/pi/05-06-sw-poweroff.py &

exit 0

 

③USBにcsvデータを保存

取得データはラズパイじゃなくていつも使っているwindowsで

グラフにしたり操作したかったので、USBに保存されるように変更することにした。

 

前回のbme280_csvの11行目あたりにある、データの保存先を指定するコードを

 

DATA_DIR = '/home/pi/~~~/data/'

 ↓

DATA_DIR = '/media/pi/8.2 GB Volulme/~~~/data/'

 

8.2 GB VolulmeはUSBの名前のようです。

~~~はデータの保存先に応じて適宜修正。

 

これで目指す流れになったはず?また夜通し放置してみて

データがUSBにとれているか確認してみます。

 

【後日追記】

USB保存はできていませんでした。

パスが間違ってたのかな? 残念。

いくつかのブログを当たった結果、このページの方法で成功した。

コードがすべてGithubに公開されていたのでそのまま使わせていただいて

csvファイルのの保存先だけ修正した。

https://kagemomiji.hateblo.jp/entry/2016/08/16/003224

 


 

ただ、以前からcronへの書き方がいまいち理解できず成功したことがなかったので、

crontabへの記述の仕方はこちらを参考にした。

 

https://www.server-memo.net/tips/crontab.html

 

 

無事10分ごとにプログラムが自動で実行されて、データがcsvに書き出されるようになった!

 

でも今のままだと電源を落とすのに周辺機器(ディスプレイ、キーボード、マウス)につながないと

いけないので、次はタクトスイッチで電源がOFFできるように設定する。

図書館で借りてきた本にタクトスイッチの説明やLEDとの配線の仕方が載っていたので、

センサ取得情報をtweetさせるのはいったんあきらめて、スイッチで動作させることにした。

 

タクトスイッチの基本的な仕組みを理解するため、最初にLEDの点灯をスイッチで操作するところからはじめた。

 

 1)LEDライトに接続し、スイッチが入ったタイミングで点灯させる
 2)タクトスイッチをプログラムによりトグル動作させLEDの点灯、消灯を繰り返す
 3)温度・湿度・気圧を、タクトスイッチが押されたタイミングで取得する

 

※参考書籍「Raspberry Piで学ぶ電子工作 超小型コンピュータで電子回路を制御する」

※温度・湿度・気圧 取得センサ BME280

 

 

  

 

写真にあるブレッドボードの「+」を3.3Vのピンへ

「-」をGROUNDのピンへ。

 

あとLED側の線とスイッチ側の線は任意のピンへ

今回は

 LED側 → ピン 25

 スイッチ側 → ピン 7

 

1)LEDライトに接続し、スイッチが入ったタイミングで点灯させる

 

 

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
GPIO.setup(7, GPIO.IN)

try:
    while True:
        if GPIO.input(7) == GPIO.HIGH:
            GPIO.output(25, GPIO.HIGH)
        else:
            GPIO.output(25, GPIO.LOW)
        sleep(0.01)

except KeyboardInterrupt:
    pass

GPIO.cleanup()

 

 

意外とすんなりできた。

 

2)タクトスイッチをプログラムによりトグル動作させLEDの点灯、消灯を繰り返す

 

1)は押している間中点灯し、離すと消えた。

これだと連続点灯させたい時ずっと押してないといけない。

次は1回押したら点灯し、次に押したら消灯するように変更した。

 

 

import RPi.GPIO as GPIO
from time import sleep

def my_callback(channel):
    global ledState
    if channel == 7:
        ledState = not ledState
        if ledState == GPIO.HIGH:
            GPIO.output(25, GPIO.HIGH)
        else:
            GPIO.output(25, GPIO.LOW)

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=200)

ledState = GPIO.LOW

try:
    while True:
        sleep(0.01)
except KeyboardInterrupt:
    pass

GPIO.cleanup()

 

 

これも無事完成。

 

3)温度・湿度・気圧を、タクトスイッチが押されたタイミングで取得する 

 

最後に本命の、センサを動作させるプログラム。

センサとスイッチの回路をなにか連結させるのかと思っていたけれど、

スイッチが押される信号がラズパイにきたら、ラズパイからセンサを動作させる、

という流れになるため、センサから出る配線をブレッドボードにつないだりせず

センサの配線は以前のまま、スイッチの配線も1)2)のまま使えた。

 

考え方としては、センサ用のコードの最後の5行を、2)のコードと合体させて

スイッチが押されたらセンサが動くようにする。

 

if __name__ == '__main__':
    try:
        readData()
    except KeyboardInterrupt:
        pass

 

 

#coding: utf-8

~~~省略~~~

(センサを動作させるプログラム。公式サイトからそのまま。

 上に書いた最後の5行は★に変形させて後で使うのでここからは削除。)

~~~ここからスイッチ用のコード。2)をアレンジ~~~

import RPi.GPIO as GPIO
from time import sleep

def my_callback(channel):
    if channel == 7:
        readData()           ←★センサ用のコード

GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=200)

GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.IN)

if __name__ == '__main__':     ←★センサ用のコード
    try:
        while True:
            sleep(0.01)

    except KeyboardInterrupt:
        pass

GPIO.cleanup()

 

 

これで、タクトスイッチを押したタイミングで温湿度が取得されました。やった~。

 

【失敗談】

はじめ1)ができた時点でよし!と思いセンサにつないだら、

タクトスイッチを押している間中継続してデータ取得してしまった。

(一回「カチッ」と押しただけのつもりなのにデータが20個くらいずらっとでてくる)

スイッチ押下をイベントとして捉えるためのコードが必要だとわかった。

 

※あくまでもきちんとした知識のない個人の記録です。

 色々変なところがあると思いますので薄目で見てください。