Reading a Rotary Encoder with a Shield Shield using attachInterrupt()

I’m using a rotary encoder from this link and using the Encoder library in the web IDE.
When I attach the A-B pins directly to the Photon’s D2,D3 pins, I can read the encoder via serialPrintln(), albeit not very stable, even though I’m turning it relatively slowly.
When I attach them to pins 11-12 (D2, D3) on the Shield Shield, I get nothing on the serial monitor.
Is the Shield Shied not capable of Interrupts or am doing something wrong?

How does your test code look?
Have you got your pull-up resistors installed?
What value are you using?
With the Shield Shield I’d not rely on the internal pull-ups.

1 Like

my code is as simple as I can make it.

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit-MotorShield-V2.h>
#include "Encoder.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);

Encoder myEnc(D5, D6);

long oldPosition  = -999;
long newPosition = 0;
//bool directionFlag = FALSE;

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

    AFMS.begin();
    myMotor->setSpeed(255);

    delay(500);
}

void loop() {
    newPosition = myEnc.read();
    
    if (newPosition != oldPosition) {
        oldPosition = newPosition;
         Serial.println(newPosition);
    }
    
   if (newPosition > 10000){ myMotor->run(BACKWARD); }
   if (newPosition < 1){ myMotor->run(FORWARD); }
}

I have two resistors from A and B phase to the +5v pin on the Shield Shield.
The Motor Shield only uses the two I2C pins. D0-D1 on photon; 5-6 on the Shield Shield.
the Encoder library uses INPUT_PULLUP, so I manually added the Encoder.h file and removed the _PULLUP.
I’ve tried pins D3-D4 and D5-D6, but I still get the same result, which is nothing being printed to the Serial Monitor, unless I hook up the pins directly to the photon.

I’d have to test with my Shield Shield but have no such rotary encoder so I’ll try to simulate an open-drain output with one of the other pins.

Still about your pull-ups

Maybe try lowering the value (e.g. 4k7 or 2k2) and maybe measure the voltage on the pins (directly after the pull-up without the encoder and on the Photon)

To simplify the test code even further I’d see what this renders on your setup

#define OPEN_DRAIN

const int intPin = D2;  
const int tstPin = D4;  // bridge tstPin to intPin to trigger the interrupt
const int ledPin = D7;

void isr(void) {
  digitalWrite(ledPin, digitalRead(intPin));
}

void setup() {
  pinMode(intPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(tstPin, OUTPUT);
  digitalWrite(tstPin, LOW);
  
  attachInterrupt(intPin, isr, CHANGE);
}

void loop() {
  static int x = 0;
  
#if defined(OPEN_DRAIN)
  if (++x & 1) {
    pinMode(tstPin, INPUT); // for Shield Shield external pull-up 4k7/2k2 required
  }
  else {
    pinMode(tstPin, OUTPUT);
  }
#else
  digitalWrite(tstPin, ++x & 1);
#endif

  delay(1000);
}

Update:
On my Shield Shield a 4k7 pull-up to 5V on D2 worked as expected with above code.

Ok, I will give it a try, I had 4.7K on there before, but right now I have 10K installed.
I will give your code a try as well. thanks a bunch for taking the time to try it on your Shield.

1 Like