I'm working on a rather complex robotics project run on an arduino mega. Part of the machine uses DC motors with rotary encoders. I gather that I should use interrupt functions to track when the encoder value changes, but this thread suggests that the interrupts can crash the code if they come at the wrong moment:
First understand that the interrupt can interrupt at ANY time. On an 8-bit Arduino, that can occur in between requesting the two bytes of a 16-bit integer. So this code will have problems...
The poster then goes on to suggest a "safe copy" function that blocks interrupts while reading the value that the interrupt function modifies.
My question is, do I need such function only when I'm reading something that the interrupt could affect, or could the interrupt function crash the code while ANY integer is being read, or calculation is being made, etc....
The problem relates to multi byte variables that are changed by an ISR then used outside of the ISR and is easily worked around by copying the variable with interrupts turned off then working with the copy
You can recognize those variables because they are the same ones you have to put the "volatile" keyword on: Any variable changed in an ISR that is also used outside the ISR.
Warning: The ISR could increment 'count' half-way through your code setting 'count' to zero. This is probably not a problem in this case since I assume that the unsigned long is set in byte order and an Arduino UNO is little-endian (LSB first). That would mean the increment would be from 0 to 1.
On a big-endian processor, you might have a count of 0x0007FFFF and get an interrupt between setting the top two bytes to 0 and setting the bottom two bytes to 0:
I think that when a byte variable is incremented or decremented in an ISR (e.g. count++) the arithmetic operations are not atomic, and the "safe copy' protected access method should be used in all cases.
That is true when the byte variable is read AND WRITTEN in both places. The reported problem was an increment in the ISR was not staying in effect when it happened in the middle of a decrement outside the ISR. If only one or the other modified the byte, but not both, then no discrepancy would have occurred.