• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
 

Arduino を PHP で制御する

on

  • 322 views

Firmata はシリアル通信を介してPC等のホストマシンから Arduino やその他マイコンボード等のデバイスを制御するためのプロトコルです。

Firmata はシリアル通信を介してPC等のホストマシンから Arduino やその他マイコンボード等のデバイスを制御するためのプロトコルです。
\PHPMake\Firmata は Firmata の PHP ライブラリです。

Statistics

Views

Total Views
322
Views on SlideShare
276
Embed Views
46

Actions

Likes
1
Downloads
1
Comments
0

2 Embeds 46

https://twitter.com 44
https://tweetdeck.twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via SlideShare as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Arduino を PHP で制御する Arduino を PHP で制御する Presentation Transcript

    • Arduino を PHP で制御する @oasynnoum PHPカンファレンス関西2014
    • 自己紹介 ● @oasynnoum ● PHP が好きです ● 物を動かせるものに惹かれます ● シリアルポートを制御するモジュール – http://sandbox.n-3.so/Gorilla/ ● USB制御するモジュール(libusbラッパー) – http://oasynnoum.hatenablog.com/entry/2013/03/22/013251 ● CD,DVDドライブを(☝ ՞ ՞)☝ ™ウイーンਊ するモジュール – https://github.com/oasynnoum/php-eject – http://eject.kokuda.org/ ● 工作の腕はお察し下さい
    • まとめ firmata プロトコルを実装した PHP ライブラリ、 PHPMakeFirmataを使えば ArduinoとWebを連携させたアプリが 簡単にPHPで作れる!
    • Arduino を PHP で制御する ご清聴ありがとうございました m(_ _)m 終
    • お話したいこと ● firmataとは これの次に述べる PHPMakeFirmata API の根底を理解して もらう目的で firmata プロトコルを少し細かく説明 – PHPのカンファレンスで話す内容としては不適切かもしれ ません。PHP関係なさすぎて ● PHPMakeFirmata について – 導入方法 – API – デモ
    • firmata プロトコル概要 ● firmata はPCのようなホストマシンから Arduino の ようなデバイスを制御するためのプロトコル ● firmata はシリアル通信の上のアプリケーションプ ロトコル
    • firmata プロトコル概要 ● ホストからデバイスにリクエストを出し、 デバイスはそれに応じ動作し、必要に応じて レスポンスを返す – 必ずしも「リクエスト対レスポンス」ではない ● デバイスが断続的にピンの状態を通知したり ● ホストから一方的にピンの状態を変化させたり ● 通信データの形式は MIDI メッセージ形式 ● 色々なデバイス側の実装がある – https://github.com/firmata
    • firmata プロトコル概要 ● 最大0xF個のデジタルポートをサポート – 一つのポートは8個のデジタルピンを持つ – つまり最大128個のデジタルピンをサポート ● 最大0xF個のアナログ入力ピンをサポート
    • firmata プロトコル概要 ● 用途(メリット) – もっとお手軽プロトタイピング(スクリプティング) ● ホスト側でプログラムを書ければ言語は何でもいい ● あるデバイスが firmata を実装しているとわかれば、その デバイス専用のプログラマ(ライター)・IDE等が無くてもいい – ホストとデバイスが協調動作するようなアプリ開発 – 場合によってはホストから電源が供給される ● デメリット – ホストとデバイスはケーブルで繋がる必要がある ● firmata over XBeeとかアイディアはあるらしい・・・ – ホストが無いと何も出来ない ● 単にデバイスだけを動かせばいいようなアプリの場合、 ホストの計算資源を要求するため無駄が多い
    • StandardFirmata 概要 ● Firmata のデータ形式は大雑把に – シンプルな固定長のコマンド – 可変長データを内包するコマンド(SysEx) ● #define START_SYSEX 0xF0 ● #define END_SYSEX 0xF7 に分けられる ● ホストからの接続時にデバイスの状態がリセットされ る
    • StandardFirmata 概要 ● リセット時、デバイスから特定のメッセージが送られる ● デバイス初期化実装例 https://github.com/firmata/arduino/blob/45c67d3c18351d23eb979bc2 ff32537dac180560/Firmata.cpp#L66 void FirmataClass::begin(long speed) { Serial.begin(speed); FirmataSerial = &Serial; blinkVersion(); printVersion(); printFirmwareVersion(); }
    • ファームウェア情報の取得 ● REPORT_FIRMWARE – #define REPORT_FIRMWARE 0x79 – pack('C3', START_SYSEX, REPORT_FIRMWARE, END_SYSEX); ● ファームウェア名(StandardFirmata.ino)と、 バージョン番号がレスポンスとして返ってくる ● ただし、この情報は前述したリセット時の特定のデータに 含まれるため、このクエリを発行する場面は稀
    • ピンの機能を調べる ● デバイスに存在するピン一つ一つについて、 それが持つ機能を返す ● つまり、ピンの総数とピンそれぞれの機能がこのコ マンドでわかる ● CAPABILITY_QUERY – #define CAPABILITY_QUERY 0x6B – pack('C3', START_SYSEX, CAPABILITY_QUERY, END_SYSEX);
    • ピンの機能を調べる ● 定義されている Capability は次の通り – digital input – digital output – analog read – PWM – servo – I2C ● このコマンドはGUIアプリケーションの初期化時に有用 – ピンの数、機能に応じたコントロールを配置する
    • デジタル出力 ● 3バイトのコマンド ● 先頭バイトは DIGITAL_MESSAGE|ポート番号 – 下位4bitはポート番号 – #define DIGITAL_MESSAGE 0x90 – $n番目のピンがあるポート番号は floor($n/8) ● ピン番号を8で割り、端数を切り捨て ● つまりピンは8毎にグループ化される ● 6番目のピンはポート0に、13ピンはポート1にある ● 2バイト目、3バイト目はポート中のピン状態を示す
    • デジタル出力 ● 1バイト目例:0x90|1 – ポート1に対するデジタル出力 ● 2バイト目例:01011011 – 最上位ビットは 0 固定 – 最下位ビットから順にポート中のピン番号 0 ~ 6 の状態を示す ● 3バイト目例:00000001 – 最上位ビットから2ビット目まで 0 固定 – 最下位ビットはポート中のピン番号 7 の状態を示す ● ポート 0 に対し偶数ピンをHIGHにするコマンド ● pack('C3', 0x90|0, 0b00101010, 0b00000001);
    • デジタル入力 ● ポートの状態を監視し、変化があれば通知する – 読み出さないとバッファにどんどんデータが溜まっていく – 入力を受け取るアプリの場合、 この理由でポーリングが必要になる ● REPORT_DIGITAL – #define REPORT_DIGITAL 0xD0
    • デジタル入力 ● 2バイトのコマンドで監視、または監視をやめるポートを指定 ● 1バイト目は REPORT_DIGITAL|ポート番号 – 下位8bitはポート番号 – 特定のピンの状態だけ教えてくれればいいよという訳にはいかない – 5ピンはポート0に属するので、5ピンの状態が欲しい場合、そのポートの他 のピンの状態変化の通知も受け取ることになる ● 2バイト目は真偽値、0もしくは1 – 1で状態通知お願いします – 0で状態通知、もう結構です ● pack('C2', REPORT_DIGITAL|0, 1); – ポート0に属するピンの状態を通知
    • デジタル入力 ● 指定したポート中のピンに状態変化があった場合 3バイトのデータを受け取る ● データの形式はデジタル出力のコマンドと同じ
    • アナログ入力 ● デバイスがアナログピンの状態を監視し、変化があれば 通知する ● 監視要請のコマンドの形式は デジタル入力のそれとほぼ同じ ● #define REPORT_ANALOG 0xC0 ● pack('C2', REPORT_ANALOG|1, 1); アナログピン1の状態を監視させる ● デジタル入力同様、読み出さないとバッファにデータが 蓄積されていく
    • アナログ入力 ● 指定したアナログピンに状態変化があった場合 3バイトのデータを受け取る ● 1バイト目は監視要請のコマンドと同じ – REPORT_ANALOG|ピン番号 ● 2バイト目はピンの状態(値)の下位7bit ● 3バイト目はピンの状態(値)の上位7bit ● $pinState = (($first << 7) | $second) & 0xFF
    • その他主要コマンド ● PWM(アナログ出力) – 単位時間あたりのピンがHIGHとなる時間を調整し、 デジタル(二値的)なピンにアナログ(多値的)な振舞をさ せる ● Servo – 特別な場合の PWM コマンド ● I2C – 他のデバイス、マイコン等とシリアル通信を行う
    • PHPMakeFirmataについて ● Firmataのホスト側実装 ● 先に述べたプロトコルの詳細を隠蔽 – PHPMakeFirmataDevice が対象のデバイスを表現 ● コンストラクタは Capability チェックなど、まず必要となりそうなやりとりをデ バイスと行う – digitalWrite(), analogWrite(), ピンを監視する仕組み などをフレームワークとして提供する ● PHP による firmata のホスト側実装は他に https://github.com/ThomasWeinert/carica-firmataがある – 両者の API の違いはピン監視のAPIにおいて interface を用いるの か callable を用いるのか程度 – callable 多用するのが嫌いな人は PHPMakeFirmata を使うといい と思う
    • PHPMakeFirmataについて ● WebSocket の機能(余計なお世話) – Ratchet との連携により WebSocket サーバーの機能 も提供 – フレームワークユーザーがピン監視のポーリングと Ratchet が提供するイベント駆動の API を組み合わせ て整合性を取りつつ WebSocket アプリを作るのは多 分めんどくさいだろうと思ったので – しかし、 Ratchet の API は少し調べただけなので、 恐らく今のところあまりいい実装ではない
    • PHPMakeFirmataについて ● ホスト側実装のキモは parser だと思う – バッファはデジタルピン、アナログピンの状態通知など 色々なデータが混じる ● 例えば REPORT_FIRMWARE のクエリを投げた 直後に受け取るバッファ先頭のデータは必ずしも START_SYSEX, REPORT_FIRMWARE, END_SYSEX ではない – 動かない下手くそなパーサーを何度も書いては捨てた – 今のところパーサーは動くが、依然下手くそ
    • 導入 ● Composer で簡単に firmata プロジェクト作れる! しかし、依存の PHPMakeSerialPort は拡張モジュール なのでこれを先に手動でインストールする必要がある – ちなみに、先に上げた carica-firmata もシリアル通信部分に PHPMakeSerialPort がインストールされていれば使うように なっています ● PHPMakeFirmata のインストールについては http://sandbox.n-3.so/Gorilla/download/ を参照してください ● ArduinoにStandardFirmataを書き込む必要があります http://qiita.com/oasynnoum@github/items/91aed30 9bd9de8af8d0a を参照してください
    • LEDを点滅させよう(Lチカ) ● 要約: – Device のインスタンスを作って、 digitalWrite() をコール – http://qiita.com/oasynnoum@github/items/91aed309bd9de8af8d0a <?php require dirname(__FILE__) . '/vendor/autoload.php'; /* initialize the device */ $device = new PHPMakeFirmataDevice('/dev/ttyACM0'); /* for Windows */ // $device = new PHPMakeFirmataDevice('COM3'); $pin = 13; for ($i = 0; $i < 3; ++$i) { $device->digitalWrite($pin, PHPMakeFirmata::HIGH); // light sleep(1); $device->digitalWrite($pin, PHPMakeFirmata::LOW); // unlight sleep(1); }
    • デジタル入力を読む ● コードは少し長いので省きました – http://qiita.com/oasynnoum@github/items/cd9f90cfec8c0 18a47c6 を参照してください ● $dev->setPinMode(13, PHPMakeFirmata::INPUT); ● 監視したいピンを reportDigitalPin() で指定する – 前述のとおり、プロトコル自体はポート単位で監視・通知を行 うがフレームワークがそこを隠蔽しピン単位での監視・通知を 行う ● PinObserver を実装し、そのインスタンスを Device に addDigitalPinObserver() で渡す – ピン変化通知を notify() で受け取る
    • デジタル入力を読む ● デバイスから送られる通知を取得するため、 なるべく短い時間間隔でバッファを確認する必要がある (ポーリング) – このポーリングの事をデバイスループと呼んでます – デバイスループに入るには Device の run() メソッドをコールします ● 引数については後述 ● デバイスループに入ると処理はそこでブロックされる – run() 呼び出しの後に続くコードブロックが実行されるのはデ バイスループが終了したあと – このままだとフレームワークユーザーは何も出来ない
    • デジタル入力を読む ● LoopDelegate – デバイスループ以降何も出来なくなることを回避するため用 意されたインターフェース – このインスタンスを run() の引数に渡す – LoopDelegate の tick() メソッドはそのループの間隔ごとに コールされます – getInterval() メソッドはループの間隔を定義します ● デバイスループが実行される最初にだけ Device 内部でコールさ れます ● デバイスループを止めるには Device の stop() をコー ルします – 典型的には tick() 内から stop() とか
    • アナログ入力を読む ● デジタル入力とほぼ同じです ● ただし、 PinObserver のインスタンスは addAnalogPinObserver() メソッドで Device に渡 します ● $dev->setPinMode(13, PHPMakeFirmata::ANALOG);
    • PWM(アナログ出力) ● $dev->setPinMode(13, PHPMakeFirmata::PWM); ● Device の analogWrite() をコールします ● 第一引数はピン、第二引数は値 ● 第二引数の値のとり得る範囲は 0~上限値 ● 上限はデバイス、ピンにより異なる ● Capability により定義されている – $capability = $dev->getPin(13)->getCapability(); $pwmResolution = $capability->getResolutionPWM();
    • デモ1 ● firmata-websocket-taste – https://github.com/PHPMake/firmata-websocket-taste – Taste は test のタイポ。 面白いと思ったのでそのままにしています。 ● firmata.org が提供しているテストGUIアプリがUbuntuで動かな かったため作った ● バグっぽいです ● Onsenui で作った – http://onsenui.io/ ● Onsenui は素晴らしい。 このデモがバグっぽいのは実装者のせい ● ピンモードを変えられるようにと思ってセグメントコントロールをつ けましたが、今のところ実装していません
    • デモ2 ● firmata-space-travel – https://github.com/PHPMake/firmata-space-travel ● Arduino でしょぼい宇宙船制御コンソール ● phoria.js でなんちゃって太陽系 – http://www.kevs3d.co.uk/dev/phoria/ – phoria.js は悪くない。悪いのは実装者の腕
    • PHPMakeFirmata の課題 ● firmata のメリットはそのままにデメリットを減じたい – デメリット ● ホストとデバイスはケーブルで繋がる必要がある ● ホストが無いと何も出来ない – 普通に Wiring 使えば?というのは無し ● 俺はぺちぱーだ! ● Wiring(Arduinoの開発言語というかフレームワーク) ● ドキュメントが無い – 申し訳程度の Janglish で書かれた phpdoc オンリー
    • 参考資料 ● firmata.org – http://firmata.org/wiki/Main_Page ● firmata/arduino – https://github.com/firmata/arduino ● Arduino Uno/Leonardo で始める電子工作 – http://www.amazon.co.jp/dp/4877832963