2021年11月28日日曜日

本書の演習をウェブカメラで実行する方法

1. はじめに

本書では、Raspberry Piの公式カメラモジュールを用いた電子工作の例をいくつか紹介しました。 第6章のカメラ台、第7章の画像処理、第8章の六脚ロボットへのカメラの搭載などです。

本ページでは、カメラモジュールではなく市販のウェブカメラで演習を行う方法を紹介します。こちらで動作検証したカメラはロジクール社のC270およびC920です。

本ページでは「××社の○○と言うカメラで動くか」という質問や「××社の○○と言うカメラで動くようにして欲しい」という要望には応えることができません。

カメラが異なることによるそのようなトラブルを避けるために、本書ではRaspberry Pi専用のカメラモジュールを使用する方針としたのだったからです。 本ページは上級者向けのサービスという位置づけとしますのでご理解ください。

ところで、2022年2月、Raspberry Pi OS Bullseye の 64-bit 版が正式にリリースされました。この 64-bit 版 OS では、本書でこれまで用いていたカメラモジュールを用いるプログラムをそのまま利用することができません。カメラモジュールの利用法が大きく変わったためです(32-bit 版 OS ではこれまでどおり利用可能)。 本ページの「本書の演習をウェブカメラで実行する方法」を用いると、「64-bit 版 OS でカメラモジュールを用いた演習」が可能になる、という副作用があります。ただし、この方法は準備がやや面倒ですので、カメラモジュールを用いた演習を行いたい方はこれまで通り 32-bit 版 OS の利用をお勧めします。

2. 手順

それではターミナルアプリケーションLXTerminalを開き、本書のサンプルファイル(「bb2-」で始まるファイル)が存在するディレクトリに移動してください。 サンプルファイルをユーザーpiのホームディレクトリに展開した方は移動の必要はありません。bluebacksディレクトリに展開した方は下記のコマンドを実行するのでした。
cd bluebacks
次に、下記の3つのコマンドを順に実行して、必要なファイルのダウンロードと展開を行ってください。コマンドはコピー&貼り付けで実行することを推奨します。展開後はダウンロードした圧縮ファイルは不要となるので削除しています。
wget https://github.com/neuralassembly/raspi/raw/master/raspi2-webcam.zip
unzip raspi2-webcam.zip
rm raspi2-webcam.zip
なお、展開されるファイルの名前は既存のサンプルファイルとは異なりますので、サンプルファイルが上書きされることはありません。展開により現れるファイルは下記の通りです。ファイル名の末尾付近に全て「-webcam」がついていることに注意してください。
bb2-06-03-stream-webcam.sh
bb2-07-01-preview-webcam.py
bb2-07-02-binary-webcam.py
bb2-07-03-cannyedge-webcam.py
bb2-07-04-circle-webcam.py
bb2-07-05-face-webcam.py
bb2-07-06-tracking-circle-webcam.py
bb2-07-07-tracking-face-webcam.py
bb2-07-08-tracking-circle-pca9685-webcam.py
bb2-07-09-tracking-face-pca9685-webcam.py
あとは、以下に従って実行します。

3. 実行

実行に関する注意を、いくつか例を挙げながら解説します。 例えば、本書 p.224 に、下記のコマンドを実行するよう指示があります。
sh bb2-06-03-stream.sh
このファイル「bb2-06-03-stream.sh」に対しては、ウェブカメラ対応の代替ファイル「bb2-06-03-stream-webcam.sh」が存在します。 そのような場合、上記コマンドの代わりに下記のコマンドを実行して欲しい、ということです。
sh bb2-06-03-stream-webcam.sh
同様に、p.239 には下記のコマンドを実行するよう指示があります(Python3 用のコマンドに変更してあります)。
python3 bb2-07-01-preview.py
このファイル「bb2-07-01-preview.py」に対しては、ウェブカメラ対応の代替ファイル「bb2-07-01-preview-webcam.py」が存在します。 そのような場合、上記コマンドの代わりに下記のコマンドを実行して欲しい、ということです。
python3 bb2-07-01-preview-webcam.py
以上のように、実行するファイルを書籍から読み替える形でコマンドを実行してください。

OpenWeatherの天気予報データをLCDに表示する

0. はじめに

