2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Raspberry Pi 3 ModelBにシャットダウン/起動ボタンをつける

Posted at

目的

Raspberry Pi 3 ModelBに(物理的な)シャットダウン/起動ボタンをつける

環境

Raspberry Pi 3 ModelB
gpio制御言語:C言語1

作業メモ

構成図

具体的な作業内容に入る前に構成図について説明する

shutdown_start.png

  • 画像の左側がシャットダウンボタン/右側が起動ボタンになる
  • ざっくり動きの流れを説明する
    • GPIO制御によって端子をプルアップ(High)設定
    • ボタンを押下するとGND(Low)に落ちる
    • それを検知してシャットダウンを実現する(起動ボタンは違う仕組みで動くので後述)

GPIO制御環境を整える

参考サイト
https://tool-lab.com/raspi-gpio-controlling-command-2/
http://wiringpi.com/examples/gertboard-and-wiringpi/blink/

  • WiringPi(GPIO制御環境)を導入

参考サイトの通り導入しようと思ったのだが、自分の環境ではデフォルトで入っていた
そのため、改めて導入はしていない
参考にgpio -vを実行したときの情報を載せておく

$ gpio -v
gpio version: 2.46
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 3, Revision: 02, Memory: 1024MB, Maker: Embest
  * Device tree is enabled.
  *--> Raspberry Pi 3 Model B Rev 1.2
  * This Raspberry Pi supports user-level GPIO access.
  • WiringPiの動作確認

gpioと言えばということで、Lチカで動作確認する
ここでは起動ボタンで使うGPIO端子(pin16/GPIO23)を制御する
GPIO端子とWiringPiの対応は以下のコマンドで確認できる
pin16はWiringPiだと"4"になる(wPiの列で確認可能)

$ gpio readall
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 1 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+

上記を元に、WiringPiのサイトに載っているサンプルコードほぼそのまま使う
変更したのは#define LED 4のところ、先ほど確認した"4"を入れた

# include <stdio.h>
# include <wiringPi.h>

// LED Pin - wiringPi pin 0 is BCM_GPIO 17.

# define LED     4

int main (void)
{
  printf ("Raspberry Pi - Gertboard Blink\n") ;

  wiringPiSetup () ;

  pinMode (LED, OUTPUT) ;

  for (;;)
  {
    digitalWrite (LED, 1) ;     // On
    delay (500) ;               // mS
    digitalWrite (LED, 0) ;     // Off
    delay (500) ;
  }
  return 0 ;
}

シャットダウンボタンを作成

参考サイト
http://gurochoro.blogspot.com/2017/08/debounce-in-a-microcomputer.html
https://qiita.com/marumen/items/78f65ad946a69603382e

  • シャットダウンを検知するプログラムを作成

作ったのは、2秒ボタンを押すとシャットダウンするプログラム
先に作ったLチカプログラムをベースに必要なところを変更する
pullUpDnControl(SHUTDOWNPIN, PUD_UP); でGPIO端子(pin16/GPIO23)をプルアップ(High)にする
参考サイトの"ディレイ方式"を参考にチャタリング除去処理
チャタリング除去した上でLowを検知したらシャットダウン処理をする

shutdownbutton.c
include <stdlib.h>
# include <wiringPi.h>

# define SHUTDOWNPIN     4
# define SHUTDOWNTIME    2000

int main(void) {

    wiringPiSetup();

    /* setting INPUT/PULLUP */
    pinMode(SHUTDOWNPIN, INPUT);
    pullUpDnControl(SHUTDOWNPIN, PUD_UP);

    /* for shutdown proc */
    while(1){
        if( digitalRead(SHUTDOWNPIN) == LOW ){
            delay(SHUTDOWNTIME);
            if( digitalRead(SHUTDOWNPIN) == LOW ){
                system("sudo shutdown -h now");
            }
        }
    }
  return 0;
}
  • シャットダウンプログラムをサービス化

以前自分で作ったものを参考にプログラムを常駐させる(サービス化)

serviceファイルを作る
WantedBy=multi-user.target で起動後常駐する
Type=simple は1度動作する = シャットダウンなので、simpleにしている

shutdownbutton.service
[Unit]
Description=shutdown button
DefaultDependencies=no

[Service]
Type=simple
ExecStart=/usr/bin/shutdownbutton

[Install]
WantedBy=multi-user.target

各種プログラムを必要なところへ配置

$ sudo chown root:root *
$ sudo cp shutdownbutton /usr/bin/
$ sudo cp shutdownbutton.service /etc/systemd/system/
$ sudo systemctl list-unit-files --type=service | grep shutdown
shutdownbutton.service                 disabled

サービスとして動作しているか確認2

$ sudo systemctl status shutdownbutton
● shutdownbutton.service - shutdown button
   Loaded: loaded (/etc/systemd/system/shutdownbutton.service; disabled; vendor
   Active: active (running) since Fri 2021-01-22 08:22:56 JST; 4s ago
 Main PID: 2905 (sample_chatter_)
   CGroup: /system.slice/shutdownbutton.service
           |-2905 /usr/bin/sample_chatter_remove

 1月 22 08:22:56 raspberrypi systemd[1]: Started shutdown button.

動作したので、サービスを常駐させる

$ sudo systemctl enable shutdownbutton
Created symlink /etc/systemd/system/multi-user.target.wants/shutdownbutton.service → /etc/systemd/system/shutdownbutton.service.

再起動して起動時に有効になることを確認

$ sudo reboot
$ sudo systemctl status shutdownbutton
● shutdownbutton.service - shutdown button
   Loaded: loaded (/etc/systemd/system/shutdownbutton.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2016-11-04 02:16:42 JST; 4 years 2 months ago
 Main PID: 83 (sample_chatter_)
   CGroup: /system.slice/shutdownbutton.service
          |-83 /usr/bin/sample_chatter_remove

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

これで起動後、2秒ボタンを押すとシャットダウンするようにできた

起動ボタンを作成

参考サイト
https://qiita.com/clses/items/e701c1cb6490751a6040

こちらは参考サイトでも書かれているが、最初に構成図で触れた通りGPIO3(pin5)をGNDに落とせばいいだけである
元々OS側にシャットダウンからの起動が機能として備わっているらしい
そのため、特にソフトウェアでの処理は何もいらない

まとめ

目的を達成!

Raspberry Pi 3 ModelBに(物理的な)シャットダウン/起動ボタンをつける

今はスイッチをブレットボード上に実装しているが、すっきりさせるためにこのサイトで使われているようなスイッチでスリム化もしたい

  1. 内容的にはいまさらだが、CでGPIO制御を書いているサイトがあまりなかったので参考に残しておく

  2. sudo systemctl start [service名]としないでも動いていた。WantedBy=multi-user.targetの設定だから?

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?