Why is my rotary encoder working when just the switch and ground are wired?

Due to an embarrassing lack of buttons, I have a rotary encoder connected to a breadboard using only the switch and ground pins. It's hooked up as an input pullup, and works perfectly well as intended. There is no code or library associated with twisting the encoder anywhere in my sketch.

Alas, it works when turning it, counting up the values that the button would, and counting down backwards the same. It's a cool perk, but it's unintended. Should I be concerned due to some wiring problem I've overlooked? Rather, is this damaging my hardware in any way?

Are you saying that you connected an encoder to pins programmed as button switch inputs, and it works with the application by accident?

It's a 5 pin rotary encoder, so you can push the knob down as a button. The SW is connected as a momentary button, the ground is going to the common ground. No other pins are connected than those ones, and it works by accident.

It's my understanding that the clock and data pins are the ones that govern pulse and direction (or the other way around). Pulse is probably the wrong term, but the high and low states from the knob itself.

This post's a good candidate for op posting a schematic and the sketch I'd say.

The sketch is a whole project, so watch out. The section for the push button is in the loop after the potentiometer section. As for the schematic, it includes 12 potentiometers and five other push buttons. The board I'm using is a Teensy 4.1, with these being the connections as they relate to the other elements on the board:

Encoder SW pin > Teensy pin 9
Encoder GND pin > Breadboard ground pin, where one other 6mm momentary push button is connected.

I'm going across the board in the correct direction, the ground is connected to the ground, all the other components work. It's a mystery. For the record, I'm only using the encoder purely as a pushbutton for the time being. It will be replaced with a proper momentary button, so I'm not trying to achieve anything else. The encoder working is just an accident but I just want to make sure it's not damaging my board.

Here's the code. You'll notice that digitalRead(9), the one connected to the encoder, is the button that counts down in the code while digitalRead(eight) counts up. Perhaps it's triggering the pin next to it?

#include <MIDI.h>
#include <EEPROM.h>

MIDI_CREATE_DEFAULT_INSTANCE();

