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

Thread: Teensy 2.0 interrupt

  1. #1
    Junior Member
    Join Date
    Mar 2018
    Posts
    9

    Teensy 2.0 interrupt

    Hello

    I am just learning to code microcontrollers and my current project is to build a MIDI controller using a teensy 2.0. I need at least six pins with interrupt capability as I am using three encoders. I have started prototyping with an arduino and I was able to make it work by using the arduino library "EnableInterrupt.h", which allows me to use any pin as an interrupt. So with the arduino (UNO) I have had no problems but I cannot figure out how to do this with a teensy, or whether it is possible at all.

    Any help would be appreciated.

    Cheers!

  2. #2
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,938
    Unless your goal is to handcraft an encoder library probably easier to use:
    https://www.pjrc.com/teensy/td_libs_Encoder.html
    and follow the table there.

  3. #3
    Junior Member
    Join Date
    Mar 2018
    Posts
    9
    Thanks for your reply. If I understand it correctly the table shows that I can only use 4 pins with interrupt capability, but I need 6. If use only one interrupt capable pin for two encoders this would give me good performance rather than best performance, which is still good enough probably, but I was just wandering if there was a library that could achieve the same result with teensy as the enable interrupt library does with arduino uno.

  4. #4
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    300
    Just to let you know the Teensy 2.0 (ATMega32U4) has 4 INT External Interrupt and 8 PCINT Pin Change Interrupts.
    Click image for larger version. 

Name:	schematic2.gif 
Views:	226 
Size:	13.8 KB 
ID:	13378
    Click image for larger version. 

