2015年4月20日月曜日

Lapdock for Motorola Atrixを使ってRaspberry Pi 2をモバイルPCにしてみた

はじめに

最近、仕事でRaspberry Piのデスクトップ環境を使う機会が増えているのですが、HDMI液晶ディスプレイ、キーボード、マウスを常に用意しておくのは場所をとるのであまり嬉しくありません。

省スペース化する何かいい方法はないかと調べてみると、海外で販売されているスマートフォン用ドック「Lapdock for Motorola Atrix」をRaspberry Piで使うというのがメジャーなようで、ksksueさんによる下記のページが非常によくまとまっていましたので参考にさせて頂きました。
最終的には、下記のようにRaspberry Piと補助基板をこのLapdockの背面に貼り付け、モバイルPCのように使えるようにしてみました。LapdockとRapsberry Piの両方をバッテリー駆動できていますので、移動中に膝に乗せて使うことも可能です。


背面に貼り付けず、もう少し配線が見えるようにした写真が下図です。


手順

Lapdock for Motorola Atrixは、ebayを検索し、「Buy It Now(ヤフオクでいういますぐ落札)」でInternational Shippingが可能なものを探すとイスラエル発送のものが最安値だったのでそちらで注文しました。

またこのLapdockをRaspberry Piに接続するためにはいくつか必要なケーブルやコネクタなどがあり、これらも全て「Beaglebone BlackやRaspberry Piを使うときのオススメガジェット Lapdock(ksksueさん)」で紹介されているものを購入しました。

LapdockとRaspberry Piの接続の概略は下図(A)のようになります。旧型のRaspberry Pi Model A/BではLapdockのUSBをRaspberry PiのUSB端子に接続するだけでRaspberry Piが起動しました。これはLapdockのUSB端子にスマートフォン充電用の5Vが供給されているからですが、Raspberry Pi Model A/BがUSB端子からの給電で起動するのは今回初めて知りました。


しかし、Raspberry Pi Model A+/B+やRaspberry Pi 2では下図(A)のように別途5Vの電源を接続しなければRaspberry Piは起動しません。すると、図(A)の通りLapdockとRaspberry Piとで2系統の電源が必要になり、あまりスマートではありません。

そこで、図(B)のように、LapdockのUSB端子からの信号を電源とUSB信号の2つに分配し、外部電源をLapdockの1系統に統一することにします。Lapdockにはバッテリーも搭載されているため、アダプタを接続しない状態でもRaspberry Piに給電することができ、モバイルでの利用も可能になります。

参考にしたのはYouTube動画「Raspberry Pi Laptop with Atrix 4G Dock (by Adafruit Industries)」ですが、この動画の通りにケーブルを分割するのは少し面倒です。なるべく作業を楽にするため、簡単な補助基板を作成することにしました。必要なものは下記のとおりです。
これらを下図のように配線します。なお、AタイプのUSBコネクタですが、4つの端子を基板にはんだづけするだけではグラグラして不安定なので、ホットボンドで基板に固定しました。


補助基板が完成したら、Raspberry Piの5V電源とUSB端子との両方に接続しますが、どちらも市販の「USB(A)オス-USB(Micro B)オス」ケーブルを用いることができます(冒頭の2枚めの図をよく見ると接続の様子が見えます)。

以上でRaspberry Piをモバイルで利用することが可能になりました。必要な物品の一覧は下図のようになります。最もかさばるのは左上に見えるLapdockのアダプタですが、バッテリーで動作させるならばこのアダプタは不要です。


さらに、冒頭で述べたように、ケーブル類やRaspberry Pi本体をLapdockの背面に貼り付けると、さらに快適になりました。Raspberry PiをノートPC化するPi-Topも持っていますが、キーボードがまともな分、このLapdockの方が断然使いやすいですね。


作り方は単純で、例えばこんな感じの耐震マットで
  • ケース入りのRaspberry Pi
  • 上記の自作基板
を背面に貼り付けているだけです。ただし、ユニバーサル基板には耐震マットはほとんど貼りつかないので、基板にプラ板などをネジ止めし、そのプラ板を貼りつけるようにしています。

なお、短くてやわらかいHDMIケーブルが必要になったので、米amazonでこちらを購入してみました。日本でも似たようなものは売ってないでしょうか?

おわりに

