FirmataはPC - マイコン間でやり取りするためのプロトコルです。汎用入出力の値の取得・書き込みその他の操作をPC側からArduinoのようなマイコンに対して行う為に使用されます。
ArduinoでFirmataプロトコルを使用してホストコンピュータとやり取りする場合は、ArduinoIDEを立ち上げて、ファイル
-> スケッチの例
-> Firmata
-> Standard Firmata
を選択、開きそのままArduinoに書き込めば良いです。
##プロトコルフォーマット
- 現在の最新バージョンは2.3です。
- 扱えるアナログの最大点数は16点です。
- 扱えるデジタルの最大点数は128点です。
- デジタルメッセージではデジタル状態の取得、書き込みを行います。
- マイコンからホストコンピュータへ送信した場合は値の通知になります。
- ホストコンピュータからマイコンへ送信した場合は値の書き込み要求になります。
- Arduinoの場合、ホストコンピュータからデジタル入力pinに対してONビットを送信した場合はプルアップ回路の使用が有効になります。
内容 | 値 | 説明 |
---|---|---|
種別コード + port番号 | 0x90 - 0x9F | 種別コード。0から数えて3番目のportは"0x93"となる |
0〜6bitデジタル状態 | 0b00000000 - 0b01111111 | 指定ポートの1〜7bitの状態をbitで表す。8bitめは使用不可 |
7bitデジタル状態 | 0b00000000 - 0b00000001 | 指定ポートの8bitの状態をbitで表す。2bitめ以降は不使用 |
デジタルのON,OFF状態をbitの0,1として表現します。デジタル状態は8bitのまとまりを1portとして扱いますが、送信データの8bitめは使用できませんので8bitのうち 1-7bitを上位1byteに、8bitめだけを2byteめに埋め込んで、デジタルデータ部分全体で2byteとして送信します。
例として、全てのデジタルpinがONした(0から数えて)1portめの状態を送信する場合を考えます。
1portめの値を送信するので、種別コードは 0x91
となります。
8bit全てONなので、11111111
ですが、8bitめは使えないので8bitめを2byteめに入れ、1byteめの8bitめには0を入れておきます。
00000001 01111111
種別コードを先頭に足した、最終的に送信する電文は
0x91 0x7F(0b01111111) 0x01(0b00000001)
となります。
- アナログメッセージではアナログ状態の取得を行います。
- マイコンからホストコンピュータへ送信した場合は値の通知になります。
内容 | 値 | 説明 |
---|---|---|
種別コード + pin番号 | 0xE0 - 0xEF | 種別コード。0から数えて3番目のpinは"0xE3"となる |
アナログ値下位7bit | 0〜127 | 指定アナログ値の下位7bitの値 |
アナログ値上位7bit | 0〜127 | 指定アナログ値の上位7bitの値 |
アナログ値の送信に使用します。アナログ値は一つの値を下位7bitと上位7bitとに分割して送信します。 デジタル値同様、値送信各1バイトの最上位ビット(8bitめ)は使用できません。
例として、アナログ値327を送信する場合を考えます。
327は00000001 01000111
です。しかし8bitめは使えませんので、下位の8bitめを上位の1ビットめに入れて、上位を全体に1bitずらします。
00000001 01000111 -> 00000010 01000111
下位の8bitめにあった 0
を上位の1bitめにずらして上位bit全体を左にシフトしています。
送信するときは下位 -> 上位の順番ですので、01000111 00000010
として送信します。
この場合、pin番号が3だとすると、送信する電文全体を1バイト16進数で表すと
0xE3 0x47(0b01000111) 0x02(0b00000010)
となります。受け取った側はこれとは逆の操作をして元の値を取り出します。
- Firmataのプロトコルバージョンを通知します。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF9 | 0xF9固定 |
メジャーバージョン番号 | 0〜127 | |
マイナーバージョン番号 | 0〜127 |
バージョン番号を通知します。
例として、バージョン番号 2.3
の場合はメジャーバージョン番号は 2
マイナーバージョン番号は 3
となります。
8bitめは使えませんのでそれぞれが取り得る値は 0〜127となります。
バージョン番号2.3を送る場合は
0xF9 0x02 0x03
となります。
- 指定pinの入出力モードを設定します。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF4 | 0xF4固定 |
pin番号 | 0〜127 | pin番号 |
モード | 0〜4 | 0:入力 1:出力 2:アナログ 3:PWM(アナログ出力) 4:SERVO |
pin番号5をデジタル入力として設定する場合に送信する電文は
0xF4 0x05 0x01
となります。
- 指定アナログpinの、一定時間おき値通知の有効・無効を設定します。
内容 | 値 | 説明 |
---|---|---|
種別コード + pin番号 | 0xC0〜0xCF | pin番号が0から数えて3の場合は0xC3となる |
有効/無効 | 0〜127 | 0:無効 0以外:有効 |
有効/無効のフラグは0か、0以外の値かで判断します。例として4番pinのアナログ値通知を有効にするには
0xC4 0x01
となります。
この設定を有効にした場合、以後は有効にしたpinのアナログメッセージ アナログメッセージ(0xE0 - 0xEF)
を一定時間おきに受け取る事になります。
- 指定デジタルportの、状態変化時通知の有効・無効を設定します。
- デジタル8点を1portとして、状態変化があったportの状態を通知するように設定します。
- 例として4番pinが変化した場合、port0の通知を受け取ります。9番pinの場合はport1となります。
内容 | 値 | 説明 |
---|---|---|
種別コード + port番号 | 0xD0〜0xDF | port番号が0から数えて1の場合は0xD1となる |
有効/無効 | 0〜127 | 0:無効 0以外:有効 |
有効/無効のフラグは0か、0以外の値かで判断します。例として1番portのデジタル変化通知を有効に設定するには
0xD1 0x01
となります。
この設定を有効にした場合、以後はデジタル状態が変化した際に デジタルメッセージ(0x90 - 0x9F)
を受け取る事になります。
- マイコンに対して、Firmataプロトコルのバージョンを通知するように要求します。
- 送信データは種別コードのみです。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF9 | 0xF9固定 |
送信するデータは種別のみですので
0xF9
となります。
このリクエスト送信後にマイコンより バージョン通知(0xF9)
を受け取ります。
SysExメッセージフォーマットは可変長のデータを扱えるデータフォーマットです。SysExフォーマットでのデータでは
- 1byteめは
0xF0
固定 - 2バイトめはSysExコマンドの種別コード(
0x00
-0x7F
) - 3バイトめ以降は任意の長さのデータ
- 最後に
0xF7
で終了
となります。
3バイトめ以降のデータ長は固定されていません。プログラム上では0xF7が出現した時点で一塊のデータを受信し終えたと判断します。
コマンド種類 | コード | 説明 |
---|---|---|
RESERVED_COMMAND | 0x00 | 2nd SysEx data byte is a chip-specific command (AVR, PIC, TI, etc). |
ANALOG_MAPPING_QUERY | 0x69 | ask for mapping of analog to pin numbers |
ANALOG_MAPPING_RESPONSE | 0x6A | reply with mapping info |
CAPABILITY_QUERY | 0x6B | ask for supported modes and resolution of all pins |
CAPABILITY_RESPONSE | 0x6C | reply with supported modes and resolution |
PIN_STATE_QUERY | 0x6D | ask for a pin's current mode and value |
PIN_STATE_RESPONSE | 0x6E | reply with a pin's current mode and value |
EXTENDED_ANALOG | 0x6F | analog write (PWM, Servo, etc) to any pin |
SERVO_CONFIG | 0x70 | set max angle, minPulse, maxPulse, freq |
STRING_DATA | 0x71 | a string message with 14-bits per char |
SHIFT_DATA | 0x75 | shiftOut config/data message (34 bits) |
I2C_REQUEST | 0x76 | I2C request messages from a host to an I/O board |
I2C_REPLY | 0x77 | I2C reply messages from an I/O board to a host |
I2C_CONFIG | 0x78 | Configure special I2C settings such as power pins and delay times |
REPORT_FIRMWARE | 0x79 | report name and version of the firmware |
SAMPLING_INTERVAL | 0x7A | sampling interval |
SYSEX_NON_REALTIME | 0x7E | MIDI Reserved for non-realtime messages |
SYSEX_REALTIME | 0x7F | MIDI Reserved for realtime messages |
- Firmataプロトコルのバージョン番号とファームウエア名称を送信するようにマイコンに要求します。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF0 | 0xF0固定 |
SysEx種別コード | 0x79 | 0x79固定 |
SysEx終了コード | 0xF7 | 0xF7固定 |
送信データは以下のようになります。
0xF0 0x79 0xF7
- Firmataプロトコルのバージョン番号、ファームウエア名称を受信します。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF0 | 0xF0固定 |
SysEx種別コード | 0x79 | 0x79固定 |
メジャーバージョン番号 | 0〜127 | |
マイナーバージョン番号 | 0〜127 | |
ファームウエア名(0-6bit) | 0〜127 | |
ファームウエア名(7-14bit) | 0〜127 | |
ファームウエア名(15-22bit) | 0〜127 | |
..... | 0〜127 | |
SysEx終了コード | 0xF7 | 0xF7固定 |
受信データは以下のようになります。
0xF0 0x79 ...(名称バイナリ)... 0xF7
ファームウエア名は、名称を表す文字列バッファを7bitずつに分け、おのおのの先頭に1bitの0を追加したものになります。
受信した場合はこの逆の操作をし、各バイトから下位7bitを取り出して連結するとファームウエア名称となります。
- マイコンに対して、アナログ値のサンプリング周期を指定します。
- この設定はデジタル状態の通知には影響しません。
内容 | 値 | 説明 |
---|---|---|
種別コード | 0xF0 | 0xF0固定 |
SysEx種別コード | 0x7A | 0x7A固定 |
サンプリング周期(ms)下位 | 0〜127 | サンプリング周期の下位7bitを格納します |
サンプリング周期(ms)上位 | 0〜127 | サンプリング周期の上位7bitを格納します |
SysEx終了コード | 0xF7 | 0xF7固定 |
例として、サンプリング周期を300ミリセカンドに設定したい場合、300
は2進数で 00000001 00101100
であり、8bitめは使用できない為、下位の8bit目を上位1bitめに入れ、上位は左に1bitシフトし 00000010 00101100
を得ます。
送信するデータは 下位
-> 上位
の順であり、これに種別コード、SysExコード、SysEx終了コードを加えると
0xF0 0x7A 0x2C(0b00101100) 0x02(0b00000010) 0xF7
となります。このデータを送信後は、マイコンからの アナログ値通知設定(0xC0 - 0xCF)
受信が300ミリセカンド毎となります。なお、Arduinoの Standard Firmata
でのデフォルトのサンプリング周期は19ミリセカンドです。