IT女子のラズベリーパイ入門奮闘記

第19回「ラズベリーパイで手作り目覚まし時計!ストップボタン編」

raspberrypi19_main

ラズベリーパイを触り始めて、もうすぐ一年。ラズベリーパイだけでなく、新しい小型コンピュータに関するニュースもしっかりとチェックする習慣がついてきて、着々と電子工作にハマってきています。
ちなみに最近気になっているのは「CHIP」というワンボードマイコンです。

わずか1000円の激安コンピューター「CHIP」とは? – GIGAZINE
CHIPは売価9ドルの何でもできる超小型コンピュータ | TechCrunch Japan

9ドル(約1000円)で買えるということは、ラズベリーパイよりも安い!Debianの軽量版をインストールできるそうなので、ラズベリーパイで身に着けた知識をいかして使えるのがうれしいポイントです。日本で買えるようになる日が待ち遠しいですね!

それでは本題のラズベリーパイに戻りましょう。
ラズベリーパイの基礎的な内容はおおむね身に付いてきたので、今回からは少し趣向を変えて、数回に分けて1つの作品をじっくり作り込んでいきたいと思います。プチ連載「目覚まし時計編」のスタートです!
第1回目は、目覚まし時計の必須機能、ストップボタンの実装です。カチッとボタンを押すとアラームが止まる、とても単純な仕組みですが、電子工作となるとなかなか難しい!?

動作の流れはこちらです。まずはシンプルな単機能目覚まし時計を作りましょう!

raspberrypi19_main2

 

スイッチについて

シール形タクタイルスイッチ 形B3W | オムロン電子部品情報サイト

raspberrypi19_img01

図1(オムロン電子部品情報サイトより)

今回はこちらの部品を使用しました。タクタイルスイッチ(タクトスイッチともいいますね。)は、ボタンを押すと内部の回路がつながり、電流が流れる仕組みとなっています。
向きが少し分かりにくいのですが、この部品の場合は、ピンの先端が少し内側に曲がっているのが目印となります。向き合っているピン同士が内部で連結されており、ボタンを押すと、すべてのピンがつながります。

raspberrypi19_photo01

写真1

実際にブレッドボードに設置したところが写真1です。強く差し込まず、ブレッドボードの穴にピンの足先を引っかける程度でOKです。軽く押してみると、タクタイル(触覚のある)という名前の通り、カチッと触感がありますね。

 

配線

raspberrypi19_photo02

写真2

今回使用する部品はこちらです。
・タクタイルスイッチ × 1
・抵抗器 × 1
・ジャンパーワイヤー × 3

raspberrypi19_img02

図2

部品はこのように配線しました!
電源は1番ピンの3.3Vを使用します(緑色のジャンパーワイヤー)。スイッチの入力を感知するGPIOは、今回は3番ピンのGPIO2を使用しました(青色のジャンパーワイヤー)。

これだけでも動きそうな気がしますが、重要な部品がもう1つ。スイッチとGPIO2の間に置いた抵抗器です。これは「プルダウン抵抗」と呼ばれるもので、GNDと接続しておくことで(黒色のジャンパーワイヤー)、電流を安定させる役割を果たします。前回の「プルアップ抵抗」の反対ですね。
ちなみに、実際にプルダウン抵抗を省いてテストしてみたところ、スイッチの状態に関わらず「1」の値が取得されてしまいました。

ラズベリーパイでスイッチの状態を感知する

ラズベリーパイからGPIOへの「出力」は、第9回のLチカ編でやりましたね!今回はその逆、GPIOからラズベリーパイへの「入力」を感知します。入力モードも出力モードも、基本的なやり方は同じです。
まずはGPIOポートを使用する準備を行います。今回使用しているのは3番ピン「GPIO2」のポートなので、「2」を指定します。

echo 2 > /sys/class/gpio/export

次は、このGPIOポートで「入力」と「出力」のどちらを行うかの設定です。「出力」の場合は「out」でしたが、今回は「入力」なので「in」を指定します。

echo in > /sys/class/gpio/gpio2/direction

設定はここまで!出力モードと違うのは「in」と「out」の指定だけですね。
スイッチの入力状態を感知するには、「value」の値を取得するので「cat」コマンドを使ってファイルにアクセスします。

cat /sys/class/gpio/gpio2/value

raspberrypi19_img03

図3

ボタンを押していない状態では「0」と出力されます。ここで「1」が出力されてしまう場合は、配線に問題がある可能性があります。タクトスイッチの向きが間違っているか、プルダウン抵抗がうまく働いていないなどの原因が考えられますので、ブレッドボードを確認してみましょう。

最後は終了処理。「unexport」にGPIOのポート番号を書き込むことで終了できます。

echo 2 > /sys/class/gpio/unexport

スイッチの感知に必要なコマンドは以上です。これらをプログラムに組み込んで、目覚まし時計を仕上げていきます!

 

プログラムの準備

目覚まし時計のアラームを鳴らすプログラムと、スイッチを感知してアラームを止めるプログラムを用意します。言語はPHPを使用しました。
まずはアラーム音を鳴らすプログラムです。今回は「mpg321」パッケージを使って、アラーム音の音声ファイルを再生します。

/var/www/start.php

