Raspberry Pi 覚え書き

小型PC、ラズベリーパイ3を使って遊んだプロセスを記録するページ

Raspberry Pi 3でNAS-ファイルサーバーを作る

1.Raspbain jessie with Pixelをインストールする

Windows10-PCを使ってラズベリーパイを設定する手順を解説する。
用意するもの
・SD Formatter 4.0
   https://www.sdcard.org/jp/downloads/formatter_4/
・Win32 Disk Imager 0.9.5
   https://ja.osdn.net/projects/sfnet_win32diskimager/
以上のフリーソフトをあらかじめWindowPCにインストールしておく。

ラズベリーパイ公式サイト>DOWNLOADS>RASPBIANのページ*から
RASPBIAN JESSIE WITH PIXEL-"2017-04-10-raspbian-jessie.zip"をダウンロード。
ZIP形式になっているので解凍してイメージファイル"2017-04-10-raspbian-jessie.img"を取り出す。
*https://www.raspberrypi.org/downloads/raspbian/
※このページ執筆時点の最新RASPBIAN JESSIE WITH PIXELが"2017-04-10-raspbian-jessie.zip"であった。
※torrent形式かzip形式どちらかを選ぶことができる。torrentユーザーならtorrent経由でダウンロードした方が速い。torrentを持っていない/何のことかわからない人はzip形式をダウンロードすべし。

■MicroSDカードをフォーマットする
PCにMicroSDカードをセットし、SD Formatter 4.0を開く。
"Drive"を間違えないように。"クイックフォーマット、論理サイズ調整ON"とする。"Volume Label"は空欄でもよい。
※MicroSDカードは16GB以上を推奨する。
※調子が悪ければ"上書きフォーマット"を試してみる。
※MicroSDカードとラズベリーパイには相性がある。詳しくは下記のサイト参照。
*http://elinux.org/RPi_SD_cards

■MicroSDカードにイメージファイルを展開する
Win32 Disk Imager 0.9.5を開く。
"Image File"は"2017-04-10-raspbian-jessie.img"を選択、"Device"でMicroSDカードが挿入されているドライブを選択したのち、"Write"を押す。

イメージファイルを展開したMicroSDカードをラズベリーパイに挿し、電源を入れる。問題なければ、Raspbian jessie with Pixelのデスクトップ画面が表示されるはずである。

■Raspbian jessie with Pixelの初期設定をする
メニューバー>Preferences>Raspberry Pi Cofigurationを開く。
"Interfaces"のタブの下、SSHがDisabeleになっているのでEnableをオンにする。以後、リブートのたびにパスワード変更を促す警告メッセージが出る。パスワードを変更するかしないかはご自身の判断で。
→SSHで接続しないのなら、当然Enableにする必要はない。後述するTera TermでラズベリーパイにアクセスするためにはSSHをオンにする必要がある。しかし、SSHをオンにしなくてもWindows標準のリモートデスクトップ接続を使ってアクセスすることができる。
"Lacarization"のタブの下、"Local"の"Language"を"ja(Japanese)"に、"Country"を"JA(Japan)"に、
"Timezone"を"Japan"に、"Keyboard"を"Japanese(PC-98xx Series)"に、
"WiFi Country"を"JP Japan"に設定。
※Timezoneを変更してもすぐに時計はアジャストされない。
※"Local"をデフォルトのままにしておくとメニューが日本語化されない。英語のメニューがお好きならここはそのまま。最低限"Keyboard"だけは"Japanese(PC-98xx Series)"に変えておいたほうがいいと思う。

■WiFiの設定をする
画面右上、メニューバーの中、Bluetoothの右の記号をクリック。
自宅のWiFiのSSIDを選んで"Pre Shared key"にパスワードを入力。
すぐにSSIDが表示されないときは、いったん"Turn off Wi-Fi"を選んだのち、再び"Turn On Wi-Fi"を選ぶと表示が正常化される。

■とりあえずアップデートする
以下の日本語IMEをはじめ、いくつかのアプリをインストールする時は事前にOSをアップデートしておいた方がいい。インストールに失敗しないためのおまじないだ。
左から4つ目のアイコン"LXTerminal"ターミナルを開いて以下を入力。
$ sudo apt update
※apt-getコマンドじゃなくてaptだけでもいいみたい。

■心配ならアップグレードもしてみる
$ sudo apt upgrade

最新のRaspbian jessie with Pixelは日本語フォントを内蔵しているので、別途日本語フォントをインストールする必要はない。しかし、日本語IMEをインストールしないと日本語の入力ができない。

■日本語IMEをインストールする
mozcをインストールする。ターミナルを開いて以下を入力。
$ sudo apt install uim uim-mozc
途中、続行しますか?[Y/n]が出たらyを押してEnter。
※"Language"が"en(English)"のままだと日本語入力できない。
再起動後にmozcが有効になる。
ちなみに再起動は
$ reboot
あるいは
$ sudo reboot
※SSHによるリモート接続からリブートを実行するときはsudoから書き始めないといけないようだ。

■ディスプレイ解像度を設定する
私のモニタはHDMI-1920 x 1080(スピーカ付き)だが、デフォルトでは画面いっぱいに表示されず黒い非表示領域が残る。そこでディスプレイ解像度を設定して表示領域をモニタにフィットさせる。
ターミナルを開いて以下を入力。
$ sudo nano /boot/config.txt
長い文字列が表示されるが、ずーっと下まで送って、最後の行に以下のコマンドを追記する。
hdmi_drive=2
hdmi_group=2 # DMT
hdmi_mode=82 # 1080p 60Hz
その後、Ctrl+O(上書き)を押す。Config.txtを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
→hdmi_drive=2でスピーカ付きHDMIモニタから音が出るようになる。
→#に続く文字はコメントなので省略可。
→hdmi_mode=82は1920x1080/60Hzディスプレイに対応した設定である。それ以外の解像度の設定については以下のページを参照。
https://www.raspberrypi.org/documentation/configuration/config-txt.md
※メニューバー>Preferences>Raspberry Pi Cofiguration>Systemタブの下に"Set Resolution"ボタンがあるが、この中に"DMT mode 82 1920x1080 60Hz 16:9"が見当たらないので、/boot/config.txtを直接編集する。

以上で汎用PCとしての体裁が整った。

2.HDDをマウントしてファイルサーバーにする

■ntfs-3gをインストール
NTFS形式のHDDをマウントするためにntfs-3gをインストールする。
ターミナルを開いて以下を入力。
$ sudo apt install ntfs-3g
そしてリブート

■HDDを接続する
今回はSeagate(3TB)HDDを用意した。これをUSBでラズベリーパイに接続する。
ターミナルを開いてdf(disk filesystem)コマンドを入力。
$ df
以下のような文字列が表示される。
ファイルシス       1K-ブロック         使用          使用可 使用% マウント位置
/dev/root            29320680  3822304     23985904  14% /
devtmpfs                469688             0         469688   0% /dev
tmpfs                     474004             0         474004   0% /dev/shm
tmpfs                     474004      12596         461408   3% /run
tmpfs                         5120             4            5116   1% /run/lock
tmpfs                     474004             0          474004  0% /sys/fs/cgroup
/dev/mmcblk0p6       64366      19974           44392 32% /boot
/dev/sda2          930134012    290184    929843828  1% /media/pi/Seagate
tmpfs                       94804            0            94804   0% /run/user/1000

Seagate HDDのデバイスネームとして/dev/sda2が与えられている。
Seagate HDDは臨時に/media/piディレクトリにマウントされている。
以上を確認。※デバイスネームはシステムが勝手に割り当てるもので状況により変わる。
$ df -h
と入力するともう少しわかりやすい単位で表示してくれる。

■新規にディレクトリ(フォルダ)を作る
ターミナルを開いて以下を入力。
$ sudo mkdir /mnt/usbhdd
mkdir(make directory)コマンドでmntフォルダの下にusbhddフォルダを作成した。

■HDDのマウント位置を変える
/media/piにマウントしたままでは以下の設定ができないのでマウント位置を変える。
ターミナルを開いて以下を入力。/dev/sda2をいったんアンマウントする。
$ sudo umount /dev/sda2
次に以下を入力。
$ sudo mount -t auto /dev/sda2 /mnt/usbhdd
これで先ほど作成した/mnt/usbhdd直下にマウントされる。