もちろん、Raspberry PiだけではなくBeagleBone BlackやOdroidなども起動できます(下図はOdorid U3)。スタバでLinuxボードでドヤリングしたい方は是非。




「ラズパイ4対応 カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」、「Raspberry Piではじめる機械学習」を執筆しました。

2015年2月28日土曜日

Intel Edison備忘録

はじめに

Intel Edisonについての過去の投稿の内容を久しぶりにアップデートをしようとして、ログイン方法すら思い出せず途方にくれることがありました。
そこで、自分用のメモを残すことにしてみました。

用いるのはIntelが配布しているYocto Linuxとします。

ユーザー名とパスワード

  • ユーザー名:root
  • パスワード:なし

タイムゾーンの設定

参考:えびめも
# rm -f /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

時刻の設定

参考:えびめも
# date -s "2014.12.3-15:55:00"

usb0のネットワークを変更する

usb0ではデフォルトで192.168.2.15/24が使われますが、これが既存のネットワークとかぶる場合、/etc/systemd/network/usb0.network内下記の行を書き換えます。
Address=192.168.2.15/24

名前、Wifi接続などの設定

参考:スイッチサイエンス
# configure_edison --setup
これを複数回実行すると、ネットワークの設定が/etc/wpa_supplicant/wpa_supplicant.conf にどんどん追記されていくので、削除したい場合はファイルを直接編集します。

IPアドレス固定

参考:Intelのフォーラム
/etc/wpa_supplicant/wpa_cli-actions.shにて、下記のようにudhcpcを起動している部分を見つけてコメントアウトし、2行追加します。下記の例は、192.168.1.2に固定する場合を示しています。
if [ "$CMD" = "CONNECTED" ]; then
  kill_daemon udhcpc /var/run/udhcpc-$IFNAME.pid
#  udhcpc -i $IFNAME -p /var/run/udhcpc-$IFNAME.pid -S
  ifconfig $IFNAME 192.168.1.2 netmask 255.255.255.0
  route add default gw 192.168.1.1
fi

proxy設定

参考:OpenWrt
/etc/opkg/opkg.confに、下記の例のような行を追加します(サンプルが中にあるので真似します)。
option http_proxy http://proxyサーバー名:ポート番号/
option ftp_proxy ftp://proxyサーバー名:ポート番号/
これで、下記が通るはずです。
opkg update
opkg upgrade
他のコマンド用に、.profile にも下記を記入して保存します。
export http_proxy=http://proxyサーバー名:ポート番号/
export https_proxy=https://proxyサーバー名:ポート番号/
export ftp_proxy=ftp://proxyサーバー名:ポート番号/

sshによるログイン可能に

参考:スイッチサイエンス
外部からIntel Edisonにsshでログインできなくなった場合、/lib/systemd/system/sshd.socket 内の1行を下記のようにコメントアウトします。
#BindToDevice=usb0

2014年12月12日金曜日

Intel Edisonで映像配信中のカメラのパン・チルトを制御してみた

はじめに



にて、Intel EdisonにてWebカメラを有効にし、mjpg-streamerで映像を配信してみました。

今回は、Intel Edisonを使ったデモとして、そのWebカメラにサーボモーターを2つ取り付け、Web経由でパン・チルト(水平方向と垂直方向)を制御してみました。

全体像は下図のようになります。カメラの他は、Intel Edison Breakout Board、レギュレータやレベルシフタを含む周辺回路、バッテリー(Eneloop Pro6本)が見えます。

コントローラーはPC、タブレット、スマートフォンなどのブラウザです。



動作状況の動画はこちらになります。




カメラ雲台の準備

カメラとサーボモータ2つを接続する方法ですが、なるべく楽をしたかったので、秋月電子通商にある


を用いました。



この組み立て方は


にあります。これを見るだけでも大変そうなのはわかりますが、実際に手元に届いてみると

  • ニッパ、ピンバイス、ヤスリによるパーツの加工が必須
  • 必要なネジが全然足りない(と思う)
  • 2つのサーボSG-90の品質が悪く、最初から正常動作しないことがある

のように、なかなか骨のあるキットです。

ちなみにサーボSG-90は秋月やamazonなどでも追加注文できますが、店によってはバージョン違いなのかサーボのケースサイズやサーボホーンの径が異なり、さらに加工が必要になったりします。なお、私の場合、SG-90を計12個入手して、正常動作したものは10個でした。

