Proposals

From Firmata

Revision as of 20:04, 22 November 2011 by Firmata (Talk | contribs)
Jump to: navigation, search

This is a place to propose extensions to the Firmata protocol

Contents

SysEx

The idea for SysEx is to have a second command space using the first byte after the SysEx Start byte. The key difference is that the data can be of any size, rather than just one or two bytes for standard MIDI messages.

#define RESERVED_COMMAND        0x00 // 2nd SysEx data byte is a chip-specific command (AVR, PIC, TI, etc).
#define SERVO_CONFIG            0x70 // set max angle, minPulse, maxPulse, freq
#define STRING_DATA             0x71 // a string message with 14-bits per char
#define PULSE_DATA              0x74 // pulseIn/pulseOut data message (34 bits)
#define SHIFT_DATA              0x75 // shiftOut config/data message (34 bits)
#define I2C_REQUEST             0x76 // I2C request messages from a host to an I/O board
#define I2C_REPLY               0x77 // I2C reply messages from an I/O board to a host
#define I2C_CONFIG              0x78 // Configure special I2C settings such as power pins and delay times
#define REPORT_FIRMWARE         0x79 // report name and version of the firmware
#define SAMPLING_INTERVAL       0x7A // sampling interval
#define SYSEX_NON_REALTIME      0x7E // MIDI Reserved for non-realtime messages
#define SYSEX_REALTIME          0x7F // MIDI Reserved for realtime messages

Extended Analog (added in version 2.2)

As an alternative to the normal analog message, this extended version allows addressing beyond pin 15, and supports sending analog values with any number of bits. The number of data bits is inferred by the length of the message.

/* extended analog
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  extended analog message (0x6F)
 * 2  pin (0 to 127)
 * 3  bits 0-6 (least significant byte)
 * 4  bits 7-13
 * ... additional bytes may be sent if more bits needed
 * N  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */


Capability Query (added in version 2.2)

These queries are intended to allow GUI-based programs to discover the capabilities and current state of any board running Firmata. The idea is to facilitate displaying highly accurate on-screen representation of the board.

The capabilities query provides a list of all modes supported by all pins, and the resolution used by each mode.

/* capabilities query
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  capabilities query (0x6B)
 * 2  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */
/* capabilities response
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  capabilities response (0x6C)
 * 2  1st mode supported of pin 0
 * 3  1st mode's resolution of pin 0
 * 4  2nd mode supported of pin 0
 * 5  2nd mode's resolution of pin 0
 ...   additional modes/resolutions, followed by a single 127 to mark the
       end of the first pin's modes.  Each pin follows with its mode and
       127, until all pins implemented.
 * N  END_SYSEX (0xF7)
 */

Each pin shall have 2 bytes for each supported mode, and a single 127 to mark the end of that pin's data. The number of pins supported shall be inferred by the message length. The GUI should use this query to discover how many pins exist. The list of supported modes may be used to provide a mode configuration menu that only shows the valid choices when the user configures a pin, or disables/grays choices which do not apply. The resolution information may be used to adapt to future implementations where PWM, Analog and others may have different resolution.

Analog Mapping Query (added in version 2.2)

