Simple Question about using encoder to set two different integer values

I am trying to set two values by only using one push button encoder. I have both the digilent encoder mounted on board with slide switch and integrated push button, and the ky-040 modules.

I am trying to mock up a very simple display that sets two seperate integer values using only one encoder knob with pushbutton. I really only need to set each integer value between 0-10. But I need to be able to set them completely independent of eachother but I only can use one knob.

Beginning of the sketch, both pos1 and pos2 are set to zero. Turning the knob will increase or decrease pos1 value as long as button isnt pressed. If button is pressed, and the knob is turned while button is down, pos2 should increase or decrease.

If I miss some steps im not very worried about it.

A simple example would be a digital radio that allowed you to set the volume of a radio by rotating the encoder, and also be able to adjust the bass when the knob is pushed down and rotated.

I have tried every possible encoder library and tried modifying each one and several hours later I give up. If anyone could shed some light on what I am missing it would be very appreciated. I can’t find a single example online that uses an encoder in this style. Here is my last attempt.

// -----
// InterruptRotator.ino - Example for the RotaryEncoder library.
// This class is implemented for use with the Arduino environment.
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// More information on: http://www.mathertel.de/Arduino
// -----
// 18.01.2014 created by Matthias Hertel
// -----

// This example checks the state of the rotary encoder in the loop() function.
// The current position is printed on output when changed.

// Hardware setup:
// Attach a rotary encoder with output pins to A2 and A3.
// The common contact should be attached to ground.







#include <RotaryEncoder.h>

// Setup a RotaryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);

int pushButton = 2;

bool buttonPushed = false;

void setup()
{
  Serial.begin(57600);
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");

  pinMode(pushButton, INPUT);


  // You may have to modify the next 2 lines if using other pins than A2 and A3
  PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.
} // setup()



// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3: exactly where we need to check.
ISR(PCINT1_vect) {
  encoder.tick(); // just call tick() to check the state.
}


// Read the current position of the encoder and print out when changed.
void loop()
{
  
  static int pos = 0;
  static int pos1 = 0;
  static int pos2 = 0;
  static int diff = 0;
  
  int newPos = encoder.getPosition();
     if (pos != newPos && pushButton == LOW)
     {
      diff = (newPos - pos);
      pos1 = (pos+diff);
      }
      
        else if (pos != newPos && pushButton == HIGH)
        {
          diff = (newPos - pos);
          pos2 = (pos+diff);
        }
        pos = newPos;
      
    Serial.print(pos1);
    Serial.print(",");
    Serial.print(newPos);
    Serial.print(",");
    Serial.println(pos2);}

What you're trying to do is definitely possible, but very likely the existing libraries don't allow for this use case. You may have to write your encoder code yourself, it's not that hard.

You don't need interrupts for a hand-turned encoder. That only adds unnecessary complications. Just poll the inputs frequently and do state change detection. Do look up the signals you get from a quadrature encoder (yours must be one of those or you can't detect direction).

Check the topic. With my library and you can control different values with a single encoder!!!

     if (pos != newPos && pushButton == LOW)
     {
      diff = (newPos - pos);
      pos1 = (pos+diff);   <<<--- you mean pos1 += diff;
      }
      
        else if (pos != newPos && pushButton == HIGH)
        {
          diff = (newPos - pos);
          pos2 = (pos+diff);   <<<--- you mean pos2 += diff;
        }
        pos = newPos;

Yea you are right, I tried this and it still doesnt work however. 16 hours later…

MarkT:

     if (pos != newPos && pushButton == LOW)

{
      diff = (newPos - pos);
      pos1 = (pos+diff);  <<<— you mean pos1 += diff;
      }
     
        else if (pos != newPos && pushButton == HIGH)
        {
          diff = (newPos - pos);
          pos2 = (pos+diff);  <<<— you mean pos2 += diff;
        }
        pos = newPos;

enjoyneering:
Check the topic. With my library and you can control different values with a single encoder!!!

I couldn't get any of your sketches to work with my Uno...

to run AVRRotaryEncoderAdvancedMultiValuesLCD.ino you need to download extra libraries:

TimerOne.h - https://github.com/PaulStoffregen/TimerOne
LiquidCrystal_I2C.h - https://github.com/enjoyneering/LiquidCrystal_I2C

If you change initialization string, you can run it with arduino LiquidCrystal_I2C

  • encoder button pin must be connected to interrupt pin 2 or 3 for UNO

  • add 100nF/0.1uF capacitors between button pin & ground!!!

  • add 100nF/0.1uF capacitors between A pin & ground!!!

  • add 100nF/0.1uF capacitors between B pin & ground!!!

Switch bounce theory - link
Hardware Debounce calaculator - link

Have you done all this steps?

yamablaster024:
Yea you are right, I tried this and it still doesnt work however. 16 hours later...

Post your latest code. Did you actually make the changes I commented? They don't work if
only in the comments!!