Skip to main content

Meadow.Foundation.Sensors.Rotary.RotaryEncoderWithButton

RotaryEncoderWithButton
StatusStatus badge: working
Source codeGitHub
NuGet packageNuGet Gallery for Meadow.Foundation

Rotary encoders are similar in form factor to potentiometers, but instead of modifying a voltage output, they send a digital signal encoded using Gray Code when rotated that can be decoded to ascertain the direction of turn.

Rotary encoders have several advantages over potentiometers as input devices, namely:

  • They’re more power efficient; they only use power when actuated.
  • They’re not rotation-bound; they spin infinitely in either direction.
  • Many rotary encoders also have a built-in pushbutton.

Rotary encoders are used almost exclusively on things like volume knobs on stereos.

And because they’re not rotation bound, they are especially useful in the case in which a device might have multiple inputs to control the same parameter. For instance, a stereo’s volume might be controlled via a knob and a remote control. If a potentiometer were used for the volume knob, then the actual volume could get out of synch with the apparent value on the potentiometer when the volume was changed via the remote.

For this reason, rotary encoders are particularly useful in connected things, in which parameters might be controlled remotely.

Code Example

protectedintvalue=0;
protectedRotaryEncoderWithButton rotaryEncoder;

publicoverrideTaskInitialize()
{
Resolver.Log.Info("Initializing Hardware...");

// Note: on the rotary encoder in the hack kit, the pinout is as
// follows:
//
// | Encoder Name | Driver Pin Name |
// |--------------|-----------------|
// | `SW` | `buttonPin` |
// | `DT` | `aPhasePin` |
// | `CLK` | `bPhasePin` |

// initialize the encoder
rotaryEncoder =newRotaryEncoderWithButton(Device.Pins.D07, Device.Pins.D08, Device.Pins.D06);

//==== Classic Events
rotaryEncoder.Rotated += RotaryEncoder_Rotated;

rotaryEncoder.Clicked +=(s, e)=> Resolver.Log.Info("Button Clicked");

rotaryEncoder.PressEnded +=(s, e)=> Resolver.Log.Info("Press ended");

rotaryEncoder.PressStarted +=(s, e)=> Resolver.Log.Info("Press started");

Resolver.Log.Info("Hardware initialization complete.");

return Task.CompletedTask;
}

privatevoidRotaryEncoder_Rotated(object sender,RotaryChangeResult e)
{
switch(e.New)
{
case RotationDirection.Clockwise:
value++;
Resolver.Log.Info($"/\\ Value = {value} CW");
break;
case RotationDirection.CounterClockwise:
value--;
Resolver.Log.Info($"\\/ Value = {value} CCW");
break;
}
}

Sample project(s) available on GitHub

###Two-bit Gray Code

This rotary encoder driver works with most rotary encoders which return a two-bit Gray Code which is the minimum number of bits necessary to describe direction. Most common rotary encoders use two-bit Gray Code, so this driver should work with most common rotary encoders.

###PushButton

Some rotary encoders, such as the ones pictured above, have an integrated push button. This driver exposes that button as a PushButton via the Button property.

The following example shows how to register event handlers to print in the console when pressing and relasing the push button:

publicclassMeadowApp:App<F7Micro, MeadowApp>
{
protectedRotaryEncoderWithButton _rotary =null;
protectedPwmLed _led =null;
// how much to change the brightness per rotation step.
// 0.05 = 20 clicks to 100%
protectedfloat _brightnessStepChange =0.05F;

publicMeadowApp()
{
// instantiate our peripherals
_rotary =newRotaryEncoderWithButton(Device, Device.Pins.D07, Device.Pins.D08, Device.Pins.D06);
_rotary.Rotated += RotaryRotated;
_rotary.Clicked += RotaryClicked;

_led =newPwmLed(Device.Pins.D12, TypicalForwardVoltage.Red);
}

protectedvoidRotaryRotated(object sender,RotaryTurnedEventArgs e)
{
// if clockwise, turn it up! clamp to 1, so we don't go over.
if(e.Direction == RotationDirection.Clockwise)
{
if(_led.Brightness >=1)
{
return;
}
else
{
_led.SetBrightness((_led.Brightness +
_brightnessStepChange).Clamp(0,1));
}
}
else// otherwise, turn it down. clamp to 0 so we don't go below.
{
if(_led.Brightness <=0)
{
return;
}
else
{
_led.SetBrightness((_led.Brightness -
_brightnessStepChange).Clamp(0,1));
}
}
}

privatevoidRotaryClicked(object sender,EventArgs e)
{
if(_led.Brightness >0)
{
_led.SetBrightness(0f);
}
else
{
_led.SetBrightness(_lastOnBrightness);
}
}
}

Sample projects available on GitHub

Wiring Example

close