Compile errors using interrupts on Teensy 3.1

Status
Not open for further replies.

disquisitioner

New member
Greetings,

I'm brand new to Teensy 3.1 but am keen to come up to speed with it as a better platform for several of my more extensive Arduino projects. I am trying to port over code that depends on using pin change interrupts to detect button pushes as part of controlling the code (and device). I've followed the instructions for installing the Teensy 3.1 IDE environment and using interrupts but can't get even the most basic code to compile properly.

Here's my sample code, which at the moment I'm just trying to get to compile:

===========================
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

volatile boolean newScreen = false;

void setup() {
// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:

}

// ********************** UTILITY FUNCTIONS **********************

// Convenience utility called within setup() to initialize interrupt handling
// For this test there's just one -- the pushbutton interrupt
void initialize_interrupts()
{
/*
* We're using pin A0 to read the push button so we need to configure the right
* interrupt settings to enable a pin change interrupt on A0. Based on
* http://playground.arduino.cc/Learning/Pins we see that A0 is on Port C
* as PCINT8, with PCMSK of 0 within PCMSK1. The '1' in the PCMKS1 value means
* that we need to clear/enable interrupts and provide an interrupt service
* routine on port/bank 1 overall.
*
* If you want to use a different pin then you'll need to figure out which
* port/mask values to use here...
*/
cli(); // Disable interrupts while adjusting interrupt settings
PCIFR |= bit(PCIF1); // Clear any pending interrupts on Port C (#1)
PCICR |= bit(PCIE1); // Enable interrupts on port 1 (pins A0 -> A5 inclusive)
PCMSK1 |= bit(PCINT8); // Enable interrupts just for pin A0 (which is also PCINT8)
sei(); // Re-enable interrupts now that we have everything set up
}

/*
* We're using a pin change interrupt to read the 'next screen' button which means
* the associated port interrupt service routine will be called here when that
* button's value changes. We therefore handle that as a 'next screen' button push.
* To keep things simple and short here, we just set a flag that'll get handled
* in the main loop.
*/
ISR(PCINT1_vect)
{
// If pin A0 is now HIGH then button was pushed. If LOW the button was released.
if(digitalRead(A0)==HIGH) newScreen = true;
}

=======================================

When I attempt to verify the code using the Arduino 1.6.4 IDE with the Teensy 3.1 board selected I get the following errors:

ISR_test.ino: In function 'void initialize_interrupts()':
ISR_test:36: error: 'PCIFR' was not declared in this scope
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/WProgram.h:15:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/Arduino.h:1,
from ISR_test.ino:6:
ISR_test:36: error: 'PCIF1' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/wiring.h:109:25: note: in definition of macro 'bit'
#define bit(b) (1UL << (b))
^
ISR_test:37: error: 'PCICR' was not declared in this scope
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/WProgram.h:15:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/Arduino.h:1,
from ISR_test.ino:6:
ISR_test:37: error: 'PCIE1' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/wiring.h:109:25: note: in definition of macro 'bit'
#define bit(b) (1UL << (b))
^
ISR_test:38: error: 'PCMSK1' was not declared in this scope
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/WProgram.h:15:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/Arduino.h:1,
from ISR_test.ino:6:
ISR_test:38: error: 'PCINT8' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/wiring.h:109:25: note: in definition of macro 'bit'
#define bit(b) (1UL << (b))
^
ISR_test.ino: At global scope:
ISR_test:49: error: expected constructor, destructor, or type conversion before '(' token
expected constructor, destructor, or type conversion before '(' token

If I specify "Arduino Uno" as the board everything verifies correctly with no errors.

Currently I'm concerned something might have gone wrong in the installation of the Teensyduino as poking around in the installed directories shows a copy of interrupt.h that is zero bytes long . Clearly something is keeping the compiler from finding definitions of PCIFR, PCIF1, etc. Moreover, if I remove the code in initialize_interrupts() I get an error message associated with the use of the ISR() macro:

ISR_test:31: error: expected constructor, destructor, or type conversion before '(' token
expected constructor, destructor, or type conversion before '(' token

On the other hand perhaps interrupt.h is supposed to be zero bytes long with Teensy 3.1 as some other magic is happening. I've done the full installation of the Arduino 1.6.4 IDE and Teensyduino on two different Windows machines and had the exact same problem on both.

In any event, googling all sorts of variations on this error message, teensy 3.1 pin change interrupts, etc. hasn't resulted in any tips as to how I might solve the problem.

Thanks in advance for any help!

David
 
PCIFR - an Atmel AVR named register.
I'll guess that the Teensy 3.1 target - Freescale MCU - is in error with PCIFR not supported by the Teensyduino libraries that partially emulate Atmel AVR.

To do external interrupts with a Teensy 3.1, you could use the Teensy specific library calls for that.
attachInterrupt()