Analog messages are numbered 0 to 15, which traditionally refer to the Arduino pins labeled A0, A1, A2, etc. However, these pins are actually configured using "normal" pin numbers in the pin mode message, and when those pins are uses for non-analog functions. The analog mapping query provides the information about which pins (as used with Firmata's pin mode message) correspond to the analog channels.

/* analog mapping query
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  analog mapping query (0x69)
 * 2  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */
/* analog mapping response
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  analog mapping response (0x6A)
 * 2  analog channel corresponding to pin 0, or 127 if pin 0 does not support analog
 * 3  analog channel corresponding to pin 1, or 127 if pin 1 does not support analog
 * 4  analog channel corresponding to pin 2, or 127 if pin 2 does not support analog
 ...   etc, one byte for each pin
 * N  END_SYSEX (0xF7)
 */

The above 2 queries provide static data (should never change for a particular board). Because this information is fixed and should only need to be read once, these messages are designed for a simple implementation in StandardFirmata, rather that bandwidth savings (eg, using packed bit fields).

Pin State Query (added in version 2.2)

The pin state query allows the GUI to read the current configuration of any pin. Normally this is needed when a GUI-based program starts up, so it can populate on-screen controls with an accurate representation of the hardware's configuration. This query can also be used to verify pin mode settings are received properly.

/* pin state query
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  pin state query (0x6D)
 * 2  pin (0 to 127)
 * 3  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */
/* pin state response
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  pin state response (0x6E)
 * 2  pin (0 to 127)
 * 3  pin mode (the currently configured mode)
 * 4  pin state, bits 0-6
 * 5  (optional) pin state, bits 7-13
 * 6  (optional) pin state, bits 14-20
 ...  additional optional bytes, as many as needed
 * N  END_SYSEX (0xF7)
 */

The pin "state" is any data written to the pin. For output modes (digital output, PWM, and Servo), the state is any value that has been previously written to the pin. A GUI needs this state to properly initialize any on-screen controls, so their initial settings match whatever the pin is actually doing. For input modes, typically the state is zero. However, for digital inputs, the state is the status of the pullup resistor.

The pin state query can also be used as a verification after sending pin modes or data messages.


pulseIn/pulseOut

/* pulseIn/Out (uses 32-bit value)
 * -------------------------------
 * 0  START_SYSEX (0xF0) (MIDI System Exclusive)
 * 1  pulseIn/Out (0x74)
 * 2  dataPin (0-127)
 * 3  bits 0-6 (least significant byte)
 * 4  bits 7-13
 * 5  bits 14-20
 * 6  bits 21-27
 * 7  bits 28-34 (most significant byte)
 * 8  END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
 */


ShiftOut

Supporting shift registers should be possible without much difficulty now that sysex has been implemented.

/* shiftIn/Out (uses 8-bit value)
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  shiftOut (0x75)
 * 2  dataPin (0-127)
 * 3  clockPin (0-127)
 * 4  latchPin (0-127)
 * 5  msbFirst (boolean)
 * 6  bits 0-6 (least significant byte)
 * 7  bit 7 (most significant bit)
 * n  ... (as many byte pairs as needed)
 * n+1  END_SYSEX (0xF7)
 */

Or perhaps this should be more like the servo messages, with a SET_PIN_MODE-specific mode, like SHIFT, then a SHIFT_CONFIG message.

/* shiftIn/Out config
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  SHIFT_CONFIG
 * 2  dataPin (0-127)
 * 3  clockPin (0-127)
 * 4  latchPin (0-127)
 * 5  msbFirst (boolean)
 * 6  END_SYSEX (0xF7)
 */


/* shiftIn/Out data (total bits chopped to multiple of 8 so extra bits are ignored)
 * ------------------------------
 * 0   START_SYSEX (0xF0)
 * 1   SHIFT_DATA
 * 2   dataPin (0-127)
 * 3   bits 0-6 (least significant byte)
 * 4   bits 7-13
 * 5   bits 14-20
 * 6   bits 21-27
 * n   ...
 * n+1 END_SYSEX (0xF7)
 */


Stepper Motor Proposal

Listed below is the current implementation as created for the Maxuino project. It is useable only for stepper drivers that use the STEP and DIRECTION input configuration (most of the mainstream ones fall into this catagory). It will not work for those rolling their own directly controlled steppers (using darlington arrays and such). Feedback appreciated.

/* Stepper CONFIG
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  Stepper Command (0x67)
 * 2  config command (0)    //0=config subcommand, 1=step subcommand, 2=speed subcommand 
 * 3  device# (0-5)  //supporting 6 motors at the moment
 * 4  steps-per-revolution lsb (least significant byte)
 * 5  steps-per-revolution msb  (most significant bit)  //the common rage is 100-400 but I am unsure of how much more flexibility might eat resources
 * 6  directionPin# (0-127)
 * 7  stepPin# (0-127)
 * 8  END_SYSEX (0xF7)
 */
/* Stepper STEP
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  Stepper Command (0x67)
 * 2  config command (1)
 * 3  device# (0-5)
 * 4  #steps lsb (least significant byte)
 * 5  #steps msb  (most significant byte)  //it is not uncommon to need to send tens of thousands of steps
 * 6  direction (0-1)   //doubles the range of steps for positive and negative
 * 7  END_SYSEX (0xF7)
 */
/* Stepper SPEED
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  Stepper Command (0x67)
 * 2  config command (2)
 * 3  device# (0-5)
 * 4  #speed lsb (least significant byte)
 * 5  #speed msb  (most significant byte) 
 * 6  END_SYSEX (0xF7)
 */

Hardware Pin Querying (old proposal)

This functionality was added via the capability query in version 2.2. This section should probably be deleted.

Get the available pins and resolution that the device supports.

/* hardwareSetup query request
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  hardwareSetup (0x??)
 * 2  END_SYSEX (0xF7)
 */
/* hardwareSetup data message
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  hardwareSetup (0x??)
 * 2  analog pins (0-127)
 * 3  analog resolution (0-127)
 * 4  digital pins (0-127)
 * 5  PWM resolution (0-127)
 * 6  PWM pin (0-127)
 * 7  next PWM pin (0-127)
 * ...
 * n  END_SYSEX (0xF7)
 */


Report Available Pin Modes (old proprosal)

This functionality was added via the capability query in version 2.2. This section should probably be deleted.

This is from a proposal by Shigeru. This is tricky because it needs to be a giant bitmask with each bit representing a boolean value of whether that pin mode is supported or not. This is basically like a HID Descriptor. This version removes the "number of pins" value of Shigeru's proposal. The number of pins can be easily derived from the number of bytes.

/* availablePinModes
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  availablePinModes (0x??)
 * 2  The available pin modes for the 0th pin (0b0000000-0b1111111)
 * 3  The available pin modes for the 1st pin (0b0000000-0b1111111)
 * ...
 * n  END_SYSEX (0xF7)
 */

Report Pin Configuration (old proprosal)

This functionality was added via the pin state query in version 2.2. This section should probably be deleted.

This is from a proposal by Shigeru, Massimo has also expressed interest in having an API for reporting pin configurations. This version removes the "number of pins" value of Shigeru's proposal. The number of pins can be easily derived from the number of bytes.

/* pinSettings
 * ------------------------------
 * 0  START_SYSEX (0xF0)
 * 1  pinSettings (0x??)
 * 2  port mode of the 0th pin (0-6)
 * 3  resolution of the 0th pin (0-127)
 * 4  port mode of the 1st pin (0-6)
 * 5  resolution of the 1st pin (0-127)
 * ...
 * n  END_SYSEX (0xF7)
 */


Query Pull-up Resistor Status

When a digital pin is in INPUT mode, setting the pin HIGH will turn on the internal pull-up resistors. It could be useful to query the state of that pin somehow.

SPI

There has been some preliminary work done on including SPI in Firmata. It would most likely be based on SysEx.

Building and dependencies

I've searched for Firmata java library not depending from Processing sources to use in JaxaFX 2.0 or in Android projects. So i does not exist at this moment( I suggest to:

1. create Firmata class out of existing Arduino, which will work with ... 
2. ISerial interface
3. create adapters (Processing, regular Java, Android) which implement ISerial interface and use concrete implementation

Also suggest to use Maven as build tool as it is java wide used practice. Can make it myself (dev [at] antonsmirnov [dot] name)

Personal tools