I need some support, I'm attempting to have a program which checks when the counts (or pulses) on an encoder exceeds a required counts variable. I understand that the volatile qualifier must be used when dealing with interrupts, but I'm concerned that the counts may exceed the 8bit size of a volatile long.
If the required counts variable is say 1,000,000, can the count variable ever reach this value? My understanding is that the largest 8 bit number is 255. If so is there a work around?
I don't know why you're limited to 8-bits or if that's what's really happening.
...With serial communications you usually send/receive one byte at a time and the software has to take care of splitting & reassembling longer types/variables but I assume you're not using serial communication.
I don't believe there are any additional or artificial limits in interrupts but you need to be aware of variable scope and volatility in functions (and objects).
Thanks for the help everyone. I've confused myself, I misunderstood ' If the volatile variable is bigger than a byte (e.g. a 16 bit int or a 32 bit long), then the microcontroller can not read it in one step, because it is an 8 bit microcontroller. This means that while your main code section (e.g. your loop) reads the first 8 bits of the variable, the interrupt might already change the second 8 bits. This will produce random values for the variable.' this part of the documentation.
So just to clarify if I have a variable: 'volatile long counts;'. It can store values greater than 255?
'This means that while your main code section (e.g. your loop) reads the first 8 bits of the variable, the interrupt might already change the second 8 bits. This will produce random values for the variable.' this part of the documentation. ' Can someone please explain in simple terms what is meant by this?
To answer the first question, volatile is a modifier that tells the compiler that a variable might be updated externally so it doesn't accidentally optimize it out. It doesn't affect the size of the variable.
The second question is a common concern in shared-data systems. It's possible that while the main loop is in the middle of accessing a multi-byte variable, an interrupt occurs and changes that variable, leading to corrupted data. There are many ways of handling this situation (and in fact, asking about this is one of my favorite interview questions). On an arduino the easiest way is probably to disable interrupts before accessing the shared data and re-enable it later. e.g.,
Sorry, what do you mean by 'then long is 32bits'? Is there a case when long wouldn't be 32bits. Am I missing something, like is it not 32bits during an interrupt?
Long is always 32 bits on every type of Arduino I have encountered. Making it volatile or updating it during interrupts doesn't change it's size, as @cedarlakeinstruments already said.
The size of a variable can vary between processor types or operating systems, etc. If you are doing something where the variable size is significant, it's best to be explicit about it.
e.g., using uint32 instead of unsigned long clearly defines the variable to be 32 bits in size.
So interrupts are considered an external update, which means they require the volatile modifier?
'asking about this is one of my favorite interview questions' - love it, I think I would've walked out at that point . Thanks for taking the time to explain, its starting to make sense!
Doesn't matter if the interrupt is external or internal, you need to make it volatile if it's going to be updated in an interrupt routine and read in the main code. Otherwise the optimiser within the compiler will make incorrect assumptions about when the value might have changed.
I've got the case where the the variable could be anywhere between 0 & 1e6 so I guess long is overkill. Would you recommend using using something with a smaller bit size, is there any benefit to making the bit size of the variable smaller?