I am writing an arduino code where I want to read an encoder REALLY FAST, for this I am planning on using a register variable to temporarily track it's position, this variable would be incremented/decremented in the interrupt, but when I disassemble the code, it appears that the register supposed to be reserved is being used in other parts of the program.
Here is the variable declaration:
register int8_t counter asm("r0");
And here the interrupt code:
void enc_interrupt(){
counter--;
if (PIND & (1<<4))
counter+=2;
}
I would actually like to change the interrupt code to:
dec r0
sbic PIND, PIND4
subi r0, -2
I would later update the total steps counted on a long variable, something like this:
long enc_read() {
long temp += counter;
counter = 0;
return temp;
}
What do you think? How should I do this? What did I make wrong?
"register" is just a suggestion to the compiler - it is free to ignore the qualifier.
It just isn't reasonable to reserve a register solely for use in an interrupt for an AVR with a very limited register set.
When using volatile variables (counter had better be declared volatile), using a local / temporary generally makes the code much smaller / much faster...
void enc_interrupt()
{
int temp; // I assume counter is an int. The datetype has to be the same as counter.
temp = counter;
temp--;
if (PIND & (1<<4))
temp+=2;
counter = temp;
}
I checked the link referenced by Coding Badly and saw the info regarding the registers. I then looked into my disassembled code and checked which registers were used. I managed to reserve r20, which wasn't used, for the counter and the disassembled code looked ok after that. Can I assume the register was reserved for the variable or might the compiler change it's mind as the code increases?
I am writing an arduino code where I want to read an encoder REALLY FAST, for this I am planning on using a register variable to temporarily track it's position, this variable would be incremented/decremented in the interrupt ...
I'm sorry but this seems a waste of time to me. As described here it takes something like 40 clock cycles (a couple of microseconds) to enter and leave an ISR, so the slight time saving by incrementing a register rather than a variable would be insignificant.
Besides, this must be damn fast encoder. Are you getting a million pulses a second?
Plus, your 8-bit variable would overflow after 256 reads, what are your plans for saving it before it does?
Guess I am just going to use volatile variables then. I would store and reset the counter on each read.
The encoder I am talking about has 128 position and the motor spins at 8000rpm, which should give me a little bit over 17Khz, but I want to use 2 motors and also check other sensors (IMU, ultrassonic range sensor and a color sensor) on a self-balancing robot I am building.