さらに、このキットに付属するWebカメラはMJPEGモードに対応していないので、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた 」で紹介した方法では映像配信できません。

私は手元で余っていたLogicool C210を加工して取り付けました。Logicoolのものなら大抵大丈夫だと思います(今にして思えば、もっと画質の良いものにすれば良かったかも)。


回路の接続

作成したカメラ雲台を下図のようにIntel Edisonと接続します。


いくつかコメントします。

USBカメラを使うため、電源は7V~15VをJ21に入力します。バッテリーを用いたかったので、Enelooop6本を用いることにしました。容量の大きいEneloop Proにしましたが、これはお好みで。

サーボモーターは5Vで駆動するため、レギュレータTA4805Sで5Vを作ります。これは手元にあったものをそのまま用いました。

Intel Edisonからは下記の5つの信号を引っ張りだしました。Intel Edisonを外した状態で、Breakout Boardにケーブルを直接半田づけしました。

  • J17-1:サーボ用PWM
  • J18-1:サーボ用PWM
  • J18-2:GPIO。プルアップされた入力として用いて、シャットダウンスイッチに利用します。
  • J19-2:1.8V
  • J19-3:GND
各ピンの情報はIntel Edison Breakout Board Hardware GuideのPDFファイルを参考にしてください。

サーボモータ用に出力するPWM信号は1.8Vなので、サーボモータに与えるために5Vにレベル変換します。これも手元にあった「8ビット双方向ロジックレベル変換モジュール」を用いました。

PCとの接続は、J3のシリアルコンソールにより行います。

libmraaライブラリの準備

ここからはIntel Edison上での作業になります。あらかじめ、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた」に基づいてWebカメラの映像配信を有効にしておいてください。エントリ作成当時はポート8080を用いていましたが、ポート9000を用いるように変更しましたので、ご注意ください。

さて、スイッチサイエンスさんのページ「Intel Edison opkgのフィードを設定する」および「libmraaを使ってC++で開発する」を参考に、GPIOにアクセスするためのlibmraaライブラリをインストールします。

# vi /etc/opkg/myfeeds.conf

このファイルに下記の内容を記述して保存します。

src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic
src all http://iotdk.intel.com/repos/1.1/iotdk/all
src i586 http://iotdk.intel.com/repos/1.1/iotdk/i586
src x86 http://iotdk.intel.com/repos/1.1/iotdk/x86

書けたら、下記のコマンドを実行します。

# opkg update
# opkg upgrade
# opkg install libmraa0

これでlibmraaのインストールが完了しました。

node.jsで用いるモジュールの準備

node.jsによるWeb連携で用いるconnectモジュールとsocket.ioモジュールをインストールします。

# npm install connect@2.27.4
# npm install socket.io@0.9.17

使っているスクリプトの関係上、バージョンを指定して最新のものではないファイルをインストールしました。

これらのモジュールは/home/root/node_modules以下にインストールされます。

なお、libmraaライブラリに対応するmraaモジュールは/usr/lib/node_modules/mraaとしてインストールされていますが、これを/home/root/node_modulesにリンクしておかないと、自作のnodeスクリプトを/etc/rc.localから起動するときに失敗します。そのため、下記を実行しておきます。

# ln -s /usr/lib/node_modules/mraa /home/root/node_modules/mraa

ソースのダウンロード

ソースのダウンロードのために、gitをインストールします。

# opkg update
# opkg install git

次に、ソースをダウンロードし、pantiltという名前のディレクトリに保存します。

# cd
# git clone https://github.com/neuralassembly/Edison_pantilt.git pantilt

以下、いくつか解説を加えていきます。

シャットダウンスイッチ

シャットダウンスイッチを有効にするためには、下記のコマンドを実行します。

# python /home/root/pantilt/shutdown.py &

この状態で、回路上のタクトスイッチを2~3秒程度長押しすると、poweroffコマンドが実行され、シャットダウンが始まります。

中身は下記のようなPythonプログラムになっています。GPIO15はJ18-2のことであり、プルアップ抵抗つきの入力として設定しています。GPIO番号とピン番号の対応はこちらを参照。

import mraa
import time
import subprocess

