Using Quadrature Encoder Library - Issue

Hello,

I am using the following encoder library:

https://www.pjrc.com/teensy/td_libs_Encoder.html

I am using a 3-axis controller I developed, whereby I would like to use the library in order to find out the current positions of the axes.

The encoders were installed correctly, the signals are seen at the Arduino pins (by the way, I am using an Arduino Due) using an oscilloscope, but for some reason the output is only working correctly for 1 of the 3 axes. Not sure why I am not seeing all three working correctly. Thank you in advanced.

/*
Pin Definition

- Axial
  - MCHA --> 21
  - MCHB --> 20

- Radial 
  - MCHA --> 19
  - MCHB --> 18
  
- Knob 
  - MCHA --> 17
  - MCHB --> 16
*/

#define ENCODER_OPTIMIZE_INTERRUPTS

#include <Encoder.h>

#include <stdio.h>

// Master and Slave Encoder Signals

long mAxialPosition = 0;
long mRadialPosition = 0;
long mKnobPosition = 0;

Encoder mAxial(21, 20);
Encoder mRadial(19, 18);
Encoder mKnob(17, 16);

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

void loop()
{ 
  if ((millis() % 100) == 0){
    Serial.print(mAxialPosition);
    Serial.print("||");
    Serial.print(mKnobPosition);
    Serial.print("||");
    Serial.println(mRadialPosition);
  }

// Read Controller Encoders
  mAxialPosition = mAxial.read();
  mRadialPosition = mRadial.read();
  mKnobPosition = mKnob.read();
}

Output Example

-1929||0||0
-1928||0||0
-1922||0||0
-1904||0||0
-1897||0||0
-1895||0||0
-1636||0||0
-818||0||0
422||0||0
1601||0||0
1768||0||0
984||0||0
-571||0||0
-2130||0||0
-2688||0||0

What happens to the output if you change the order in which the 3 values are read ? Does the first one always work ?

What happens if you change the pins used by the encoders so that mKnob, for instance, is on pins 20 and 21 ?

In passing
  if ((millis() % 100) == 0)relies on millis() returning all values when checked, but I am sure that this is not always the case, so the output may not always happen at regular intervals. It would be more certain if you used the if (millis() - startTime >= interval)technique although in your test program it will not matter I assume if a few readouts are missed.

Hello UKHeliBob

In software, I disabled some encoders and attempted to run each separately, but that was not the issue.

Using another (new) Arduino Due, doesn't solve the problem.

However, switching the connections (rather, switching the axes of the encoders to the Arduino) works. Telling me that the installation of the encoders and the developed controller itself is working no problem.

This comes down to the software and possibly the library.

Regarding switching the pins. I prefer to keep how it set up, since I have developed the PCB already. You may ask why I haven't tested it, well I have using my own code - but I would like to try and get this working with this library.

Also, thank you for noting the millis() concern. It was not problem, as I am debuging my code differently now - so that cannot be the issue.

If you are interested I am essentially now using the example linked previously.

Thank you again.

/*
Pin Definition

- Axial
  - MCHA --> 21
  - MCHB --> 20

- Radial 
  - MCHA --> 19
  - MCHB --> 18
  
- Knob 
  - MCHA --> 17
  - MCHB --> 16
*/

#define ENCODER_OPTIMIZE_INTERRUPTS

#include <Encoder.h>

#include <stdio.h>

// Master and Slave Encoder Signals

long mAxialPosition = 0;
long mRadialPosition = 0;
long mKnobPosition = 0;

Encoder mAxial(21, 20);
Encoder mRadial(19, 18);
Encoder mKnob(17, 16);

void setup()
{
  Serial.begin(9600); // PC
}

void loop() {
  long newAxial, newRadial, newKnob;
  
// Read Controller Encoders
  newAxial = mAxial.read();
  newRadial = mRadial.read();
  newKnob = mKnob.read();
  
  if (newAxial != mAxialPosition || newRadial != mRadialPosition || newKnob != mKnobPosition) {
  Serial.print("Axial = ");
  Serial.print(newAxial);
  Serial.print(", Radial = ");
  Serial.print(newRadial);
  Serial.print(", Knob = ");
  Serial.println(newKnob);
  mAxialPosition = newAxial;
  mRadialPosition = newRadial;
  mKnobPosition = newKnob;
  }

  if (Serial.available()) {
    Serial.read();
    Serial.println("Reset all counts to zero");
    mAxial.write(0);
    mRadial.write(0);
    mKnob.write(0);
  }


}

So I am still not sure why this library wasn't working properly.

I resorted back my original method. It is 4x less resolved (since I am only using 1 interrupt on one channel) but it will do for now.

If someone can figure out why it isn't working. I will be happy to learn the explanation.