ラズベリーパイ活用
1 2 次 カテゴリ選択 今日の出来事 連絡事項 報告事項 ミーティング 本・雑誌 ニュース 映画・テレビ 音楽 スポーツ パソコン・インターネット ペット 総合学習 アニメ・コミック 1件 5件 10件 20件 50件 100件
前回作ったBME280のロガーと,ログをグラフ化するコードを合体させてみました。1秒間隔で温度・湿度・気圧を測定し,表示を更新します。ログへの記録は5分間隔で行います。ログは日にちごとに分けて保存します。画面のどこかをクリックすると「グラフ作成中...」と表示され,しばらく待つとグラフが表示されます。ログファイルがない場合は「ログファイルがありません」と表示されます。グラフの画面をクリックすると,リアルタイムデータの画面に戻ります。
Raspberry Pi -Zeroシリーズで実行すると,グラフを作成するところでフリーズしたかと思うほど待つので,別スレッドでグラフを作り,グラフ作成中もリアルタイムの計測値を表示し続けるようにしてみました。(また,メッセージ表示の枠の角を丸くするなど,どうでもよいところに力を入れています。なぜか,どうでもよいところほどやる気がでるのです。)
画面表示にはpygameライブラリを,グラフ作成にはmatplotlibライブラリを使っています。
気圧が下がると一部の発達障害の子どもたちは気持ちが落ち着かなくなるとよく言われますが,あまり事例のデータは無いようです。本当にそうなのか,今回作った装置&コードを使って確かめてみたいと思っています。
☆関連する記事 ☆Pythonのコード 下のコードは,ハードはRaspberry Pi - Zero WHにBME280をI2C接続したもの,OSはRaspbian Buster,Pythonのバージョンは 3.7.3 で作成・動作確認をしています。
Raspberry Pi Zeroシリーズが非力であるのは分かっているが,matplotlibでグラフを作成するのに8~10秒かかるので,サブスレッドで処理することにした。
下のコードはサブスレッドに引き数を渡し,サブスレッドの終了時に返り値を受け取るサンプル。
先日作った,BME280ボードを使った,温度・湿度・気圧ロガーのデータをmatplotlibでグラフ化してみました。
DATA_DIRにあるログデータを読み込んで,PIC_DIRに画像で出力します。
Y軸のラベルの向きと位置を変えて,Y軸の単位の表示にしていますが,出力画像のサイズを変えると位置がずれてしまいます。
Y軸の目盛を 3種類にしたり,X軸のラベルを斜めにしたり,少し凝って作ってみました。。
これを前回作ったロガーと合体させて。1つにし,簡易Webサーバーで外部から参照できるように機能追加しようと思っています。
☆コード pygameではデフォルトでは日本語を表示できないので,IPAゴシックをダウンロードし,同じフォルダに配置して使っています。
import csv import matplotlib .pyplot as pltimport matplotlib .ticker as tickerimport matplotlib .font_manager as mfontmimport matplotlib .dates as mdatesimport datetime DATA_DIR = "./BME280log/" LOG_NAME = " BME280.log" PIC_DIR = "./BME280log/" PIC_NAME = " BME280.png" PIC_SIZE = (4.8 , 3.2 ) LINE_WIDTH = 1 DAYS_AGO = 0 timestamps = [] tempertures = [] humidities = [] pressures = [] date = "{0:%Y.%m.%d}" .format (datetime.date.today () - datetime.timedelta (days=DAYS_AGO)) log_filename = DATA_DIR + date + LOG_NAMEwith open (log_filename, "r" ) as f: reader = csv.reader (f) for row in reader: timestamps.append (datetime.datetime.strptime (row[0 ] ,"%Y/%m/%d %H:%M:%S" )) tempertures.append (float (row[1 ])) humidities.append (float (row[2 ])) pressures.append (float (row[3 ])) fp = mfontm.FontProperties (fname="./ipag.ttf" ) fig = plt.figure (figsize=PIC_SIZE) plt.subplots_adjust (left=0.07 , bottom=0.15 , top=0.9 , right=1) ax1 = fig.add_subplot (111 ) ax2 = ax1.twinx () ax3 = ax1.twinx () ax1.plot (timestamps, tempertures, color='orange' , alpha=1.0 , lw=LINE_WIDTH, antialiased=True) ax2.plot (timestamps, humidities, color='deepskyblue' , alpha=0.6 , lw=LINE_WIDTH, antialiased=True) ax3.plot (timestamps, pressures, color='green' , alpha=0.8 , lw=LINE_WIDTH, antialiased=True) ax1.set_ylim (0 , 40 ) ax2.set_ylim (0 , 100 ) ax3.set_ylim (960 , 1020 ) ax1.yaxis.set_major_locator (ticker.MultipleLocator (5 )) ax2.yaxis.set_major_locator (ticker.MultipleLocator (10 )) ax3.yaxis.set_major_locator (ticker.MultipleLocator (10 )) fig.subplots_adjust (right=0.80 ) ax3.spines["right" ].set_position (("axes" , 1.13 )) hoursfmt = mdates.DateFormatter ("%H:%M" ) ax1.xaxis.set_major_formatter (hoursfmt) xlabels = ax1.get_xticklabels () plt.setp (xlabels, rotation=45) ax1.yaxis.set_label_coords (-0.045 , 1.03 ) ax2.yaxis.set_label_coords (1.07 , 1.09 ) ax3.yaxis.set_label_coords (1.21 , 1.09 ) ax1.set_ylabel ("(℃)" , fontproperties=fp, rotation=0) ax2.set_ylabel ("(%)" , fontproperties=fp, rotation=0) ax3.set_ylabel ("(hPa)" , fontproperties=fp, rotation=0) fig.legend (["温度" , "湿度" , "気圧" ], bbox_to_anchor= (0 , 0 ), bbox_transform=ax1.transAxes, loc="lower left" , prop=fp) pic_filename = PIC_DIR + date + PIC_NAME plt.savefig (pic_filename)
先日作った,BME280ボードを使って,温度・湿度・気圧ロガーを作ってみました。画面の表示はpygameを使っています。1秒ごとに測定と画面更新を行い,10秒ごとにログに出力します。ログは日が変わる毎に新しく作られます。480 x 320のミニ液晶が前提で,フルスクリーン表示で起動します。ESCキーで終了します。
今後は,画面タッチで1日の変化をmatplotlibを使ってグラフ表示するよう機能追加をしていきます。
☆コード pygameではデフォルトでは日本語を表示できないので,IPAゴシックをダウンロードし,同じフォルダに配置して使っています。
import smbus2 import bme280 import datetime import time import pygame from pygame .locals import *import sys import csv BME280_PORT = 1 BME280_ADDRESS = 0 x76 PYGAME_SCREEN_SIZE = (480 , 320 ) LOG_INTERVAL = 10 bus = smbus2.SMBus (BME280_PORT) calibration_params = bme280.load_calibration_params (bus, BME280_ADDRESS) pygame.init () screen = pygame.display.set_mode ((PYGAME_SCREEN_SIZE), FULLSCREEN) pygame.display.set_caption ("温度・湿度・気圧計" ) myfont1 = pygame.font.Font ("ipag.ttf" , 35 ) myfont2 = pygame.font.Font ("ipag.ttf" , 62 ) old_time = time.perf_counter ()while True : new_time = time.perf_counter () if new_time - old_time >= 1 : old_time = new_time data = bme280.sample (bus, BME280_ADDRESS, calibration_params) timestamp_str = "{0:%Y年%m月%d日 %H時%M分%S秒}" .format (data.timestamp) temperture_str = "温度:{0:>6.1f} ℃" .format (data.temperature) humidity_str = "湿度:{0:>6.1f} %" .format (data.humidity) pressure_str = "気圧:{0:>6.1f} hPa" .format (data.pressure) timestamp = myfont1.render (timestamp_str, True , (255 , 255 , 255 )) temperture = myfont2.render (temperture_str, True , (255 , 255 , 255 )) humidity = myfont2.render (humidity_str, True , (255 , 255 , 255 )) pressure = myfont2.render (pressure_str, True , (255 , 255 , 255 )) screen.fill ((0 , 0 , 0 )) screen.blit (timestamp, (0 , 10 )) screen.blit (temperture, (0 , 70 )) screen.blit (humidity, (0 , 155 )) screen.blit (pressure, (0 , 240 )) pygame.display.update () if data.timestamp.second % 10 == 0 : filename = "./BME280log/{0:%Y.%m.%d} BME280.log" .format (datetime.date.today ()) f = open (filename, "a" ) writer = csv.writer (f) csvrow = [] csvrow.append ("{0:%Y/%m/%d %H:%M:%S}" .format (data.timestamp)) csvrow.append ("{0:.1f}" .format (data.temperature)) csvrow.append ("{0:.1f}" .format (data.humidity)) csvrow.append ("{0:.1f}" .format (data.pressure)) writer.writerow (csvrow) f.close () for event in pygame.event.get (): if event.type == QUIT: pygame.quit () sys.exit () elif event.type == KEYDOWN and event.key == K_ESCAPE: pygame.quit () sys.exit ()
Amazonで安かったのでQuimat 3.5inch モニターを買ってみました。 HDMI接続で,タッチパネルでSPIを1つ使いますが,GPIOのピンが出ているので便利です。残念ながら最初に購入した物は初期不良でだったので返品し,再度購入しました。(HDMIケーブルを接続しないときの「No Signal」の表示も崩れていたので,不良なのは間違いないと思います。) Amazonのカスタマーレビューなどを参考にしながら設定したのですが,タッチパネルの設定がうまくいかず,180度タッチパネルだけ回転していたり,X軸・Y軸が入れ替わったりとなかなか手強かったので,備忘録として残しておきます。☆ディスプレイの設定 Amazonのカスタマーレビューを参考にしました。一度でうまく表示されました。
①/boot/config.txt を書き換えるのですが,管理権限がないと書き込めないので,まずファイルマネージャを管理権限で起動します。(やっぱりGUIの方が楽なので。)
②
/boot/config.txtの末尾 に次の設定を書き込み,保存して再起動する。
# for Quimat 3.5inch Monitor
hdmi_force_hotplug=1
hdmi_drive=2
hdmi_group=2
hdmi_mode=87
hdmi_cvt=480 320 60 6 0 0 0
☆タッチパネルの設定 Amazonのカスタマーレビューにある,config.txtに書き込む方法では,タッチパネルの反応が180度回転してしまいました。(
display_rotate=1 にすれば全部ひっくりかえって使えるようになるのですが,HDMIの端子が下に出ることになるので,やっぱり使いにくいです。)
/usr/share/X11/xorg.conf.d/99-calibration.conf にキャリブレーションの設定を書き込む方法は,設定が無視されてしまい,だめでした。
OSがRaspbian busterと新しかったり,やらない方がよいというrpi-updateをしたりしたからかもしれません。
結局,うまくいったのは,下のように,gitからドライバをダウンロードしてインストールする方法でした。
$ git clone https://github.com/goodtft/LCD-show.git $ chmod -R 755 LCD-show $ cd LCD-show $ sudo ./MPI3508-show
☆参考にしたwebページ ・Amazon カスタマーレビュー
https://www.amazon.co.jp/gp/customer-reviews/RVTJH47O2U2YT/ref=cm_cr_dp_d_rvw_ttl?ie=UTF8&ASIN=B075K56C12 ・GitHub - goodtft/LCD-show
: 2.4" 2.8"3.2" 3.5" 5.0" 7.0" TFT LCD driver for the Raspberry PI 3B+/A/A+/B/B+/PI2/ PI3/ZERO/ZERO W
https://github.com/goodtft/LCD-show 前回ブレッドボードで試作したBME280ボードをラズパイZero用ユニバーサル基板で作り直しました。
I
2 C通信での接続なので配線が少ないのはよいのですが,どうしても配線がクロスするので少し悩みました。(結局,配線を短くするため,BME280キットを逆さにしました。)
I 2 C通信に設定するには J3をはんだジャンパするとのことだったが,
秋月のマニュアル の回路図を見ると,J3はCSBとVDDをショートするだけなので,CSBにVDDを入力すれば,はんだジャンパをする必要がないことがわかりました。(はんだジャンパ,うまくできずにイモはんだでかっこ悪いので,吸い取り線で除去して,CSBにVDDを繋ぐことにしました。)
☆材料 ラズパイZero用ユニバーサル基板 秋月 P-14031 100円 ラズパイ用スタッキングコネクタ 秋月 C-10702 150円 BME280使用 温湿度・気圧センサモジュールキット 秋月 K-09421 1,080円 カーボン抵抗 1/4W 0Ω 秋月 R-25000 (100本)100円 合計 1,430円
☆配線図 ☆できあがり import smbus2 import bme280 import time port = 1 address = 0 x76 bus = smbus2.SMBus (port) calibration_params = bme280.load_calibration_params (bus, address)while True : data = bme280.sample (bus, address, calibration_params) print ("{0:%Y年%m月%d日 %H時%M分%S秒}" .format (data.timestamp)) print (" 温度:{0:.2f} ℃" .format (data.temperature)) print (" 湿度:{0:.2f} %" .format (data.humidity)) print (" 気圧:{0:.2f} hPa\n" .format (data.pressure)) time.sleep (1 )
>>> %Run BME280_Rpi.bme280.py
2019年xx月xx日 xx時xx分xx秒
温度:30.02 ℃
湿度:50.79 %
気圧:1007.31 hPa
2019年xx月xx日 xx時xx分xx秒
温度:30.03 ℃
湿度:50.71 %
気圧:1007.34 hPa
秋月で買った温度・湿度・気圧センサーBME280をラズパイに繋いでみました。
校正をしていないLM335Zよりも正確そうな数値が得られました。
☆材料 ブレッドボード BB-801 秋月 P-05294 200円 ラズベリーパイ用ブレッドボード接続キット 秋月 K-08892 450円 BME280使用 温湿度・気圧センサモジュールキット 秋月 K-09421 1,080円 ブレッドボードジャンパーワイヤセット 秋月 C-05159 (60本)220円 合計 1,950円
☆回路図 ☆できあがり ☆チェック ①「i2cdetect -y 1」でアドレス76が表示されれば認識されています。 $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 --
☆ライブラリのインストール ①smbus2をインストールする。(Python3を使っているときは「pip3」でインストールする。) $ sudo pip3 install smbus2 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting smbus2 Using cached https://www.piwheels.org/simple/smbus2/smbus2-0.2.3-py2.py3-none-any.whl Installing collected packages: smbus2 Successfully installed smbus2-0.2.3
②RPi.bme280をインストールする。 (Python3を使っているときは「pip3」でインストールする。) $ sudo pip3 install RPi.bme280
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting RPi.bme280
Using cached https://files.pythonhosted.org/packages/8a/55/2c738564ceb478952f15d6331759c0ca4f4d518e8e44689766deac9f42de/RPi.bme280-0.2.3-py2.py3-none-any.whl
Requirement already satisfied: smbus2 in /usr/local/lib/python3.7/dist-packages (from RPi.bme280) (0.2.3)
Installing collected packages: RPi.bme280
Successfully installed RPi.bme280-0.2.3
☆テストコード RPi.bme280ライブラリを使えばとても簡単なコードで温度・湿度・気圧が取得できます。(SWITCHSCIENCEさんのサンプルコードとほぼ同じ数値が得られました。「ほぼ」なのは,同時刻に取得した数値ではないからで,まったく同じといってよいと思います。) 参考にしたWebページ によると,この温度は湿度・気圧を求めるときの補正用に使うセンサー自身の温度であって,周辺の環境の温度とは異なるとのことです。校正していないLM335Zと比べると,確かに3℃近く高い温度を示しますが,市販の温度計や体温計などを近くに置いてみると,BME280に近い温度を示します。気温・湿度・気圧のロガーを作る際に,気温だけLM335Zで測るようにしようかと思いましたが,校正するのも大変そうなので,BME280の温度をそのまま使うことにします。 import smbus2 import bme280 import time port = 1 address = 0 x76 bus = smbus2.SMBus (port) calibration_params = bme280.load_calibration_params (bus, address)while True : data = bme280.sample (bus, address, calibration_params) print ("{0:%Y年%m月%d日 %H時%M分%S秒}" .format (data.timestamp)) print (" 温度:{0:.2f} ℃" .format (data.temperature)) print (" 湿度:{0:.2f} %" .format (data.humidity)) print (" 気圧:{0:.2f} hPa\n" .format (data.pressure)) time.sleep (1 )
>>> %Run BME280_Rpi.bme280.py
2019年xx月xx日 xx時xx分xx秒
温度:32.58 ℃
湿度:58.63 %
気圧:1005.91 hPa
2019年xx月xx日 xx時xx分xx秒
温度:32.57 ℃
湿度:58.55 %
気圧:1005.87 hPa
上の直後にSWITCHSCIENCEさんのサンプルコードを実行した結果が下です。ほぼ同じ値です。
>>> %Run BME280_SRpi.bme280.py
temp : 32.56 ℃
pressure : 1005.89 hPa
hum : 58.47 %
☆参考にしたwebページ ADコンバータのMCP3002と,温度センサーのLM335Zで気温を測ってみます。
spidevとgpiozeroでテストコードを作ってみましたが,どうも2つの値が一致しません。交互に測ってもgpiozeroで計測した方が,生の値で1大きくなる傾向がありました。基準電圧にラズパイの3.3Vを使っていますし,コンデンサーも省略しているので,処理によって微妙に基準電圧がゆらいでいるのかもしれません。
基準電圧が3.3Vなので,3.3 * 100 - 273.15 = 56.85℃ まで測れます。気温計に使うには十分です。
また,3.3 * 100 / 1023 ≒ 0.32℃ 刻みの測定になります。LM335Zは非校正時には2℃の誤差があることを考えれば精度は十分ですが,0.1℃刻みで測定したい気もします。0.1℃刻みにするには,3.3 * 100 / 0.1 = 3300 なので,12bit(=4095)のMCP3204あたりを使う必要がありそうです。(パッケージの小さい12bit2chのMCP3202は秋月にもないみたい。)
☆材料 ブレッドボード BB-801 × 2 秋月 P-05294 400円 ラズベリーパイ用ブレッドボード接続キット 秋月 K-08892 450円 10bit 2ch ADコンバータ MCP3002-I/P 秋月 I-02584 160円 精密級高精度温度センサーLM335Z 秋月 I-11158 75円 カーボン抵抗 1/4W 1kΩ 秋月 R-25102 (100本)100円 ブレッドボードジャンパーワイヤセット 秋月 C-05159 (60本)220円 合計 1,405円
☆回路図 ☆できあがり ☆テストコード ①spidevを使ってMCP3002に繋いだLM335Zの値を読む。 import spidev import time SPI_BUS = 0 SPI_DEVICE = 0 SPI_MAX_SPEED = 200000 MCP3002_VREF = 3.3 MCP3002_START = 0 b01000000 MCP3002_SGL = 0 b00100000 MCP3002_DIFF = 0 b00000000 MCP3002_ODD_CH0 = 0 b00000000 MCP3002_ODD_CH1 = 0 b00010000 MCP3002_MSBF =0b00001000 MCP3002_LSBF =0b00000000 while True : spi_values = [] spi_values.append (MCP3002_START | MCP3002_SGL | MCP3002_ODD_CH0 | MCP3002_MSBF) spi_values.append (0 x00) spi = spidev.SpiDev () spi.open (SPI_BUS, SPI_DEVICE) spi.max_speed_hz = SPI_MAX_SPEED result = spi.xfer2 (spi_values) data = int.from_bytes (result, byteorder='big' ) & 0 x3FF print ("{0} {1}℃" .format (data, data * MCP3002_VREF / 1023 * 100 - 273.15 )) spi.close () time.sleep (1 )
>>> %Run MCP3002_LM335Z_spidev.py 934 28.140322580645147℃ 934 28.140322580645147℃ 934 28.140322580645147℃ 934 28.140322580645147℃ 934 28.140322580645147℃ 934 28.140322580645147℃ 934 28.140322580645147℃
②gpiozeroを使って MCP3002に繋いだLM335Zの値を読む。 何と簡単!
でも,raw_valueがspidevを使ったときの値より1大きい気がする。
from gpiozero import MCP3002import time ch0 = MCP3002 ()while True : result = ch0.raw_value print ("{0} {1}℃" .format (result, result * ch0.max_voltage /1023 * 100 - 273.15 )) time.sleep (1 )
>>> %Run MCP3002_LM335Z_gpiozero.py 935 28.462903225806485℃ 935 28.462903225806485℃ 934 28.140322580645147℃ 935 28.462903225806485℃ 935 28.462903225806485℃ 935 28.462903225806485℃ 935 28.462903225806485℃
ラズパイ工作の定番と言われる,起動・リブート・シャットダウンスイッチです。
赤のタクトスイッチが起動ボタンです。出力として使用しているときに押されてもショートしないように330kΩの抵抗を挟んでいます。(1kΩでは起動しませんでした。330Ωであれば,電流は10mA(3.3 / 330 = 0.01)に抑えられるので,簡単に壊れたりはしないと思います。)
白のタクトスイッチがリブート・シャットダウンボタンです。プルアップし,Pythonで立ち下がりを検出するようにします。LEDが3回点滅するまで押し続けることでリブート,5回点滅するまで押し続けることでシャットダウンするようにPythonのコードを書きます。また,LEDは0.5秒ごとに点滅するようにします。
ケースに組み込んだときなどに,外付けのボタンで操作できるように,タクトスイッチと平行にXHコネクタを付けておくことにします。
☆材料 ラズパイZero用ユニバーサル基板 秋月 P-14031 100円 ラズパイ用スタッキングコネクタ 秋月 C-10702 150円 タクトスイッチ×2(赤・白) 秋月 P-03648 20円 XHコネクタ(2ピン)×2 秋月 C-12247 20円 超高輝度5mmオレンジ色LED 秋月 I-06404 (10個)200円 カーボン抵抗 1/4W 0Ω 秋月 R-25000 (100本)100円 カーボン抵抗 1/4W 330Ω 秋月 R-25331 (100本)100円 カーボン抵抗 1/4W 1kΩ 秋月 R-25102 (100本)100円 カーボン抵抗 1/4W 10kΩ 秋月 R-25103 (100本)100円 合計 890円
☆配線図 (抵抗のカラーコードの間違いを修正しました。R01.08.26) ☆できあがり ☆テストコード ①まずは,LEDチカチカ LEDを10回,0.5秒間隔で点けたり消したりする。
import RPi .GPIO as GPIOimport time LED_PIN = 12 GPIO.setwarnings (False ) GPIO.setmode (GPIO.BCM) GPIO.setup (LED_PIN, GPIO.OUT)for i in range (10 ): GPIO.output (LED_PIN, GPIO.HIGH) time.sleep (0.5 ) GPIO.output (LED_PIN, GPIO.LOW) time.sleep (0.5 ) GPIO.cleanup ()
②タクトスイッチの押下検出 タクトスイッチを押すまで待ち,スイッチを押したら,"Button Pushed.”のメッセージを表示する。
import RPi .GPIO as GPIOimport time BUTTON_PIN = 26 GPIO.setwarnings (False ) GPIO.setmode (GPIO.BCM) GPIO.setup (BUTTON_PIN, GPIO.IN) GPIO.wait_for_edge (BUTTON_PIN, GPIO.FALLING)print ("Button Pushed." ) GPIO.cleanup ()
☆リブート&シャットダウン ①タクトスイッチの押下でリブートまたはシャットダウンするコード
・wait_for_edge()を使うと,killしても待ち続け,すぐに終了しない。(killしたあと,タクトスイッチを押した時点で終了する。)そのため,add_event_detect()を使ってコールバック関数を呼ぶようにし,ループで待機する。
・コールバック関数で長い時間処理をすると,チャタリングが起きるのか,2回連続でコールバック関数が呼ばれることがあった。そのため,コールバック関数ではフラグをセットしてすぐに終了し,待機ループでフラグの変化を検知して必要な処理を行うようにした。
import RPi .GPIO as GPIOimport time import sys import os import signal LED_PIN = 12 BUTTON_PIN = 26 button_flag = False def main (): GPIO.setwarnings (False ) GPIO.setmode (GPIO.BCM) GPIO.setup (LED_PIN, GPIO.OUT) GPIO.setup (BUTTON_PIN, GPIO.IN) GPIO.output (LED_PIN, GPIO.LOW) blink_led (3 , 0.1 ) GPIO.output (LED_PIN, GPIO.HIGH) GPIO.add_event_detect (BUTTON_PIN, GPIO.FALLING, callback=button_pushed, bouncetime=300) signal.signal (signal.SIGTERM, sigterm_handler) global button_flag try : while True : time.sleep (0.1 ) if button_flag: choose_action () button_flag = False except KeyboardInterrupt: pass finally : GPIO.output (LED_PIN, GPIO.LOW) GPIO.remove_event_detect (BUTTON_PIN) GPIO.cleanup () def blink_led (times, wait): for i in range (times): GPIO.output (LED_PIN, GPIO.HIGH) time.sleep (wait) GPIO.output (LED_PIN, GPIO.LOW) time.sleep (wait)def button_pushed (gpio_pin): global button_flag button_flag = True def choose_action (): GPIO.output (LED_PIN, GPIO.LOW) time.sleep (0.2 ) count = 0 while True : blink_led (1 , 0.5 ) count += 1 if GPIO.input (BUTTON_PIN) == GPIO.HIGH: if count == 3 : blink_led (3 , 0.1 ) os.system ("sudo reboot" ) sys.exit () if count == 5 : blink_led (5 , 0.1 ) os.system ("sudo shutdown -h now" ) sys.exit () blink_led (5 , 0.1 ) GPIO.output (LED_PIN, GPIO.HIGH) break def sigterm_handler (signal_number, stack_frame): sys.exit ()if __name__ == "__main__" : main ()
②サービスとして自動起動するために,下のUnit定義ファイルをファイル名「reboot_shutdown.service」で保存する。 [Unit] Description=for Reboot and Shutdown board [Service] ExecStart=/usr/bin/python3 /home/pi/reboot_shutdown.py [Install] WantedBy = multi-user.target
③「 /etc/systemd/system/」にUnit定義ファイルをコピーする。 $ sudo mv reboot_shutdown.service /etc/systemd/system/
④サービスとして起動 LEDが3回点滅したあと,点灯して待機することを確認。 $ sudo systemctl start reboot_shutdown
⑤サービス再起動 LEDが一度消灯し,その後再起動することを確認。 $ sudo systemctl restart reboot_shutdown
⑥サービス終了 LEDが消灯し,終了することを確認。 $ sudo systemctl stop reboot_shutdown
⑦サービス自動起動を有効にする
$ sudo systemctl enable reboot_shutdown Created symlink /etc/systemd/system/multi-user.target.wants/reboot_shutdown.service ? /etc/systemd/system/reboot_shutdown.service.
⑧再起動 再起動後,LEDが点灯し,自動起動したことを確認。 1 2 次 カテゴリ選択 今日の出来事 連絡事項 報告事項 ミーティング 本・雑誌 ニュース 映画・テレビ 音楽 スポーツ パソコン・インターネット ペット 総合学習 アニメ・コミック 1件 5件 10件 20件 50件 100件