Rotary won't work on specific pins

Hi all,

I have an issue using a rotary encoder. Here are the tests i have made so far :

Here is the encoder i am using : Iduino Rotary encoder 1 pc(s) SE055 | Conrad.com

Pin setup is : 2 (Clock), 3 (Data) and 4 (Switch)

  1. i have originally made a custom PCB with an ATMEGA328P on which i attached the rotary encoder. After a lot of issues and debugging i finally figured i had strange signal (if not at all) from the encoder to the pins.

  2. to be sure i changed the encoder for a new one, but problem persisted

  3. to be able to debug more conveniently i chose to use a spare arduino nano that i have. But same issues.

  4. of course i have tried tens of different codes (with or without interrupts. With or without libraries. Some libraries like Encoder, RotaryEncoder and ClickEncoder…)

  5. i then tried changing the pins setup. I attached the encoder on pins 8 and 9 and then 11 and 12 and it seems to work. A least i can read state changes on the pins.

I don’t understand what the issue can be. I have searched the code and hardware wiring but i can’t figure it out.

I am using the Basic example code from the Encoder library which i adapted ti my needs (but the issues are consistent no matter the library or the code i use) : Encoder/Basic.pde at master · PaulStoffregen/Encoder · GitHub

#include <Encoder.h>

#define ROTARY_CLK 2
#define ROTARY_DT 3
#define ROTARY_SW 4
#define ENCODER_DO_NOT_USE_INTERRUPTS

Encoder encoder(ROTARY_CLK, ROTARY_DT);

void setup() {
  pinMode(ROTARY_CLK, INPUT);
  pinMode(ROTARY_DT, INPUT);
  pinMode(ROTARY_SW, INPUT_PULLUP);

  Serial.begin(9600);
}

long oldPosition  = -999;

void loop() {

  long newPosition = encoder.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

Thanks for the help.

Did you connect the ground on the module to the Nano ground?

Yes. +5V and GND from the nano pins

What do you get if you write something simpler that just digitalReads pins 2,3 and 4 and echoes the result to Serial?

What happened when you connected per the datasheet and used the code in the datasheet ?

(deleted)

#include <Encoder.h>
#define ENCODER_DO_NOT_USE_INTERRUPTS

I would be surprised if defining ‘ENCODER_DO_NOT_USE_INTERRUPTS’ AFTER the “#include <Encoder.h>” will do anything. The included file can’t act on your #define if it has not been defined yet.

FYI: Here is the sketch from the ‘datasheet’ provided by the vendor:

int pinA = 3; // Connected to CLK
int pinB = 4; // Connected to DT
int encoderPosCount = 0;
int pinALast;
int aVal;
boolean bCW;
void setup()
{
  pinMode (pinA, INPUT);
  pinMode (pinB, INPUT);
  /* Read Pin A
    Whatever state it's in will reflect the last position
  */
  pinALast = digitalRead(pinA);
  Serial.begin (9600);
}
void loop()
{
  aVal = digitalRead(pinA);
  if (aVal != pinALast)  // Means the knob is rotating
  {
    // if the knob is rotating, we need to determine direction
    // We do that by reading pin B.
    if (digitalRead(pinB) != aVal)   // Means pin A Changed first -
    {
      // We're Rotating Clockwise
      encoderPosCount ++;
      bCW = true;
    }
    else    // Otherwise B changed first and we're moving CCW
    {
      bCW = false;
      encoderPosCount--;
    }
    Serial.print ("Rotated: ");
    if (bCW)
    {
      Serial.println ("clockwise");
    }
    else
    {
      Serial.println("counterclockwise");
    }
    Serial.print("Encoder Position: ");
    Serial.println(encoderPosCount);


  }
  pinALast = aVal;
}

wildbill:
What do you get if you write something simpler that just digitalReads pins 2,3 and 4 and echoes the result to Serial?

Inconsistent behaviour...

spycatcher2k:
Did you remember to fit pull-up resistors? or turn on the internal pull-ups?

CLK and DT input needs pullup ?

johnwasser:
I would be surprised if defining ‘ENCODER_DO_NOT_USE_INTERRUPTS’ AFTER the “#include <Encoder.h>” will do anything. The included file can’t act on your #define if it has not been defined yet.

Yeah i know, but IDE threw me an error when declaring at the top.

Anyway the encoder is connected to pins 2 and 3 which have interrupt and i have tested sketches with and without interrupts

galloro:
CLK and DT input needs pullup ?

Yes, but the Paul Stoffregen library, at least, does that for you by setting the inputs to INPUT_PULLUP...

aarg:
Yes, but the Paul Stoffregen library, at least, does that for you by setting the inputs to INPUT_PULLUP...

...but that won't save you if you set the mode to INPUT after the Encoder object gets instantiated:

Encoder encoder(ROTARY_CLK, ROTARY_DT);

void setup() {
  pinMode(ROTARY_CLK, INPUT);
  pinMode(ROTARY_DT, INPUT);

The datasheet for the shield shows a couple of 10K pullup resistors. That's why you are supposed to supply +5 volts. Of course, I would want to visually inspect the shield and verify for myself.

Interestingly, the sample code in the datasheet sets the pin modes as INPUT, not INPUT_PULLUP.

Lots of useful insights here ! thanks a lot to all of you !

I think i have found the issue which is accumulated hardware problems, that’s why i had hard time debugging it !

It appears i had a loose cable on the wire strap i am using with the PCB AND a faulty connection on a pin on the bread board i use with the nano…

I need to clean the code and some debouncing but at least i get some consistent signal