本書第4章では、「お天気Webサービス」の天気予報データをインターネット経由で取得し、それをLCDに表示するという演習を行いました。
しかし、「お天気Webサービス」は2020年7月でサービスを終了したらしく、その演習プログラムはそのままでは実行できなくなっています。

そこで、その代替として、OpenWeather というサイトから天気予報データを取得し、それをLCDに表示するプログラムを作成しました。
「お天気Webサービス」と比べると、「サイトにアカウントを作成し、APIキーを取得する」というひと手間が必要なところがやや面倒ですが、その点をクリアできれば、本書と (ほぼ) 同等の内容を実現できます。

OpenWeather の料金体系を見ると、無料枠から課金枠まで、様々な利用方法が提供されていることが分かります。 本ページでは、無料 (Free) の One Call API を利用します。一日1,000 呼び出し、一か月30,000呼び出しが可能であることが記されています。

以下、本ページではその利用方法を紹介します。

1. OpenWeather でのアカウントの作成とAPIキーの取得

OpenWeather の天気予報データを利用するには、まずサイトでアカウントを作成しなければなりません。その手順を簡単に解説します。
  1. OpenWeatherのアカウント作成ページで必要事項を記入ます。
    • Username: 英語サイトなので、アルファベットからなるユーザー名を入力するのが良いでしょう。アカウント作成後に変更できます。
    • email: アカウント作成時に確認メールが届きますので、正確に入力してください。
    • Password / Repeat Password: パスワードを二回入力します。
    • I am 16 years old and over (16歳以上) の条件を満たしていればチェック
    • I agree with Privacy Policy ... 使用条件などをを理解したらチェック
    • System news, Product news, Corperate news はサイトからのメールを受け取りたければチェック
    • 「私はロボットではありません」にチェック
    • 以上を確認したら「Create Account」ボタンをクリック
  2. 遷移先のページで、Company と Purposeを入力します。
    • Company は、個人ならば記入しなくて構いません
    • Purpose (使用目的) は、私の場合「Education/Science (教育と科学)」を選択しました
    • 「Save」ボタンをクリック
  3. 以上が終わると、登録したメールにOpenWeather からメールが届きます。メールの中の「Verify your email」ボタンをクリックすると、登録完了です。
さて、以上が終わったあと、OpenWeather において、下図のように「ユーザー名」→「My API keys」と辿ると、API key を取得できます。 このAPI keyをコピーしてメモ帳などで保存しておきましょう。
なお、この API key は Raspberry Pi 上で用いるので、Raspberry Pi 上のブラウザでコピーし、Raspberry Pi 上のテキストエディタ Mousepad で保存するのが良いかもしれません。
また、この API key は登録したメールアドレスにも届きますので、そちらからコピーしても良いでしょう。その中に「Within the next couple of hours, it will be activated and ready to use」とあるので、利用可能になるまで数時間かかることがあるのかもしれません。 私の場合、すぐに使えたように思うのですが、ちょっと自信がありません。

2. OpenWeatherの天気予報データを利用するプログラムのダウンロードと準備

ここからは、OpenWeatherの天気予報データを利用するプログラムの利用方法を解説します。 これらのプログラムは、本書4章のプログラムの OpenWeather バージョン、ということができます。

プログラムのダウンロードは Raspberry Pi 上で下記の2命令を実行することで行います。 命令はどこで実行しても構いませんが、本書のサンプルプログラムが存在する場所で実行すると、ファイルがまとまるので良いかもしれません。
https://raw.githubusercontent.com/neuralassembly/raspi/master/bb2-04-openweather.zip

unzip bb2-04-openweather.zip
一つ目の命令で圧縮ファイルをダウンロードし、二つ目の命令で展開しています。 展開により現れるファイルは下記の5つです。
  • bb2-04-00-checkcity.py
  • bb2-04-01-weather-ow.py
  • bb2-04-02-forcast-ow.py
  • bb2-04-04-lcd-4modes-ow.py
  • bb2-04-05-lcd-3modes-ow.py
最初の「bb2-04-00-checkcity.py」は、本書のサンプルプログラムには存在しなかったファイルです。 bb2-04-01~bb2-04-05 のファイルは本書のサンプルプログラムに同じ番号のものがありますが、 新しいファイルにはファイル名の末尾に「-ow」がついているので、区別することができます(OpenWeathterの略です)。

