Giter Site home page Giter Site logo

rotary's Introduction

Rotary Encoder Arduino Library

Arduino library for reading rotary encoders that output a 2-bit gray code.

Rotary r = Rotary(2, 3);

void setup() {
  r.begin();
}

void loop() {
  result = r.process();
  if (result) {
    Serial.println(result == DIR_CW ? "Right" : "Left");
  }
}

This is a repackaged version of Ben Buxton's excellent rotary library organized for the Arduino 1.x IDE, keyword highlighting, polling example, Arduino library capitalization conventions.

Features

  • Debounce handling with support for high rotation speeds
  • Correctly handles direction changes mid-step
  • Checks for valid state changes for more robust counting / noise immunity
  • Interrupt based or polling in loop()
  • Counts full-steps (default) or half-steps
  • Supports use with pull-up (default) and pull-down resistors

Installation / Usage

  1. Download and unzip to Arduino\libraries\Rotary. So for example Rotary.h will be in Arduino\libraries\Rotary\Rotary.h.
  2. Restart Arduino IDE
  3. File -> Examples -> Rotary

Note: Resistor usage is specified through void begin(bool internalPullup=true, bool flipLogicForPulldown=false).

  • r.begin() enables the Arduino's internal weak pull-ups for the rotary's pins
  • r.begin(false) disables the Arduino's internal weak pull-ups for the given pins and configures the rotary for use with external pull-ups
  • r.begin(false, true) disables the internal pull-ups and flips the pin logic for use with external pull-downs

Background

A typical mechanical rotary encoder emits a two bit gray code on 3 output pins. Every step in the output (often accompanied by a physical 'click') generates a specific sequence of output codes on the pins.

There are 3 pins used for the rotary encoding - one common and two 'bit' pins.

The following is the typical sequence of code on the output when moving from one step to the next:

Position   Bit1   Bit2
- - - - - - - - - - - 
Step1       0      0
 1/4        1      0
 1/2        1      1
 3/4        0      1
Step2       0      0

From this table, we can see that when moving from one 'click' to the next, there are 4 changes in the output code.

  • From an initial 0 - 0, Bit1 goes high, Bit0 stays low.
  • Then both bits are high, halfway through the step.
  • Then Bit1 goes low, but Bit2 stays high.
  • Finally at the end of the step, both bits return to 0.

Detecting the direction is easy - the table simply goes in the other direction (read up instead of down).

To decode this, we use a simple state machine. Every time the output code changes, it follows state, until finally a full steps worth of code is received (in the correct order). At the final 0-0, it returns a value indicating a step in one direction or the other.

It's also possible to use 'half-step' mode. This just emits an event at both the 0-0 and 1-1 positions. This might be useful for some encoders where you want to detect all positions. In Rotary.h, uncomment #define HALF_STEP to enable half-step mode.

If an invalid state happens (for example we go from '0-1' straight to '1-0'), the state machine resets to the start until 0-0 and the next valid codes occur.

The biggest advantage of using a state machine over other algorithms is that this has inherent debounce built in. Other algorithms emit spurious output with switch bounce, but this one will simply flip between sub-states until the bounce settles, then continue along the state machine. A side effect of debounce is that fast rotations can cause steps to be skipped. By not requiring debounce, fast rotations can be accurately measured. Another advantage is the ability to properly handle bad state, such as due to EMI, etc. It is also a lot simpler than others - a static state table and less than 10 lines of logic.

License

GNU GPL Version 3

rotary's People

Contributors

brianlow avatar mortalfool avatar pat1 avatar per1234 avatar snt avatar steveguidi avatar uchip avatar voneiden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rotary's Issues

where to put?

do i just put the "Rotary.h" file into the atom folder and do i do the same thing with other libraries i download?

Compliment

Thanks for making this library (and sorry for abusing issues for this message).

It is such a brilliant library. Before I used the Encoder library and my cheap encoders where behaving really jaggy. I thought its the encoders but with the Rotary library, the encoders work incredible and super smooth. They never return a wrong direction, even in half step mode.

Much love and much appreciated! ๐Ÿ’™

question: multiple rotary encoders

Hello. I am currently using your library. Wanted to know how setup() routine should be defined so that two rotary encoders could be used. for instance in an Arduino Mega..
Thanks.

Maintainer Help

I could use help maintaining this project.

If interested, feel free to:

  • comment on issues to help others, ask for more info
  • close issues (*)
  • review PRs
  • merge PRs (*)
  • (*) ping me for admin access

This is a project by a hobbyist for other hobbyists. You don't need to be an expert. If unsure ask. Also feel free to help without asking permission. Just be courteous to others.

Example sketch of Pro Micro

The example sketch of Pro Micro informs that "These registers support interrupts on Pro Micro pins 8, 9, 10 or 11". But there is no pin 11 available on Pro Micro. I am stuck as I want to use 2 rotary encoders with 1 pro micro board. Please guide.
BTW, Thanks for this awesome library. It generates pretty robust cw and ccw.
Waiting for response.
Regards,
Ravi

Changes detected only after two mechanical steps

Hi all,

I am quite new to Arduino, just managed to gather enough info for writing a sketch for a dishwasher and it is working. I used this library for the rotary encoder based menu. But changes are only detected after two mechanical steps, I cannot find a way to detect every single click. I tried with #define HALF_STEP but made no change. The encoder is a KY-040:

https://www.rcscomponents.kiev.ua/datasheets/ky-040-datasheet.pdf

Any help appreciated, thanks !

Quarter step

Hi all,

Do this library support quarter encoder step?

Will be really handly to support this, as the library is really compact and lightweight.

Thakns for supporting!

Encoder requires two clicks in opposite direction to register a change in direction

Encoder library works fine incrementing up or down but when a direction change occurs the first encoder click in the opposite direction doesn't register anything, a second click in the same opposite direction registers an increment in the changed direction.

Code I am using below (basically your example code with SPI OLED screen display added)

/**************************************************************************
 This is an example for our Monochrome OLEDs based on SSD1306 drivers

 Pick one up today in the adafruit shop!
 ------> http://www.adafruit.com/category/63_98

 This example is for a 128x64 pixel display using SPI to communicate
 4 or 5 pins are required to interface.

 Adafruit invests time and resources providing this open
 source code, please support Adafruit and open-source
 hardware by purchasing products from Adafruit!

 Written by Limor Fried/Ladyada for Adafruit Industries,
 with contributions from the open source community.
 BSD license, check license.txt for more information
 All text above, and the splash screen below must be
 included in any redistribution.
 **************************************************************************/

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold24pt7b.h>
#include <Rotary.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Comment out above, uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RESET, OLED_CS);

// Rotary encoder is wired with the common to ground and the two
// outputs to pins 2 and 3.
Rotary rotary = Rotary(2, 3);

// Counter that will be incremented or decremented by rotation.
int counter = 0;

void setup() {
  Serial.begin(57600);
  attachInterrupt(2, rotate, CHANGE);
  attachInterrupt(3, rotate, CHANGE);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Clear initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.clearDisplay();
  display.display();
  display.setFont(&FreeSansBold24pt7b);
}

void loop() {
  
}

void writeNumber(int num) {
  display.clearDisplay();
  display.setCursor(0,48);             // Start at top-left corner
  display.setTextSize(1);             // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.println(num);
  display.display();
}

// rotate is called anytime the rotary inputs change state.
void rotate() {
  unsigned char result = rotary.process();
  if (result == DIR_CW) {
    counter++;
    Serial.print("Counter: ");
    Serial.println(counter);
    //writeNumber(counter);
  } else if (result == DIR_CCW) {
    counter--;
    Serial.print("Counter: ");
    Serial.println(counter);
    //writeNumber(counter);
  }
}

does click supported ?

am wondering if click are supported or not , i think will be good if click support is added too

Rotary switch type

I want to make a controller for a si5351 signal generator, and have found a sketch which uses Rotary.h. I notice that Rotary.h is designed for a switch which makes 4 changes per click. I have bought a typical switch from ebay, but find that it makes just one change of state per click, going 00, 01, 11, 00 over 4 clicks. Is there any way in which rotary.h can be used or modified to suit this type of switch ? An alternative approach would be to find the intended type of switch which makes all 4 changes in 1 click. But where does one look for this type of switch ? I suspect that all of the easily available switches on ebay advertised as being suitable for arduino projects are of the simpler type making one change per click. Comments much appreciated

support reactive callbacks

please add support for reactive callbacks, i.e.:

class RotaryReactor: public Rotary {
private:
    static void noop() {
    }
    void (*reactorPositive)() = &noop;
    void (*reactorNegative)() = &noop;
public:
    RotaryReactor(char pinA, char pinB) :
            Rotary(pinA, pinB) {
    }
    void attachReactorPositive(void (*reactor)()) {
        reactorPositive = reactor;
    }
    void attachReactorNegative(void (*reactor)()) {
        reactorNegative = reactor;
    }
    void react() {
        unsigned char result = this->process();
        if (result == DIR_CW) {
            reactorPositive();
        } else if (result == DIR_CCW) {
            reactorNegative();
        }
    }
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.