byte potPin[] = {24, 25, 26, 27, 38, 39, 40, 41, 14, 15, 16, 17 };
int CCChannel[] = { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33};
int bankAddr[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
int buttonState1;
int lastButtonState1;
int buttonState2;
int lastButtonState2;
int buttonState3;
int lastButtonState3;

int BankNumber = 1;
int FirstSelectedPresetWithinBank = 1;

void setup() {
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
MIDI.begin();
//Serial.begin(9600);
}

void loop() {
delay(30);


byte initPot[12];
byte lastInitPot[12];
byte potVal[12];
byte threshold = 1;
 
  for(int i = 0; i < 12; i++){
        initPot[i] = map(analogRead(potPin[i]), 0, 1023, 0, 127);  
      if (abs(initPot[i] - lastInitPot[i]) > threshold){
        lastInitPot[i] = initPot[i];
 //          lastInitPot[i] = map(analogRead(potPin[i]), 0, 1023, 0, 127);
              potVal[i] = initPot[i];
               MIDI.sendControlChange(CCChannel[i], potVal[i], 1);
      }
  }
lastButtonState1 = buttonState1;
lastButtonState2 = buttonState2;
lastButtonState3 = buttonState3;

buttonState1 = buttonState2 = buttonState3 = HIGH;

  buttonState1 = digitalRead(8);
  if (buttonState1 != lastButtonState1) {
    if (buttonState1 == LOW) {
      FirstSelectedPresetWithinBank = FirstSelectedPresetWithinBank + 12;                  
      if (FirstSelectedPresetWithinBank > 181) FirstSelectedPresetWithinBank = 1;             
    }
  }
    buttonState2 = digitalRead(9);
    if (buttonState2 != lastButtonState2) {
      if (buttonState2 == LOW) {
        FirstSelectedPresetWithinBank = FirstSelectedPresetWithinBank - 12;
        if (FirstSelectedPresetWithinBank < 1) FirstSelectedPresetWithinBank = 181;
      }
    }
  buttonState3 = digitalRead(10);  
  if (buttonState3 != lastButtonState3) {
    if (buttonState3 == LOW) {
      BankNumber = BankNumber + 1;         
      if (BankNumber > 8) BankNumber = 1;
      FirstSelectedPresetWithinBank = 1;
    }                                                     
  }
  for(int i = 0; i < 12; i++){
  
/*  buttonState3 = digitalRead(10);
  if (buttonState3 != lastButtonState3) {
    if (buttonState3 == LOW) {
      EEPROM.update(bankAddr[i], potVal[i]);
     // Serial.println("~~~~Saved!~~~~");  
    }
  }*/   
    bankAddr[i] = BankNumber*192 + FirstSelectedPresetWithinBank + i;

//else{
    if (buttonState1 != lastButtonState1){          
    potVal[i] = EEPROM.read(bankAddr[i]);
    MIDI.sendControlChange(CCChannel[i], potVal[i], 1);
  }
    if (buttonState2 != lastButtonState2){
    potVal[i] = EEPROM.read(bankAddr[i]);  
    MIDI.sendControlChange(CCChannel[i], potVal[i], 1);
  }
}
  for(int i = 0; i < 12; i++){
    MIDI.sendControlChange(CCChannel[i], potVal[i], 1);
    Serial.print( "ADDR:");
    Serial.println(bankAddr[i]);    
    Serial.print( " ");
    Serial.print( "POTVAL");
    Serial.println(potVal[i]);    
    Serial.println( " ");    
  }                                              
//  Serial.println("~~~ ~~~");    
//delay(2000);       
  }

Hi,
Can you post a picture of your project please?

Thanks.. Tom... :slight_smile:

I left it plugged in overnight on accident and everything still works. Not terribly worried at this point but I'll gladly continue posting for anybody who is intrigued.

The purple wire is going from the Teensy GND pin into the breadboard by way of the negative rail on the red protoboard. The Orange wire I'm holding is the encoder wire that goes straight into Pin 9 on the Teensy.

This is my first electronics project that I've been working on steadily for a few months, so that's why it looks crappy. Also, ignore the arduino that's tucked under the surface there. It's not hooked up to anything. I just taped it to that little piece of acrylic if I needed to test anything independent of my teensy rat-king of wires.

It doesn’t look like you have +Vcc connected on the encoder

Yes, to reiterate the point of the post, it was never intended to be used as a "rotary encoder", but only for the momentary push button attached. I ran out of buttons and grabbed the 5 pin encoder for the button. For some reason however, the rotary encoder is working like a rotary encoder.

Imagine if you put apples in an empty bowl and suddenly there were apples, bananas, and oranges all in there. It's not really a problem because I have all my apples, but where did the bananas and oranges come from?

Same deal.

Hi,

Alas, it works when turning it, counting up the values that the button would, and counting down backwards the same. It's a cool perk, but it's unintended. Should I be concerned due to some wiring problem I've overlooked? Rather, is this damaging my hardware in any way?

What is the button supposed to do when it is "pressed"?
If you remove the encoder and just open and close the connection between the switch wire and ground, what happens?

Tom.... :slight_smile:

ok, acknowledged... I should have figured that... the encoder pins are not used.

Does the encoder push switch toggle between +Vcc and Groundon the pcb, or open-circuit and ground?

What is the button supposed to do when it is "pressed"?

It's an array counter which increments ++ when pressed. All of the values in the array are EEPROM addresses that assign the stored value to a MIDI CC parameter.

If you remove the encoder and just open and close the connection between the switch wire and ground, what happens?

Nothing happens. The value stays the same.
Is this behavior very unusual? If I wasn't grappling with my own code at the moment I would test it out on a stripped down version without all the other bits. It's amusing to say the least.

Hi,
Have you got a DMM?
If so with the encoder removed, measure the voltage between gnd and the switch wire, the one that is connected to the controller input pin.
Then measure it with the switch wire connected to gnd.

Tom... :slight_smile:

Hi,
What if you swap the encoder with the tactile button you have at the other end of your proto board?

Tom... :slight_smile:

The encoder serves the tactile button's function when pressed low (which is the down-counter to the rotary encoder button's usual up counter), and by way of being the down counter, it counts down when I turn it clockwise and up counter clockwise :smiley:

Hi,
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Not a Fritzy picture.

If you haven't got a circuit diagram, now is the time to make one.

Thanks.. Tom... :slight_smile:

Whenever there are spurious counts I'd immediately suspect floating inputs or a lack of strong pullup.

The internal pullups in the chip are weak and would not guarantee correct operation when signals come
over wires for some distance, due to noise on the cables. So unless the whole project is compact and
away from any high current devices (motors/relays/solenoids), use 4k7 pull ups on switch inputs.

Mechanical vibration in the switch could also cause spurious spikes on the switch output, so you must,
like any switch, debounce the signal (note the encoder lines themselves inherently don't need
de-bouncing as quadrature encoders self-debounce by the nature of quadrature).