Name:	ATmega32U4.jpg 
Views:	416 
Size:	97.3 KB 
ID:	13377

    Add Interrupt pins to Teensy 2.0
    Last edited by Chris O.; 03-24-2018 at 05:12 PM.

  5. #5
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    300
    Pin change interrupts
    There are two ways you can detect external events on pins. The first is the special "external interrupt"on the Atmega328-(Arduino UNO) pins, D2 and D3. These general discrete interrupt events, one per pin. You can get to those by using attachInterrupt for each pin. You can specify a rising, falling, changing or low-level condition for the interrupt.
    However there are also "pin change" interrupts for all pins (on the Atmega328, not necessarily all pins on other processors). These act on groups of pins (D0 to D7, D8 to D13, and A0 to A5). They are also lower priority than the external event interrupts.

  6. #6
    Junior Member
    Join Date
    Mar 2018
    Posts
    9
    Thank you Chris very helpful. Are you aware of any library that exist to simplify using the pin change interrupts? I have only just started learning arduino two months ago so I think that I may struggle without a library to simplify the use of them. As I said, I have been able to use the arduino ones without problem (with the enable interrupt library).
    Also I am not sure I am using the attachinterrupt function properly for the teensy. It is straightfoward on the arduino but when I upload the same code on the teensy (just changing the pin number (INT number are the same 0 and 1) it does not work. It will compile and upload no problem but the encoder does not work.
    I have now used the encoder library example for the Teensy and I didn't use the attachinterrupt function, I suppose that this is all dealt by the encoder library? the instructions on the example state:

    // Change these two numbers to the pins connected to your encoder.
    // Best Performance: both pins have interrupt capability
    // Good Performance: only the first pin has interrupt capability
    // Low Performance: neither pin has interrupt capability

    So I suppose that I am using the external interrupts by using this example code?....

  7. #7
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,938
    The Teensy encoder library automatically uses interrupts if available. If performance is provable such an issue that you need more interupts you should probably look at a more capable CPU. Unless you are making 10s of thousands of units it is very easy to spend more time and effort getting code to run on minimal hardware than spending a couple more dollars on more capable hardware.

    For three hand operated encoders your T2 is probably fine. The need for high performance comes in when the encoder is being driven mechanically as a position or RPM sensor. In your case if the user flicks the dial and the count comes up short they just keep turning until they do reach the set point they needed.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,742
    Quote Originally Posted by Fluxia View Post
    It will compile and upload no problem but the encoder does not work.
    Generally the way we work here involves showing the complete non-working code. "Complete" means anyone can copy it into Arduino and upload it to their board, to recreate the problem. That is assuming they've got an encoder wired up, and generally when you show such code you should be clear about how you've wired up your hardware. Photos are the easiest and best way.

    We can talk at length about how the library is designed and alternate ways it might be made, but if you want actual help with getting things working (which should be able to work), you need to show what you're actually doing.

  9. #9
    Junior Member
    Join Date
    Mar 2018
    Posts
    9
    Thank you both. I have now been able to make the encoder work using the attachinterrup function. Not sure what happened yesterday as I used exactly the same code (just rewired my breadboard...), and ... yes probably in my case polling may even be fast enough for my encoder to do their job. It 's also good to know what are the applications that really need interrupts. However while I am working on this project I also I wanted to learn how to properly use interrupts so may be helpful to clarify these issues.
    I have pasted below the code I am using. I have commented out the enableinterrupt function and the code as it is works well both with arduino and Teensy (clearly I need to change the variables outputA and outputB to make them match the right pin). However, using the enableinterrup function only works with arduino. If I try to use it with the teensy it will not let me compile. Now if Teensy has PCINT in the pins PB0 to PB7 why would this not work? I suppose I would need to use the values 0 and 1 for outputA and outputB as they would correspond to PB0 and PB1?
    I have also attached a pic of my breadboard connections when using pin 0, 1 and 5,6.Click image for larger version. 

Name:	P_20180325_142554.jpg 
Views:	96 
Size:	100.9 KB 
ID:	13393Click image for larger version. 

Name:	P_20180325_142525.jpg 
Views:	70 
Size:	100.8 KB 
ID:	13394

    Code:
    //#include <EnableInterrupt.h>
    
    #define outputA 5
    #define outputB 6
    
    int counter = 0;
    int aState;
    int aLastState;
    
    void setup() {
    
      attachInterrupt(outputA, encoder, CHANGE);
      attachInterrupt(outputB, encoder, CHANGE);
    
    //    enableInterrupt(outputA, encoder, CHANGE);
    //    enableInterrupt(outputB, encoder, CHANGE);
    
      pinMode (outputA, INPUT_PULLUP);
      pinMode (outputB, INPUT_PULLUP);
    
      Serial.begin (9600);
    
      aLastState = digitalRead(outputA);                         // Reads the initial state of the outputA
    }
    
    void loop() {
    
    }
    
    void encoder () {
    
      aState = digitalRead(outputA);                            // Reads the current "state" of the Encoder
    
      if (aState != aLastState) {                              // If the previous state and the current state of outputA are different a pulse occurred
    
        if (digitalRead(outputB) != aState) {                   // If the outputB state is different from outputA the Encoder is rotating clockwise
          counter ++;
        }
        else {                                                // otherwise the Encoder is rotating anticlockwise
          counter --;
        }
        Serial.println(counter);
      }
      aLastState = aState; // If the output_B state is different from OutputA it means that the Encoder is rotating clockwise...
    }
    Last edited by Fluxia; 03-25-2018 at 02:29 PM.

  10. #10
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    300
    Ok I was wrong on the INT External Interrupts available, there is actually 5 External Interrupts on Teensy 2.0
    Unfortunately you need to access the interior pin 24, INT6 (marked in red color).

    External Interrupts (INT)
    Board Digital Pins Usable For Interrupts :
    Uno, Nano, Mini, Atmega328-based 2, 3
    Micro, Leonardo, Atmega32u4-based 0, 1, 2, 3, 7
    Teensy 2.0, Atmega32u4-based 5, 6, 7, 8, 24 --- (5 INT) External Interrupts
    Click image for larger version. 

Name:	Teensy 2.0 INT pins.jpg 
Views:	231 
Size:	100.4 KB 
ID:	13406

  11. #11
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    300
    Give this a try:
    NOTE: Completely untested code since i don't have Teensy 2.0
    Example: Pin change interrupt test, setup for PIN 0.
    Code:
    // Pin change interrupt test PCINTn
    // Uno Atemga Atmega328-based (PCINT0_vect,8-9-10-11-12-13),(PCINT1_vect, A0-A5),(PCINT2_vect, D0-D7)
    // Teensy 2.0 Atmega32u4-based (PCINT0_vect, PINs 0-1-2-3-4-13-14-15) --- (8 PCINT) Pin Change Interrupts
    
    byte Debug_led = LED_BUILTIN; // TEENSY 2.0 LED on pin 11
    byte PinChangeI_pin = 0; // USE ONLY PINs 0-1-2-3-4-13-14-15 on Teensy 2.0.
    
    // The elapsedMillis feature is built into Teensyduino.
    // For non-Teensy boards, it is available as a library.
    elapsedMillis sinceLed;
    
    // --------- Pin change interrupt setup ------------------
    // Install Pin change interrupt for a pin, can be called multiple times
    void PciSetup(byte pin)
    {
      *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin
      PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
      PCMSK0 |= bit (digitalPinToPCICRbit(pin)); // Enable Mask
      PCICR  |= bit (digitalPinToPCICRbit(pin)); // Enable interrupt
    }
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin (9600);
      pinMode(Debug_led, OUTPUT);
    
      pinMode(PinChangeI_pin, INPUT_PULLUP);
      // USE ONLY PINs 0-1-2-3-4-13-14 or 15 on Teensy 2.0.
      PciSetup(PinChangeI_pin); // Enable Pin Change Interrupt for pin...
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      if (sinceLed >= 250) { // run every 0.nnn ms
        //sinceLed = 0; // reset since
        digitalWrite(Debug_led, LOW);
      }
    }
    
    // ---------------- ISR ------------------
    // Pin change interrupt.
    // USE ONLY PINs 0-1-2-3-4-13-14 or 15 on Teensy 2.0.
    ISR (PCINT0_vect) //
    {
      // TODO, responsibility of the single PinChange interrupt service routine.
      // determine Which pins changed, and in what direction
      sinceLed = 0; // reset since
      digitalWrite(Debug_led, HIGH);
    }

  12. #12
    Junior Member
    Join Date
    Mar 2018
    Posts
    9
    I have tried it and the led lighten up when changing the state of the pin 0 with a push button but it's not very consistent. Not sure that I am actually using it appropriately but thank you. Now I now where the PCINT are, maybe at some point I will be able to use them
    Where did you find about INT 6 on pin 24? and is't it strange that they call it INT6 (if there are no INT4 and INT5)?

  13. #13
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    300
    Where did you find about INT 6
    https://www.pjrc.com/teensy/atmega32u4.pdf

Posting Permissions

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