Go Down

### Topic: Calculating if I'm within 10% of the center of a pot (Read 1 time)previous topic - next topic

#### SouthernAtHeart

##### Feb 02, 2013, 07:16 am
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...

Code: [Select]
`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;}`

#### Krodal

#1
##### Feb 02, 2013, 11:02 amLast Edit: Feb 02, 2013, 11:03 am by Krodal Reason: 1
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.
Code: [Select]
`// example, not testedboolean StraightAhead( void) {  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);}`

#### robtillaart

#2
##### Feb 02, 2013, 01:27 pm

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

Code: [Select]
`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.
Code: [Select]
`boolean straight(void){  steering = steeringVal();  if ((steering*5) < (left*3 + right*2))  {    return false;  }  return (steering*5 > (left*2 + right*3) );}`
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### SouthernAtHeart

#3
##### Feb 02, 2013, 02:54 pm

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.
Code: [Select]
`// example, not testedboolean StraightAhead( void) {  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.

#### SouthernAtHeart

#4
##### Feb 03, 2013, 01:01 am
Here's what I ended up with:
Code: [Select]
`boolean StraightAhead( void) {  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?
Code: [Select]
`boolean StraightAhead( void) {boolean StraightAhead() {`

#### Krodal

#5
##### Feb 03, 2013, 01:05 am
'void' indicates that no parameter is used. In this situation void means 'nothing here'.

#### retrolefty

#6
##### Feb 03, 2013, 01:07 am
Quote
What is the difference between these two lines?  Are they the same?

Code: [Select]
`boolean StraightAhead( void) {boolean StraightAhead() {`

They are functionally equivalent. One is explicitly stating that there are no variables passed to the function, the other implies it by omission. Not sure what the C/C++ standards say but the present gcc compiler is happy with either.

Lefty

#### SouthernAtHeart

#7
##### Feb 03, 2013, 01:13 am
thanks for the info.

#### michinyon

#8
##### Feb 03, 2013, 03:04 pm
Quote
What is the difference between these two lines?  Are they the same?

It's my understanding that the ( void ) was originally required in function declarations but
not in function definitions.

But now, either appears to be OK.

Go Up

Please enter a valid email to subscribe

To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy