teensy-3.2, mcp23017 with encoders & interrupt..

Status
Not open for further replies.

DanieleFromItaly

Active member
HI guys, I'm trying to use this sketch: https://github.com/raspibo/I2C_rotary_encoder/blob/master/I2C_rotary_encoder.ino..
First of all, a basic sketch like this: https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/examples/toggle/toggle.ino works fine, so teensy and mcp23071 are ok.

So, I'm using pin 23 for interrupt. First problem at line 192: EIFR = 0x01 (EIFR not defined in this scope), replaced with: PORTC_ISFR = CORE_PIN23_BITMASK but really don't know if is right. Anyway the sketch does not work; I see in console monitor "Startup" (line 118) then nothing :(

Interrupts & C. are alien thigs for me, please help.

Thanks,

Daniele.
 
First problem at line 192: EIFR = 0x01 (EIFR not defined in this scope), replaced with: PORTC_ISFR = CORE_PIN23_BITMASK

I would just delete that line with EIFR.

I'd also get rid of "arduinoInterrupt" and go with this:

Code:
  // enable interrupts before going to sleep/wait
  // And we setup a callback for the arduino INT handler.
  attachInterrupt(digitalPinToInterrupt(arduinoIntPin), intCallBack, FALLING);

and...

Code:
  // disable interrupts while handling them.
  detachInterrupt(digitalPinToInterrupt(arduinoIntPin));

Very old versions of Arduino lacked digitalPinToInterrupt(), but it's in all modern copies and automatically takes care of getting the right interrupt number for whatever pin you're using.

This whole approach of detaching and reattaching the interrupt handler every time the interrupt happens probably involved quite a bit of unnecessary overhead. But then everything will be terribly slow because the I2C overhead, so I guess it's probably not that big of a problem.

Might also be worthwhile to try 400 kHz I2C with Wire.setClock(400000), but get it working first with the default speed.
 
Hi, I did all the changes you suggest me, nothing.
I added some debug ouput and if I manually short interruptPin to gnd, the sketch works !
So the problem is on the the mcp side.
mcp23017.jpg

I've: pin 10 (reset) to 3.3v with 10k resistor.
I read 3,10v on pins 21, 22, 23 and 0v on pin 20.

Thanks,

Daniele.
 
Trying new libs

Hello guys, after almost a year I'm still here..:cool:
Now I'm trying this lib: https://github.com/maxgerhardt/rotary-encoder-over-mcp23017

I've the polling example running fine with 1 encoder.
How to handle buttons ?
For 16 encoders, I'would use 3 mcp: 2 for encoders and 1 for buttons but how ??
The third mcp should be handled in different/separate way..

Any hints ?

Here the code:

Code:
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Rotary.h>
#include "RotaryEncOverMCP.h"

// https://github.com/maxgerhardt/rotary-encoder-over-mcp23017

/* Our I2C MCP23017 GPIO expanders */
Adafruit_MCP23017 mcp;

//Array of pointers of all MCPs if there is more than one
Adafruit_MCP23017* allMCPs[] = { &mcp };
constexpr int numMCPs = (int)(sizeof(allMCPs) / sizeof(*allMCPs));

/* function prototypes */
void RotaryEncoderChanged(bool clockwise, int id);

/* Array of all rotary encoders and their pins */
RotaryEncOverMCP rotaryEncoders[] = {
        // outputA,B on GPA7,GPA6, register with callback and ID=1
        RotaryEncOverMCP(&mcp, 7, 6, &RotaryEncoderChanged, 1)
};
constexpr int numEncoders = (int)(sizeof(rotaryEncoders) / sizeof(*rotaryEncoders));

void RotaryEncoderChanged(bool clockwise, int id) {
    Serial.println("Encoder " + String(id) + ": "
            + (clockwise ? String("clockwise") : String("counter-clock-wise")));
}

void setup(){
    Serial.begin(9600);
    Serial.println("MCP23007 Polling Test");

    mcp.begin();      // use default address 0

    //Initialize input encoders (pin mode, interrupt)
    for(int i=0; i < numEncoders; i++) {
        rotaryEncoders[i].init();
    }
}

void pollAll() {
    //We could also call ".poll()" on each encoder,
    //however that will cause an I2C transfer
    //for every encoder.
    //It's faster to only go through each MCP object,
    //read it, and then feed it into the encoder as input.
    for(int j = 0; j < numMCPs; j++) {
        uint16_t gpioAB = allMCPs[j]->readGPIOAB();
        for (int i=0; i < numEncoders; i++) {
            //only feed this in the encoder if this
            //is coming from the correct MCP
            if(rotaryEncoders[i].getMCP() == allMCPs[j])
                rotaryEncoders[i].feedInput(gpioAB);
        }
    }
}

void loop() {
    pollAll();
}


Thanks,
Daniele.
 
Status
Not open for further replies.
Back
Top