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

Thread: Teensy 4 Interrupt problems

  1. #1
    Junior Member
    Join Date
    Sep 2019
    Location
    Denmark
    Posts
    4

    Teensy 4 Interrupt problems

    Hello forum,

    Just bought the Teensy 4 for my Bachelor Project, where I'm designing a digital synthesizer.

    I'm setting up interrupt rutines for handling rotary encoders using the Teensy 4.
    I'm fairly new to Teensy and the Arduino Framework, as I've always used AVR and Atmel Studio.

    Arduino has the easy "attachInterrupt()" function that I'm using. The code is as simple as it gets:

    Code:
    #include <Arduino.h>
    
    volatile int counter = 0;
    unsigned long lastInterrupt = 0;
    unsigned long currentInterrupt;
    
    #define INTERRUPT_PIN 2
    
    void rotaryEncoder()
    {
      currentInterrupt = millis();
      if (currentInterrupt - lastInterrupt < 5)
        return;
      
      if (digitalRead(4))
      {
        counter++;
      }
      else
      {
        counter--;
      }
      lastInterrupt = currentInterrupt;
      Serial.print("Counter: ");
      Serial.println(counter);  
    }
    
    void setup() {
      // put your setup code here, to run once:
      pinMode(4, INPUT);
      Serial.begin(9600);
      attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), rotaryEncoder, RISING);
    }
    
    void loop() {
    }
    The usage of Serial in the interrupt is just for test purposes, where I've also tried flagging the counter etc. to make better practice of the interrupt handler. This isn't the issue.

    I just exported the program to an Arduino Nano and it worked perfectly.
    I've also made a debounce filter in hardware to really eliminate any errors. I've scoped it, and it looks exactly as I expect it to.

    Yet the Teensy 4 doesn't react on the interrupt as I expected. I've tried logging the state of the pin, and it even interrupts while being LOW state. Usually the interrupt is activated 3-4 times - even though I have the 5ms software delay/filtering. And the counter is usually incremented and decremented at each turn of the rotary encoder.
    I've also increased the software delay/filtering and it's kinda working sometimes - but that's not useful for me at all.

    I'm not interested in interrupting both pins and thereby comparing states. As said, this works exactly as expected with an Arduino Nano.

    Am I overseeing something? Is it a bug?
    Is it possible to use "avr/interrupt.h" instead? Can't find any PCINT in the datasheet.

    Thanks, Hans

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,443
    You might try adding: asm("dsb");
    To the end of your ISR...
    Code:
    void rotaryEncoder()
    {
      currentInterrupt = millis();
      if (currentInterrupt - lastInterrupt < 5)
        return;
      
      if (digitalRead(4))
      {
        counter++;
      }
      else
      {
        counter--;
      }
      lastInterrupt = currentInterrupt;
      Serial.print("Counter: ");
      Serial.println(counter);  
      asm("dsb");
    }
    And see if that helps. There is probably a much better explanation of why and what this does, but have found that the IMXRT at times does not reevaluate that the ISR has happened and calls the ISR a second time. This has helped in some of the code I have played with

  3. #3
    Junior Member
    Join Date
    Sep 2019
    Location
    Denmark
    Posts
    4
    It helped to get rid of the bouncing. But it still interrupts like on "CHANGE" instead of RISING.
    Turning the encoder one way.
    Code:
    Counter: 1
    Counter: 0
    Counter: 1
    Counter: 0
    Counter: 1
    Counter: 0
    Keeping it between the detents it keeps the value. When fully turned, the counter decrements again.
    Thanks for the fast reply.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    Have you tried the Encoder library?

  5. #5
    Junior Member
    Join Date
    Sep 2019
    Location
    Denmark
    Posts
    4
    Quote Originally Posted by PaulStoffregen View Post
    Have you tried the Encoder library?
    I read the Library through - I can see that it'll use the multi interrupt settings for the Teensy 4, as all digital pins are interrupt-able.
    I've tested my code as:
    Code:
      
    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), rotaryEncoder, RISING);
    and
    Code:
    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), rotaryEncoder, CHANGE);
    .. where the result is exactly the same. Also the scope results are as expected; one turn has one rising edge - for both signals of course, but I'm only interrupting one of them.
    I'm gonna start working on the actual class now, and will implemented a signal CHANGE interrupt on both pins. Seems like it's better practice now that I have all the interrupt pins available anyways.

    But just to be clear: the interrupt on rising edge really doesn't work right now?

    Scope (forgot my USB stick, sorry for quality):
    Click image for larger version. 

Name:	IMG_20190919_105001.jpg 
Views:	2 
Size:	138.0 KB 
ID:	17630

  6. #6
    Junior Member
    Join Date
    Sep 2019
    Location
    Denmark
    Posts
    4
    Quote Originally Posted by PaulStoffregen View Post
    Have you tried the Encoder library?
    .. and.. I'd use your library any time, but for my thesis, I'll have to do my own..

Posting Permissions

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