bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

Haskell+Ubuntu Mate+Raspberry Pi (1)

1.Ubuntu Mate

Raspberry Piの第二世代が2015年2月より販売され(プロセッサはARMv7)、それに伴って、利用できるOSも多様化した。Ubuntを利用したいという開発者にとっては、これは大きなニュースである。Raspberry Pi 2用にUbuntu Mate (15.04)も用意された。こちらの方が新しい版のHaskellが利用できるので、早速、これを試すこととした。

Raspberr Pi2用のUbuntu Mate 15.04をSDディスクに焼くことにする。これは、例によって、SDFormatterでフォーマットし、DDWinを用いて、(管理者権限で)Ubuntu MateのイメージをSDディスクに書き込む。

この後、SDディスクをRaspberry Pi 2に挿入し、電源を入れて立ち上げる。途中、言語、場所、キーボードの種類、利用者の情報(Piは後で用いるので、Piはここではログイン名として用いない)などを求められる。うまくいけば、Ubuntuのシステムが立ち上がってくる(Failed to start OCM_Config...で停止することがあるが、この場合は立ち上げなおす。ユーザ選択の画面が現れるので、自身のユーザ名を選びパスワードを入力する)。

2.ファイルサイズ変更

システムが立ち上がったら、SDディスクのファイルのサイズが4GBになっているので、その容量の全部を利用できるようにするため、ファイルサイズの変更を行う。
最初に、

sudo fdisk /dev/mmcblk0

最初に、2番目のパーティションを消去する。

Command (m for help): d (消去のコマンド)
Partition number (1,2, default 2): 2 (2番目のパーティションを指定)

つぎに、2番目のパーティションを再度作成する

Command (m for help): n  (新しいパーティションを指定する)
Parttion type
  p  primary (1 primary, 0 extended, 3 free)
  e  extended (container for logical parttions)
Select (default p): p (パーティションの指定)
Partition number (2-4, default 2): 2 (2番目の指定)
First sector (133120-120946687, default 133120): enter (数値は容量によって異なるがそのまま改行)
Last sector, +sector of +size{K,M,G,T,P} (133120-120946687, default 120946687):enter (数値は容量によって異なるがそのまま改行)

最後に書き込みを行う。

Command (m for help): w (書き込んで終了). 

システムをリブートする。そして、リサイズする。

sudo resize2fs /dev/mmcblk0p2

3.システムのグレードアップとSSH通信

システムをアップデート及びグレードアップし、さらに、SSH通信ができるようにする。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install ssh

4.GPIOを利用できるようにする。

ファイルシステム(シェルスクリプト)でgpioを利用したいときは、gpioというグループを作成し、gpioを利用したいユーザを追加する。ここでは、このユーザをpiとする。設定の仕方は以下のとおりである。

sudo groupadd -f --system gpio
sudo adduser --group gpio pi        (piというユーザを加える。)
(sudo usermod -G gpio username)     (既存のユーザの時はこれを使う。但し、最初に登録したユーザに対してこれを行うとsudoが利用できなくなるので注意すること)
more /etc/group                     (作成されたグループを見る)

この後、udevの規則を加える。60-python-pifacecommon.rulesは以下のようになっているので、これをまねて、60-gpio.ruesを作成し、/etc/udev/rules.dの直下に加える。

KERNEL=="spidev*", GROUP="spi", MODE="0660"
SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio; chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio'"

システムをリスタートし、変更が正しく行われているかを確認する。

ls -al /sys/class/gpio

を実行し、グループがgpioになっていれば大丈夫である。

5.GPIOを利用する。

これで、gpioが利用できるようになったので、シェルスクリプトを用いて、gpioの4番ピンにLEDを接続し、それを点滅させる。
f:id:bitterharvest:20150814101814j:plain

4番ピンを使えるようにするため、次のコマンドを打つ。

echo "4" > /sys/class/gpio/export

このコマンドを打つ前には、ディレクトリ/sys/class/gpioは次のようになっていた。
f:id:bitterharvest:20150814094627p:plain
しかし、このコマンドにより、このディレクトリにgpio4というディレクトリが作成される。なお、生成には200m秒程度必要とする。
f:id:bitterharvest:20150814095232p:plain
そして、さらにその先には次のようなファイルが用意される。
f:id:bitterharvest:20150814095422p:plain

それでは、LEDを点滅させる。LED側に指示を与えるので、gpio 4をoutとして設定する。

echo "out" > /sys/class/gpio/gpio4/direction

LEDを点灯するために、gpio 4をhighにする。

echo "1" > /sys/class/gpio/gpio4/value

LEDを消灯するために、gpio 4をlowにする。

echo "0" > /sys/class/gpio/gpio4/value

gpio 4の値を読む。

cat /sys/class/gpio/gpio4/value

最後に、今までの作業を完了させるために、生成したディレクトリを消去する。

echo "4" > /sys/class/gpio/unexport

6.HaskellでLEDを点滅させる

Haskellを利用できるようにするため、ghchaskell-platformを実装する。

sudo apt-get install ghc haskell-platform

また、delayを必要とするので、これも読み込む。

cabal update
cabal install concurrent-extra

ついでにnetwireも読み込んでおく。

cabal install netwire

LEDを点滅させるためには、シェルスクリプトの部分をwriteFileで置き換えればよいので次のようにプログラムを用意する。

import System.IO
import Control.Concurrent.Thread.Delay

pin = "4"

path = "/sys/class/gpio/"

main = do
  writeFile (path++"export") pin
  delay 5000000                                      --ファイル作成が終了するのを待つ
  writeFile (path++"gpio"++pin++"/direction") "out"
  writeFile (path++"gpio"++pin++"/value") "1"
  delay 5000000                                      --光らせる時間
  writeFile (path++"gpio"++pin++"/value") "0"
  writeFile (path++"unexport") pin

このプログラムをghcコンパイルし、実行する。初期の目的が叶えられているはずである。