2013年12月21日土曜日

気温をつぶやくRaspberry Pi

今回は
  • I2C温度センサで室温測定
  • コマンドラインTwitterクライアントでつぶやく
の合わせ技を試してみました。
RPiが30分おきに室温をつぶやいてくれる一種のbotのようなものですな。

I2C温度センサモジュールADT7410の接続

アナログデバイセズのI2C温度センサIC「ADT7410」を搭載したセンサモジュールがいつものオシャレ雑貨店もとい秋月電子で1個500円(http://akizukidenshi.com/catalog/g/gM-06675/)で手に入ります。こいつをRaspberry Piのピンヘッダ(P1)へ下記のように接続します。
  • ピン3 - SDA
  • ピン4 - VDD
  • ピン5 - SCL
  • ピン6 - GND
ピンソケットを2x2に並べて、気合の空中配線。



RaspbianでI2Cを使えるようにする

ハードワーク(いろんな意味で)はここまでです。ソフトの方をいじっていきましょう。
まずOSのRaspbianで、I2Cドライバがデフォルトでブラックリストに入っているため、これを解除しておきます。
エディタでblacklistファイルを開き、
$ sudo vim /etc/modprobe.d/raspi-blacklist.conf
下記の行をコメントアウト。
# blacklist i2c-bcm2708
次にロードするカーネルモジュールにI2Cドライバを追加。
$ sudo vim /etc/modules
末尾に下記の行を追加。
i2c-dev
それから、I2C使用のパーミッションを与えるため、ユーザをi2cグループに追加します。
$ sudo gpasswd -a pi i2c
これで下回りの準備はOK。

i2c-toolsのインストールと温度の取得

コマンドでI2C温度センサの値を取得できるようにします。i2c-toolsをインストール。
$ sudo apt-get install i2c-tools
これで、i2cgetコマンドでセンサ値を読み出せるようになります。
$ i2cget -y 1 0x48 0x00 w
0xe80d
が、エンディアンが逆転して出てくるので、上位バイトと下位バイトを入れ替えて読む必要があります。その上で、初期設定の解像度13ビットで読んでいる場合、下位3ビットは捨て、4ビット目から16ビット目(すなわち[15:3])が有効な値として扱えます。このうちMSBが符号で、1なら零下の気温をあらわします。MSBを除いた12bitで、1階調あたり0.0625℃の解像度で温度の値が示されます。
たとえば上記の0xe80d場合、まずエンディアン入れ替えで0x0de8となり、これを下位3ビット捨てて(つまり8で割って)0x1BD、10進数に直して445、解像度の0.0625℃をかけて、27.8125℃となります。

コマンドラインTwitterクライアント「TTYtter」のインストール

さて、ただの温度計ではつまらないので、計測された室温を全世界に向けて盛大につぶやいていただきましょう。自動でTwitterへ投稿させるため、コマンドラインのTwitterクライアント「TTYtter」を使用します。
まずはダウンロードとインストール。Perlスクリプトなのでビルドはしません。chmodで実行パーミッションだけ与えておきます。
$ wget http://www.floodgap.com/software/ttytter/dist2/2.1.00.txt
$ sudo mv 2.1.00.txt /usr/local/bin/ttytter
$ sudo chmod +x /usr/local/bin/ttytter
初回の実行でOAuthのためのPINコード入力を求められます。次のように表示されたら、とりあえずENTERを押し、
$ ttytter
(中略)
** This wizard will overwrite /home/pi/.ttytterkey
Press RETURN/ENTER to continue or CTRL-C NOW! to abort.
つづいて下記リストの中ほどにあるような、ランダムトークンをクエリに含むURLが表示されるので、これをブラウザで開きます。
Request from http://api.twitter.com/oauth/request_token ... SUCCEEDED!

1. Visit, in your browser, ALL ON ONE LINE,

https://api.twitter.com/oauth/authorize?oauth_token=<ランダムトークン>

2. If you are not already signed in, fill in your username and password.

3. Verify that TTYtter is the requesting application, and that its permissions
are as you expect (read your timeline, see who you follow and follow new
people, update your profile, post tweets on your behalf and access your
direct messages). IF THIS IS NOT CORRECT, PRESS CTRL-C NOW!

4. Click Authorize app.

5. A PIN will appear. Enter it below.

Enter PIN>
Twitterにログインしていれば、下の画像のようなページにPINコード(複数桁の数字)が表示されます。このPINコードをコマンドラインに入力しENTERを押します。



これでTTYtterでTwitterを利用できるようになります。試しに普通のツイートをしてみます。
$ ttytter -status="Hello, TTYtter"
trying to find cURL ... /usr/bin/curl
test-login SUCCEEDED!
post attempt SUCCEEDED!
タイムラインに表示されればOK。


気温を取得するスクリプトの作成、TTYtterとの連携

TTYtterに流すため、温度の取得、エンディアンの入れ替え、摂氏への換算をワンストップで処理するスクリプトを作成します。さっきのi2cgetコマンドをpopenで実行したあと、ちょこちょこ処理して数字を標準出力させます。
$ vim temperature.py
#!/usr/bin/env python
import os
import re

hex_temp = os.popen("/usr/sbin/i2cget -y 1 0x48 0x00 w").read()
hex_temp = hex_temp[4:6] + hex_temp[2:4]

print int(int(hex_temp, 16) / 8 * 0.0625)
とりあえず零下には未対応。屋内仕様なのでね。そんな部屋いたら死んでまう。あと小数点以下は切り捨て。
スクリプト内ではi2cgetコマンドはフルパスで書いておきます。これをしないと、後でcrontabに登録したときになぜかうまく実行できないってなことになります。
で、パーミッションを実行可能に。
$ chmod +x temperature.py
実行してみます。
$ ./temperature.py
27
できたかな。これをTTYtterに食わせると
$ ttytter -status="$(/home/pi/temperature.py) ($(date +\%R))"
世界中のフォロワーたち(総勢0名)が我が城の室温を知るわけです。クールだぜ。
ttytterコマンドの引数-statusとしてtemperature.pyスクリプトの出力が入るように指定します。dateコマンドで時刻も併せて入れておくといいでしょう。


crontabによる定期実行

一回つぶやいただけだと見逃してしまううっかりなフォロワーさんもいらっしゃると思うので、30分おきに最新の気温を測定してツイートします。さながらデータロガーといったところ。
$ crontab -e
0,30 * * * * /usr/local/bin/ttytter -status="$(/home/pi/temperature.py) ($(date +\%R))" -silent
ttytterの-silentオプションは、インタラクティブなコマンドラインのTwitterクライアントとしての使用をせず、今回のようにスクリプト等で実行させる場合のために、標準出力を無効にします。


参考情報

TTYtter for Perl - Floodgap Software
I2C and Raspbian wheezy - AB Electronics UK

2013年12月17日火曜日

Raspberry Piからメール送信

異常が生じたとか、センサに何か入力があったとか、Raspberry Piに何かさせて近くを離れるときにリモートでレスポンスが欲しいことがあります。方法はいろいろありますが、メールがシンプルな方法の一つでしょう。なのでコマンドラインからメールを送れるようにしてみます。

送信時にSMTPサーバが必要になるので、自分のアカウントでGmailのSMTPをリレーするようにします。

まずはMTA(メール転送エージェント)のインストール。Postfixとかqmailとかいろいろ選択肢がありますが、とりあえずここではEximを。
次にEximの設定を行っていきます。

General type of mail configuration:
mail sent by smarthost; received via SMTP or fetchmail
System mail name:
localhost
IP-addresses to listen for incoming SMTP connections:
127.0.0.1 ; ::1 (そのまま)
Other destinations for which mail is accepted:
(空白)
Machines to relay mail for:
(空白)
IP address or host name of the outgoing smarthost:
smtp.gmail.com::587
Hide local mail name in outgoiong mail?
<No>
Keep number of DNS-queries minimal (Dial-on-Demand)?
<No>
Delivery method for local mail:
mbox format in /var/mail/
Split configuration into small files?
<No>
Root and postmaaster mail recipient:
<Ok>

続いて、SMTPの認証情報をファイルに書き込みます。 内容は以下のとおり。使いたいGmailアカウントのアドレスとパスワードを書いておきます。
変更の適用。
mailコマンドを使うためmailutilsをインストール。
では送信テスト。
うまく設定できていれば、程なくして設定したGmailのアカウントからメールが送られてきます。

参考情報

debianサーバでメールを送る(exim4編)- ひゃまだのブログ

2013年12月1日日曜日

UDOOのArduino DueでLED点灯

i.MX6とArduino Dueが一体になったUDOOが家にやってきたわけですが、2つのパートがどのように連携できるか探るために、まずはAuruino DueでLチカから試してみたいと思います。一応、初めて使うことになるので、必要なツールのインストールとかも含めてメモっておきます。

UDOO上のArduino IDEを使ってみる

まずは点灯するLEDを接続しておきます。適当なLEDを持ってきて、アノード(長い方のリード)をGPIO13ピンに、カソード(短い方のリード)を隣のGNDに接続します。公式サイトのチュートリアルだと電流制限抵抗なしで繋いでますが、私は心配なので一応470Ωをはさんでおきました。

公式で配布しているLinaro Ubuntu 12.04 LTSのSDカードイメージを使っている場合、プリインストールされたArdiono IDEが利用可能です。起動するとデスクトップにアイコンがあるので、ダブルクリックして起動します。
gnome-screenshotをインストールするとスクリーンキャプチャできます
で、LED点灯のための下記コードを記述します。
VerifyしてUpload。とりあえずLEDの点灯を確認できるわけですが。

何でしょう、Arduino IDEでのコンパイル、めっちゃ重い!たったこれだけのコードなのに、1分くらいはかかってるように感じます。PCと比べると、組み込み向けのCortex-A9での使用感はこんなもんでしょうか。。さすがにこれだと作業性が悪いので、PCのArduino IDEから扱えるようにしたいと思います。

Arduino IDE 1.5 インストール & パッチ当て

まず、Arduino IDEは1.5以降のバージョンである必要があるそうです。ここから1.5.5 BETAをダウンロードします。インストーラを使うか、ZIP版を任意のフォルダに展開するかしてインストールしたら、次にパッチ当てをします。UDOOのArduino Dueパートを担うAtmel Sam3Xを書き換えるためにはERASE信号とRESET信号が必要なのですが、通常のArduinoボードと違ってUDOOにはこれが実装されていないらしく、Arduino IDEにパッチを当てることでこれに対応するそうです。環境に合わせて、ここにおいてあるパッチをダウンロードしてきて展開し、中身をArduino IDEのインストールディレクトリの所定の場所に上書きコピーします。Windowsであれば、<arduino-1.5.5のインストール場所>\hardware\tools\の下にbossac.exeを上書きコピー、同梱のcygwin1.dllも一緒にコピーします。

シリアルドライバのインストール

それから、UDOOのUSBコネクタ(CN6)にシリアル接続するためのPC側のドライバをインストールしておきます。ここからOSに合わせたZipファイルをダウンロードし、展開してインストーラを実行します。その上でPCとUDOOのCN6をマイクロUSBケーブルで接続すると、ドライバが自動インストールされ、COMポートとして認識されます。


コード記述、実行

PCにインストールしたArduino IDE 1.5.5で、コードを記述しVerify、Uploadします。このとき、USB接続したUARTのラインがi.MX6ではなくSAM3Xにつながるよう、J18のジャンパは外しておく必要があります。これでPCからもArduino Dueに書き込みできるはずですが、電源を切っても先ほどのプログラムがフラッシュに残っていて、再起動時にそのまま実行されるので、同じコードだと変化がわからないかも知れません。その場合はdigitalWrite()する値をLOWに変えるとか、コードを少し変えてみるといいです。私は、LED点滅するよう下記のコードで試しました。



参考情報

Getting started with Arduino-IDE on UDOO - udoo.org
Get the Arduino-IDE ready to program UDOO - udoo.org
UDOO programming the embedded Arduino microcontroller - elinux.org

2013年11月29日金曜日

Raspberry PiにWebカメラを繋げて動画撮影してみたが


すっかり秋も深まり、毎日寒くなってきました。Raspberry Piにカメラを繋げていろいろ面白いことしたくなる季節です。

Raspberry Piのカメラといえば、Camera Boardが定番です。 OmniVisionの5MP裏面照射型CMOSセンサを積んでいて、FullHD 30fpsの動画撮影にも対応、MIPIインタフェースでRPiと接続するモジュールです。ボード上の専用コネクタにフレキで繋ぐようになっています。

それから最近、赤外線イメージセンサ搭載のPiNoirというカメラモジュールも発売されたみたいですね。夜目の利くRPiも楽しそう。

でも今のところ私はRPi用のカメラモジュールを持っていません。そこで、家に転がっていたUSB接続のWebカメラを繋いでちょっと遊んでみます。

使用したのは、バッファローさんのBSW32KM01H。UVC対応なのでLinuxでもばっちりです。早速繋いでみる。dmesgとlsusbはこんな感じ。
自動的にuvcvideoドライバがロードされ、/dev/video0が追加されているはずです。では、ビデオ録画を試してみます。まずffmpegをインストールします。
ffmpegコマンドを使ってカメラ録画しファイルに書き出します。 なんとなく、flvだとうまくいったのでとりあえず。

それで、録画したファイルをWinSCPとかでWindowsに持ってきてプレーヤーで再生してみるわけですが。。数秒は撮影したはずなのに、一瞬で再生が終わってしまう!
何故?もう一度撮り直してみると、、、
1fpsしか出てない!

うーん、何だろう。。エンコードが重い?topでCPU使用率見ても、だいたい10~30%くらいなんだけどなぁ。
まぁ気が向いたら追い追い見てみますか。

カメラ繋いだついでに静止画撮影もしてみましょう。まずuvccaptureをインストール。
で、とりあえず撮影。
これでカレントディレクトリにsnap.jpgができます。見てみるとちょっとホワイトバランスがおかしいんですが、その辺は調整できるようです。一応、撮影はできました。


カメラモジュール買うかなぁ。


参考情報
How to stream from the linux (ubuntu :) command line to UStream - KnowledgeVoid
How to capture a webcam input - FFmpeg
uvccaptureで画像取得 - ともの技術メモ

2013年11月22日金曜日

UDOOボード 開封の儀

Freescale i.MX6 SoCとArduino Due互換プロセッサを一体化したハイブリッド校正のボード、UDOO(ユードゥー)が届きました!WandboardArduino Dueを一枚のボードに載っけてシリアル接続したような感じの楽しげなボードです。さっそくunboxingしたいと思います。

デリバリーはUPS。貨物状況を詳細に見られるトラッキングは魅力ですね。調べてみたら、イタリアから発送され、ドイツ、インド、中国を経由していました。長旅おつかれさま。UPSの難点は、日本では休日の再配達に対応していないことでしょうか。事業が拡大すれば休日配達のサービスを始めることもあるかもしれませんが、今回はヤマト便への転送にて週末に再配達してもらいました。


UPSバッグの中にはエアキャップ封筒。

その中にボード本体のパッケージとACアダプタの箱が入っています。

本体箱の両サイドには「MAKE」と「LEARN」の文字。小洒落たデザインがにくい。


ACアダプタは世界対応、DCサプライは12V/2A。

外ふたを開くと、getting startedページへの誘導に始まるインストラクションに加え、「WELCOME ON BOARD」の粋なメッセージ。

内ふたを開いてスポンジクッションを除けると、静電防止袋に包まれた本尊が。

いよいよご対面です。大き目のヒートシンクよりも少し背伸びしたピンソケットが個性的。サイズはだいたい109x86mmくらい。ちょうどRaspberry Piを横に2枚並べたくらいの大きさです。

さっそく起動してみましょう。公式のDownladsページにあるLinaro Ubuntu 11.10のイメージをダウンロードし、Win32 Disk Imagerで8GB以上のmicroSDに書き込みます。microSDをヒートシンクの下のスロットに挿入し、HDMIでモニタを接続。ACアダプタを繋ぐと電源が入ります。

デスクトップが起動したところ。

USB接続でキーボードとマウスが使えます。デスクトップ上部のパネルのApplicationsからターミナルを起動してみます。

デスクトップにはArduino IDEのアイコンも見えますね。夢が広がりますが、とりあえず今回はそんなところで。

参考情報

UDOO Getting started - eLinux.org

Raspberry Piをワイヤレス化してみた


Raspberry Piをワイヤレス化して遠隔データロガーにしようと誰でも考えると思いますが、ワイヤレスコネクティビティが搭載されていないので後付けしてあげる必要があります。たとえばWi-Fiが使える環境なら、USBの無線LANアダプタを使うことでワイヤレス化できます。

今日日、ラップトップやタブレットはWi-Fi標準装備のものばかりでしょうから、後付けのUSB無線LANアダプタの需要は少ないように思いますが、結構流通はあるようで、案外安く手に入ります。中でもBUFFALOのWLI-UC-GNMは、Amazonでわずか600円(しかも通常配送料無料)で手に入るという手軽さ。ポチらずにはいられませんね。Web上の記事によっては、WLI-UC-GNMはLinuxでは使えない(動作実績がない)、というも記載も見られますが、まぁチップベンダ(MediaTek)でドライバ配布してるっぽいしなんとかなるだろ、という根拠のない自信のもと、今回Raspberry Piに接続してみたらあっさり動いてしまったので、とりあえずその辺の手順をメモっておきます。

とりあえず繋いでみる

何は無くともUSBコネクタに挿してみて、いろいろ情報を覗いてみましょう。ということで繋いでみたんですが、それまでEthernetでSSH接続していたターミナルのウィンドウが突如クローズしてしまいました。どうやらRPiのネットワーク接続が一時的に途切れてしまったようです。ハングでもしたのかとあせりましたが、すぐにSSH接続を再開できたので、あくまで一時的な現象のようです。

さて、再開したターミナルからまずはdmesg。
接続されてますね。ベンダIDとプロダクトIDはWindowsに接続してデバイスマネージャを見てみると一致を確認できます。チップベンダはRalinkですが同社はMediaTekに買収された模様。

lsusbは
こんな感じ。いらっしゃいますねバッファローさん。

無線LANインタフェースの状態を調べるというiwconfigを見てみると
とりあえずwlan0デバイスができていることがわかります。ためしに外した状態と比べてみるといいでしょう。

ドライバは
ということで、これも接続前と比べてみれば、rt2800usbというのがロードされいることがわかります。
このドライバが問題なく動いてくれれば、意外と面倒な手順なしに夢のワイヤレス化が実現できそうです。

接続設定する

ここからは実際に無線LANを使えるようにするための設定をします。暗号化方式によって手順が違う場合があるようです。以下は我が家の環境、WPA2(AES)での実施例です。

IEEE 802.11i通信を無線LANクライアントに提供する、というツール、wpa_supplicantの設定を行います。このツールはRaspbianでは/sbin/wpa_supplicantにプリインストールされていると思いますが、無い場合でもsudo apt-get install wpasupplicantでインストールできそうです。
んで、設定ファイルをいじるんですが、root読み書きのみのパーミッションになっているので、otherにも権限を付与してから書き込みします。セキュリティが気になる場合は、あとで戻すといいでしょう。
それからESSIDと事前共有キーが必要です。あらかじめWi-Fiルータの設定を確認するなどして調べておきます。
エディタで開いて、少し付け加えます。
次にバックグラウンドで動いているwpa_supplicantを一旦止めてから再起動します。
コマンド行の末尾に" &" を加えてバックグラウンドプロセスとして起動します。

再起動したらiwconfigを見てみます。
さっきと違ってESSIDとアクセスポイントの情報が入りました。いい感じっぽいですね。

ためしにDHCPでIPアドレスを取得してみます。
IPアドレスが割り当てられたら、もうLANケーブルを外してWi-FiでSSH接続できるはずです。

最後に、起動時に有効になるよう設定を加えておきます。
これでおk。もはやRPiを縛るものは電源用のアンビリカルマイクロUSBケーブルのみとなりました。次はワイヤレス給電化を・・・やりませんよ^^。バッテリー化はすると思います。


参考情報

RPi Ralink WLAN devices - eLinux.org
Linuxで無線LANを使おう(Fedora) - LinuxMania

2013年11月19日火曜日

DisplayLinkモニタでRaspberry Piデスクトップを使用する

これまで、DisplayLinkモニタ用のフレームバッファドライバudlfbをカーネルコンフィギュレーションで有効化し、フレームバッファデバイスをXで扱うためのグラフィックドライバxf86-video-fbdevをインストールしました。

今回はDisplayLinkモニタでデスクトップを立ち上げるようにしたメモです。

1. xorg.confを設定

エディタでxorg.confの設定をします。
内容は以下。
これを保存すれば、usb_modeswitchでモニタをストレージからDisplayLinkデバイスへ切り替えるだけで、デスクトップを表示させることができるはずです。コマンドは前々回に書いたので割愛します。

2. udevルールでストレージ認識を回避

起動後、自動的にDisplayLinkモニタにデスクトップを立ち上げるようにするための設定です。Raspbianの起動中にudevdがDisplayLinkモニタを見つけたとき、ストレージではなくDisplaLinkデバイスとして認識するようにします。
エディタで下記のルールファイルを作成します。
中身には下記の行を記述。
こうすることでドライバとしてcdromではなくudlfbがロードされます。

3. X起動設定

RPiが起動したら自動的にstartxするよう、次のファイルに記述を加えます。
exit 0の直前に一文追加するだけでOKです。
4. 再起動

ここまでで、起動後にDisplayLinkモニタでデスクトップが表示されるようになったはずです。ためしに再起動してみます。
再起動後、下の画像のように(デフォルトのままなら)LXDEのデスクトップが表示されます。

5. タッチパネルのキャリブレーション

さて、とりあえずLXDEが起動し、キーボードとマウスを繋げばデスクトップPCとして使えるようになりました。しかし、今回使用しているDisplayLinkモニタLCD-USB10XB-Tはタッチパネル搭載です。マウスで使うなんて野暮。触って操作しましょう。
幸運にもRaspbianにはタッチパネルコントローラeGalaxに対応するドライバが標準でインストールされていまです(万が一無かったとしてもカーネルコンフィギュレーションで有効化するだけですけどね)。したがって、既にタッチ操作はできるはずです。
ただし初期状態ではタッチ位置とデスクトップ上の座標にズレがあったり、ドライバ等ソフトウェアの仕様によって反転していたりすることがあります。タッチ点を画面の座標上に正しく対応させるため、キャリブレーション(校正)を行う必要があります。
キャリブレーションには、xinput_calibratorというツールを使います。freedesktop.orgからソースをダウンロードしてきてインストールします。
インストールしたら、X上のターミナルから起動します。そのターミナルを起動するためにデスクトップのアイコンをダブルクリックするのは、キャリブレーションしていないタッチスクリーンではちょっと苦労します(笑)。キーボードやマウスで操作したほうが早いと思います。
コマンドを実行すると画像のようなフルスクリーンのUIが表れます。4つの十字マークが順次表示されるので、交点をなるべく正確に押していきます。中心の円グラフは操作の残り時間を示しています。残り時間がなくなるとプログラムは終了しますが、上記コマンドで何度でもやり直しできます。

4点の入力が終わるとプログラムが終了しますが、これで完了ではありません。コマンドラインにコンフィギュレーションスクリプトが生成されるので、これをコピーして下記ファイルに書き込みます。
以上で終了です。

参考情報

DisplayLink - wiki.archlinux.org
RPi Debian Auto Login - elinux.org
xinput calibrator - freedesktop.org
How to get eGalax TouchScreen film (0eef:0001) working in Linux for Raspberry Pi - Black God

2013年11月9日土曜日

Raspberry Piにxf86-video-fbdevをインストール

前回、DisplayLinkモニタのためのudlfbドライバをRaspberry Piにインストールしました。今回はフレームバッファデバイスのためのX11グラフィックドライバ、xf86-video-fbdevをインストールしたので、メモ。

まずはここからソースをダウンロードし、解凍。
で、いつものconfigureとmakeではなく、シェルスクリプトautogen.shを走らせます。 何やらエラーが。autoreconfのソースをダウンロードしてビルドしてみる。 おや。
sanitize.shってのは、acscriptsっていうのに入ってるらしい。 ではもう一度autoreconfのビルドを。 おやおや。m4のインストールが必要。 おk。ではもう一度。 ではxf86-video-fbdevのインストールに戻りまして。 うーん、今度はautoconf? これでいいかな。もう一度。 xorg-macrosとやらが必要とな。ぐぐってみるとxutils-devを入れればOKとのこと。 今一度。 にゃー。libtoolが欲しいって。 んでもう一度。 ここはシンボリックリンクで対応。 もう一度。 RANDRとな。ぐぐってxorg-devをインストール。 もーいっかい。 これでautoconf.shは通った。Makefileが生成されるので、あとはいつものやつです。

2013年11月4日月曜日

Raspberry Pi でDisplayLinkのudlfbドライバを使う

前回、RPiに接続したDisplayLinkコントローラ搭載のUSBモニタにlibdloライブラリを使って描画するテストをしてみました。今回はフレームバッファデバイスとして汎用的に使えるようにするため、udlfbドライバをインストールし、ロードできることを確認します。操作は下記のとおり。

1. udlfbドライバのインストール(カーネル再構築)


DisplayLinkをフレームバッファデバイスとして使うためのドライバとしてudlfbが必要です。ぐぐってみると、udlfbはPlugableのサイトでソース配布されていて、これをビルドすればOK、という記述もちらほら見つかるんですが、実はカーネルソースツリーのdrivers/gpu/drm/udlに(バージョン2.6.31以降?)入っていて、コンフィギュレーションしてビルドすればカーネルモジュールが生成されるようになっています。そこで今回は、udlfbのビルドを有効にしたうえでカーネルを再構築しインストールしてみます。
本当はeLinux.orgの記事にあるとおり、PCのlinuxマシンで作業したほうがビルドが早く済むんですが、今回はRPi上で作業しちゃってます。

まずはGitHubのレポジトリからカーネル取得。
使用中のカーネルのコンフィギュレーションをコピーしてきて、適用する。 次に、udlfbのドライバを有効にする。 下記のように進んで、Displaylink USB Framebuffer supportをモジュール選択します。依存するEnable Video Mode Handling Helpersも自動的に有効になります。 menuconfigの画面上では、下の画像の項目です。

SaveしてExitします。で、さっそくビルド。 RPi上でビルドしたせいもあり、たぶん10時間くらいかかったかな。
ビルドが終わったら、モジュールとカーネルをインストールして再起動します。

2.usb_modeswitchのインストール


今回使用しているLCD-USB10XB-Tは(もしかしたら他のDisplayLinkモニタも同様かもしれませんが)、コンピュータにUSB接続すると、初めにストレージデバイスとして認識されます。ストレージ内にはautorun.infが入っていて、Windows PCなどの場合、同梱のドライバインストーラを起動する仕組みになっています。ドライバがインストールされた後はストレージではなく、DisplayLinkモニタとして認識されるようになります。この仕組みはUSB接続のモデムなどでも見られることがあります。こうすることで、デバイスメーカーはドライバのCDを製品に添付せずに済むわけです。
Linuxマシンに接続した場合も、この仕組みのせいでストレージデバイスとして認識され、本来のDisplayLinkデバイスとしての使用を妨げてしまいます。 そこで、どのデバイスとして認識するかの切り替えができるusb_modeswitchを導入します。デスクトップのUbuntuではパッケージレポジトリに登録されているようですが、Raspbianではapt-getでインストールできなかったので、ソースからビルドします。#追記:Raspbianでも、ちゃんとapt-get updageすればレポジトリからインストールできるようです。ただしバージョンが古く(Version 1.2.3)今回の用途では正しく動作しないため、新しいVersion 2.0.1をソースビルドしてインストールする必要があります。
ここからusb_modeswitchのソースをダウンロードして、makeします。
バイナリのインストール。


3.udlfbドライバのロード


modprobeコマンドで、モジュールをロードします。 lsmodコマンドを打つと、モジュールがロードされていることを確認できます。 udlfb本体と同時に、依存するモジュールもロードされています。
最後に、インストールしたusb_modeswitchコマンドで切り替えを行います。あらかじめlsusbコマンドやdmesg等でDisplayLinkモニタのベンダIDとプロダクトIDを調べておく必要があります。 DisplayLinkというデバイスの17e9:0156がベンダIDとデバイスIDの対です。これをusb_modeswitchコマンドの-vパラメータと-pパラメータに指定して実行します。 成功すれば、DisplayLinkモニタの画面がクリーン一色になります。
udlfbはフレームバッファドライバなので、デバイスファイルfb1が増えていることも確認できます。


参考情報

DisplayLink - ArchWiki
RPi Kernel Compilation - eLinux.org
Raspberry Pi でカーネルにaufsを組み込む - よもやま雑記帳
LCD-USB10XB-TをUbuntuで使う - PPE : Petit Panda Extreme
UbuntuでEmobileのD21LCを利用する - Blog.37to.net

2013年10月29日火曜日

Raspberry PiにlibdloをインストールしてDisplayLinkモニタを動かす

巷には、PCにUSB接続するLCDのサブモニターやグラフィックアダプタ(参考:Amazon)というものがあります。これらに採用されているのがDisplayLink社のデバイスコントローラです。公式のドライバはWindowsとMac用なんですが、Freedesktop.orgでLinuxドライバの対応が行われているので、実はLinuxでも動かすことはできます。

今回はうちにあるIODATAのLCD-USB10XB-TをRaspberry Piに接続して、libdloライブラリを導入してテスト表示が映るところまでやってみたので、手順をメモっておきます。

DisplayLinkデバイスを何らかのLinuxディストリビューションで動かす話をぐぐってみるといろいろな登場人物が出てきてややこしいんですが、私なりに整理すると、
  • udlfb: デバイスドライバ
  • libdlo: DisplayLinkに描画するためのユーザスペースライブラリ
  • xf86-video-displaylink: udlfbのクライアントとなるX Server
って感じだと思います。たぶんに誤解を含むと思いますが。。中にはlibdloがドライバっていう記述もあったりしますが、libdloをビルドしてもカーネルモジュールは生成されません。でもudlfbなしに表示を試せたりしちゃいます。この辺のソフトウェアスタックがどうなってるのか、あまり詳しく調べてないのでよくわかりません。規模も大きくないので、そのうちソースでも読んでみようかとも思います。

さて、今回はlibdloをインストールして表示のテストを。

まずは所要のライブラリをインストール。
次にlibdlo本体をダウンロード、続けてアーカイブ展開し、いつものようにconfigureとmakeでビルド。
ビルドができたら表示のテストをしてみます。DisplayLinkデバイスをUSB接続し、
とコマンドしてモニタに何か表示されれば成功です。次のように直接バイナリをたたいてもOKです。


参考情報

libdlo - Freedesktop.org
What is udlfb? - kernel.org
DisplayLink - archlinux

MarsBoardでSATA接続に挑戦 (3)

今までの話:
 [MarsBoardでSATA接続に挑戦]
 [MarsBoardでSATA接続に挑戦 (2)]

とりあえずRomanさんのMinimal Debian "Server"をSDブートしてHDDをSATA接続してみたMarsBoard。今回はfdiskでフォーマットしてからmountしてファイル読み書きできるようにしたのでメモ。

まずはHDDを接続してからdmesgでアタッチされたデバイスを調べる。
続いてfdisk。pコマンドで現在のパーティションを見てみる。
dコマンドでパーティションを削除。
nでパーティション作成。
ここで、tでパーティションタイプを選択できますが、今回はLinuxでOKなので何もしないまま、wコマンドで書き込みます。
これでfdiskの作業は終了。次にmkfsでファイルシステムを初期化します。
んで早速マウント。
ファイルを書いてみます。
おk。じゃぁunmountしてさようなら。

2013年10月27日日曜日

Raspberry Pi で DirectFB

Raspberry Pi で DirectFB を動かしてみたいと思います。本当は別マシンでクロスコンパイルしてRPiにロードするのがかっこいいと思うんですが、なかなかうまくいかなかったので妥協してオンターゲットでやっちゃいます。
なおOSはRaspbian wheezyの2013-09-25版です。

まずDirectFBの公式より、本体とExamplesをダウンロードしておきます。
で、ビルドをしていきます。
もしconfigureで
というエラーが出る場合は、
をしてからもう一度。
ビルドができたら、まず
でライブラリを認識させます。これを忘れると
というようなエラーが出ます。
インストールしたライブラリの認識ができたら、
とコマンドしてみます。dfbinfoはDirectFBのユーティリティの一つで、ScreenとInputデバイスの一覧が表示されます。/dev/fb0はvideoグループで、Raspbianのデフォルトユーザのpiはvideoグループに属しているのでアクセスできるはずですが、rootグループの/dev/tty0を使う必要があるらしく、sudoで呼ばないと失敗します。
次にExamplesのインストール。本体と同様に、
でおk。

HDMIを繋いで再起動します。んで仮想コンソールなりSSHなりから、
と打ってみます。ペンギン(Tux?)が大量発生してうじゃうじゃ動き回ってる映像が出れば成功です。仮想コンソールなら[ESC]キーで終了できます。SSHからの終了はよくわかりません。

参考情報

Steps to setup DirectFB dev enviroment on Ubuntu - Sun Wei's space

MarsBoardでSATA接続に挑戦 (2)

前回の続きで。

Allwinner A10でSATAを使っている事例はないかとぐぐってたら、RomanさんのサイトでSATAデバイスからDebianをブートする記事を見つけました。
同氏がポーティングしたMinimal Debian "Server"のイメージはSATAが有効なようなので、とりあえずSDブートしてからHDDにSATAを接続してみます。

まずはここから最新のイメージをダウンロード。

続いてダウンロードしたイメージをbz2アーカイブから解凍して取り出します。こちらの手順の2に書いてあるように、bzip2による解凍をSDカードのデバイスファイルにリダイレクトしてもいいと思うんですが、なぜか私の環境ではパーミッションエラーになったので、代わりにWindows上でCygwinのbzip2により解凍した後、Win32 Disk ImageによりSDカードへ書き込みました。なおSDカードの容量は2GB~でOK。

んでUARTでコンソールを繋ぎつつブートしてみる。上記の手順ページに書いてあるユーザ名とパスワードでログイン。バージョンは

ここでSATAに接続したHDDの電源を入れてみる。なぜか標準出力にもカーネルメッセージっぽいのがだだ漏れてくるけど、気にせずdmesgで接続後に出たメッセージを拾うと、

それから、今度はHDDの電源をOFFしたとき。

ってな感じ。

2013年10月26日土曜日

MarsBoardでSATA接続に挑戦


Allwinner A10搭載のローコストARMボードMarsBoardでちょっと遊んでみたいと思います。

同じA10搭載のCubieBoardもそうなんですが(CubieBoardのほうがコミュニティが盛り上がってて楽しそう・・・)、MarsBoardの特徴の一つはSATAコネクタを搭載していること。

OSは公式で配布されてるLinaro版ARM Linux(linaro-alip-armhf-t4.img)をSDカードに焼いてブート。バージョンは
です。
HDMIは使わずピンヘッダ用ホールからUARTを引っ張ってきて、ホストPCのターミナルからCUIアクセスします。

とりあえずSATAコネクタに、部屋に転がってた2.5インチHDDをつないでみる。電源はUSB-SATAアダプタ付属のAC電源を流用。

んでホットプラグしてみたり、リブートしてみたりしつつ、
とか
とか打ってみるけど、何の痕跡も見当たらない。
もちろん
でもHDDっぽいのは見当たらないし、/dev下にもそれっぽい名前のデバイスファイルはない。

カーネルはSATAが使えるようなコンフィギュレーションでビルドされてるのか、と思って調べてみると、
ということで、なんとなくOKそうだが。

でもlsmodではそれっぽいドライバは見当たらない。んで/lib/modulesの下を掘ってみると、/lib/modules/3.0.36-t3+/kernel/drivers/ata/sw_ahci_platform.koなんてのが見つかる。ためしに
してみると、
なんていうエラーメッセージらしきものを標準出力に延々垂れ流し始める。んでSATAを外すと(あるいは外した状態でinsmodすると)、
とだけ、一発返す。

う~ん。

Invalid module formatと格闘

Linuxデバイスドライバを作ってみようかな、と思い立って、Free Software Magazineのチュートリアルをウォークスルーしてみる。

曰く、まずは空のソースコードをコンパイルしてカーネルモジュールを作り、insmodしてみましょうと。
んで、カーネルモジュールのコンパイル時に、そのロード先と同じカーネルが必要とのこと。今回はクロスコンパイルではなくホストシステムをそのままターゲットにするので、ホストと同じカーネルのソースが必要になる。

ホストのLinuxバージョンは
とりあえずKernel/Compile - Community Ubuntu Documentationを参考に
ツール類のインストール
カーネル取得
終わるとカレントディレクトリの下にカーネルのディレクトリができるので、入る。
んで現システムで使われているconfigを持ってきてoldconfigした後、make。
ひとまずこれでビルドOK

ということで、カーネルモジュールを作ってみる。 # 移動、ソース作成
しかし
とのこと。
enakai00さんの記事によれば、vermagicの不整合がまずいらしい。

modinfoコマンドでカーネルモジュールを調べてみる。
う~ん、vermagicがちょいと新しくないか?
いまいちど、カーネルのディレクトリに行って、バージョンを確認してみる。手順はここのQA参考。
あれ、思ってたのと違うお。。
Makefileを見てみると、
うん、やっぱり変だな。

クレバーじゃないと思いつつ、カーネルのMakefileのバージョン指定を無理やり変えてビルドしてみる。
で、カーネルモジュールのディレクトリに移動してもう一度ビルド。それからmodinfoしてみる。 ということで、vermagicはそろったものの、insmodしてみると うーむ、以前状況は変わらず。

そんで悩んで行き着いたのがStack OverflowのこのQA。なんでも、
で行けるっぽい。調べてみると、このbuildってのは/usr/src/linux-headers-$(uname -r)へのシンボリックリンクになっている。linux-headersがインストールしてあればOKなんですな。
成功したぽい。

2013年9月15日日曜日

最近気になるボードたち ~2013秋~

ようやく暑さも引いてきた昨今、CNXSoftさんのブログを眺めていて、秋の夜長を熱くするかもしれないボードがいくつか目に留まったのでメモ。

1. UDOO

http://www.udoo.org/
image from www.udoo.org

Kickstarterで64万ドルを調達。
コンセプトは、RaspberryPi 4枚分のパワーと、Arduinoの機能を一つに、というもの。 パワフルなLinuxミニPCと便利なフィジカル系ボードが一体になる上に、コネクティビティはEthernetとWi-Fiに加えUSB接続のBluetoothドングルに対応、グラフィックスはHDMIとLVDSタッチスクリーン、さらにはSATA、カメラコネクタ、USB Mini/USB Mini OTGと、全部盛り!そしてフィジカル側のコネクションはArduino Due互換配置の使いやすい2.54mmピッチピンソケット。
何より興味深いのは、Wandboardと同じ、Cortex-A9搭載Freescale i.MX 6と、Arduino Dueと同じCortex-M3搭載Atmel SAM3X8Eの、ダブルSoC構成!これら二つのプロセッサ間の接続は、こちらのページの説明によれば、USB OTGとUARTが用意されており、OTGを使ったAndroid ADK使用も可能だし、フィジカル入力をUART経由でi.MX上のLinuxに送る、なんてこともできちゃう。熱い!
2013年10月出荷に向け、99ドル、109ドル、129ドルの3ラインナップでプレオーダー受付中

2. MicroZed

http://www.zedboard.org/product/microzed
image from www.zedboard.org

今回のチョイスの中ではこれもかなり熱い。Cortex-A9 1GHz デュアルのハードコアを持つXilinx Zynq-7000 FPGA搭載ボードにして、$199のローコストぶり。プロセッサからはUART、USB、Ethernetなど基本的なコネクティビティが提供される一方、裏面にはプログラマブルロジックと接続可能なマイクロヘッダが用意されており、オリジナルのデバイスコントローラロジックを構築して入出力可能というわけです。フィジカル系のプロジェクトでちょっと大きい規模のシステムを構成しようとすると、外部回路がデジタルICの焼きそば回路になってしまう・・・そんな悩みを解決してくれそうです。
グラフィックス出力が欲しい場合は、上位版のZedBoardでHDMIとVGAが利用可能。価格は395ドル。

3. RFduino

http://www.rfduino.com/
image from www.rfduino.com

Kickstarterで35万ドルを集めたArduino互換ボードで、指先に乗るほどの超小型モジュールにまとめているというだけでも魅力的なのに、最大の特徴としてワイヤレスを謳っているあたりがにくい。Bluetooth 4.0でスマホとかと連携していろんなすごいことができちゃうというのが触れ込み。価格も$21~といい感じ。

4. $9 ARDUINO Compatible board

http://borderlesselectronics.org/
image from www.indiegogo.com

クラウドファンディングサイトindiegogoのプロジェクトで12万ドルの調達を達成した、Arduino Leonardo互換ボード。Arduinoって手軽すぎて、こまごまとしたプロジェクトを手元にどんどん増やしちゃうので、いくら使い回しがきくとは言ってもついつい買い増ししちゃうんですよね。でも気軽に何枚も買うには、やっぱりちょっと高い。それが10ドルを切るセカンドソースだっていうんだから嬉しい。(でも私はArduino Pro Miniラブなんですけどね。。。)
1枚ならシッピング込みで$12から、10枚や100枚というすごい単位でのまとめ売りもしています。何でも教育用に導入しやすいように、というのが目的だそうで。 本稿ポスト時点(2013/9/15)ではすべての販売単位で売り切れになっていますが、また増産されるかもしれません。Arduinoの浪費家にはぴったりかも。

5. MC HCK

http://mchck.org/
image from mchck.org
そんなArduinoコンパチよりもさらに安くて小さい、超小型マイコンボードがこちら。MC HCKはMcHackと発音するそうで、日本語ではマックハックとでも呼べばいいでしょうか。
このボードの触れ込みは、たった5ドルのコストで、自前でのファブリケーションが可能ということ。販売は消極的で、回路図、部品表、基板データといった設計情報を公開しています。
SoCはFreescaleのK20、コアはCortex-M4というガチガチ組み込み仕様。





基板がUSBコネクタになっているのもいい感じですね。実にミニマルにまとまっていてクールです。販売してたら即買いなんだけどなー。

6. Minnowboard

http://www.minnowboard.org/
image from uefidk.intel.com

Intel E640を搭載したx86ボード。1GHz 1コアとコンピューティングリソースにやや物足りなさがある上、$199とオンボードCPUのミニPCとして考えるとちょっと割高にも感じますが、x86アーキテクチャのボードでATX電源ではなくACアダプタ一本で動いちゃうお手軽さは、ニッチな需要をうまく突いてるなぁ、という感じ。OSはYoctoプロジェクトÅngströmを標準サポートするようですが、せっかくx86なんだし、いろいろ夢を広げたいですよね。ただしCNXSoftの記事に書かれているとおり、Gizmo Boardと比べると魅力に欠けるのは否めず。x86のAMD G-Series搭載で同じ$199なら、やっぱりGizmoかなぁ、というのが正直なところです。

Raspberry Piで田無タワー風天気予報ガジェットを作る(ソフトウェア編)

前回(ハードウェア編)から続く...

今回はソフトウェアの実装をまとめていきます。ソフトで実現すべきことは、
  • 天気予報のAPIを叩いて明日の天気を取得する
  • 取得した天気に応じてGPIOでLEDを点灯させる
の二つです。

これらを実現する方法はいくつもあると思いますが、ここではコンパイル不要で再修正も楽なPythonを使ってみることにします。Python用にRaspberry PiのGPIO操作ライブラリRPi.GPIOが提供されているので、ファイルIOで直接叩くよりも比較的シンプルに実装できます。

公式からダウンロードしたRaspbian wheezyのイメージにはデフォルトでRPi.GPIOがインストールされているはずです。もしモジュールのimportに失敗する場合はこちらの手順などを参考にインストールします。

OpenWeatherMap

インターネットで天気予報を提供するAPIのひとつに、OpenWeatherMapというものがあります。OpenWeatherMapは、天気を知りたい場所を指定してHTTPでリクエストを送ると、XMLまたはJSON形式でレスポンスを返してくれます。予報だけでなく、現在の天気を知ることもできます。取得したレスポンスを適当に処理して、天気とか気温とかを取り出します。

まずは、試しにレスポンスを取得してみます。公式のAPIサンプルに、下記のリクエスト例が置いてあります。


これをベースに編集してみましょう。
地名はLondonからTokyoに変更、レスポンス形式はXMLからJSONへ、unitsはそのまま、cntは翌一日分のみで十分ですので1にします。
http://api.openweathermap.org/data/2.5/forecast/daily?q=Tokyo&mode=json&units=metric&cnt=1
こんな感じかな。試しにブラウザのURL欄に入力してみると、、
{"cod":"200","message":0.0176,"city":{"id":1850147,"name":"Tokyo","coord":{"lon":139.691711,"lat":35.689499},"country":"JP","population":8336599},"cnt":1,"list":[{"dt":1378605600,"temp":{"day":25.58,"min":19.64,"max":25.58,"night":19.64,"eve":20.69,"morn":25.58},"pressure":1018.16,"humidity":91,"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}],"speed":1.81,"deg":275,"clouds":92,"rain":16}]}
ってな感じでレスポンスが返ってきました。問題なさそうですね。

では、このリクエストをPythonコードから投げて、レスポンスを取得してみましょう。 適当な作業ディレクトリにPythonファイルを作って編集していきます。 実行してみます。 ブラウザで表示させた時と同様、JSON形式のレスポンスが返ってきたでしょうか?
次に、このJSONレスポンスをスクレイピングして、天気の部分だけを取り出してみます。 これを実行すると、天気の部分のテキストだけが抽出されるはずです。 こんな風に↓

GPIO

続いてLEDを点灯させるためのGPIO操作をPythonプログラムに追加していきます。まずGPIO.setmode()でピン番号の指定方法を銘記します。これに合わせ、あらかじめR、G
、B変数にはRPiボードのP1コネクタ上でのピン番号を入れておきます。続くGPIO.serwarnings()は、GPIOを再操作した時に、既に当該ピンが使用中である旨の警告が出るので、これを抑止するために書いておきます。次にGPIO.setmode()で各ピンを出力に設定。あとは、天気予報に合わせた色をRGBで各ピンに設定するだけです!

さて、天気をどの色で表現するか。ご所望の田無タワーが、どの天気のときにどの色で光るかを調べてみるわけですけどね。。

スカイタワー西東京さん(公式)によれば
曇りは緑雨は水色に決定し、残りの紫が晴れ

Wikipedia先生によれば
晴れ=紫色 曇り=黄緑色 雨=青色

西東京市さんによれば
紫色:晴れ緑色:曇り青色:雨

と、若干矛盾系の殺伐とした雰囲気が感じられるんですが、とりあえずここでは
  • 晴れ:R+Gで紫
  • 曇り:Gで明るい緑
  • 雨:G+Bで水色
ということにしましょう。いずれでもない場合はとりあえず例外ということでだけ光らせておきます。

最終的なPythonコードは下記のようになります。 では実行してみましょうか。 天気予報によって異なる色でLEDが点灯するのを確認できます。

「曇り」のとき
「晴れ」のとき
カメラの露出開けすぎた?なんだか眩しい・・・


(おまけ) Raspbian起動時に実行、定期的に実行

自動化してみたいと思います。
上で作成したPythonファイルを、あらかじめ/usr/local/bin/にインストールしておきます。
それから、/usr/local/bin/getweather.pyの冒頭に次の1行(Shebang)を追加しておきます。 /usr/local/bin/にはPATHが通っているので、こうすることでgetweather.pyとだけコマンドすれば実行できるようになるわけです。

では、まずRPiの電源を入れてSDカードからRaspbianが立ち上がったときに一度実行させる方法。まず/etc/init.d/の下に適当な名前(ここではgetweather)でテキストファイルを作ります。
中身には次のスクリプトを書きます。
スクリプトファイルを実行可能に。
update-rc.dコマンドでスクリプトを登録します。今はinsserv使う方がナウいのかな?

次に、一定時間ごとに更新する方法。OpenWeatherMapの更新間隔というのもあると思いますが、ここでは単純に1時間おきのcronジョブを設定します。
rootのcrontabを編集します。この辺の扱いは諸説あると思いますが(crontab -eは間違えて-rで全消ししそうで危ないとか、直接エディタを使うのは行儀が悪いとか)、まぁ好みの方法でやったらいいと思います。
で、毎時0分に更新が行われるよう、下記の行を追加します。


参考情報

Free weather data API for developers - Open Weather Map
Weather information from openweathermap.org JSON API by Python - Techdoc Blog 
1: Getting Started with Raspberry Pi GPIO and Python - OPENMICROS.org
RPi Low-level peripherals - eLinux.org
How to add a program to run at startup in Ubuntu Linux Server edition - Temp Variable