firmata/arduino — pull request #115 by nicolaspanel (2014-02-14 11:10:01+00:00)
Title: Encoder Feature

Provide incremental encoders support, for both [linear](http://en.wikipedia.org/wiki/Linear_encoder) and [rotary](http://en.wikipedia.org/wiki/Rotary_encoder#Incremental_rotary_encoder) encoders.

This feature is based on based on [PJRC's implementation](http://www.pjrc.com/teensy/td_libs_Encoder.html) (see [article](http://www.pjrc.com/teensy/td_libs_Encoder.html) for more informations about how it works, well explained!).

Testing :
* Unit tests are in /test/encoder_test/encoder_test.ino. All tests are passing using [arduinounit](https://github.com/nicolaspanel/arduinounit) (note : I made a little change on arduinounit to support FakeStream#flush function. This changes should be integrated soon in main arduinounit repo, see [PR#31](https://github.com/mmurdoch/arduinounit/pull/31))
* I made end-to-end tests using [firmata for node](https://github.com/jgautier/firmata). All tests passing.

Example files :
* I updated ConfigurableFirmata.ion to include EncoderFeature. I use this firmware for my end-ti-end tests (no regression/conflicts found). As is, it takes between 25kbytes and 30kbytes.
* I also create dedicated example SimpleEncoderFirmata.ino

Protocol :
```c
/* =====================================================
* Encoder PROTOCOL
* =====================================================
*
* Attach encoder query
* -----------------------------------------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_ATTACH (0x00)
* 3 encoder # ([0 - MAX_ENCODERS-1])
* 4 pin A # (first pin)
* 5 pin B # (second pin)
* 6 END_SYSEX (0xF7)
* -----------------------------------------------------
*
* Report encoder's position
* -----------------------------------------------------
* Sysex Query
* ------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_REPORT_POSITION (0x01)
* 3 encoder # ([0 - MAX_ENCODERS-1])
* 4 END_SYSEX (0xF7)
*--------------------
* MIDI Response
* ------------------
* 0 ENCODER_MESSAGE (0x80) | Channel (encoder #, 0-4)
* 1 direction (positive = 0, negative = 1)
* 2 current position, bits 0-6
* 3 current position, bits 7-13
* 4 current position, bits 14-20
* 5 current position, bits 21-27
* -----------------------------------------------------
*
* Report all encoders positions
* -----------------------------------------------------
* Sysex Query
* ------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_REPORT_POSITIONS (0x02)
* 3 END_SYSEX (0xF7)
*--------------------
* Sysex Response
* ------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 first encoder # ([0 - MAX_ENCODERS-1])
* 3 first enc. dir. (positive = 0, negative = 1)
* 4 first enc. position, bits 0-6
* 5 first enc. position, bits 7-13
* 6 first enc. position, bits 14-20
* 7 first enc. position, bits 21-27
* ...
* N END_SYSEX (0xF7)
* -----------------------------------------------------
*
* Reset encoder position to zero (Sysex Query)
* -----------------------------------------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_RESET_POSITION (0x03)
* 3 encoder # ([0 - MAX_ENCODERS-1])
* 4 END_SYSEX (0xF7)
* -----------------------------------------------------
*
* Enable/disable reporting (Sysex Query)
* -----------------------------------------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_REPORT_AUTO (0x04)
* 3 enable (0x00 => false, true otherwise)
* 4 END_SYSEX (0xF7)
* -----------------------------------------------------
*
* Detach encoder (Sysex Query)
* -----------------------------------------------------
* 0 START_SYSEX (0xF0)
* 1 ENCODER_DATA (0x61)
* 2 ENCODER_DETACH (0x05)
* 3 encoder # ([0 - MAX_ENCODERS-1])
* 4 END_SYSEX (0xF7)
*--------------------
*/
```

I will send a pull request to `firmata / protocol` repository later.

Next steps : I'm currently working on [firmata for node](https://github.com/jgautier/firmata) and [johnny-five](https://github.com/rwaldron/johnny-five) to make this feature available for node developpers.