reading from I2C inside ISR on M0 Pro

Hello, I am using an Arduino M0 pro and have set up an interrupt timer so I can periodically read from some sensors via I2C inside of the interrupt handler. However, the I2C commands will not work inside the ISR :slightly_frowning_face: I think the timer interrupts are working as they will blink LEDs with no problems. I had a similar issue a while back on an UNO but could fix it by briefly enabling interrupts inside the ISR using interrupts() while the sensors were read then disabling them again with noInterrupts(). This does not seem to work on the M0 pro for some reason. I would be very grateful if someone knows what is going on! :slight_smile:

Thanks in advance,
Matt

sensors_v8.ino (6.21 KB)

An interrupt can be used to set a few variables and maybe change an output pin. Don't use the Serial library in a interrupt, and neither any LCD, SD, I2C or other libraries.

Stay away from interrupts, unless you really need them. For example when decoding a rotary encoder.

The millis() can be used to do things with a certain interval. That works on every Arduino board. Start with the Blink Without Delay: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

Koepel, Thanks very much for your input, and I see your point. However its bugging me that it won't work when the same thing worked like a charm on the uno...

Cheers,

Matt

Make nice and good code ;) Don't waste time with thinking about bad and ugly code :o

the same thing worked like a charm on the uno...

It did not "work like a charm". You were just lucky that enabling interrupts whilst in an ISR did not cause a problem.

What do you think might happen if you enabled interrupts when in an ISR and an interrupt occured, maybe even the same type of interrupt that the ISR was already servicing ?

Noted, though I would have thought that since the board uses an ARM Cortex M0+ you should be able to deal with this using the NVIC?

Use the ISR to set a flag indicating that it's time to read the sensors. Then, pick up that flag in the loop() function and do your I2C operations there with interrupts enabled. Don't forget to clear the flag.

UKHeliBob:
It did not “work like a charm”. You were just lucky that enabling interrupts whilst in an ISR did not cause a problem.

What do you think might happen if you enabled interrupts when in an ISR and an interrupt occured, maybe even the same type of interrupt that the ISR was already servicing ?

Multi-level interrupts is what I’m used to when I was programming MCS51 microcontrollers; it was implemented in hardware though. I don’t really see the problem where a lower priority interrupt can be interrupted by a higher priority interrupt.

In the AVRs the same can be achieved by selectively disabling interrupts before reactivating the global interrupt enable.

I have to admit that I have not had a need for a multi-level interrupt in the AVR (Arduino) environment.

May be useful, may not be. - Arduino and the MCP23017 I/O Expander

dougp: May be useful, may not be. - Arduino and the MCP23017 I/O Expander

Very useful, thankyou :)