Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: teensy-3.2, mcp23017 with encoders & interrupt..

  1. #1

    teensy-3.2, mcp23017 with encoders & interrupt..

    HI guys, I'm trying to use this sketch: https://github.com/raspibo/I2C_rotar...ry_encoder.ino..
    First of all, a basic sketch like this: https://github.com/adafruit/Adafruit...gle/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.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Quote Originally Posted by DanieleFromItaly View Post
    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.

  3. #3
    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.
    Click image for larger version. 

Name:	mcp23017.jpg 
Views:	273 
Size:	19.0 KB 
ID:	13627

    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.

  4. #4
    This sketch: http://www.g7smy.co.uk/2014/08/rotar...n-the-i2c-bus/ with polling instead of interrupt, works.
    So something in interrupt setup is not ok in previous sketch..

  5. #5

    Trying new libs

    Hello guys, after almost a year I'm still here..
    Now I'm trying this lib: https://github.com/maxgerhardt/rotar...-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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •