Project log: More about the Arduino Uno + “reprap d1scount display” and “rrd smart adapter”. Rotary encoder button debouncing.

Continuing from the previous entry, I have completed the mapping of pins to the so-called rrd smart adapter. This board is meant for 3D printers of some kind but I am not using it for that purpose. I got it simply because it is a useful board for my purposes and my local shop had it in stock. Anyhow, here is the complete pinout. The indicated Arduino pins are not indicative of much, just what I am using for my application at the moment.

rrd adapter 2.png
The colors don’t mean anything in particular.

There are no pull-ups on the rotary pins, so you must declare them in AVR.

pinMode(PIN_ROTBTN, INPUT_PULLUP);
pinMode(PIN_ROTIN1, INPUT_PULLUP);
pinMode(PIN_ROTIN2, INPUT_PULLUP);

Unfortunately when trying to use the rotary encoder I get back a lot of signal bounce. This issue could have been avoided in hardware using some simple passives but they are missing on the board. On to finding a mitigation solution short of soldering some caps on there.

The solution is to add some debouncing to each pin, and to then go through a state transition table to filter out invalid moves. This works because the rotary encoder moves through a gray-code type phase system, with a new step is indicating by a transition back to phase 0 after going through the four phases. I used the library Bounce2 by Thomas Ouellet Fredericks to simplify a little bit, I would recommend the library for general button debouncing use.

#include <Bounce2.h>

Bounce bounce2 = Bounce();
Bounce bounce3 = Bounce();

int position = 0;
enum
{
  INVALID,
  CW,
  CCW,
};

uint8_t table[] = {0,1,2,0,2,0,0,1,1,0,0,2,0,2,1,0};

void setup() {
  bounce2.attach(3, INPUT_PULLUP);
  bounce3.attach(2, INPUT_PULLUP);
  bounce2.interval(10);
  bounce3.interval(10);
  
  Serial.begin(9600); // start the serial monitor link
  Serial.print("hello\n");
}

void loop(){
  static int previous = 0;

  bounce2.update();
  bounce3.update();

  // get current state.
  bool A = bounce2.read();
  bool B = bounce3.read();

  int current = (A << 1) | B;

  if (current != previous) {
    // state transition
    uint8_t direction = table[ (previous << 2) | current ];

    if (direction != INVALID) {

      if (direction == CW && current == 0) position++;
      if (direction ==CCW && current == 0) position--;

      previous = current;
  
      Serial.println(position);
    }
  }

out:
  return;
  
}
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s