/* Generic Sysex Message
* 0 START_SYSEX (0xF0)
* 1 sysex command (0x00-0x7F)
* x between 0 and MAX_DATA_BYTES 7-bit bytes of arbitrary data
* last END_SYSEX (0xF7)
*/
// extended command set using sysex (0-127/0x00-0x7F)
/* 0x00-0x0F reserved for user-defined commands */
#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
#define STRING_DATA 0x71 // a string message with 14-bits per char
#define SHIFT_DATA 0x75 // a bitstream to/from a shift register
#define I2C_REQUEST 0x76 // send an I2C read/write request
#define I2C_REPLY 0x77 // a reply to an I2C read request
#define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
#define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
#define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
#define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
#define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
#define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
#define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
#define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
#define REPORT_FIRMWARE 0x79 // report name and version of the firmware
#define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
// these are DEPRECATED to make the naming more consistent
#define FIRMATA_STRING 0x71 // same as STRING_DATA
#define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
#define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
#define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
実装するもの
Sysexコマンド
PC-Firmata間で2byte以上のデータをやりとりする時に使う。StandardFirmataではArduino→PCへのDIGITAL_MESSAGE, ANALOG_MESSAGE, REPORT_VERSIONで使われている。 自作のコマンドを実行させるのにも使われる。
[START_SYSEX, コマンド名, 7bitを32個分のデータ, END_SYSEX] を1セットとして送信する。 http://firmata.org/wiki/V2.1ProtocolDetails#Sysex_Message_Format
MAX_DATA_BYTESは /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata/Firmata.h で定義されている。 デフォルトで7bitのデータを最大32個送れる。
既に定義されているsysex command。0x00-0x0Fはユーザが自分のアプリ内で定義していいらしい。
現在のgem内での実装
arduino_firmata gemでは、START_SYSEXとEND_SYSEXが const.rbで定義されてる https://github.com/shokai/arduino_firmata/blob/master/lib/arduino_firmata/const.rb
ArduinoFirmata::Arduino::write関数はprivateにしてある。 PC→Arduinoへsysexコマンドを送る関数を作る必要アリ。 Arduino→PCにコマンドが来た時のイベントも登録できるようにしたい。
Arduino側にSysexコマンドを登録する
/Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata/Firmata.cpp にあるattach関数にsysex command (0x00-0x7F)を引数として、コールバックを登録する。
http://firmata.org/wiki/V2.1ProtocolDetails#Sysex_Message_Format を見ると、0x00~0x0Fはユーザが自由に使って良い様に予約されているんだけど、登録しても現在Arduino IDEに付属しているFirmata.cpp内では呼び出されるように実装されてない。
方法は2つで、
のどちらか。
1. STRING_DATA (0x71)コマンドが来た時のイベントを登録
STRING_DATAは自作アプリで使える。
STRING_DATA (0x71)はFirmata.cpp内でコールバックとして登録できるようになっているが、Arduino IDE付属のStandardFirmata.inoからは使われていない。
スケッチ例のEchoStringで使ってる。
2. Sysexを受信した時のコールバック関数を登録
StandardFirmataの void sysexCallback(byte command, byte argc, byte *argv) 関数内のswitch文に書き足すといい。 I2C関係はここで定義されている。
参考になる