Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
2 contributors

Users who have contributed to this file

@nicolaspanel @soundanalogous
179 lines (154 sloc) 5.64 KB

#Encoder Feature

Provide incremental encoders support, for both linear and rotary encoders.

This feature is based on based on PJRC's implementation. See this article for more informations about how it works (well explained!).

Current implementation supports 5 encoders at the same time (#[0-4]) and you can activate automatic position reports every (SAMPLING_INTERVAL)ms. Reports are disabled by default.

For best Performances, connect only interrupt pins.

Added in Firmata protocol version 2.4.0.

Example files :

Compatible client librairies

TODO : Update this

Tested boards

This feature has been tested on :

  • Arduino Uno
  • Arduino Mega
  • Arduino Leonardo
  • Arduino Due

Protocol details

The protocol below use exclusively SysEx queries and SysEx responses.

Attach encoder query

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)
 * -----------------------------------------------------
 */

No response.

Report encoder's position

Query

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 ENCODER_REPORT_POSITION    (0x01)
 * 3 Encoder #                  ([0 - MAX_ENCODERS-1])
 * 4 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

Response

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 Encoder #  &  DIRECTION    [= (direction << 6) | (#)]
 * 3 current position, bits 0-6
 * 4 current position, bits 7-13
 * 5 current position, bits 14-20
 * 6 current position, bits 21-27
 * 7 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

Note : Byte #2 contains both encoder's number (i.e. channel) and encoder's direction. Direction is stored on the seventh bit, 0 (LOW) for positive and 1 (HIGH) for negative.

directionMask = 0x40; // B01000000
channelMask   = 0x3F; // B00111111 

//ex direction is negative and encoder is on index 2
direction = 1;
channel = 2;
bytes[2] =  (direction << 6) | (channel);

Report all encoders positions

Query

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 ENCODER_REPORT_POSITIONS   (0x02)
 * 3 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

Response

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 first enc. #  & first enc. dir. 
 * 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
 * 8 second enc. #  & second enc. dir. 
 * ...
 * N END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

Note : Report encoder's position response is a special case of Report all encoders positions response.

Reset encoder position to zero

Query

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 ENCODER_RESET_POSITION     (0x03)
 * 3 encoder #                  ([0 - MAX_ENCODERS-1])
 * 4 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

No response.

Enable/disable reporting

Query

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 ENCODER_REPORT_AUTO        (0x04)
 * 3 enable                     (0x00 => false, true otherwise)
 * 4 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

No response.

Note : when reports are enabled, EncoderFirmata feature send the message below at every SAMPLING interval (19ms by default) :

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 first enc. #  & first enc. dir.   [= (direction << 6) | (#)] 
 * 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
 * 8 second enc. #  & second enc. dir. [= (direction << 6) | (#)]
 * ...
 * N END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

Detach encoder

Query

 /* -----------------------------------------------------
 * 0 START_SYSEX                (0xF0)
 * 1 ENCODER_DATA               (0x61)
 * 2 ENCODER_DETACH             (0x05)
 * 3 encoder #                  ([0 - MAX_ENCODERS-1])
 * 4 END_SYSEX                  (0xF7)
 * -----------------------------------------------------
 */

No response.

You can’t perform that action at this time.