Encoder Mouse help needed

Really struggling with this, I'm wanting a fast simple Button encoder to act as a mouse scroll wheel and left click, then trying to add 3 more push buttons on the sketch -with functions: right mouse, middle mouse, and another left button.
Am I going about it the right way? or will I need to use interrupts?


// **  Trying to make a mouse encoder scroll wheel with 4 buttons.


#include <Mouse.h>
#include <Encoder.h>

static unsigned encA=2, encB=3, encBTN=4;

//scaling:
static unsigned hFactor=10, vFactor=5, scrollFactor=4;
unsigned h=0, v=255;

Encoder myEnc(encA, encB);

long oldPosition  = -999;

const int mouseButtonLeft = 6;
const int mouseButtonRight = 8;


int buttonState = 0;   

void setup(){
  
  pinMode(mouseButtonLeft, INPUT);
  pinMode(mouseButtonRight, INPUT);  
  pinMode(encBTN,INPUT);
  Serial.begin(9600);
  Mouse.begin();   
}

int change=0;
int hChange=0;
int vChange=0;


void loop(){

int clickStateLeft = digitalRead(mouseButtonLeft);
int clickStateRight = digitalRead(mouseButtonRight);

  
  if (clickStateLeft == HIGH) {
    if (!Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.press(MOUSE_LEFT);
      Serial.println("mouseButton_Left");  
      delay(200);
    }
  }
  else {   
    if (Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.release(MOUSE_LEFT);
    }
  }
    if (clickStateRight == HIGH) {
    if (!Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.press(MOUSE_RIGHT);
      Serial.println("mouseButton_Right");
    delay(200);
    }
  }
  else {
    if (Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.release(MOUSE_RIGHT);
    }
  }

 unsigned long newPosition = myEnc.read();

    if (newPosition != oldPosition)
    {
      change += newPosition-oldPosition;
    oldPosition = newPosition;
    }
    
  if(change<-3 || change>3) 

      if(digitalRead(encBTN))  //VALUE
      {
        vChange=change*vFactor;
        if((signed)v+vChange<0) v=0; //prevent int underflow
        else if(v+vChange>255) v=255; //prevent int overflow
        else v+=vChange;
      }

      else //HUE
      {
        hChange=change*hFactor;
        if((signed)h+hChange<0) h=1541; //prevent int underflow
            else if(h+hChange>1541) h=0; //prevent int overflow
        else h+=hChange;{      
         
         Mouse.move(0,0,+change/scrollFactor);
    
      }
      Serial.print("pos: ");
      Serial.println(newPosition);
      Serial.print("change: ");
      Serial.println(change);
      Serial.print("Scroll: ");
      Serial.println(-change/scrollFactor);
      Serial.println();
      change=0;
   }
  }
 
1 Like

Your use of delay() may cause missed button events. Study the IDE examples Debounce and StateChangeDetection how to handle buttons without blocking other events.

Interrupts don't help with bouncing buttons. They may help with encoder reading, but that's hidden in the Encoder library. Have you ever tried to understand an encoder and write your own code, or looked into the many encoder forum topics?

1 Like

It looks like you have your buttons (momentary switches) wired to Vcc and using an external pull down resistor. The more accepted way to wire a switch is to wire one side to ground and the other to an input set to pinMode INPUT_PULLUP. The input will read high for not pressed and low for pressed. Adjust program logic accordingly.

See my state change for active low inputs tutorial for wiring and example code.

2 Likes

Hi @nomadone77

welcome to the forum.
One important information is what exact type of microcontroller are you using?
There is a library call NewEncoder which reads encoders and delivers a vlaue that is counting up/down depending on rotating clockwise/counterclockwise
You can limit the min and max-value or use an upclick / downclick

This library requires to use interrupt-capable IO-pins.

best regards Stefan

2 Likes

I like the Encoder library (available via the IDE library manager). It can use 2, 1 or no interrupts per encoder, depending on use case. A manual encoder probably needs no interrups. A motor encoder probably does.

2 Likes

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