sw = mraa.Gpio(15)
sw.dir(mraa.DIR_IN)
sw.mode(mraa.MODE_PULLUP)

state = 0

while True:
    if sw.read() == 0:
        if state == 2:
            state = 0
            args = ['poweroff']
            subprocess.Popen(args)
        else:
            state += 1
    else:
        state = 0

    time.sleep(0.5)

このshutdown.pyスクリプトを起動時に有効にするには、mjpg-streamerの自動起動の際に作成した/etc/rc.localに上記のコマンドを追記してください。

サーバーの起動

サーバーを起動するには、下記のコマンドを実行してください。

# node /home/root/pantilt/pantiltserver.js &

その状態でブラウザで


  • http://(Intel EdisonのIPアドレス):8080/


にアクセスすると、操作用のアプリが開きます。使用されているポートは下記の通りです。

  • 8080:ページの閲覧
  • 8888:socket.ioによるソケット通信
  • 9000:mjpg-streamerによる映像配信

JavaScriptで記述したpantiltserver.jsの中では、下記のようにJ17-1およびJ18-1ピンに対してPWM信号を出力しています。

var mraa = require('mraa');
var p0 = new mraa.Pwm(0);  // J17-1
var p1 = new mraa.Pwm(14); // J18-1

p0.period_us(19500);
p0.enable(true);
p1.period_us(19500);
p1.enable(true);

// For upper servo
var duty0min = 0.03; // min
var duty0max = 0.11; // max
var duty0 = (duty0min + duty0max)/2;

// For lower servo
var duty1min = 0.031; // min
var duty1max = 0.115; // max
var duty1 = (duty1min + duty1max)/2;

p0.write(duty0);
p1.write(duty1);

サーボモータに50Hzの信号を与えるのですが、細かな周期やパルス幅はオシロスコープの波形を見たりサーボモーターの振る舞いを見ながら微調整しました。Duty比は0~1の実数で指定します。

このpantiltserver.jsをIntel Edison起動時に自動実行する場合は、やはり/etc/rc.localに上記コマンドを追記してください。

ブラウザ上のアプリ

ブラウザのアプリは下図のように映像の下と右にjQuery UIによるスライダを配置してサーボモーターへの指令をJavaScriptで送るようにしています。iOSのSafari/ChromeやAndroidのChrome/Firefoxなどで動作を確認しています。画面の回転にも対応しています。



このアプリは、主に下記のファイルで構成されています。

  • index.html
  • js/pantilt.js
  • js/socket.io.js:node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.jsと同じもの
  • js/jquery/:jQuery UI用ファイル
  • css/pantilt.css

js/pantilt.js内で、映像の取得と命令の送信を行っています。

展示

このデモを2014年12月21日に東海大学高輪キャンパスで開催されたAndroid Bazaar and Conference 2014 Winterで展示しました(週アスPLUSさんにも写真があります)。


Androidのイベントなので、カメラを「Androidタブレットおよびそれとペアリングされた腕時計Android Wear」から操作できるデモとしました。Android Wearでの操作の技術的詳細は、「Android Wear (LG G Watch) でカメラからの映像を見ながら三輪ロボットを操作してみた」が関連します。

沢山の方にお越しいただき、ありがとうございました。

終わりに

Intel Edisonを用いた簡単なデモということで、カメラのパンチルトを制御してみました。

mraaモジュールを用いるとJavaScriptで直接GPIOにアクセスできるので、Web連携が容易であるという印象を持ちました。ただし、ドキュメントがあまり充実していないように思われるのが残念なところです(Pythonの入力ピンのプルアップ抵抗を有効にする方法を調べるために、mraaのソースをgrepしたりしました)。そのあたりは今後に期待でしょうか。

あとは、7V以上の電源の確保と1.8VのGPIO入出力のレベルシフトがやや面倒、というところです。

他のボードとの比較で言えば、Raspberry Piで同じことをやろうとする場合、Webカメラでは性能が出ないので、Raspberry Pi用のカメラモジュールを用いる必要があります。さらに、Raspberry PiではハードウェアPWMが一つしか使えないので、全く同じことをするのは少し面倒です。

BeagleBone Blackでは全く同じことを実現できるはずですが、私はBeagleBone BlackでのGPIOプログラミングは未経験なのでノーコメントです。

以上でした。