I'm currently writing the UI for a small uC project. Having some trouble with the calculating the position of a vertical line. The idea is to move the red line along the x - axis towards the end of the rectangle.
The value that is being incremented with an endless rotary encoder and has a range of 0 to 800 with increments of 1. Left side of the rectangle is the beginning of the x - axis aswell with x = 0. The range 0 - 800 represents 0 - 100.00 in Q13.3 fixed point notation with the data type being uint16_t.
The rectangle is currently 300pixel wide, i'm flexible with that but it shouldn't be less than 240pixel. Line is 1pixel wide.
The catch is, that due to performance limitations i can only use fixed point math, there should be no access to the floating point unit at all.
What i'm currently doing is having a counter that increments with every click of the encoder. sth. like:
if(direction) counter++; //Running forwards
if(!direction) counter--; //Running backwards
if((counter % 8 ) == 0){
if(direction) line.x += 3;
if(!direction) line.x -= 3;
}
which is less than optimal since the spacing is 3 pixel.
Ideally if float calculation was an option i would simply increment the counter with 0.375
Appreciate any advice on this issue.
cheers
Just take the position of the counter in terms of 0 ... 800
and scale it down to 0 ... width
?
I.e. multiply the value of counter by width
and then do an integer division by max
where max is the max of your logical range.
uint16_t scale(uint16_t value, uint16_t logical_max, uint16_t physical_max)
{
uint32_t val = value * physical_max; // use a wider type to cope with overflow
return (uint16_t) ((val / logical_max) & 0xFFFFU);
}