ClickEncoder & Bounce2 Interfering

I am currently trying to use both the ClickEncoder & Bounce2 libraries simultaneously. I have verified that each library works on its own. If I use them together, and I declare each bounce instance separately, it works as expected (buttons work, encoder works, no interference, no false positives). (see first code example)

If I declare an array of buttons and an array of bounce objects, then the ClickEncoder library is interfered with and the encoder value constantly increments without any user input. (second code example)

Any ideas why this is happening?

Working:

#include <Bounce2.h>
#include <Wire.h>
#include <ClickEncoder.h>
#include <TimerFour.h>

//Button Pins
#define enter 25
#define up 26
#define down 27
#define systemReset 30

//Encoder Pins
#define encBtn 2
#define encA 4
#define encB 3
#define encGreen 52
#define encRed 53

Bounce debouncer = Bounce();
Bounce debouncer1 = Bounce();

ClickEncoder *encoder;
int16_t last, value;

void setup() {
  Serial.begin(9600);

  pinMode(enter, INPUT);
  digitalWrite(enter, HIGH);
  debouncer.attach(enter);
  debouncer.interval(10);
  
  pinMode(up, INPUT);
  digitalWrite(up, HIGH);
  debouncer1.attach(up);
  debouncer1.interval(10);
  
  encoder = new ClickEncoder(encB, encA, encBtn);

  Timer4.initialize(1000);
  Timer4.attachInterrupt(timerIsr); 
  
  last = -1;
}

void loop() {  
  value += encoder->getValue();
  
  if (value != last) {
    last = value;
    Serial.print("Encoder Value: ");
    Serial.println(value);
  }
 
  btnScan(); 
}

void btnScan() {
 if (debouncer.update()) {
 Serial.print("Enter: ");
                Serial.println(debouncer.read());
 }
         if (debouncer1.update()) {
 Serial.print("Up: ");
                Serial.println(debouncer1.read());
 }
}

void timerIsr() {
  encoder->service();
}

Not Working

#include <Bounce2.h>
#include <Wire.h>
#include <ClickEncoder.h>
#include <TimerFour.h>

//Button Pins
#define enter 25
#define up 26
#define down 27
#define systemReset 30

//Encoder Pins
#define encBtn 2
#define encA 4
#define encB 3
#define encGreen 52
#define encRed 53

byte buttons[] = {
 enter,
 up 
};

Bounce * debouncer = new Bounce[sizeof(buttons)];

ClickEncoder *encoder;
int16_t last, value;

void setup() {
  Serial.begin(9600);

  for (int b = 0; b <= sizeof(buttons); b++) {
 pinMode(buttons[b], INPUT);
 digitalWrite(buttons[b], HIGH);
 debouncer[b].attach(buttons[b]);
 debouncer[b].interval(10);
  }
  
  encoder = new ClickEncoder(encB, encA, encBtn);

  Timer4.initialize(1000);
  Timer4.attachInterrupt(timerIsr); 
  
  last = -1;
}

void loop() {  
  value += encoder->getValue();
  
  if (value != last) {
    last = value;
    Serial.print("Encoder Value: ");
    Serial.println(value);
  }
 
  btnScan(); 
}

void btnScan() {
 for (int b = 0; b <= sizeof(buttons); b++) {
 if (debouncer[b].update()) {
 Serial.print("buttons: ");
                        Serial.println(debouncer[b].read());
 }
 }
}

void timerIsr() {
  encoder->service();
}

Thanks

EDIT: Meant to put this in the "Programming Questions" forum. Posted in the wrong tab. Mod, please move if possible. Thanks and my apologies for the inconvenience.

ClickEncBounce_Working.ino (1.2 KB)

ClickEncBounce_NotWorking.ino (1.15 KB)

Hi,

with two buttons, the loops with <= sizeof(buttons) seems suspicious.
Should be < sizeof(buttons), so that it uses the index 0 and 1 only.

I'd put the call to btnScan() into the timer ISR. Instead of the for-loop, I usually do
b = (b + 1) % sizof(buttons);, so that only one button is checked on every call.

Actually, the ClickEncoder supports double-click, so that you don't need an enter and an up button.
Click = Enter, Doubleclick: Up.

Best,
pit

Could maybe work like that, I did not test it:

#include <Bounce2.h>
#include <Wire.h>
#include <ClickEncoder.h>
#include <TimerFour.h>

enum Pins {
  enter = 25,
  up = 26,
  down = 27,
  systemReset = 30,
  encBtn = 2,
  encA = 4,
  encB = 3
};

uint8_t buttons[] = {
  enter,
  up
};

Bounce * debouncer = new Bounce[sizeof(buttons)];
ClickEncoder *encoder;
int16_t last, value;

void setup() {
  Serial.begin(9600);

  for (uint8_t b = 0; b < sizeof(buttons); b++) {
  	pinMode(buttons[b], INPUT);
  	digitalWrite(buttons[b], HIGH);
  	debouncer[b].attach(buttons[b]);
  	debouncer[b].interval(10);
  }

  encoder = new ClickEncoder(encB, encA, encBtn);

  Timer4.initialize(1000);
  Timer4.attachInterrupt(timerIsr);

  last = -1;
}

void loop() {
  value += encoder->getValue();
  if (value != last) {
    last = value;
    Serial.print("Encoder Value: ");
    Serial.println(value);
  }
}

void btnScan() {
  static uint8_t b = 0;

  if (debouncer[b].update()) {
    Serial.print("button: ");
    Serial.print(b);
    Serial.print(" ");
    Serial.println(debouncer[b].read());
  }

  b = (b + 1) % sizof(buttons);
}

void timerIsr() {
  encoder->service();
  btnScan();
}

I am actually using 10 buttons and an encoder. I just pulled that out to shorten the code in the examples I was posting. I'll move btnScan to the isr and fix the sizeof() comparator and see if that resolves the problem. Thanks

EDIT: Yep, sure enough, that worked. Your code fixed it. Particularly removing the for loop in btnScan and checking each button one at a time.