■ラズベリーパイ起動時に自動マウントされるようにする
上記の設定のままでは再起動すると設定がリセットされてしまう。再起動後も自動マウントされるようシステムファイル/etc/fstabに追記する。
ターミナルを開いて以下を入力。
$ sudo nano /etc/fstab
最後の行(# a swapfile is not swap partition,...の前)に以下を追記。
※長い空白はTabキーを入力。
/dev/sda2     /mnt/usbhdd     ntfs-3g     defaults     0     0
その後、Ctrl+O(上書き)を押す。fstabを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
※書く場所を間違えると次回の起動でつまずくので注意。

■Sambaをインストールする
ファイルサーバを作成するためのプログラム、sambaをインストールする。
ターミナルを開いて以下を入力。
$ sudo apt install samba

■Sambaの設定をする。
ターミナルを開いて以下を入力。
$ sudo nano /etc/samba/smb.conf
最後の行に以下を追加
[RaspNAS]
comment = USBHDD
path = /mnt/usbhdd
public = Yes
read only = No
writable = Yes
guest ok = Yes
force user = pi

その後、Ctrl+O(上書き)を押す。smb.confを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
※[RaspNAS]はWindowsPCで閲覧する時のサーバー名である。任意の文字を名称として設定して差し支えないが、Sambaが予約している単語は避ける。どのような単語が予約されているかはsmb.confを読めばわかる。
※comment =に続く文字はコメント文である。自分のための覚え書きなので何を書いてもよい。
$ reboot
でリブートするとSambaが起動する。
以上で、ファイルサーバ完成。

■ラズベリーパイのローカルIPアドレスを知る
ターミナルを開いて以下を入力。
 $ ifconfig
以下のような文字列が表示される。
eth0
Link encap:イーサネット ハードウェアアドレス x0:00:xx:00:00:x0
inet6アドレス: xx00::0x00:0xx0:0000:x0xx/64 範囲:リンク
UP BROADCAST MULTICAST MTU:1500 メトリック:1
RXパケット:0 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:0 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:0 (0.0 B) TXバイト:0 (0.0 B)

lo
Link encap:ローカルループバック
inetアドレス:127.0.0.1 マスク:255.0.0.0
inet6アドレス: ::1/128 範囲:ホスト
UP LOOPBACK RUNNING MTU:65536 メトリック:1
RXパケット:140 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:140 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:0
RXバイト:11712 (11.4 KiB) TXバイト:11712 (11.4 KiB)

wlan0
Link encap:イーサネット ハードウェアアドレス x0:00:xx:00:x0:x0
inetアドレス:192.168.0.5 ブロードキャスト:192.168.0.255 マスク:255.255.255.0
inet6アドレス: xx00::xx00:xxxx:xx00:x0x0/64 範囲:リンク
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:599 エラー:0 損失:490 オーバラン:0 フレーム:0
TXパケット:194 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:94274 (92.0 KiB) TXバイト:30525 (29.8 KiB)

→注目すべきはwlan0の2行目、inetアドレス:192.168.0.5 
これがWiFiのローカルIPアドレスである。
192.168.0.Xとなる数列で、末尾の1桁はルータが勝手に割り当てる。

※ラズベリーパイのローカルIPアドレスを知る別の手段。
※私のWiFiルータはバッファロー製である。バッファロー製ルータの付属ユーティリティ"エアステーション設定ツール"の管理画面トップページ、"ネットワークサービス一覧を表示"を押すと、ローカルWiFi接続機器の一覧が表示される。そこからラズベリーパイのIPアドレスを知ることもできる。
※iPhineユーザーならばFingというiPhoneアプリが利用できる。ローカルWiFiをスキャンし、接続しているデバイスとIPアドレスのリストを表示してくれる。
※ルータを再起動するとローカルIPアドレスの割り当てがリセットされる。おそらく末尾1桁の数字が変わる。

■WindowsPCからファイルサーバにアクセスする
WindowsPCでエクスプローラを開き、検索窓に"\\192.168.0.5"を入力する。末尾の1桁は環境により変わる。
ネットワーク資格情報の入力欄
ユーザー名:pi
パスワード:raspberry
でアクセス可能。

上記の方法でアクセスすると以後、PCの電源を落とすまでエクスプローラ>ネットワーク経由でもアクセス可能となる。

3.ラズベリーパイのローカルIPアドレスを知る

ターミナルを開いて以下を入力。
 $ ifconfig
以下のような文字列が表示される。
eth0 
Link encap:イーサネット ハードウェアアドレス x0:00:xx:00:00:x0
inet6アドレス: xx00::0x00:0xx0:0000:x0xx/64 範囲:リンク
UP BROADCAST MULTICAST MTU:1500 メトリック:1
RXパケット:0 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:0 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:0 (0.0 B) TXバイト:0 (0.0 B)

lo 
Link encap:ローカルループバック
inetアドレス:127.0.0.1 マスク:255.0.0.0
inet6アドレス: ::1/128 範囲:ホスト
UP LOOPBACK RUNNING MTU:65536 メトリック:1
RXパケット:140 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:140 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:0
RXバイト:11712 (11.4 KiB) TXバイト:11712 (11.4 KiB)

wlan0 
Link encap:イーサネット ハードウェアアドレス x0:00:xx:00:x0:x0
inetアドレス:192.168.0.5 ブロードキャスト:192.168.0.255 マスク:255.255.255.0
inet6アドレス: xx00::xx00:xxxx:xx00:x0x0/64 範囲:リンク
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:599 エラー:0 損失:490 オーバラン:0 フレーム:0
TXパケット:194 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:94274 (92.0 KiB) TXバイト:30525 (29.8 KiB)

→注目すべきはwlan0の2行目、inetアドレス:192.168.0.5 
これがWiFiのローカルIPアドレスである。
192.168.0.Xとなる数列で、末尾の1桁はルータが勝手に割り当てる。

■ラズベリーパイのローカルIPアドレスを知る別の手段。
私のWiFiルータはバッファロー製である。バッファロー製ルータの付属ユーティリティ"エアステーション設定ツール"の管理画面トップページ、"ネットワークサービス一覧を表示"を押すと、ローカルWiFi接続機器の一覧が表示される。そこからラズベリーパイのIPアドレスを知ることもできる。
■iPhoneユーザーならばFingというiPhoneアプリが利用できる。ローカルWiFiをスキャンし、接続しているデバイスとIPアドレスのリストを表示してくれる。
※iOS11よりMACアドレスが読めなくなったとかでFingが使いにくくなった。新規のデバイス名が不明と表示される。何らかのデバイスがIPアドレスを取得したのはわかるがデバイスの詳細はわからない。
■WindowsならAdvanced IP Scannerというフリーソフトが利用可能だ。窓の杜で入手できる。窓の杜ライブラリ>インターネット・セキュリティ>サーバー・ネットワーク>ネットワーク調査*~に分類されている。*https://forest.watch.impress.co.jp/library/nav/genre/inet/servernt_netanlz.html
ローカルネットワーク内のデバイスを検出してリスト化してくれる。

■ルータを再起動するとローカルIPアドレスの割り当てがリセットされる。おそらく末尾1桁の数字が変わる。

■WindowsPCからファイルサーバにアクセスする
WindowsPCでエクスプローラを開き、検索窓に"\\192.168.0.5"を入力する。末尾の1桁は環境により変わる。
ネットワーク資格情報の入力欄
ユーザー名:pi
パスワード:raspberry
でアクセス可能。

上記の方法でアクセスすると以後、PCの電源を落とすまでエクスプローラ>ネットワーク経由でもアクセス可能となる。

4.ラズベリーパイをリモート接続する

WindowsPC、ラズベリーパイそれぞれに別々のモニタ、キーボード、マウスを用意できればよいが、通常はリモート接続によってひとつのモニタ、キーボード、マウスを共用することになろう。

■ラズベリーパイにSSHでリモート接続する
WindowsPCにTera Termをインストールする。ラズベリーパイ側はSSHをオンにしておく。
Tera Term
https://ja.osdn.net/projects/ttssh2/

Tera Teamを起動し、"ホスト"にローカルIPアドレス"192.168.0.X"を入力。
ユーザ名:pi
パスフレーズ:raspberry
でOKを押す。
ターミナル画面が開き、コマンド入力待ち状態となる。
SSHで開くことができるのはターミナル画面のみである。しかし、この画面からすべてのことが行えるので問題ない。

■ラズベリーパイにリモートデスクトップ接続する(xrdp)
ラズベリーパイにリモートデスクトップ接続する方法は二つある。ひとつはxrdp経由で行うもの。Windows標準のリモートデスクトップ接続になる。Windowsスタート画面、Windowsアクセサリの中にある"リモートデスクトップ接続"で接続できる。後述するVNCとは同時に利用できない。
ラズベリーパイ側の準備。リモートデスクトップ接続を有効にするために以下のふたつのプログラムをインストールする。ターミナルを開いて以下を入力。
$ sudo apt install tightvncserver
$ sudo apt install xrdp
WindowsPC側でリモートデスクトップ接続を起動。
"コンピュータ(C):"にローカルIPアドレス"192.168.0.X"を入力。
USERNAME:pi
PASSWORD:raspberry
でOKを押す。

■ラズベリーパイにリモートデスクトップ接続する(REALVNC)
ラズベリーパイに標準で組み込まれているリモートデスクトップ接続サービスはREALVNC経由によるものだ。そのクライアントソフトVNC ViewerはWindows、Mac、iOS、Andoroid...様々なホストをサポートしている。VNCを利用するためにはメニューバー>Preferences>Raspberry Pi Cofiguration "Interfaces"のタブの下、VNCをオンにする。リブートするとメニューバーにVNCアイコンが現れる。このVNCアイコンをクリックするとラズベリーパイのローカルIPアドレス"192.168.0.X"が表示される。
■WindowPCにVNC Viewerをインストールする。
VNC Viewerのダウンロードページ*にアクセスしてWindouws用VNC Viewerアプリをダウンロードする。
*https://www.realvnc.com/download/viewer/
ダウンロードしたVNC-Viewer-6.0.2-Windows-64bit.exeを好きなフォルダに置いてダブルクリックする。
空白部分で右クリック""New Connection"を選ぶ。"VNC Server"にローカルIPアドレス"192.168.0.X"を記入。"Name"は”RaspberryPi"とでもしておく。"Continue"を押して、USERNAME:pi、PASSWORD:raspberry、"Remember Password"にチェックを入れておく。OKボタンで接続を始める。
※iOSもサポートしているのでiPhoneにVNC Viewerを入れておけば、iPhone からもリモートデスクトップ接続できる。

WindowsPCとファイル共有する

Sambaを使ってWindowsPCとファイル共有する

■ntfs-3gとSambaをインストールする
前述の通り
$ sudo apt install ntfs-3g
$ sudo apt install samba

■Sambaの設定をする
ターミナルを開いて以下を入力。
$ sudo nano /etc/samba/smb.conf
最後の行に以下を追加
[RaspSHARE]
comment = HomePi
path = home/pi
public = Yes
read only = No
writable = Yes
guest ok = Yes
force user = pi
directory mode = 0777
create mode = 0666

その後、Ctrl+O(上書き)を押す。smb.confを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
※[RaspSHARE]はWindowsPCで閲覧する時のサーバー名である。任意の文字を名称として設定して差し支えないが、Sambaが予約している単語は避ける。どのような単語が予約されているかはsmb.confを読めばわかる。
※comment =に続く文字はコメント文である。自分のための覚え書きなので何を書いてもよい。
※前述のファイルサーバ制作の時path =に続く文はpath = /mnt/usbhddで"mnt"の前に"/"があった。しかし今回、"home"の前に"/"はない。よくわからないがこれで確かにつながっている。

■Sambaを起動する
ターミナルを開いて以下を入力。
$ sudo service samba-ad-dc restart
または、リブート。

■WindowsPCからRaspberry Piにアクセスする
WindowsPCでエクスプローラを開き、検索窓に"\\192.168.0.X"を入力する。末尾の1桁は環境により変わる。
ネットワーク資格情報の入力欄
ユーザー名:pi
パスワード:raspberry
でアクセス可能。

■ファイルサーバとファイル共有を同時に実行する

[RaspNAS]
comment = USBHDD
path = /mnt/usbhdd
public = Yes
read only = No
writable = Yes
guest ok = Yes
force user = pi

[RaspSHARE]
comment = HomePi
path = home/pi
public = Yes
read only = No
writable = Yes
guest ok = Yes
force user = pi
directory mode = 0777
create mode = 0666

というように前述のファイルサーバの構文に続けて、ファイル共有の構文を書き足すことができる。この場合、WindowsPCから"\\192.168.0.X"にアクセスすると[RaspNAS][RaspSHARE]ふたつのフォルダが見える。

Raspberry Pi 3にポータブルSSDをつなぐ

ポータブルSSD(USB給電タイプ)をつなぐ

Sandisk製外付けポータブルSSDを入手したのでラズベリーパイにつないでみる。USB経由で給電を受けるタイプである。
■USB給電のアンペア数を上げる
ラズベリーパイ側からの出力電流は0.6Aに制限されているらしいので、これを1.2Aに引き上げる。
ターミナルを開いて以下を入力。
$ sudo nano /boot/config.txt
最後の行に以下を追加
safe_mode_gpio=4
その後、Ctrl+O(上書き)を押す。config.txtを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。

■exFAT形式のドライバをインストールする
Sandiskの外付けSSDはexFATとかいうフォーマット形式らしい。これもそのままではラズベリーパイで扱えないのでドライバをインストールする。
$ sudo apt-get install exfat-fuse
そして再起動。

ラズベリーパイに外付けSSDをつなぐと臨時に/media/piフォルダの中にマウントされる。マウントポイントを変えたい時は上記「HDDをマウントしてファイルサーバーにする」の項を参照。SSDを外す時は必ずデスクトップ画面右上のイジェクトボタンを押してマウントを解除する。安全に取り外すためのおまじない。

Raspberry Pi 3に3.5インチタッチパネルをつなぐ

1.機器を接続する

ラズベリーパイのGPIOに3.5インチLCDを挿す。挿す場所は取説などに従う。HDMI接続のLCDの場合、二股のHDMI端子が付属するが、まだLCDドライバを入手していないので、今はこれを使わない。ラズベリーパイのHDMI端子には一般のモニタをつなげておく。

2.GitHubからドライバを入手し、インストールする

ここ*に行くと最新のタッチパネルディスプレイドライバが入手できるらしい。
*https://github.com/goodtft/LCD-show
このURLを覚える必要はない。「GitHub LCD-show」くらいのキーワードでググればたどりつける。
このページを見れば丁寧にドライバの入手方法が書いてある。以下はその覚え書き。
ターミナルを開いて以下を入力。
$ sudo rm -rf LCD-show
$ git clone https://github.com/goodtft/LCD-show.git
$ chmod -R 755 LCD-show
$ cd LCD-show
$ sudo ./LCD35-show


1行目は先に古いLCD-showフォルダがあった場合、それを消すコマンド。初めてのイントールならばLCD-showフォルダは存在しないはずなので、1行目は省略可。
2行目でドライバを入手。piフォルダにLCD-showフォルダができているはずだ。
3行目でLCD-showフォルダのアクセス権変更
4行目cd(change directory)コマンドでLCD-showフォルダの中に入る。
5行目でシェルスクリプトLCD35-showの実行、自動的に再起動して、3.5インチLCDにデスクトップが表示される。もしあなたのLCDが3.5インチでなく5インチだったら、5行目はsudo ./LCD5-showとなる。詳しくは上記URLを参考にしていただきたい。

■一般のHDMIモニタに戻したい時
ターミナルを開いて以下を入力。
$ cd LCD-show
$ ./LCD-hdmi

■再び3.5インチLCDに戻したい時
ターミナルを開いて以下を入力。
$ cd LCD-show
$ ./LCD35-show

3.ドライバを直接ダウンロードし、インストールする方法

GitHubから入手した方が楽である。以下の方法はお勧めしない。
■waveshare.com-LCDの記事*にアクセス
*http://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A)
文中のリンクからLCD-show-170703.tar.gzファイルをダウンロードする。リンクをクリックするとダウンロードを開始する。

ダウンロードしたファイルは/home/pi/Downloadsフォルダに保存されているはずである。このフォルダから出して/home/piフォルダに移動する。WindowsPCと同様、右クリックで「切り取り」→「コピー」でファイルを移動できる。
※上記リンクにはLCDパネル設定手順が英文で書いてある。以下はその覚え書き。
※3.5inch_RPi_LCD_(A)と3.5inch_RPi_LCD_(B)がある。(B)を使うと表示がネガポジ反転する。

■初期設定
ターミナルを開いて以下を入力。
$ sudo raspi-config
初期設定画面が開く。
下↓カーソルキーを2回叩いて"3 Boot Options"をハイライトさせてEnter。
"B1 Desktop/CLI"をハイライトさせてEnter。
下↓カーソルキー3回たたいて"B4 Desktop Autologin"をハイライトさせてEnter。
Tabキー2回叩いて"Finish"をハイライトさせてEnter。
"Yes"をハイライトさせてEnter。自動でリブートする。

■tarファイルを解凍(tarファイルはzipのようなもので複数のフォルダ/ファイルをまとめて圧縮している)
ターミナルを開いて以下を入力。
$ tar xvf LCD*.tar.gz
/home/piフォルダの中にLCD-showフォルダが現れる。
※LCD-show-170703.tar.gzをダブルクリック、LCD-showフォルダが見えるのでこれを1回クリックで選択、アクションメニューから[展開]、次に開くダイアログボックスの設定は変えずにそのまま[展開]ボタンを押しても結果は同じ。ターミナルからコマンドを打ちたくない人はこちらの手順で。

■3.5インチタッチパネルディスプレイ用ドライバを起動
ターミナルを開いて以下を入力。
$ cd LCD-show
$ ./LCD35-show

■HDMIに戻したい時
ターミナルを開いて以下を入力。
$ cd LCD-show
$ ./LCD-hdmi

Raspberry Pi 3でAmazon Echoを作る

1.準備

Amazon EchoはAlexa(アレクサ)と呼びかけると反応する音声コントロールによる人工知能である。開発者向けのボイスサービスサンプルプログラムを使うことで、ラズベリーパイからも利用できる。

まずはラズベリーパイを使用可能な状態にするための最低限の下ごしらえをしておく。
■SDカードをフォーマットし、Rasipbian Jessie with Pixelを書き込む。
■キーボード、マウス、モニタを接続、そしてSDカードをラズベリーパイに挿し、起動する。
■WiFiを使えるようにしておく。
■"Locarization"の設定をしておく。
■OSをアップデートする。心配ならアップグレードもしておく。
■SSH経由でリモート接続するつもりなら、SSHをオンにしておく。
■WindowsPCからリモートデスクトップ接続するつもりならtightvncserverとxrdpもインストールしておく。

以上、詳細は前項に記載済みなのでそちらを参照。
さらに今回はUSBマイクと3.5mmイヤホンジャック入力のスピーカーも接続する。AlexaはUSBスピーカーに対応していない。
※HDMIモニタを接続していると音声出力が自動的にHDMIにセットされる。強制的に3.5mmイヤホンジャックに出力させるには
$ sudo raspi-config
7 Advance Optionsを>A4 Audio>1 Force 3.5mm ('headphone')jackをハイライトさせてTabキー<Ok>を選んでenter。Tabキー2回押して<Finish>選んでenter。

なお、ラズベリーパイでAlexaを利用する手順を詳細に説明するウェブページ*が既にある。私の説明はここに書かれていることとほぼ同じ内容である。
*https://github.com/alexa/alexa-avs-sample-app/wiki/Raspberry-Pi

2.Amazon Developerアカウントの登録

開発者向けのウェブサービス、Amazon Developerアカウントを取得し、ラズベリーパイで利用可能なセキュリティIDを発行してもらう。
まずはAmazon Developer Serviceのウェブページ*にアクセスする。
*https://developer.amazon.com/

言語設定から"Japanese(日本語)"も選べるが"English"のままにしておく。"Japanese(日本語)"を選択するとAlexaに関するリンクが非表示になってしまう。
上段のメニュー、Alexa>Alexa Voice Srevice>Stert Buildindのリンクをたどる。
Getting Started with the Alexa Voice Serviceのページ、"Sign up for a free Amazon developer account"のリンク*をクリック。
*https://developer.amazon.com/home.html

Sign Inのページ
■E-mail or mobile numberの欄にEメールアドレス
■初回登録時は◎I am a new costomer.に丸をつけて次へ
1.Profile Infomation-個人情報を偽りなく記入。日本の国番号は+81。
2.App Distribution Agreement-合意して次へ
3.Payments-開発したアプリで金儲けする意思があるか聞いている。両方とも◎No
※次回以降はパスワードを入力して// DEVELOPER CONSOLEポータルサイトにリンクする。

登録が完了すると// DEVELOPER CONSOLE(開発者のためのポータルサイト)にアクセスできるようになる。ここで上段ALEXA>Alexa Voice Service>Get Startedのリンクをだどる
[Register a Product Type]のメニューで"Device"を選択。

Create a new Device Typeのページ
Device Type Info
Company Nameのところにあなたの登録した名前が入っている。
Device Type IDは"my_device"とすること。他の名前では先へ進めない。
Display Nameは"My Device"
次へ

[Security Profile]ドロップダウンリストから"Create a new profile" を選択。
[General]タブ
Security Profile Nameに"Alexa Voice Service Sample App Security Profile"と記入。
Security Profile Descriptionに"Alexa Voice Service Sample App Security Profile Description"と記入。
次へ

・Security Profile ID
・Client ID
・Client Secret
が発行される。このうちClient IDとClient Secretは後々使用するのでコピーしておく。

次に、[Web Settings]タブをクリック。
[Alexa Voice Service Sample App Security Profile]のドロップダウンリストはそのまま
[Edit]をクリック。
Allowed Origins [Add Another]クリック、ブランクに"https://localhost:3000"と記入。
Allowed Return URLs[Add Another]クリック、ブランクに"https://localhost:3000/authresponse"と記入。
次へ

Devise Details
横142x縦130pixels以内のJPEG画像を登録できる。画像はリストに表示される。画像はあってもなくてもよい。
[Category]ドロップダウンリストから"Other" を選択。
Descriptionに"Alexa Voice Service sample app test"と記入。
Do you have plans to make your product available to the general public? ◎Noを選択。
次へ

Amazon Music
Apply for access to Amazon Music?◎Noを選択。
[Submit]をクリック。

Security Profileを有効にする
ここへ行く
https://developer.amazon.com/lwa/sp/overview.html

[Select a Security Profile] ドロップダウンリストから"Alexa Voice Service Sample App Security Profile" を選択。
[Confirm]をクリック。

Consent Privacy Notice URLに"http://example.com"と記入。
[Save]をクリック。

"Show Client ID and Client Secret"のリンクをクリック。
Client ID と Client Secretが表示されていることを確認する。

なお、セキュリティプロファイルを作成する手順を詳細に説明するウェブページ*が既にある。私の説明はここに書かれていることとほぼ同じ内容である。
*https://github.com/alexa/alexa-avs-sample-app/wiki/Create-Security-Profile

3.ラズベリーパイのセットアップ

■alexa-avs-sample-appをコピーする
ターミナルを開いて以下を入力。
$ cd Desktop
$ git clone https://github.com/alexa/alexa-avs-sample-app.git
デスクトップに"alexa-avs-sample-app"という名のフォルダが作成されている。このフォルダを開いて内容を確認する。Rasipbian Jessieのファイルマネージャーがファイルの存在に気づいていないことがあるので、フォルダを開いて確かにファイルがあることを確認する。

■alexa-avs-sample-appのインストールスクリプトを編集する
ターミナルを開いて以下を入力。
$ cd ~/Desktop/alexa-avs-sample-app
$ sudo nano automated_install.sh

ProductID=my_device
ClientID=amzn.xxxxx.xxxxxxxxx
ClientSecret=4e8cb14xxxxxxxxxxxxxxxxxxxxxxxxxxxxx6b4f9

Amazonから発行されたClientIDとClientSecretをそれぞれ記入する。
その後、Ctrl+O(上書き)を押す。automated_install.shを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。

■インストールスクリプトを実行する
ターミナルを開いて以下を入力。
$ cd ~/Desktop/alexa-avs-sample-app
$ . automated_install.sh
これでAlexaインストール完了。

4.Alexaの起動

3つのターミナルウィンドウを別々に開いて3つのコマンドを実行する。
■ターミナル1
以下を入力。
$ cd ~/Desktop/alexa-avs-sample-app/samples
$ cd companionService && npm start

■ターミナル2
以下を入力。
$ cd ~/Desktop/alexa-avs-sample-app/samples
$ cd javaclient && mvn exec:exec
Webブラウザを起動する旨の警告と[Yes/No]のボタンが出るので[Yes]をクリック。直後に[OK]ボタンが出るがすぐにこれを押してはいけない。
Webブラウザが起動し、Amazon Developer Serviceにログインする。
JessieではここでしばしばHTTPS警告「この接続ではプライバシーが保護されません」が出ることが確認されている。左下[詳細設定]ボタンを押してこれを回避する。
認証が通ると"device tokens ready"と表示される。ここで先ほどの[OK]ボタンを押す。
[Listen]ボタンが表示される。このボタンを押してAlexaを呼び出すことができる。

■ターミナル3
以下を入力。
$ cd ~/Desktop/alexa-avs-sample-app/samples
$ cd wakeWordAgent/src && ./wakeWordAgent -e sensory
これでWake Wordが使えるようになる。[Listen]ボタンを押さなくても"Alexa"と呼びかけるだけでポン♪という音とともにAlexaを呼び出すことができる。
"Good morning."と呼びかけてみよう。

MP3を再生する

1.VLCをインストールする

定番のメディアプレイヤー"VLC Media Player"をインストールする。
$ sudo apt install vlc
メニューバー、ラズベリーのプルダウンメニューに"Sound & Video"カテゴリが作られる。その中に"VLC Media Player"がある。
"VLC Media Player"を選んで起動する。初期画面はオレンジのパイロン。Media>Open File...のウィンドウから聴きたいmp3ファイルを選ぶ。
※デフォルトのRaspbianにmp3ファイルは存在しない。前述のファイル共有機能等を使ってあらかじめ他所からコピーしておく必要がある。/home/pi/Musicフォルダにでも置いておけばよいだろう。
※/home/pi/python_gameフォルダの中にいくつかのビープ音が収録されている。何でもいいから音を出したい時に便利。音符の形のアイコンなのですぐに見つけられるだろう。

2.Bluetoothスピーカーを接続する

音楽をBluetouthスピーカーから流してみる。Bluetouthスピーカーの電源を入れ、どこかのボタン(スピーカーの仕様によるので取説参照)を長押ししてペアリングモードにする。
ラズベリーパイのBluetouthアイコンをクリック。Add Device...のウィンドウからBluetouthデバイス名を選んで"Pair"を押す。
Bluetouthアイコンの2つ右、スピーカアイコンを右クリック。Bluetouthデバイス名を選んでチェックを入れる。これでBluetoothスピーカーから音が出るようになる。
※Bluetoothスピーカーは安定しない。時折音飛び、音切れが発生する。
※ブラウザでYouTubeを開いてミュージックビデオ等を再生しようとするとハングアップする。正直Bluetoothスピーカーは使い物にならない。

3.USBスピーカーを接続する

スピーカアイコンを右クリック。Audio Advantage MicroIIを選ぶ。Analogを選べば3.5mmイヤホンジャックから、HDMIを選べばHDMIモニタから、Bluetoothスピーカーを選べばBluetoothスピーカーから、Audio Advantage MicroIIを選べばUSBスピーカーから音が出る仕組み。

Python-Pygameを使ってみる

1.Pygameについて

Pygameはラズベリーパイにあらかじめインストールされているプログラム言語Pythonのためのモジュールである。ラズベリーのメニューの下、Gameの中にPython Gamesがあり、たくさんのゲームが収録されている。こんな立派なゲームを作ることはできないが、簡単なプログラムなら書けそうなので挑戦してみた。

2.Pygameを使ってMP3を再生する

Pythonでmp3を再生するスクリプトを書き、実行する。
まず、/home/piフォルダの中に再生したいmp3ファイルを置いておく。
ターミナルを開いて以下を入力。
$ nano musicplay.py
白紙の画面が表示されるので、下記のスクリプトを記述。
# -*- coding:utf-8 -*-

import pygame.mixer
import time

# mixerモジュールの初期化
pygame.mixer.init()
# 音楽ファイルの読み込み
pygame.mixer.music.load("ファイル名.mp3")
# 音楽再生、および再生回数の設定(-1はループ再生)
pygame.mixer.music.play(-1)
# 60秒間だけ再生
time.sleep(60)
# 再生の終了
pygame.mixer.music.stop()

その後、Ctrl+O(上書き)を押す。musicplay.pyを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
/home/piにmusicplay.pyファイルが作成されている。その隣にmp3ファイルが置かれている。
※上記スクリプトの"ファイル名.mp3"の部分には隣に置いてあるmp3ファイル名を書いておく。

ターミナルを開いて以下を入力。
$ python musicplay.py
指定した"ファイル名.mp3"が60秒間だけ再生される。
musicplayというファイル名は私が勝手につけたファイル名である。もちろんこの名前は好き勝手に変更していただいてかまわない。

3.Pygameを使ってデジタル時計を作る

Pythonでデジタル時計を表示するスクリプトを書き、実行する。
ターミナルを開いて以下を入力。
$ nano clock.py
白紙の画面が表示されるので、下記のスクリプトを記述。
# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *
import datetime
import sys

# Pygameの初期化
pygame.init()
# 大きさ300*200の画面を生成
screen = pygame.display.set_mode((300, 200))
# タイトルバーに表示する文字
pygame.display.set_caption("clock")
# フォントの設定(25px)
font = pygame.font.Font(None, 25)

# ループを作る
while True:
    # 画面を黒色に塗りつぶし
    screen.fill((0,0,0))
    # 変数clocktimeを定義、現在の年月日時分秒を代入
    clocktime = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
    # アンチエイリアスあり、文字色を白に設定
    text = font.render(clocktime, True, (255,255,255))
    # 文字列の表示位置x方向:75ドット、y方向:85ドット
    screen.blit(text, [75, 85])
    # 画面を更新
    pygame.display.update()

    # イベント待ち受け
    for event in pygame.event.get():
        # 閉じるボタンが押されたら終了
        if event.type is pygame.QUIT:
            # Pygameの終了(画面閉じられる)
            pygame.quit()
            sys.exit()


その後、Ctrl+O(上書き)を押す。clock.pyを上書きするか尋ねてくるのでEnterを押す。
Ctrl+Xを押して完了。
/home/piにclock.pyファイルが作成されている。

ターミナルを開いて以下を入力。
$ python clock.py
デジタル時計が表示される。
もう一度言うがclockというファイル名は私が勝手につけたファイル名である。好き勝手に変更してかまわない。

4.python_gamesフォルダについて

/home/piフォルダの中にpython_gamesフォルダがある。この中にはpygameで作られたゲームがスクリプトのまま収められている。例えばpython_gamesフォルダの中のflippy.py(オセロゲーム)をダブルクリックで開くとそのスクリプトを読むことができる。そしてこれを実行して実際にゲームをプレイすることができる。
ゲームをプレイするためにはまずカレントディレクトリをpython_gamesフォルダに移す。

ターミナルを開いて以下を入力。
$ cd python_games
続けてflippy.pyを実行。
$ python flippy.py
これでオセロゲームの盤面が開く。

WindowsにPython-Pygame開発環境を構築する

1.WindowsにPythonをインストールする

■Pythonの入手
Python.orgのDownloadページ*に行って最新Pythonを入手する。
*https://www.python.org/downloads/
本稿執筆時点の最新バージョンはPython3.6.1であった。上記ページのTopに最新Pythonのダウンロードを促すボタンが配置されていた。ボタンを押してリンクをたどるとインストーラにも複数の種類があることを知る。
Windows x86-64 xxxxxは64ビット用、Windows x86 xxxxxは32ビット用。私のPCはWindows10の64ビットだが、ここはあえて動作の安定している32ビット用を選ぶ。もちろんここで64ビット用を選んでもかまわない。さらにweb-based、embeddable zip fileなど様々な形態が用意されているが、ここは実行形式:Windows x86 executable installerを選ぶべきである。様々な処理を自動で行ってくれるので楽である。
■Pythonのインストール
Windows x86 executable installer.exeをダブルクリックして起動。途中□Add Python 3.6 to PATHのチェックボックスが表示されるので、チェックを入れて続行。「環境変数の編集」とか「パスを通す」とか意味不明の手続きを自動で行ってくれる。最後、Disable path length limitの記述のところがボタンになっているのでこれを押し、ファイル名に関する制限項目を解除して完了。
インストール後、Windows(C:)フォルダの中身を確認するとWinPython-64bit-3.4.4.2フォルダが見つかる。私がインストールしたのは確かにPython-32bit-3.6.1のはずなので、これは多分付録のようなものだと思う。ではPython-32bit-3.6.1の本体はどこに保存されたのか?実は隠しフォルダの中に入っている。
■IDELを試す
IDELはPythonに付属するエディタである。IDELはWindowsメニュー>最近インストールした項目の中に入っているはずである。これを起動すると確かにPython3.6.1の記述がある。プロンプトに続けて
print("Hello World")
と入力。Enterを押してHello Worldが返ってくればインストール成功だ。
FileメニューからNew Fileを選択すると新規pyファイルを作ることができる。そのまま保存すると例の隠しフォルダの中に保存してしまうので、保存先は変えた方がいいだろう。

2.WindowsにPygameをインストールする

ラズベリーパイなら最初から入っているが、Windowsの場合、Pygameも自力でインストールしなければならない。
■Pygameの入手
Pygame.orgのページ*に行って最新Pygameを入手する。
*https://www.pygame.org/
ページの中ほどにpygame 1.9.3 released — 16 Jan, 2017の記事がある。Downloads: PyPIのリンクをたどるとインストーラの一覧が表示される。これまたたくさんの種類がある。Windwows用Python-32bit-3.6.1に適合したPygameはpygame-1.9.3-cp36-cp36m-win32.whl (md5)なので、このリンクをクリックしてpygame-1.9.3-cp36-cp36m-win32.whlをダウンロードする。これはwheel形式といって残念ながら実行形式ではない。
■Pygameのインストール
pygame-1.9.3-cp36-cp36m-win32.whlファイルをC:\Users\自分の名前のフォルダに置く。エクスプローラーでたどるなら > PC > Windows(C:) > ユーザー > 自分の名前のフォルダの中だ。
よそのチュートリアルでは、この時環境変数にパスが通っているか確認せよと忠告するところもあるがその必要はない。パスは自動で通っているはずだ。
次にスタートメニューを右クリック、コマンドプロンプトを起動。管理者でない方を選ぶ。
C:\Users\自分の名前>のプロンプトが表示されているはずである。pygame-1.9.3-cp36-cp36m-win32.whlファイルが別の場所にあるならここからcd(Change Directory)コマンドで.whlファイルが置いてある場所に移動することもできる。
プロンプト(>)に続けて以下を入力。
pip install pygame-1.9.3-cp36-cp36m-win32.whl
これでインストール完了。
■Pygameを用いたプログラムを実行する
前述のclock.pyをC:\Users\自分の名前のフォルダに置く。あるいはIDELで新規pyファイルを作り、前述のスクリプトをコピーし、clock.pyのファイル名でC:\Users\自分の名前のフォルダに保存してもよい。このスクリプトをコマンドプロンプトから呼び出して実行する。
スタートメニューを右クリック、コマンドプロンプトを起動。プロンプトに続けて以下を入力。
python clock.py
これでclock.pyの画面が開く。

3.PythonスクリプトをWindows実行形式(.exeファイル)にする

Pythonスクリプトをコマンドプロンプトから実行できるが、このままではPython-PygameがインストールされたPCでしかプログラムを動かせない。EXEファイルすなわち1個のアプリケーションとして配布でき誰でも実行できるプログラムとしたい。その方法を紹介する。
■cx_Freezeの入手
Pythonスクリプトを実行形式にするアプリはいくつかあるがここではcx_Freezeを使う。
Anthony Tuiningaさんのページ*に行って最新のcx_Freezeを入手する。
*https://github.com/anthony-tuininga
download directly from PyPIのリンクが見つかるだろうか。ここからpython.orgのcx_Freeze保存場所にたどり着くことができる。cx_Freeze-5.0.2-cp36-cp36m-win32.whl (md5)のリンクをクリックしてcx_Freeze-5.0.2-cp36-cp36m-win32.whlをダウンロードする。これはWindwows用Python-32bit-3.6.1に適合したバージョンとなる。
■cx_Freezeのインストール
cx_Freeze-5.0.2-cp36-cp36m-win32.whlファイルをC:\Users\自分の名前のフォルダに置く。
次にコマンドプロンプトを起動。プロンプトに続けて以下を入力。
pip install cx_Freeze-5.0.2-cp36-cp36m-win32.whl
これでインストール完了。
■cx_Freezeの使い方
まずsetup.pyというファイル名のpyファイルを作成、cx_Freezeはこのファイルの中でモジュールとして呼ばれる。さらにこの中にビルドすなわち実行形式に変換するための手順を記述。このpyファイルにbuildという引数を与えて実行すると、exeファイルが組み立てられる仕組み。わかりにくい。
さきほどのclock.pyを例にとって説明する。最終的にclock.pyがclock.exeという名の時計アプリに変換(コンパイル)される。
■setup.pyの記述
IDELで新規pyファイルを作成し、以下を記述。
# coding: utf-8

import sys
from cx_Freeze import setup, Executable

includes = ["pygame", "datetime"]

base = None

if sys.platform == "win32":
   base = "Win32GUI"

exe = Executable(script = 'clock.py', base = base)

setup(name = 'sample',
   version = '0.1',
   description = 'converter',
   executables = [exe])

以上。
4行目includes = ["", "", "", "" ....]で呼び出されるのはclocl.pyに使用したモジュール。clock.pyはPygameとDatetime、sysの3つのモジュールを使用している。使用したモジュールはすべてここに書き出す。ただしsysモジュールとかosモジュールとかは記述不要。
8行目exe = Executable(script = 'clock.py',の行で変換したいpyファイルを記述。
10行目setup(name = 'sample',で名前がsampleのままでいいのか不安になるが、これはこのままでも影響ない。
なお、このsetup.pyの記述はGUIを含むアプリ用である。例えばprint("Hello World")のようなGUIのないアプリの場合、また記述の仕方が少し異なってくるらしい。
■setup.pyの実行
setup.py、clock.pyともにC:\Users\自分の名前のフォルダに置いておく。
次にコマンドプロンプトを起動。プロンプトに続けて以下を入力。
python setup.py build
成功すればbuildフォルダができあがる。中にclock.exeと大量の参照ファイルが入っている。この参照ファイルが20MBもある。import pygameというようにざっくりpygameをimportするとpygameのフル機能に対応する参照ファイルが呼び出されるみたいである。
■.exeファイルの配布
大量の参照ファイルを含むbuildフォルダとなってしまったが、clock.exeだけを取り出してダブルクリックしても起動しない。参照ファイルといっしょに配布しなければならない。(全部必要ではないと思うが)これで、pythonを持っていない友人に自作のアプリケーションソフトとして配布することが可能になるが、ひとつ問題点がある。
自作の.exeファイルは他人のPCの下では発行元不明の怪しい実行ファイルとみなされWindowsのセキュリティ機能SmartScreenが発動する。起動しようとすると実行が阻止され「WindowsによってPCが保護されました」画面が表示される。もちろんこれを無視して実行することは可能だが、心臓に悪い。
これを回避するためには専門の機関に連絡して健全な発行元であることを証明するデジタル署名を発行してもらわなければならない。その話はまたPythonとはずいぶん離れた話なので割愛する。

4.アイコンを追加する

上記の手順で.exeファイルを作成できるが、完成した.exeファイルにアイコンがない。アイコンを追加する手続きを紹介する。
■PNGファイルを作る
32x32pixelのPNGファイルを作成する。Windows標準-大アイコンは128x128pixelだが、Python で扱えるのは32x32pixelのみである。
■icoファイルに変換する
PNGファイルをicoファイルに変換してくれるWebサービスがいくつかある。ここではアイコンコンバータ*を紹介する。
*http://app.tree-web.net/icon_converter/
JEPG/PNG/GIFファイルをico形式に変換してくれる。ここではとりあえずicon.icoというファイル名で保存し、clock.pyと同じフォルダに置いておく。
■setup.pyの記述
setup.pyを以下のように記述する。icon='icon.ico'が追記されている。
# coding: utf-8

import sys
from cx_Freeze import setup, Executable

includes = ["pygame", "datetime"]

base = None

if sys.platform == "win32":
   base = "Win32GUI"

exe = Executable(script = 'clock.py', base = base, icon='icon.ico')

setup(name = 'sample',
   version = '0.1',
   description = 'converter',
   executables = [exe])

以上。
これでpython setup.py buildを実行すればclock.exeにアイコンが付与される。

Python-Pygameで漢字を扱う

1.Raspbianで使える日本語フォントを調べる

Pythonで漢字を扱う練習のため、漢字を表示する簡単なアプリを制作してみようと思う。漢字を扱う上で気を付けなければいけないことは以下の2つ。
・日本語のフォントを使用する
・日本語の前にはuの字をつけてunicodeであることを宣言する(Raspbianの場合)

そこでRaspbianにプレインストールされている日本語フォントにどんなものがあるか調べてみる。
ターミナルを開いて以下を入力。
$ python
Pythonが起動し、対話モードになる。プロンプトに続けて以下を入力。
import pygame
pygame.font.get_fonts()
インストール済み使用可能なフォントの一覧を表示する。今回はdroidsansjapaneseを使ってみる。Andoroid端末用日本語フォントらしい。

2.新規フォントのインストール

好きなフォントをインストールすることもできる。
メニューバー>Preferences>Add/Remove Softwareを開く。Fontの項目をクリックするとインストール済み/未インストールフォントの一覧を表示する。ここから梅フォント、東風フォントといった有名フリーフォントを追加できる。
もちろんapt-get install...と手入力で好きなフォントパッケージをインストールすることもできる。

3.くじびきアプリを作る

漢字利用の例としてくじびきアプリを作ってみる。起動後、画面をクリックするとルーレットがスタートし、1都9県の県名がループする。もう一度クリックすると停止するというシンプルなアプリ。会社などで会議の書記担当をくじ引きで決めるケースもあるだろうと思う。県名のところを人名に書き換えれば、人名ルーレットができあがる。ループの項目の数は増減しても問題ない。
なお、Pythonを覚え始めて半年の初心者が作るプログラムである。プログラムとして不備不適当な箇所があることは承知の上である。とはいえこのレベルのプログラムなら初心者でもサッと書けるところがPythonの魅力だ。

新規.pyファイルを作って以下を入力。(コメントごとコピペしても多分大丈夫。)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import *
import time
import sys
# Pygameの初期化
pygame.init()
# 大きさ300*200の画面を生成
screen = pygame.display.set_mode((300,200))
# タイトルバーに表示する文字
pygame.display.set_caption('くじびき')
# loopリストを定義、日本語の前にはuをつけてunicodeであることを宣言
loop=[u'茨城',u'栃木',u'群馬',u'埼玉',u'千葉',u'東京',u'神奈川',u'山梨',u'長野',u'新潟']

# 関数main()を定義
def main():
    # 変数nに初期値0を代入
    n = 0
    # 変数xに初期値-1を代入
    x = -1
    # while構文の開始、PygameGUIは必ずwhile構文の形をとる
    while True:
        # 画面色にR,G,B=255,255,255(白)を設定
        screen.fill((255,255,255))
        # fontの定義、プレインストールの日本語フォントdroidsansfallbackを設定、大きさは50pix
        font = pygame.font.SysFont('droidsansfallback',50)
        # loopリストの[n]番目を呼び出してtextオブジェクトを生成、文字色はR,G,B=0,0,0(黒)
        text = font.render(loop[n], True, (0,0,0))
        # text.get_rect()でtextを内包する矩形を取得、変数textrectに代入
        textrect = text.get_rect()
        # textrect(textを内包する矩形)を画面中央にセンタリング
        textrect.center = (300/2),(200/2)
        # 以上はtextの定義、blit()を実行してtextを画面に配置、そして描画
        screen.blit(text, textrect)
        # for構文の開始、イベント待ち受け
        for event in pygame.event.get():
            # 閉じるボタンが押されたら終了、今回はQキー押下でも終了
            if event.type == pygame.QUIT or (event.type == KEYDOWN and event.key == K_q):
                # Pygameの終了
                pygame.quit()
                sys.exit()
            # もしマウスボタンが押されたら変数x(初期値:-1)に-1を乗じる
            if event.type == pygame.MOUSEBUTTONDOWN:
                # 変数xに-1を乗じるたびxの値は+1⇔-1と入れ替わる、これをトグルボタンに利用する
                x = x*-1
        # もしxが+1すなわちx>0の時
        if x>0:
            # nに1を足してインクリメント、loopリストの[n]番目の値が繰り上がる
            n = n+1
            # len(loop)でloopリストの個数を数える、今回の例ではlen(loop)=10になる
            if n >= len(loop):
                # nの値が10に達したら次の値は11でなく0にする、これでループがぐるぐる回る
                n = 0
        # 途中でマウスボタンが押されるとxの値は-1すなわちx<0になる
        if x<0:
            # インクリメントを停止する、ルーレットが止まる
            n = n
        # 画面の再描画、while構文で始めてpygame.display.update()で結ぶのがPygameGUIの基本
        pygame.display.update()
        # ルーレットの速度の調整、毎秒20歯に設定
        pygame.time.Clock().tick(20)

# ここまでの行は関数main()の定義、最後の行で関数main()を実行
main()

以上。

4.Windowsにくじびきアプリを移植する

移植というのは大げさだが、このプログラムをWindows用アプリとしてコンパイルすることは簡単だ。ただしWindowsにはdroidsansjapaneseフォントがないのでフォントだけ差し替えなければならない。
そこでWindowsにインストールされている日本語フォントにどんなものがあるか調べてみる。
コマンドプロンプトを開いて以下を入力。
python
Pythonが起動し、対話モードになる。プロンプトに続けて以下を入力。
import pygame
pygame.font.get_fonts()
インストール済み使用可能なフォントの一覧を表示する。今回はmeiryomeiryomeiryouimeiryouiitalicを使うことにする。いわゆるメイリオフォントだ。
上記スクリプトの17行目
font = pygame.font.SysFont('droidsansjapanese',50)
これを以下の文章に差し替える。
font = pygame.font.SysFont('meiryomeiryomeiryouimeiryouiitalic',50)
これでWindows上でも漢字で表示される。なお、漢字の前に追記していたuの字はWindows環境の場合、あってもなくてもどっちでもいい。
一応、差し替え後のスクリプト全文を掲載する。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import *
import time
import sys
pygame.init()
screen = pygame.display.set_mode((300,200))
pygame.display.set_caption('くじびき')
clock = pygame.time.Clock()
loop=['茨城','栃木','群馬','埼玉','千葉','東京','神奈川','山梨','長野','新潟']

def main():
    n = 0
    x = -1
    while True:
        screen.fill((255,255,255))
        font = pygame.font.SysFont('meiryomeiryomeiryouimeiryouiitalic',50)
        text = font.render(loop[n], True, (0,0,0))
        textrect = text.get_rect()
        textrect.center = (300/2),(200/2)
        screen.blit(text, textrect)
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == KEYDOWN and event.key == K_q):
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                x = x*-1
        if x>0:
            n = n+1
            if n >= len(loop):
                n = 0
        if x<0:
            n = n
        pygame.display.update()
        clock.tick(20)

main()

以上。
前述の手続きに従ってビルドすればWindows用,exeファイルに変換される。

5.外部ファイルにリストを置く

上記のプログラムだと、人名/県名を入れ替えるたびにスクリプトから書き直さなければならない。たいしたプログラムではないが、外部のテキストファイルにリストを記述し、それを利用するパターンで書き直してみた。
まず「名前リスト.txt」というテキストファイルを用意し、
茨城,栃木,群馬,埼玉,千葉,東京,神奈川,山梨,長野,新潟
というようにカンマ区切りでルーレットの項目を記述する。
その上でスクリプトを以下のように修正。Windowsは2バイト文字に対する制限がゆるゆるなのでファイル名にも普通に漢字ひらがなが使える。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import *
import time
import sys
import os
pygame.init()
screen = pygame.display.set_mode((300,200))
pygame.display.set_caption('くじびき')
clock = pygame.time.Clock()

# 名前リスト.txtを開いて中身を変数namesに転記
names = open('名前リスト.txt','r')
# for構文でnamesの項目をひとつひとつ読み出す
for name in names:
    # カンマ区切りで分割してloopリストに取り込む。
    loop = name.split(',')

def main():
    n = 0
    x = -1
    while True:
        screen.fill((255,255,255))
        font = pygame.font.SysFont('meiryomeiryomeiryouimeiryouiitalic',50)
        text = font.render(loop[n], True, (0,0,0))
        textrect = text.get_rect()
        textrect.center = (300/2),(200/2)
        screen.blit(text, textrect)
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == KEYDOWN and event.key == K_q):
                names.close()
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                x = x*-1
        if x>0:
            n = n+1
            if n >= len(loop):
                n = 0
        if x<0:
            n = n
        pygame.display.update()
        clock.tick(20)

main()

以上。
前述の手続きに従ってビルドすればWindows用,exeファイルに変換される。完成した.exeファイルの隣に名前リスト.txtを置くのを忘れずに。

Tkinterを使ってみる

1.Tkinterを使ってデジタル時計を作る

以前Pygameを使ってデジタル時計を作った。しかし実際に動かしてみると発熱が大きい。PygameモジュールはCPUへの負荷が大きいらしくCPU占有率もすぐに80%を超える。やはりPygameはゲーム用モジュールなのか。そこで動作の軽そうなもうひとつのGUI用モジュール、Tkinterを使ってデジタル時計を作り直してみた。以下にサンプルスクリプトを掲載する。素人が書くスクリプトである。おそらく冗長でお手本としては不適切だと思う。

新規pyファイルを作り、以下を記述する。
# -*- coding:utf-8 -*-

#Tkinterとdatetimeをインポートする
import Tkinter
import datetime

#メイン画面rootを生成、フォントサイズを12ポイントに設定
root = Tkinter.Tk()
root.option_add('*font','12')

#ラベルを生成、textに現在の年月日時分秒を代入、pack()で画面に配置
label = Tkinter.Label(text=datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
label.pack()

#関数timecount()を定義
def timecount():
    #Tkinterは勝手に画面を更新してくれないのでroot.after()で強制的に画面更新
    root.after(1000,timecount)
    #1000ミリ秒(1秒)ごとにtextの中の年月日時分秒を書き換え
    label.configure(text=datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'))

#関数timecount()を実行
timecount()
#root = Tkinter.Tk()で始めてroot.mainloop()で結ぶのがTkinterGUIの基本
root.mainloop()
exit()

pyファイルに名前をつけて保存する。tkclock.pyとでもしておこうか。

2.TkinterとPygameを使って音楽再生アプリを作る

mp3ファイルを再生するためにはPygame.mixerを使わなければならない。以前Pygameを使ってmp3ファイルを再生したが、今回はそのGUIをTkinterで作る。PlayボタンとStopボタンを備えたGUIとする。
新規pyファイルを作り、以下を記述する。
# -*- coding:utf-8 -*-

#TkinterとPygame.mixerをインポートする
import Tkinter
import pygame.mixer

root = Tkinter.Tk()
root.option_add('*font','12')

#関数play()を定義
def play():
    #mixerモジュールの初期化
    pygame.mixer.init()
    #音楽ファイルの読み込み
    pygame.mixer.music.load("ファイル名.mp3")
    #音楽再生
    pygame.mixer.music.play(1)

#関数stop()を定義
def stop():
    #再生の終了
    pygame.mixer.music.stop()

#Playボタンを生成、コマンドに関数playを割り当て、pack()で画面配置
button = Tkinter.Button(text='Play',command=play)
button.pack()
#Stopボタンを生成、コマンドに関数stopを割り当て、pack()で画面配置
button = Tkinter.Button(text='Stop',command=stop)
button.pack()

root.mainloop()
exit()

pyファイルに名前をつけて保存する。playmp3.pyとでもしておこうか。
playmp3.pyと同じ場所にmp3ファイルも置いておく。
$ python playmp3.py
で起動すると、PlayボタンとStopボタンだけの画面が現れる。Playボタンを押せば音楽を再生し、Stopボタンを押せば音楽を終了する。

3.上記ふたつのスクリプトを合体させて目覚まし時計を作る 

新規pyファイルを作り、以下を記述する。
# -*- coding:utf-8 -*-

#TkinterとdatetimeとPygame.mixerをインポートする
import tkinter
import datetime
import pygame.mixer

#メイン画面rootを生成、フォントサイズを12ポイントに設定
root = tkinter.Tk()
root.option_add('*font','12')

#関数play()を定義
def play():
    #mixerモジュールの初期化
    pygame.mixer.init()
    #音楽ファイルの読み込み
    pygame.mixer.music.load("ファイル名.mp3")
    #音楽再生
    pygame.mixer.music.play(1)

#関数stop()を定義
def stop():
    #再生の終了
    pygame.mixer.music.stop()

#ラベルを生成、textに現在の年月日時分秒を代入、pack()で画面に配置
label = tkinter.Label(text=datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
label.pack()
#Playボタンを生成、コマンドに関数playを割り当て、pack()で画面配置
button = tkinter.Button(text='Play',command=play)
button.pack()
#Stopボタンを生成、コマンドに関数stopを割り当て、pack()で画面配置
button = tkinter.Button(text='Stop',command=stop)
button.pack()

#関数timecount()を定義
def timecount():
    #Tkinterは勝手に画面を更新してくれないのでroot.after()で強制的に画面更新
    root.after(1000,timecount)
    #1000ミリ秒(1秒)ごとにtextの中の年月日時分秒を書き換え
    label.configure(text=datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
    #if構文、もし現在時刻が06時00分00秒なら関数play()を実行して音楽再生
    if datetime.datetime.now().strftime('%H%M%S') == '060000':
        play()

#関数timecount()を実行
timecount()
#root = tkinter.Tk()で始めてroot.mainloop()で結ぶのがTkinterGUIの基本
root.mainloop()
exit()

pyファイルに名前をつけて保存する。今回はmezamashi.pyとする。
if構文に続く'060000'=06時00分00秒の値を書き換えれば目覚まし時刻のセットができる。時刻セットのためにはスクリプトから書き直さなければならないが、まあ最初はこんなもんから。
今回はPython3の記法に従って記述してみた。すなわちTkinterでなくtkinterと小文字で書き出してみた。ラズベリーパイでこれを実行する際は
$ python3 mezamashi.py
と、あえてpython3であることを指定しないとうまく動かない。さきほど、WindowsPCにはPython3.6.1をインストールした。なのでWindowsPC上ではPython3に従った記法でないとうまく動かない。しかし、WindowsPCで上記pyファイルを実行する時は、コマンドプロンプトに
python mezamashi.py
と打ち込む。"3"はいらない。

pyaudioを使ってみる

1.pyaudioをインストールする

ターミナルを開いて
sudo apt install python-pyaudio
と入力。

2.録音アプリを作る

新規pyファイルを作成し、以下を記述。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyaudio
import wave
import Tkinter

CHUNK = 512
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 10
WAVE_OUTPUT_FILENAME = "output.wav"

root = Tkinter.Tk()
root.option_add('*font','12')

p = pyaudio.PyAudio()

def record():
    stream = p.open(format=FORMAT,
                                channels=CHANNELS,
                                rate=RATE,
                                input=True,
                                frames_per_buffer=CHUNK)

    print("* recording")

    frames = []

    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
         data = stream.read(CHUNK)
         frames.append(data)

    print("* done recording")

    stream.stop_stream()
    stream.close()
    p.terminate()

    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

button = Tkinter.Button(text='Record',command=record)
button.pack()

root.mainloop()
exit()

pyファイルに名前をつけて保存する。record.pyとでもしておこうか。
$ python record.py
で起動すると"Record"と書かれたボタンが現れる。これを押すと10秒間マイクの音を録音する。録音された音は"output.wav"という音声ファイルとして書き出される。
RECORD_SECONDS = 10の値を書き換えることで録音時間を変更できる。
自分で書いたように語るがpyaudio公式Webページ*のコードサンプルを改造しTkinterでボタンをくっつけただけである。
*https://people.csail.mit.edu/hubert/pyaudio/

TkinterでJPEG画像を表示する

1.Python Imaging Library(PIL)をインストールする

TkinterにはGIF画像を表示する機能がある。しかし、そのままではJPEG画像を扱えない。TkinterでJPEG画像を表示できるようにするためPython Imaging Library(PIL)をインストールする。
ターミナルを開いて以下を入力。
$ sudo apt install python-imaging-tk
※新たなプログラムをインストールする時はその直前にsudo apt updateでアップデートをしておくクセをつけておいた方がよい。
これでImageTk.PhotoImageコマンドが使えるようになった。

2.JPEG画像を表示するスクリプトを書く

新規pyファイルを作成し、以下を記述。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import Tkinter
from PIL import ImageTk, Image

#開始の決まり文句
root = Tkinter.Tk()

#画像をロード、インスタンス化して変数imgに代入
image = Image.open("yourfile.jpg")
img = ImageTk.PhotoImage(image)

#imgをラベルに添付、pack()で画面に配置
label = Tkinter.Label(root, image = img)
label.pack()

#結びの決まり文句
root.mainloop()

以上。
yourfile.jpgはもちろんあなたのjpg画像のファイル名に書き換える。

3.画面サイズを指定し、その中央にJPEG画像を置く

画面サイズを指定し、その中央にJPEG画像を配置するパターンで書いてみた。root.geometry("600x400")で画面サイズを600x400にしている。さらにタイトルも記入する。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import Tkinter
from PIL import ImageTk, Image

root = Tkinter.Tk()
root.title("Image")
root.geometry("600x400")

image = Image.open("yourfile.jpg")
img = ImageTk.PhotoImage(image)
label = Tkinter.Label(root, image = img)
label.pack(side = "bottom", fill = "both", expand = "yes")

root.mainloop()

以上。

4.画面枠いっぱいに広げる

画面枠いっぱいに背景を広げ、その中央にJPEG画像を配置するパターンで書いてみた。PowerPointのスライドショーのようにタイトルバーも消してしまう。タイトルバーが消えてしまうと[閉じる]ボタンも消えてしまうため、プログラムを終了できない。終了するためにはラズベリーパイの電源を抜くより方法がなくなる。それではまずいので、[Exit](終了)ボタンをつける。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import Tkinter
from PIL import ImageTk, Image

root = Tkinter.Tk()
sw, sh = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("{0}x{1}+0+0".format(sw,sh))

image = Image.open("yourfile.jpg")
img = ImageTk.PhotoImage(image)
label = Tkinter.Label(root, image = img)
label.pack(side = "bottom", fill = "both", expand = "yes")

button = Tkinter.Button(text='Exit',command=root.destroy)
button.place(x=0,y=0)

root.mainloop()

以上。
※button.place(x=0,y=0)で[Exit]ボタンを左上角に配置している。(x=0,y=0)の値を書き換えれば好きな位置に再配置できる。

5.WindowsにPython Imaging Library(PIL)をインストールする

ここ*にアクセスすると非公式ながらWindows用PIL(Python3系)がダウンロードできるらしい。
*http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil
Pillowなどという名前で呼ばれている。Python3.6(32ビット)用Pillow(PIL)はPillow‑4.2.1‑cp36‑cp36m‑win32.whlである。自分の環境にあった.whlファイルをダウンロードし、インストールする。.whlファイルのインストールの仕方は前述、Pygameの項参照。

6.Windows上でスクリプトを実行する

Windowsで上記スクリプトを記述、実行するにあたって、ひとつ注意点がある。私のWindowsの中のPythonはPython3なのでPython3系の記法に書き換えなければならない。要するにTkinterはtkinterと小文字に書き換えなければならない。

Tkinter.Canvasを使ってみる

1.Tkinter.Canvasを使って、画像をマウスドラッグで動かす

Tkinter.CanvasはGUI画面上に円、三角、四角を描くためのキャンバスとなる画面要素(ウィジェット)の一種だ。Tkinter.Canvasの中で使えるコマンド(メソッド)は実に多種で全部説明できないし、まったく理解できない。詳しくはここ*を見るといいだろう。
*http://effbot.org/tkinterbook/canvas.htm
私はJPEG画像またはPNG画像をアイコンに見立て、そのアイコンをマウスクリックすると何らかの反応を得られたリ、そのアイコン自体をマウスドラッグで移動できたり、というような一般的なGUIのデモ画面を構築したいだけだ。そのためには.Tkinter.Canvasと前述のPython Imaging Library(PIL)の力を借りる必要があった。

2.画像をマウスドラッグで動かすスクリプトを書く

新規pyファイルを作成し、以下を記述。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import Tkinter
from PIL import ImageTk, Image

#400x300のキャンバスを生成
root = Tkinter.Tk()
canvas = Tkinter.Canvas(width=400, height=300)
canvas.pack(fill="both", expand=True)

#3つの変数を初期化
item_ID=None
current_x=0
current_y=0

#たい焼きの画像(アイコン)をロード、キャンバスに配置
image1 = Image.open("taiyaki.png")
img1 = ImageTk.PhotoImage(image1)
canvas.create_image(100,150, image=img1, tags="icon")

#桜餅の画像(アイコン)をロード、キャンバスに配置
image2 = Image.open("sakuramochi.png")
img2 = ImageTk.PhotoImage(image2)
canvas.create_image(300, 150, image=img2, tags="icon")

#アイコンをマウスプレスした時の処理、アイコンのIDを取得、マウスの現在位置座標取得
def on_icon_press(event):
    global item_ID
    global current_x
    global current_y
    item_ID = canvas.find_closest(event.x, event.y)[0]
    current_x = event.x
    current_y = event.y

#アイコンを離した時の処理、3つの変数を初期化
def on_icon_release(event):
    global item_ID
    global current_x
    global current_y
    item_ID = None
    current_x = 0
    current_y = 0

#マウスドラッグした時の処理、マウスの移動量とアイコンの位置座標を同期
def on_icon_motion(event):
    global item_ID
    global current_x
    global current_y
    delta_x = event.x - current_x
    delta_y = event.y - current_y
    canvas.move(item_ID, delta_x, delta_y)
    current_x = event.x
    current_y = event.y

#3種類のイベントと3種類の関数をバインド(関連付け)
canvas.tag_bind("icon", "<ButtonPress-1>", on_icon_press)
canvas.tag_bind("icon", "<ButtonRelease-1>", on_icon_release)
canvas.tag_bind("icon", "<B1-Motion>", on_icon_motion)

#結びの決まり文句
root.mainloop()

以上。
アイコン画像に見立てたのは「いらすとや」から引用したたい焼きと桜餅のPNG画像。PILをインポートすればJPEG画像のほかにPNG画像も利用可能だ。PNG画像ならば透明色を設定でき、背景を透過させられる。
canvas.create_image(...の次に来るのは画像の座標だが、画像の中央点の位置を指定する。左上ではない。
さて、とりあえずスクリプトは書けたが、item_ID、current_x、current_yの3つの変数を3回グローバル変数として宣言するのはいかにもやぼったい。そこでもっとスマートな記述をしている他人のスクリプトをまねてみた。

3.画像をマウスドラッグで動かすスクリプトを書く(その2)

上記スクリプトを以下の通り修正。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import Tkinter
from PIL import ImageTk, Image

root = Tkinter.Tk()
canvas = Tkinter.Canvas(width=400, height=300)
canvas.pack(fill="both", expand=True)

image1 = Image.open("taiyaki.png")
img1 = ImageTk.PhotoImage(image1)
canvas.create_image(100, 150, image=img1, tags="icon")

image2 = Image.open("sakuramochi.png")
img2 = ImageTk.PhotoImage(image2)
canvas.create_image(300, 150, image=img2, tags="icon")

def on_icon_press(event):
    current["item_ID"] = canvas.find_closest(event.x, event.y)[0]
    current["x"] = event.x
    current["y"] = event.y

def on_icon_release(event):
    current["item_ID"] = None
    current["x"] = 0
    current["y"] = 0

def on_icon_motion(event):
    delta_x = event.x - current["x"]
    delta_y = event.y - current["y"]
    canvas.move(current["item_ID"], delta_x, delta_y)
    current["x"] = event.x
    current["y"] = event.y

current = {"x": 0, "y": 0, "item_ID": None}

canvas.tag_bind("icon", "<ButtonPress-1>", on_icon_press)
canvas.tag_bind("icon", "<ButtonRelease-1>", on_icon_release)
canvas.tag_bind("icon", "<B1-Motion>", on_icon_motion)

root.mainloop()

以上。
3つの変数をディクショナリにまとめた。こういう使い方ができるのか。

Orange Pi ZeroをWiFiに接続する

ラズベリーパイゼロがいつまでたっても買えないので勢いでオレンジパイゼロを買ってみた。同じようなもんだろと思ったが全然違った。私と同様興味本位でうっかり買ってしまった人のためにオレンジパイゼロを起動するまでの顛末を記述する。
なお、私が買ったのはOrange Pi Zero 512MBメモリモデルだ。オレンジパイゼロにはたくさんの種類があり、Orange Pi Zero 2+ H5とか拡張ボード付きタイプとか色々あるが、私が買ったのは無印のオレンジパイゼロだ。

1.Armbianをインストールする

オレンジパイゼロではUbuntuやAndroidが扱えると公式マニュアルには書いてあるがそれは幻想ではなかろうか。事実上使えるのはArmbianというOSだけだ。これはGUIがない。初心者には敷居が高い。
■用意するもの
・圧縮解凍ソフト7-ZIP
窓の杜*で入手できる。「圧縮・解凍」ライブラリのトップで紹介されている。圧縮・解凍を行うフリーソフト。オレンジパイゼロ用OS「Armbian」が7-ZIPで圧縮されているため、解凍にはこのソフトが必須となる。
*https://forest.watch.impress.co.jp/library/nav/genre/arc/archive_archiver.html
・SSH接続ソフトTera Term
https://ja.osdn.net/projects/ttssh2/

■Armbianを入手する
ここ*に行ってオレンジパイゼロ用Armbianのイメージファイルを入手する。
*https://www.armbian.com/orange-pi-zero/
Ubuntu server - legacy kanelのボタンをクリック。7zファイルのダウンロードが始まる。完了までに10分ほど時間がかかる。2017年10月29日時点、"Armbian_5.30_Orangepizero_Ubuntu_xenial_default_3.4.113.7z"というファイルが入手できる。Armbianはバージョンによって振る舞いが違うので注意されたい。
7-ZIPがインストールされていれば、圧縮ファイルを右クリックした時7-Zipのサブメニューが表示されるはずだ。7-Zipのサブメニューから「ここに展開」を選ぶ。同じフォルダに7zファイルが解凍され複数のファイルが展開されるが、必要なのは"Armbian_5.30_Orangepizero_Ubuntu_xenial_default_3.4.113"ディスクイメージファイルだけだ。
このディスクイメージファイルをWin32 Disk Imager 0.9.5を使ってMicroSDカードに展開する。私は16GBのMicroSDカードしか持っていないので16GBのカードを使用したが4GB以上なら大丈夫な気がする。(確認はしていない)
Armbianのディスクイメージを展開したMicroSDカードをオレンジパイゼロに挿す。さらに有線LANコネクタを接続、そして電源ON。1分ほどするとArmbianの初期動作が完了し、SSHで接続可能となる。
ここで問題。どうやってオレンジパイゼロのIPアドレスを知ることができようか。そこで前述の「ラズベリーパイのローカルIPアドレスを知る」の項を参照。2通りの手段がある。
・バッファロー製ルータを使用している場合。付属ユーティリティ"エアステーション設定ツール"の管理画面トップページ、"ネットワークサービス一覧を表示"を開くとLAN内のデバイス一覧を表示する。ここから新規に追加されたデバイスを探る。
・Windouwsの場合、Advanced IP Scannerというフリーソフトが利用可能だ。LANに接続するデバイスを検出し一覧表示する。ここから新規に追加されたデバイスを探る。

■SSH接続ソフト"Tera Term"を使う
Tera Teamを起動し、"ホスト"にローカルIPアドレス"192.168.0.X"を入力。
ユーザ名:root
パスフレーズ:1234
でOKを押す。
※バッファロー製ルータを使用の場合、IPアドレスは192.168.0.Xという数列になる。

以下のような起動画面が表示される。

You are required to change your password immediately (root enforced)
___ ____ _ _____
/ _ \ _ __ __ _ _ __ __ _ ___ | _ \(_) |__ /___ _ __ ___
| | | | '__/ _` | '_ \ / _` |/ _ \ | |_) | | / // _ \ '__/ _ \
| |_| | | | (_| | | | | (_| | __/ | __/| | / /| __/ | | (_) |
\___/|_| \__,_|_| |_|\__, |\___| |_| |_| /____\___|_| \___/
|___/崩れているが本当はASCII文字でOrangePiZeroと書かれている

Welcome to ARMBIAN 5.30 stable Ubuntu 16.04.2 LTS 3.4.113-sun8i
System load: 0.25 0.32 0.16 Up time: 5 min
Memory usage: 6 % of 494MB IP: 192.168.0.X
CPU temp: 47°C
Usage of /: 9% of 15G

[ General system configuration: armbian-config ]
Changing password for root.
(current) UNIX password:
現在のパスワード"1234"を入力してEnterを押す。カーソルは動かない
Enter new UNIX password:
新しいパスワードを入力。私は"orangepi"とした。Enterを押す。カーソルは動かない。
Retype new UNIX password:
もう一度新しいパスワードを入力。Enterを押す。カーソルは動かない。


Thank you for choosing Armbian! Support: www.armbian.com

Creating a new user account. Press <Ctrl-C> to abort

Please provide a username (eg. your forename): orangepi
新しいユーザーネームを入力。私は"orangepi"とした。Enterを押す。
Trying to add user orangepi
Adding user `orangepi' ...
Adding new group `orangepi' (1000) ...
Adding new user `orangepi' (1000) with group `orangepi' ...
Creating home directory `/home/orangepi' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
パスワードを入力。Enterを押す。カーソルは動かない。
Retype new UNIX password:
もう一度パスワードを入力。Enterを押す。カーソルは動かない。
passwd: password updated successfully
Changing the user information for orangepi
Enter the new value, or press ENTER for the default
Full Name []: Enterを押す。
Room Number []: Enterを押す。
Work Phone []: Enterを押す。
Home Phone []: Enterを押す。
Other []: Enterを押す。
Is the information correct? [Y/n]  yを押す。

Dear orangepi, your account orangepi has been created and is sudo enabled.
Please use this account for your daily work from now on.

root@orangepizero:~#
これで初回の手続き完了。
sudo apt-get updateしてみるもよし。sudo shutdown -h nowでいきなりシャットダウンするもよし。

2.WiFiの設定をする

日本の技適を通過していないのでWiFiの利用は自己責任になる。
プロンプトに続けて以下を入力。
nmtui
Networkmanagerの画面を開く
↓下矢印キーを叩いてActivate a coonectionを選択、Enterを押す。
ネットワークの一覧が表示されるので自宅のルータを選んで、Enterを押す。
パスワード入力画面が表示されるのでパスワードを入力、Enterを押す。
上下左右キーで<OK><Quit>を選んでEnterを押す。画面を抜ける。
■新しいIPアドレスを知る
有線LAN接続時とは異なる新しいIPアドレスが割り当てられる。新しいIPアドレスを知るには前述の「ラズベリーパイのローカルIPアドレスを知る」の項を参照。
ifconfig
を入力して、wlan0の数行下の数列を確認する。