Problem with Integer Remainder and Interrupts ?? Volatile ?

Here is a version of the code for my trackball, using external interrupts. There are two rollers producing 2 pairs of quadrature interrupts. 2 interrupt routines, both of which adjust the X and Y movement variables.

I use integers but scale down by 10. To avoid a integer rollover problem I zero the movement trackers (except I keep the remainder = fractional pixels) after each mouse move.

I spotted some glitches today with this code (see picture), the value eg intY jumps to -256 or +256 sometimes.

I’ve read about interrupts getting in between and spoiling 16bit math? Is that my problem? Do interrupts interrupt each other? I made a couple of variable volatile but that didn’t solve it.

Note: I have actually solved this by avoiding the problem: the range of values are low so I can use char instead of int and that solves it (I was happy to find a signed 8bit variable). But I would like to know how to solve it while still using int.

Note2: I’m thinking of using shift instead of divide after seeing some speed up notes. Divide by 8 or 16. Anyone point me to routines that cope with + and -ve numbers ?

sketch_HID_017_TRAK_SPIN_v09_test_modulo_03_simple_Int.ino (2.52 KB)

You should make all global variables written to in the interrupts volatile. You missed oldA, oldB, oldC, oldD.

You need to make sure the accesses to intX and intY in loop() are atomic. If you're using an AVR-based board, there is a useful macro for this: ATOMIC_BLOCK(ATOMIC_RESTORESTATE) in util/atomic.h:
https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html#gaaaea265b31dabcfb3098bec7685c39e4

Thanks, the ATOMIC_BLOCK was easier than I thought it was going to be, and it worked.

ATOMIC_BLOCK(ATOMIC_FORCEON)
{
ix= intX;
intX= ix%10; // close coupled so that intX doesn't get altered by interrupt in meantime
iy= intY;
intY= iy%10;
}

guess I can delete the close coupled comment now :slight_smile:

You're welcome. I'm glad to hear it worked. Enjoy!
Per