For a newbie, it's confusing, since many of the Teensy website pages are implicitly for Teensy 2 which is an AVR.
 
Thanks, @stevech! You're right that having all the website pages be for Teensy 2 and no comparable coverage for Teensy 3.X is seriously confusing.

I'm familiar with attachInterrupt() from AVR/Arduino programming for use with INT0/INT1 but not to attach a service routine to a particular pin for pin-change interrupt handling. Is there any Teensy 3.1-specific documentation somewhere or any examples, e.g. for the Teensy-specific library?

I see attachInterrupt() defined in hardware/teensy/avr/cores/teensy3/pins_teensy.c and pin definitions in core_pins.h in that same directory. So would I use attachInterrupt() on the Teensy 3.1 as follows:

attachInterrupt(CORE_INT14_PIN,my_isr,RISING);

to attach the function my_isr() as the interrupt service routine for a pin change on pin 14? (And if I'm interpreting the pinout diagram for the Teensy 3.1 correctly pin 14 is also A0 which is the pin I happen to be using for pin change interrupt handling on the Arduino version of my sketch today.) Or can/should I just say 'attachInterrupt(14,my_isr,RISING)?

I also don't see references to INT0 and INT1 anywhere in the Teensy 3.1 header files so presume that's AVR-specific language as well. So where I'm using INT0 and INT1 in my sketch currently to be Arduino pins D2 and D3 respectively I can just use pins 2 and 3 on Teensy?
 
PJRC needs to take a break and correct the web site and clarify which web page discussions apply to T2 vs. T3. Or delete obsolete T2 pages.

Sorely missing is a simple way to find what T3/LC libraries exist and how to use them and where they are centrally distributed.

T3 can do pin change interrupts, rising edge, falling edge, either edge, and so on. On many different pins. I'm not well versed in the details on attachInterrupt() vs. pin numbers permitted.
 
many of the Teensy website pages are implicitly for Teensy 2

PJRC needs to take a break and correct the web site and clarify which web page discussions apply to T2 vs. T3. Or delete obsolete T2 pages.

Sorely missing is a simple way to find what T3/LC libraries exist and how to use them and where they are centrally distributed.

T3 can do pin change interrupts, rising edge, falling edge, either edge, and so on. On many different pins. I'm not well versed in the details on attachInterrupt() vs. pin numbers permitted.

+1 to all and perhaps evolve to a WIKI that contains current info on libraries and Teensy devices. Just saw another upstart device relying on one: http://www.esp8266.com/wiki/doku.php
 
+1 to all and perhaps evolve to a WIKI that contains current info on libraries and Teensy devices. Just saw another upstart device relying on one: http://www.esp8266.com/wiki/doku.php

we discuss this every few weeks, but nothing changes. It's up to users, since PJRC hasn't done it.

And it would be SO nice if all the reusable code would have at least the quick doxygen headings for main functions (@brief, @retval and friends). Takes so little time to add.
 
Yeah - I finally made the bug thread and pulled together most of the times I added it to discussions in the short time I've been here.

I ran into a doxygen user some time back - maybe it was you? - if a template was posted or linked in the thread for consistency to a sample that might be a nudge. Also a simple consistent way to make the config files that will run from a command line? When I ran it there were so many options and I did it from the GUI, which doesn't bode well for automation.
 
Thanks, everyone.

In terms of the use of attachInterrupt() with Teensy 3.1, looks like I'll just set aside some time (hopefully this weekend) to experiment through trial & error and see if I can craft some examples that work. Certainly I'd be happy to post those somewhere.

And that leads into the idea of having a wiki so users could contribute content to help advance understanding of Teensy 3.1. I agree that we need a way to share information specific to the new version given much of the current content on pjrc.com is about Teensy 2 and so unhelpfully wrong. That said, I understand how Paul is torn between the desire to continue to evolve the platform and the effort of maintaining documentation. I, like other respondees on this thread, would welcome an opportunity to post to the wiki as a way of helping out wherever I can but it seems we're at an impasse about how to take the step of having one. I see @defragster has created a separate thread on that so will respond there too.
 
though attachInterrupt() is documented, I couldn't find a newbie definition of which pins are usable for external interrupts.
 
though attachInterrupt() is documented, I couldn't find a newbie definition of which pins are usable for external interrupts.

For the Teensy 3.1 - as per the little reference card - 'All digital pins have interrupt capability'. So pins 0 through 33 :) Just use, attachInterrupt(23, func, LOW/HIGH/etc);
 
Yup, it's on the pinout card.

card5.png

There's already a lot of info on the card, taking up all the available space. If it printed "INT" on every pin, it'd require making everything else a bit smaller. Maybe that would be a good trade-off? Maybe not?
 
Status
Not open for further replies.
Back
Top