This post has been de-listed

It is no longer included in search results and normal feeds (front page, hot posts, subreddit posts, etc). It remains visible only via the author's post history.

3
Help Optimising Maths on AVR Microcontroller
Post Body

Edit:

ADC is an analog sweep from 0-1023.
The overall code reads the analog input between 0 and 1023 and selects an output position in the 33 point array map_1[33], by right shifting the analog read value (0-1023>>5 = 0-32), this gives a step at the output every 32 input values.
Map is predefined and will be prefilled on runtime, it can be any value from 0-193, in any order, but usually ascending or descending.
After selecting a value from the table, the code will set a pin to PWM to drive an output. The system is open loop at this stage.

End Edit:

I've written the below function, if I'm understanding what it's doing correctly, it's interpolation, or at least a very simple form, it works perfectly, but it is slow. I've essentially taken the map() function from the arduino library and tried to simplify it to fit my specific case better, removing divide operations as the AVR I'm using (atmega328p) doesn't have a divide instruction.

Like I said, it works perfectly, but it halves execution speed, the only reason I can think that would be is because of the multiplication, but I'm not sure, my understanding is that bitshifting as an alternative should be a lot faster than a divide, but from what I've tested, replacing the ">>5" with a /32 runs at the exact same speed, so I assume the compiler is smarter than me.

Is there a way I can make this even faster without losing functionality? As it is, the function results in good stepping between the points of the map inline with the analog input. I just want it to be as light as possible so I can keep adding functions before having to step to a faster processor. Also, knowledge.

Cheers.

Original function as currently working:

TPSin = ADC>>5; //This is in an ISR for the ADC, putting it here for clarity
map_1[33] = {0,6,12,18,24..etc};

void interpolate(int *map)
{
  output = ((ADC - (TPSin<<5))*(map[TPSin 1] - map[TPSin])>>5)   map[TPSin];
}

Test function replacing ">>5" with /32, runs at the same speed:

void interpolate(int *map)  //divide by 32 because in_max-in_min always = 32
{
  output = ((ADC - (TPSin<<5))*(map[TPSin 1] - map[TPSin])/32)   map[TPSin];
}

Original Map() function from the arduino Library:

long map(long x, long in_min, long in_max, long out_min, long out_max) 
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min)   out_min;
}

Author
Account Strength
90%
Account Age
9 years
Verified Email
Yes
Verified Flair
No
Total Karma
3,903
Link Karma
60
Comment Karma
3,843
Profile updated: 3 days ago
Posts updated: 1 month ago

Subreddit

Post Details

We try to extract some basic information from the post title. This is not always successful or accurate, please use your best judgement and compare these values to the post title and body for confirmation.
Posted
4 months ago