これらのファイルを用いるには、上記5つのファイルに冒頭で入手した API key を記入して上書き保存しなければなりません。まずその解説を行います。

これらの5つのファイルを mousepad のようなテキストエディタや、Thonny のような開発環境で開くと、どのファイルにも下記の行が見つかります(冒頭にスペースが入っている場合もあります)。
key = 'API_KEY'
具体的には、5つのファイルの下記の行番号の位置に上の行があります。
  • bb2-04-00-checkcity.py: 5行目
  • bb2-04-01-weather-ow.py: 7行目
  • bb2-04-02-forcast-ow.py: 7行目
  • bb2-04-04-lcd-4modes-ow.py: 100行目
  • bb2-04-05-lcd-3modes-ow.py: 100行目
この行の「API_KEY」の部分を、上でコピーして保存した皆さんの API key で書き換えます。 本当の API key を書くわけにはいかないので、イメージを記すと下記のようになります。
key = '................................'
書き換えたら、ファイルを上書き保存してください。この作業を、5つのファイル全てで行います。 以上でプログラム実行前の準備は完了です。

3. OpenWeatherの天気予報データを利用するプログラムの実行

ここからは、OpenWeatherの天気予報データを利用するプログラムの実行方法を解説します。

本書に存在しないファイルである「bb2-04-00-checkcity.py」の利用法の解説のみ後まわしとし、残りの4ファイル の解説を順に行います。 なお、デフォルトでは4ファイルは東京の天気を表示します。また、全てのファイルは Python3 でのみ動作します。 本書のサンプルファイルと異なり、Python2 のサポートを外しました。

bb2-04-01-weather-ow.py の利用

Thonny で開いて実行するか、下記のコマンドで実行してください。
python3 bb2-04-01-weather-ow.py
本書の図4-7のように、入手した天気予報データを全て表示するコマンドです。表示された中身を理解する必要はなく、 「天気予報データを入手できた」ということを確認できればそれで十分です。
(省略)
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "晴天",
          "icon": "01d"
        }
      ],
      "clouds": 2,
      "pop": 0,
      "uvi": 3
    }
  ]
}
なお、取得されるデータは本書の図4-7の形式とは全く異なります。予報のデータは上の「"main": "Clear",」の部分を使っており、「"description": "晴天",」の部分は使っていません。 最終的に LCD に表示するうえで、"description" の部分はバリエーションが多すぎると思えたためです。

bb2-04-02-forcast-ow.py の利用

Thonny で開いて実行するか、下記のコマンドで実行してください。
python3 bb2-04-02-forcast-ow.py
本書の図4-8のように、3日間の予報のみをデータを整理して表示します。
今日, 雨, 9/17
明日, 雨, 12/18
明後日, 雨, 9/13
なお、「お天気Webサービス」と異なり、「時々」や「のち」を含む結果は現れません。 「Clear(晴れ)」、「Clouds(曇り)」、「Rain(雨)」、「Snow(雪)」、「Thunderstorm(雷)」、「Drizzle(霧)」 の6種類の天気しか表示されません。その点はこのサイトの特性としてご了承ください。

bb2-04-04-lcd-4modes-ow.py および bb2-04-05-lcd-3modes-ow.py の利用

これらのプログラムは本書図4-9の温度計およびLCDを含む回路を作成してから実行してください。実行結果は本書のプログラムと同じです。
python3 bb2-04-04-lcd-4modes-ow.py

python3 bb2-04-05-lcd-3modes-ow.py


bb2-04-00-checkcity.py の利用

さて、上で説明したプログラムは、全て東京での天気予報を表示するものでした。これを別の都市の天気予報に変更したいときに用いるプログラムが bb2-04-00-checkcity.py です。 その使い方を解説します。

ここまでのプログラムで天気予報の対象位置を指定するためには、実は緯度と経度を用いなければなりませんでした。5つのプログラム全てで、API key を指定した行の近くに下記の2行が存在します。
lat = '35.6895'
lon = '139.6917'
これは緯度35.6895、経度139.6917を表しており、実はこれが東京を意味していた、というわけです。「東京」という地名で位置を指定したいところですが、それは無料枠の One Call API ではできない、ということです。

