Limit Rotary Encoder Position

Howdy,

I have a sketch which counts from 0 to 255, when it reaches 255 position, it continues to 0, 1,2 ,3 and so on.

Is there a way to limit it's 'race' to 255, so that when counter reaches 255, it stops there?

Same thing when counting down:
when Position reaches 0 it does not continue to 255, 254, etc.

Any help appreciated.

The code:

volatile byte encoderPos = 0;
byte lastReportedPos = 1;

void setup() {
  pinMode(encoderPinA, INPUT); 
  pinMode(encoderPinB, INPUT); 
  pinMode(clearButton, INPUT);
  digitalWrite(clearButton, HIGH);

  
// encoder pin A on interrupt 0 (pin 3)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin B on interrupt 1 (pin 2)
  attachInterrupt(1, doEncoderB, CHANGE);

  Serial.begin(9600);

}

void loop(void) { 
  if (lastReportedPos != encoderPos) {
    Serial.print("Index:");
    Serial.print(encoderPos, DEC);
    Serial.println();
    lastReportedPos = encoderPos;
  
  }
  
  if (digitalRead(clearButton) == LOW)  {
    encoderPos = 0;
  }
}

// Interrupt on A changing state
void doEncoderA(){
  // Test transition
  A_set = digitalRead(encoderPinA) == HIGH;
  // and adjust counter + if A leads B
  encoderPos += (A_set != B_set) ? +1 : -1;
}

// Interrupt on B changing state
void doEncoderB(){
  // Test transition
  B_set = digitalRead(encoderPinB) == HIGH;
  // and adjust counter + if B follows A
  encoderPos += (A_set == B_set) ? +1 : -1;
}

Simple:

if(encoderPos > 255)
  encoderPos = 255;
if(encoderPos < 0)
  encoderPos = 0;

Pieter

PieterP:
Simple:

if(encoderPos > 255)

encoderPos = 255;
if(encoderPos < 0)
  encoderPos = 0;

The above will not work with

volatile byte encoderPos = 0;

there are no values above 255 or below 0.

withvolatile int encoderPos = 0;it would work (for a range from 0 to 255).

You don't really tell us enough, but if you're using a continuous rotation encoder, you may want to look at a signed integer - rather than an unsigned byte value.
Then you can easily detect when you roll past 0/255

There are other ways, but this would create the simplest, most readable code.

PieterP:
Simple:

if(encoderPos > 255)

encoderPos = 255;
if(encoderPos < 0)
 encoderPos = 0;




Pieter

This will work, because it is not an absolute encoder, all that is being input to the Ardunio is encoder pulses.
The counting is being done in the code, so -1 and 256 will occur.
Tom.... :slight_smile:

The counting is being done in the code, so -1 and 256 will occur.

Not if encoderPos is a byte variable, see reply #2

Hi,
Well make it an int variable, problem solved.

Tom... :slight_smile:

TomGeorge:
Hi,
Well make it an int variable, problem solved.

Tom... :slight_smile:

That was mentioned already in #2 also.

Whandall:
The above will not work with

volatile byte encoderPos = 0;

there are no values above 255 or below 0.

withvolatile int encoderPos = 0;it would work (for a range from 0 to 255).

Well, it basically works, however sometimes it detects -1 if continuing rotating below,
and 256 if continuing rotating above.

The sketch is controlling a ladder resistive network, via 8-bit binary outputs.
I'd prefer to have the byte variable, so that I'm sure there's no value below 0 and none above 255.

You will have to disable interrupts while checking and modifying a volatile var in loop context.

The var is two bytes now, you can not even read it safely while interrupts are enabled.

https://www.gammon.com.au/interrupts