Now, at least in the current IDE version that I'm using (1.6.7), this just resets the Arduino when the interrupt is triggered. To solve it, I need to do this:
This is normal behaviour. In most cases, a null pointer is equal to zero, and therefore the root of the arduino's flash memory. So, essentially, you're telling it to jump to the beginning of the bootloader when the interrupt fires, and therefore it reboots.
What're you trying to achieve? If you want to disable an interrupt, there is a seperate function for that called detatchInterrupt.
It is normal behaviour. The attachInterrupt function has to simplify use of interrupts for noobs so it is derivate of normal ISR vector. Once is ISR defined it is always used while is interrupt enabled, the definition is static, created during compilation. Arduino has predefined functions for each interrupt to be able manipulate with these dynamically.
Null vector is called as normal function from ISR.
Solution is to disable it via detach or provide an empty function as parameter. The empty function static void nothing(void) is defined already.
Well I'm not trying to detach the interrupt. Sometimes you just want the interrupt to wake up the arduino so it can do something in loop(), and then go back to sleep. As said, it used to work, but maybe I was just lucky or something
A null vector should result, I think, in a dirty (jmp 0 style) reset, but would screw up interrupts because it would now be in an isr that never returns (your program).
Doing that does not run the bootloader! That is at the other end of the flash and gets run on startup/reset thanks to he bootrst and bootsz fuses,
Thanks oqibidipo, so I'm not crazy, it used to work and was perfectly valid? I hope the speed gain was worth it...
When I try to use "nothing" in my sketch (instead of my own empty ISR) it just gives me an error about it being undeclared. I think I will still report this issue, they should rename "nothing" to something like "noISR" and make it available to use in sketches. Don't you think ?
guix:
When I try to use "nothing" in my sketch (instead of my own empty ISR) it just gives me an error about it being undeclared. I think I will still report this issue, they should rename "nothing" to something like "noISR" and make it available to use in sketches. Don't you think ?
It is a static function in WInterrupt.c and not supposed to be visible. Just use your own empty function.
I actually found a canonical way to achieve what you want to do. I found it in Nick Gammon's notes, which are themselves linked to by the documentation on attachInterrupt.
If you merely want an interrupt to wake the processor, but not do anything in particular, you can use the EMPTY_INTERRUPT define, eg.
EMPTY_INTERRUPT (/* Interrupt Vector */);
This simply generates a "reti" (return from interrupt) instruction. Since it doesn't try to save or restore registers this would be the fastest way to get an interrupt to wake it up
EMPTY_INTERRUPT (INT0_vect);
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
Table of interrupt vectors is in Nick Gammon's notes, near the top:
Available interrupts
Below is a list of interrupts, in priority order, for the Atmega328:
1 Reset
2 External Interrupt Request 0 (pin D2) (INT0_vect)
3 External Interrupt Request 1 (pin D3) (INT1_vect)
4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect)
6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect)
7 Watchdog Time-out Interrupt (WDT_vect)
8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect)
9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect)
10 Timer/Counter2 Overflow (TIMER2_OVF_vect)
11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect)
12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect)
13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect)
14 Timer/Counter1 Overflow (TIMER1_OVF_vect)
15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect)
16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect)
17 Timer/Counter0 Overflow (TIMER0_OVF_vect)
18 SPI Serial Transfer Complete (SPI_STC_vect)
19 USART Rx Complete (USART_RX_vect)
20 USART, Data Register Empty (USART_UDRE_vect)
21 USART, Tx Complete (USART_TX_vect)
22 ADC Conversion Complete (ADC_vect)
23 EEPROM Ready (EE_READY_vect)
24 Analog Comparator (ANALOG_COMP_vect)
25 2-wire Serial Interface (I2C) (TWI_vect)
26 Store Program Memory Ready (SPM_READY_vect)
Internal names (which you can use to set up ISR callbacks) are in brackets.
Warning: If you misspell the interrupt vector name, even by just getting the capitalization wrong (an easy thing to do) the interrupt routine will not be called, and you will not get a compiler error.
Also note this only applies to AVR boards (e.g. the Uno); ARM boards don't support this construct.
If you need to be able to attach and detach an actual ISR to your interrupt, but you still want it to wake your CPU when its detached, then I agree that this construct isn't for you because it will prevent you from attaching an ISR. However, if you only ever want the interrupt to wake your CPU, this is the quickest and canonical way of doing that.
EICRA &= ~(bit(ISC00) | bit (ISC01));Â // clear existing flags
EICRA |= bit (ISC01);Â Â // set wanted flags (falling level interrupt)
EIMSK |= bit (INT0);Â Â // enable it
I think I will not bother with this low level stuff and stick to attachInterrupt with my own empty ISR. Thanks anyway