ですから、天気予報の対象地を変えたいときは、下記の流れで行う必要があります。
  1. 対象地を決める
  2. 対象地の緯度と経度を調べる
  3. 調べた緯度と経度を5つのプログラムに書き込み、上書き保存する
このとき、「対象地の緯度と経度を調べる」ときに用いるのが bb2-04-00-checkcity.py であるというわけです。早速試してみましょう。

まず、こちらのサイトから対象地を決め、そのスペルを確認しておきましょう。マウスドラッグで位置変更ができ、マウスホイールで拡大率の変更ができます。
例えば、「Sapporo」を選ぶことにします。

次に、bb2-04-00-checkcity.py を Thonny や mousepad で開き、下記の行を見つけます。
city = 'Tokyo'
この行のTokyoの部分をSapporoに変更し、上書き保存します。
city = 'Sapporo'
そして、bb2-04-00-checkcity.py を Thonny または下記のコマンドで実行してください。
python3 bb2-04-00-checkcity.py
すると、下記のように Sapporo の緯度と経度が得られます。
Sapporo
lat = '43.0642'
lon = '141.3469'
このうち、下記の2行で bb2-04-01~bb2-04-05 のファイルの該当行を置き換えて保存すれば、それらのファイルは Sapporo の天気予報を出力するようになります。
lat = '43.0642'
lon = '141.3469'
以上、お疲れさまでした。

2021年11月14日日曜日

Raspberry Pi OS Bookworm / Bullseye / Buster でlircを利用する

はじめに

Raspberry Pi OS Bookworm / Bullseye / Buster での lirc のインストールは容易です。下記の手順に従ってください。

インストール (Raspberry Pi OS Bookworm / Bullseye / Buster の場合)

Raspberry Pi OS Bookworm / Bullseye / Buster の場合は下記の2コマンドをひとつずつ順に実行してlircをインストールしてください。
sudo apt update
sudo apt install lirc
以上でインストールが完了します。

インストール後の設定

さて、インストール後の設定を本書の流れに即して解説すると以下のようになります。
  • /etc/modulesへの編集 (p.142): 今回の方法では/etc/modulesを編集する必要はありません。
  • /boot/config.txtへのdtoverlayの追加 (p.142~p.143): まず、下記のコマンドで /boot/config.txt を編集用に開きます。
    sudo mousepad /boot/config.txt
    そして、「#dtoverlay=gpio-ir-tx,gpio_pin=18」または「#dtoverlay=lirc-rpi」という行を見つけ、その次の行に下記を追記してから保存してpadを閉じます。
    dtoverlay=gpio-ir,gpio_pin=24
    dtoverlay=gpio-ir-tx,gpio_pin=25
    該当する行が見つからなかった場合は、ファイルの最後の行に上の内容を追記すればよいでしょう。


次に、p.143末尾からの /etc/lirc/hardware.conf の編集ですが、このファイルは存在しませんので、 以下の設定に差し替えます。

まず、不要なファイルの名前を下記のコマンドで変えます。
sudo mv /etc/lirc/lircd.conf.d/devinput.lircd.conf /etc/lirc/lircd.conf.d/devinput.lircd.conf.dist
次に、下記のコマンドをターミナルで実行し、設定ファイル /etc/lirc/lirc_options.conf を管理者権限のmousepadで開きます。
sudo mousepad  /etc/lirc/lirc_options.conf 
開いたファイルの中に、下記の2行があるのを見つけてください。
driver          = devinput
device          = auto
これを、irrecordを用いてリモコン信号を学習させる場合は以下のように編集し、編集が終わったら保存してmousepadを終了してください。
driver          = default
device          = /dev/lirc1
なお、今回の方法ではirsendを用いて信号を送信する場合は/etc/lirc/lirc_options.conf の上記の行を下記のように変更しなければなりません。演習後半でirsendコマンドを使うときにはこれを忘れないよう注意してください。
driver          = default
device          = /dev/lirc0
以上で設定は終わりですので、Raspberry Piを再起動します。/etc/lirc/lirc_options.confを保存した場合は、Raspberry Piを再起動が必要です。

