5 Pin Rotary Encoder

A custom Arduino node that reads a rotary encoder's value using 2 interrupt pins. Also uses a digital input node to capture a click event when pushing the rotary encoder in.

See here for a tutorial about using this node group.

Supported Products

  • 5 Pin Rotary Encoder with On Switch
  • 5Pin D Shaft 20 Detents Points 360 Degree Rotary Encoder w Push Button

Decleration Code

// Using a 5 pin rotary encoder made by Keyes from the 37 in 1 Sensor Kit

const int encoderPinA = 3;     // right (labeled DT on our decoder)
const int encoderPinB = 2;     // left (labeled CLK on our decoder)

volatile unsigned int encoderPos = 0;     // a counter for the dial

int encoderMax = 20; // The # of ticks in a 0.0 to 1.0 activation range
bool rollover = false; // Activation stops at 0.0 and 1.0 when false

// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;

void doEncoderA(){
    // Test transition, did things really change?
    if( digitalRead(encoderPinA) != A_set )
    {
        A_set = !A_set;
        // adjust counter + if A leads B
        if ( A_set && !B_set )
        {
            // Increment or roll over
            if (encoderPos < encoderMax)
            {
                encoderPos += 1;
            }
            else if (rollover)
            {
                encoderPos = 0;
                FireTrigger(Output_ForwardRollover);
            }
        }
    }
}

void doEncoderB(){
    if( digitalRead(encoderPinB) != B_set )
    {
        B_set = !B_set;
        //    adjust counter - 1 if B leads A
        if( B_set && !A_set )
        {
            // Decrement or roll over
            if (encoderPos > 0)
            {
                encoderPos -= 1;
            }
            else if (rollover)
            {
                encoderPos = encoderMax;
                FireTrigger(Output_BackwardRollover);
            }
        }
    }
}

Setup Code

pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);

// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);

// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);

EveryUpdate

Output_Activation = transform(encoderPos, 0, encoderMax, 0.0, 1.0);

Trigger

encoderPos = transform(Input_SetActivation, 0.0, 1.0, 0, encoderMax);

InputChange

rollover = Input_Rollover > 0.5;

No required source files.

To use this node in your Embrio project, either add it from the Library toolbar or copy the XML in the below box and paste it into a node screen.

To use this node group, create a new agent called “Rotary Encoder”, or something similar, and add these 3 nodes to the agent. There should be nothing else on the agent unless it is directly related to encapsulation of the encoder. To use the encoder values, add this Rotary Encoder agent to the target node screen.

You might have to change a few things in the custom Arduino node. First, the encoderPinA and B variables use pins 2 and 3, which are the interrupt pins on the Arduino Nano. If you are using a different Arduino model, look up which pins are interrupt enabled.

The encoder this code was tested with has 20 clicks per revolution. If your encoder has a different amount, or you don’t necessarily want only 1 turn of the knob to take up the full output Activation range of 0.0 to 1.0 you can enter a different value for encoderMax.

That should be all you have to change. You can set the Rollover value on the node below 0.5 to turn off rollover, or above 0.5 to turn it on. When it is on, the output Activation will go from 1 back down to 0, or 0 back to 1, and the appropriate rollover trigger will fire.

Also note that the button press is connected to the reset trigger on the encoder node, if you don't want the button to reset the encoder you can remove that connection.

View Comments (0)