Micro Pro Rotary Switch Programming

I have found several topics here but I am not experienced enough to follow along with the solutions.

I have micro pro and rotary encoders. I have a flight sim with a helicopter collective that is in desperate need of a throttle addition. I think this is the way to do it. I also have an ESP32 if that is a better option.

I have no idea where to start. Anyone willing to help?

  • Yes, that is a rotary encoder, probably with an integrated push button switch.

  • There are a lot of examples out there, in what area do you need help ?

See this YouTube video:

Larry, thank you for replying.

Yes it has a push button switch that I do not require for this particular project.

Honestly, I need help with quite a bit. I'd love to know the best way to get this rotary encoder wired to the micro ie where to terminate. And then what the best code would be.

It will be a twist throttle meaning clockwise would increase the helicopters throttle. And anti-clockwise would decrease. Or visa versa

  • See Time Mark @6:15 in the video.

  • Suggest the push switch be used as an emergency stop button.

I have used QEI decoder library using interrupt on change to detect changes in the A and B levels on a number of microcontrollers ESP32, Leonardo, ETC - tested with rotary encoders similar to the one in photo in post 1
should work on a pro micro

You could also get there with a potentiometer running to an analog input.

Tell me more?

Did you check out the link?

Sorry didn't notice that is was hyperlinked. Checking it out now.

  • And there are 10 turn potentiometers too.

I have those same rotary encoders as well, I didn't get them to work properly until added 10K pullup resistors to the pins (INPUT_PULLUP from the board turned out to be to weak) and 100nF de-bounce capacitors (Pin to GND)

Then i created this test sketch to run on a Pro-mini using pin change interrupts. Now since it is using direct port manipulation it won't be working on a micro without modification. Actually i probably shouldn't post it but it may be helpful. I will set 1 encoder up with the pullups and the capacitors later and get it to work with the micro. The Pin Change interrupts seem rather different than on a Pro-mini though, so bear with me. You can also do it using the normal interrupt pins on a Micro, that may be easier to accomplish.
The basic idea is that you connect either the A or the B pin to an interrupt pin, and connect the other to a non-interrupt pin, Set the interrupt to 'FALLING' and read the status of the non-interrupt pin, which will tell you the direction the encoder was turned. For this type of encoder that is exactly what you want, but without the 10K pullups & the capacitors, all bets are off.
(example code, far from perfect for you purpose sorry about that.)

#define Y_LED 7
#define ENC1_X 16
#define ENC1_A 3
#define ENC1_B 4
#define ENC2_A 5
#define ENC2_B 6

volatile int8_t dir = 0;
volatile int8_t val = 0;
volatile bool pressed = false;

void setup() {
  pinMode(Y_LED, OUTPUT);
  pinMode(ENC1_A, INPUT);
  pinMode(ENC1_B, INPUT);
  pinMode(ENC1_X, INPUT);
  Serial.begin(115200);
  Serial.println("PCINT test started.");
  PCICR |= B110;
  PCMSK2 |= 1 << 3; 
  PCMSK1 |= 1 << 4; //B00010000;  pin A4 PC4
}

void loop() {
  static int8_t oldVal = 0;
  BlinkLed();

  if (oldVal != val) {
    Serial.print("New Value = ");
    Serial.println(val, DEC);
    oldVal = val;
  }
  if (pressed) {
    Serial.println("Button pressed !");
    pressed = false;
  }
}

void BlinkLed() {
  if ((millis() / 500) % 2) {
    digitalWrite(Y_LED, HIGH);
  }
  else {
    digitalWrite(Y_LED, LOW);
  }
}

ISR (PCINT1_vect) {  // for multiple buttons we need to keep track of which button pressed
  static uint32_t lastFired = millis();  // or we can't use press combinations
  if (!pressed) { 
    uint8_t in = PINC;
    in = in & 16;
    if ((!in) && (millis() - lastFired > 50)) {
      pressed = true;
    }
  }
  lastFired = millis();
}

ISR (PCINT2_vect) {
  uint8_t in = PIND;
  uint8_t in1 = in & 24;
  if (in1 == 16) {
    val++;
  }
  else if (in1 == 0) {
    val--;
  }
}

have a look at Encoder Library

ran File>Examples>Encoder>Basic test OK with a simple rotary QEI encoder on a Pro Micro using pins 2 and 3
serial monitor output as switch is rotated

1
2
3
4
5
6
7
8
7
8
7
6
5
4
3
2
1
0
-1
-2
-3
-4
-3
-4
-5
-6
-7
-8

Very good choice.

Just as an update, dug up an unused micro, grabbed an encoder like the one shown by the OP. (EC11) Added 100nF capacitors between the A / B & GND and added 10K pullups to A & B pins.
Put this on a breadboard, which of course makes it a tad unstable, but when i hold the encoder while i turn it, it's OK. Will make a small testing version later that is soldered.

Wrote this

#define A_PIN 2
#define B_PIN 15

volatile int8_t counter = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial);  // for native usb boards
  Serial.println("Encoder on a Micro");
  pinMode(A_PIN, INPUT);
  pinMode(B_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(A_PIN), Count, FALLING);
}

void loop() {
  static int8_t oldCounter = 0;
  int8_t loopCounter = counter;
  if (oldCounter != loopCounter) {
    Serial.print("New Value : ");
    Serial.println(loopCounter, DEC);
    oldCounter = loopCounter;
  }
  delay(1);
}

void Count() {
  if (digitalRead(B_PIN)) {
    counter++;
  }
  else {
    counter--;
  }
}

This uses an 8 bit variable as a counter, so interrupts can remain enabled while reading / copying it.

Only 1 interrupt pin per encoder is used, so with just the external interrupt pins you could use 5 encoders.

Works like a charm.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.