SpenceKonde / ATTinyCore

Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8
Other
1.57k stars 306 forks source link

Interrupt pins on the Attiny88/MH-ET-Tiny88? #707

Closed IdontKnowWhatToNameThisAccount closed 2 years ago

IdontKnowWhatToNameThisAccount commented 2 years ago

Which of the pins on the MH-ET-Tiny88 board are interrupt pins and what is the code to get these to work? I cant find any info on that topic although the datasheet for the Attiny88 mentions the word "Interrupt" 681 times and even mentions external interrupts. So how do these work in this library?

SpenceKonde commented 2 years ago

attachInterrupt works on the INT0 and INT1 pins (2 and 3) and should work like it does on a normal classic AVR. All pins can be used as pin-change interrupts - this must be implemented manually (the limitations of the C/arduino framework impose a significant performance penalty on any sort of "attached" interrupt, because right off the bat, you lose like 30 clock cycles entering and exiting the ISR saving and restoring registers, because the optimizer doesn't know what function will be called and hence can't inline it, and has to free up all 16 call used registers, instead of just r1 and r0. and restore them afterwards; Often a well-written (ie, short) manually defined interrupt can run and return to the code that was interrupted by the time that one created with an attachInterrupt like function would have been done with the prologue.

In general, barring the pin numbering differences after the first 14 pins or so, interrupts should work identically to a 328p - they tried to keep some semblance of code compatibility on the tiny x8-family with the mega x8 family (note also how there's both a real TWI and a real SPI port - on a low cost tiny, instead of that dreadful USI (Unwieldy Serial Interface*) that most tinyAVRs before the 2016 revolution got stuck with)- very un-Atmel like of them, most tinyAVRs from that era likl like they chose pin mappings and special functions by throwing darts at a pinout chart while blindfolded. Microchip seems to have whipped them into shape on that front and the modern AVRs have much more consistent pin mappings and pinouts.

* I think they called it "universal serial interface" but that does not describe it's functionality very well.

IdontKnowWhatToNameThisAccount commented 2 years ago

Sorry, I only understood maybe an eighth of what you wrote. Im looking for a more specific example. If I understood you right, The Pins labeled as 2 and 3 on the MH-ET board actually have interrupts build in, right? But what would I need to do to get them to work? I have a line of code for an arduino nano I'd like to adopt: attachInterrupt(digitalPinToInterrupt(pin), impulse, FALLING); Ive tried just replacing "pin" with "3" but that doesnt seem to work. As I understand your text digitalPinToInterrupt is bad anyways, but whats the alternative? Ive tried pin 2 too but that seems to interfere with usb functionality.

As a quick test I built a pullup resistor button circuit on a breadboard and tested it by just turning on the internal led on if the button is pressed, with a normal if(HIGH). That works fine. As a second test I just left the circuit the same and copied some code from the internet:

volatile boolean actionState = LOW;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
attachInterrupt(PIN_PD3, myEventListener, CHANGE);
}
void loop() {
// We don't do anything in the loop function since all of the event handling code will be in the myEventListener function
}
void myEventListener() {
actionState != actionState; //
// Perform other actions, e.g. turn the LED on or off
digitalWrite(LED_BUILTIN, actionState);
}

and just tried a bunch of pin numbers in the attachInterrupt, I basically tried 0, 1, 2, 3, INT0, INT1, PIN_PD3 without touching the circuit to see if anything would work, but nothing does

SpenceKonde commented 2 years ago

I think what you want is

attachInterrupt(digitalPinToInterrupt(PIN_PD3), myEventListener, CHANGE);
SpenceKonde commented 2 years ago

(PIN_PD2, AKA INT0 is generally one of the USB pins - the one that needs to respond fastest. Since, when multiple interupts are enabled and and their flag is set, if you want a prayer of USB workingf in an interrupt driven configuration,m int0 must be used for USB if you want to potentially use USB from the sketch (which still is super flaky)

If you just need an event on a change not rising/falling/level, then you can just use a PCINT, which can be used on any pin (though there's only one vector per portso things get a bit more complicated if you want more than one interrupt pin on a given port, but usually you don't do that unless it makes things more convenient rather than less