<?php
exec('mpg321 -l 0 -q /var/www/alerm1.mp3 > /dev/null &');

MP3ファイルは、こちらのサイトからお借りしました。短い音声ファイルなので、「-l」オプションでループ再生にしています。末尾の「> /dev/null &」はバックグラウンド処理をするためのおまじないですね。
次は、アラームを止めるプログラムです。ボタンの状態を監視し、ボタンが押されるとMP3の再生を終了させます。

/var/www/stop.php

<?php
$interval_sec = 0.25;
$wait_sec = 60;
exec('echo 2 > /sys/class/gpio/export');
exec('echo in > /sys/class/gpio/gpio2/direction');
for($i=0; $i<($wait_sec / $interval_sec); $i++){
    if(exec('cat /sys/class/gpio/gpio2/value')==1){
   	 break;
    }
    usleep($interval_sec * 1000000);
    echo $i.PHP_EOL;
}
exec('killall mpg321');
exec('echo 2 > /sys/class/gpio/unexport');

上記のプログラムでは、0.25秒間隔で1分間(0.25秒×240回)、ボタンの状態を監視しています。ボタンが押される、もしくは、ボタンが押されないまま1分が経過した場合に、「mpg321」を停止させています。

それではテストしてみましょう!

左側の画面で「start.php」を、右側の画面で「stop.php」を実行しています。start.phpで使用している「mpg321」コマンドは、再生を止めるまでコンソールを独占してしまうため、LX Terminalを2画面開いてテストしました。
右側の「stop.php」の画面では、カウンタの値をコンソール画面に表示しています。ループ処理の12回目で「スイッチが押された状態」が感知され、アラームの再生が止まりました。うまく感知されない場合は、usleepの値を調整するか、ゆっくり指を離すようにしてみてください。

テストが成功したら、cronに登録して、目覚まし時計として使えるように設定しましょう!

 

cron設定

cronについては前回の記事でも設定しましたが、今回は1つずつ詳しく見て行きましょう。
cronは、実行させる日時とコマンドを、半角スペースで区切って指定します。日時は5つの値に分けて記述します。日本語で並べると下記のようになります。

分 時 日 月 曜日 実行コマンド

複数の値を指定する場合は特殊記号を使用すると便利です。指定値をリスト化して記述する場合は「,」を、範囲で指定する場合は「-」を、全ての値を指定する場合は「*」を記述します。

それでは、目覚まし時計ということで、「平日(月~金曜日)6時45分」にコマンドを実行する設定をしてみましょう。
下記の状態からスタートです!(分かりやすいように実行コマンドは仮に「command」とします)

* * * * * command

まずは曜日。5番目の値です。0~6までの数値で指定します。数値は日曜始まりで、0が日曜日です。「平日」を表すには「1~5」を指定します。連番なので、特殊記号の「-」(ハイフン)を使って範囲を指定することができます。「,」(カンマ)区切りで列挙しても同じ意味合いになります。

* * * * 1-5 command
* * * * 1,2,3,4,5 command

次は日付です。実行のタイミングを曜日でしぼり込んでいるため、「日」と「月」は指定せず、「毎日」実行させる必要があります。「*」のままとしておきましょう。
最後は時間を指定します。「時」は2番目、「分」は1番目の値です。どちらも0~59の間で指定します。

45 6 * * 1-5 command

日時の設定はこれで完成!あとはコマンドを指定するだけですね!
今回は2つのプログラムを呼び出したいので、シェルスクリプトにまとめます。

/root/morning.sh
php /var/www/start.php
php /var/www/stop.php

スクリプトファイルには、「chmod」コマンドまたはファイルのプロパティ設定から、実行権限を与えておきます。cronに登録する前に、動作チェックを済ませておきしょう。
シェルスクリプトの用意ができたら、cronを完成させましょう。仮で設定していた「command」と差し替えると、次のようになります。

45 6 * * 1-5 /root/morning.sh

それではcronに登録します。

crontab -e
45 6 * * 1-5 /root/morning.sh

raspberrypi19_img04

図4

図4では、新たに登録した行の上に、前回作った温度計の命令が残っています。こうして並べてみると、シェルスクリプトにまとめる方がすっきりしていて、後から見ても分かりやすいですね!
[Ctrl]+[O]キーで保存すれば、午前6時45分にアラームで起こしてくれる目覚まし時計の完成です!

 

まとめ

シンプル機能のラズベリーアラーム完成!
実際に使ってみた印象は、MP3の再生が始まるまでに少し時間がかかることがあるので、ストップボタンの待ち時間は少し長めに設定したほうが良さそうです。ブレッドボードの上の小さなボタンをソフトに押す必要があるので、程よい緊張感のある朝がむかえられます(笑)。

次回も引き続き、目覚まし時計のカスタマイズを進めます。
アラームを止めて終わりではちょっと物足りないので、止めた後に動作する機能が欲しいところです。せっかくなので時間を教えてもらいましょう!
そんなわけで、日本語で現在時刻を読み上げてくれる機能を実装したいと思います!

出場ロボット解剖計画
円山ナカノ

プロフィール:プログラミング暦通算4年、最近IT業界に舞い戻ってきたプログラマーです。女子です。