 Calculating if I'm within 10% of the center of a pot

This one’s got me a bit stumped. On power up, I want my bot to wait until the steering mechanism is within 10% of ‘neutral’
Here’s some variables I’ve got assigned to the min/max readings of the steering POT
steering.left
steering.right

steeringVal() is another function that returns the current reading of the POT

I’d like to make a boolean that will return TRUE if the steering is within 10% of center, or FALSE is it’s not
This is as far as I got, but I’m not really sure about it…

boolean StraightAhead() {  //returns true if within 10% of center
int steeringRange = abs(steering.left - steering.right); //the total range of the steering POT
int steeringCenter = steeringRange / 2;  //the neutral steering position
int tenPercent = steeringRange * .01;  //10% of the range, I think
if (abs(steeringVal() - steeringCenter) < tenPercent) return true;
else return false;
}

Are the steering.left and steering.right the raw values from the analogRead() functions ?
Or are they calculated values from 0 to 180 (the degrees for the pot) ?

I assume they are the raw analogRead() values.
Is steering.left always the lower value, or could steering.left be the lower value ?

How do you use the 10%. Do you want the range to be from -5% to +5% around the center ?

I see 3 problems:
(1) Your center is not the range divided by two, but you have to add the steering.right or steering.left (whatever is the lowest value).
(2) Ten percent is “0.1”, you use “.01” which is 1%.
(3) A value of “0.1” or “.01” is a floating point value, and you use integers to calculate it. That is not possible.

I used many variable in the next example, to show what is going on.

// example, not tested

int lowest, range, middle;
int steering, limit_low, limit_high;

lowest = min (steering.left, steering.right);
range = abs (steering.left - steering.right);
middle = lowest + (range / 2);

limit_low = middle - (range / 20);       // 5% lower
limit_high = middle + (range / 20);     // 5% higher

steering = steeringVal();

if (steering > limit_low && steering < limit_high)
return (true);
else
return (false);
}

percentiles can be calculated with weighted average
// in int math look out for overflow.

boolean straight(float margin)  // 0.10
{
steering = steeringVal();
if (steering < (left*(0.5 + margin) + right*(0.5 - margin)) )   // becomes  left  * 0.6 + right * 0.4
{
return false;
}
return steering > (left*(0.5 - margin) + right * (0.5 + margin));  // becomes left * 0.4 + right * 0.6
}

optimized for ±10% in integer math
// as steering and left and right are max 1024 (analog read) the peak value of the math is 5120 so will fit in an int perfectly
// all divisions are replaced by multiplications.

boolean straight(void)
{
steering = steeringVal();
if ((steering*5) < (left*3 + right*2))
{
return false;
}
return (steering*5 > (left*2 + right*3) );
}

Krodal:
Are the steering.left and steering.right the raw values from the analogRead() functions ?
Or are they calculated values from 0 to 180 (the degrees for the pot) ?

I assume they are the raw analogRead() values.
Is steering.left always the lower value, or could steering.left be the lower value ?

How do you use the 10%. Do you want the range to be from -5% to +5% around the center ?

I see 3 problems:
(1) Your center is not the range divided by two, but you have to add the steering.right or steering.left (whatever is the lowest value).
(2) Ten percent is “0.1”, you use “.01” which is 1%.
(3) A value of “0.1” or “.01” is a floating point value, and you use integers to calculate it. That is not possible.

I used many variable in the next example, to show what is going on.

// example, not tested

int lowest, range, middle;
int steering, limit_low, limit_high;

lowest = min (steering.left, steering.right);
range = abs (steering.left - steering.right);
middle = lowest + (range / 2);

limit_low = middle - (range / 20);       // 5% lower
limit_high = middle + (range / 20);     // 5% higher

steering = steeringVal();

if (steering > limit_low && steering < limit_high)
return (true);
else
return (false);
}

Thanks, yes, I see all 3 problems, and your were correct.
steeringVal(), steering.left, and steering.right are all raw analog readings, though they typical range from 500-600 min/max, not 0-1024. So I think what you’ve come up with looks like it will work. I’ll make a serial monitor debug loop and check it out. Thanks.

Here’s what I ended up with:

int lowest, range, middle;
int limit_low, limit_high;
lowest = min (steering.left, steering.right); //the lowest of the 2
range = abs (steering.left - steering.right); //the range from left to right
middle = lowest + (range / 2);  //the center steering value
limit_low = middle - (range / 20);       // 5% lower than center
limit_high = middle + (range / 20);     // 5% higher than center
int curentVal = steeringVal();
if (curentVal > limit_low && curentVal < limit_high)
return (true);
else
return (false);
}

What is the difference between these two lines? Are they the same?

'void' indicates that no parameter is used. In this situation void means 'nothing here'.

What is the difference between these two lines? Are they the same?