irrecordの実行

irrecord の場合は、上で注意したように /etc/lirc/lirc_options.conf の device 行が /dev/lirc1 に設定されていなければなりませんので注意してください。
そして、引き続きターミナルでirrecordを実行するのですが、その際のコマンド (p.145) は、下記のように末尾の「TV」をつけずに実行してください。
irrecord -n
その後、p.147からのリモコンの学習に移るのですが、開始時の手順が若干変更されています。
まず、下記のメッセージが出るので一回Enterキーを押します。
(略)
Please take the time to finish the file as described in
https://sourceforge.net/p/lirc-remotes/wiki/Checklist/ an send it
to  <lirc@bartelmus.de> so it can be made available to others.

Press RETURN to continue.
すると、下記のように光の状態のチェックに入りますので、終わるまで数秒待ちます。
Checking for ambient light  creating too much disturbances.
Please don't press any buttons, just wait a few seconds...
チェックが終わったら、下記のメッセージが現れますので、ここで「TV」を入力し、Enterキーを押してください。
Enter name of remote (only ascii, no spaces) :
つまり、こうですね。
Enter name of remote (only ascii, no spaces) :TV
すると、下記のようにもう一度Enterキーを押すことを促されます。これが、p.147末尾の「2度目の[Enter]キー」に該当しますので、Enterキーを押し、その後p.148の指示に従って様々なボタンを繰り返し押して行ってください。
It is very important that you press many different buttons randomly
and hold them down for approximately one second. Each button should
generate at least one dot but never more than ten dots of output.
Don't stop pressing buttons until two lines of dots (2x80) have
been generated.

Press RETURN now to start recording.
p.154までは書籍の指示通りで構いません。

なお、ピリオド文字「.」が画面を2行分埋め尽くすまでリモコンのボタンを押し続けるステップで、1行目と2行目の間に下記のメッセージが出ることがあります。
Cannot find any gap, using an arbitrary 50 ms one. If you have a
regular remote for e. g., a TV or such this is probably a point
where you hit control-C. However, technical hardware like air
condition gear often works without any gap. If you think it's
reasonable that your remote lacks gap you can proceed.
Press RETURN to continue.
これは「信号のギャップを見つけられない」というエラーを示しています。 この場合、そのまま作業を続けてもリモコンの認識に失敗しますので、一旦キーボードで「Ctrl-c」を入力してirrecordを終了してください。

そして、部屋の照明の状態の変更(日光が部屋に入らないようにしたり、蛍光灯の状態を変えたり)を行うか、 赤外線受信モジュールとリモコンの位置関係を変えるなど、実験環境を変えて再チャレンジしてください。 ピリオド文字「.」の1行目と2行目の間に上記エラーが出ない状態を実現して演習を継続するようにしてください。

ピリオド文字「.」の1行目と2行目の間のメッセージが下記のようになっていれば正常なので、そのまま継続してください。
Got gap (XXXXX us)

Please keep on pressing buttons like described above.
なお、途中で「ボタンの名前をキーボードで入力し、ボタンを押す」というプロセスがあります。このときはボタンの押す長さをやや長め(1秒程度)とすると成功しやすいでしょう。

irrecordの終了後、書籍では「TV」というファイルに設定が保存されましたが、現在は TV.lircd.confという名前のファイルが生成されます。

次に、ターミナルで下記のファイルを実行し、ファイルを移動します。ファイルの移動先も変更を受けています。
sudo mv TV.lircd.conf /etc/lirc/lircd.conf.d/
irsend を試す場合は、上で注意したように /etc/lirc/lirc_options.conf の device 行を /dev/lirc0 に変更しなければならないので注意してください。 そしてRaspberry Piを再起動するとLIRCが再び起動し、irsendコマンドが実行できるようになります。

なお、「ps ax |grep lircd」で LIRC の実行状況を確認した際、このバージョンの LIRC で表示されるメッセージは以下のようになっています(冒頭のいくつかの数字は人により異なります)。
502 ? Ss 0:00 /usr/sbin/lircd --nodaemon
これが表示されていれば、LIRC が正常動作しているということです。p.156 に示した旧バージョンの LIRC の表示とは異なりますのでご注意ください。

それ以降は書籍と同じです。