Rotary encoder setup

Hello all,

I'm trying to setup a rotary encoder so that I can accurately track rotor position for a switched reluctance motor and I'm having a issue setting the limits of a revolution. The rotary encoder is already set to have 2400 ticks per revolution but I want it to stay 0 to 2400 and not go over or go negative. At the moment I've only been able to get the encoder to cycle 0 to 255.
Mfr. Model # E40S6-360-3-N-24-C

  • This code if initially spun cw nothing.
  • If turned ccw it starts at 2399 goes to 2654 then ticks down to 2399. After turning ccw it will tick down if spun cw to a fixed max position set when you stopped spinning ccw
  • It wont count up only down
//if initially spun cw nothing 
//if turned ccw it starts at 2399 goes to 2654 then ticks down to 2399. After turning ccw it will tick down if spun cw to a fixed max position set when you stopped spinning ccw
#include <Encoder.h>


Encoder myEnc(2, 3);
//   avoid using pins with LEDs attached

void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  static byte counter = 0;
  if (newPosition != oldPosition){
    oldPosition = newPosition;
    if (newPosition > 2399){
    newPosition = 0 + counter++;
   // if newPosition(might be better to say myEnc.read()) less than 0 which implies ccw past the 0 mark start at 2399 and count down to zero
    if (newPosition < 0) {
    newPosition = 2399 + counter--;
    Serial.println(newPosition);
    }
  }
}
}

Please help thanks in advance

Do you KNOW that you are reading the encoder correctly?

What, exactly, is counter supposed to represent?

I'm not 100% the counter is being used correctly. I think I'm using it corrently because it resets and counts up.

I'm not 100% the counter is being used correctly.

Counter? I asked about the encoder.

You know a byte can only represent 0 to 255 unsigned correct?

A byte (counter) stores an 8-bit unsigned number, from 0 to 255.
Change

static byte counter = 0;

to

static int counter = 0;

If you simply want to restrict the counter to 0-2400:

if (newPosition > 2400){
newPosition = 2400;}
if (newPosition < 0) {
newPosition = 0;}

Or, more simply:

if (newPosition > 2400) newPosition = 2400;
if (newPosition < 0) newPosition = 0;

The problem is that it wont cycle 0-2399 then repeat. At the moment it just stays 0 when newPosition <0 and stays at 2400 when newPosition > 2400.

kimibird47:
The problem is that it wont cycle 0-2399 then repeat. At the moment it just stays 0 when newPosition <0 and stays at 2400 when newPosition > 2400.

What do you mean by "cycle"?

I suspect that when newPosition increments to 2400, you want to set newPosition to 0, and when newPosition decrements to 0, you want to set newPosition to 2400. But, I could be wrong.

Tell us, in English, not code, what you are trying to accomplish.

This is corrent but after it resets to 0 i want it to count up again and for when it resets to 2400 I want it to count down. For example

clockwise turning 0,1,2,3,...,2399,0,1,2,...,2399

counter clockwise turning 0,2399,2398,....,2,1,0,2399,2398

Where is your current code?

This is what I have now. Now just the counter wont work. Im not 100% sure I need it but I cant see a way without it because it seems to me the encoder doesn't understand reset. The encoder only ticks up or ticks down. The encoder when spun clockwise ticks up to 2399 then stays constant at 2399 and spun counter clockwise it stays constantly at 0.

#include <Encoder.h>


Encoder myEnc(2, 3);
//   avoid using pins with LEDs attached
int counter = 0;
void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
 counter = 0;
  if (newPosition != oldPosition){
    oldPosition = newPosition;
    if (newPosition > 2400){
   //   newPosition = 2400;}
   //A) the following comment doesn work but I think it should be something similar because I want the newPosition to reset to 0 then count up to 2399 then reset and so on
    newPosition = 0 + counter++;}
   // if newPosition(might be better to say myEnc.read()) less than 0 which implies ccw past the 0 mark start at 2399 and count down to zero
    if (newPosition < 0) {
   //B) The same as A) but in the opposite direction when below 0 start at 2399 and count down and cycle the range    
    newPosition = 2399 + counter--;}
   // newPosition = 0;}
    Serial.println(newPosition);
    }
  }

Now just the counter wont work.

That variable REALLY needs a new name that reflects just what it is you think you are counting.

I cant see a way without it because it seems to me the encoder doesn't understand reset.

Have you looked at the methods in the Encoder class? I'm sure that there is some way to tell the encoder to consider it's current position as 0.

What I think you should do is to read the encoder position. Say it returns 1945. That's between 0 and 2399, so use the value. Say it is 3578. Subtract 2400 and increment a variable, completeRotations, by 1, until the current position is between 0 and 2399. If the value is negative, add 2400 and decrement completeRotations until the value is in the range you want. Do NOT try to force the encoder to play by your rules. Let it behave normally, and use the data according to your rules (which I don't really understand).

PaulS:
Have you looked at the methods in the Encoder class?

Are you referring to a module provided in the resources or forum tabs?

You are using a library encoder.h
https://www.pjrc.com/teensy/td_libs_Encoder.html

Look in that documentation for

myEnc.write();