Mapping values from an IR sensor to a servo

Hi all,

I’m not whether this would make sense asking this question here or in the robotics section, but this is more of a programing question than anything else. I’m trying to make 4 IR sensors map out different values to command a servo motor to turn certain degrees 2 of the IR sensors store a value for the left side, and 2 store a value for the right side. What I want to happen is that when the IR sensors pick something up between 25 inches and 5 inches, it turns the servo a certain amount of degrees based on how close/far an object is. I have the code for the right side working alright, but it doesn’t make sense to why it works. I’ve tried doing the left side with mixed results but none that I want. The basic code is below, full code is attached–can anyone help?

if(Prox01 <=25)
  {
    leftSide = Prox01;
    leftSide = map(leftSide, 5, 25, 130, 95);
    Steering.write(leftSide);
  }

That one works, while below does not.

  else if (Prox04 <=25)
  {
    rightSide = Prox01;
    rightSide = map(rightSide, 5, 25, 65, 95);
    Steering.write(rightSide);
  }

More information on my robot is here:

Thanks!

ASRB_hallways_gradual_turns.ino (6.76 KB)

That one works, while below does not.

How do you know it doesn't? What value is in Prox04? What value is in rightSide after the mapping?

There is a wealth of information not being shown you by your program. Learn to use Serial.print() and related methods to debug your code.

In the full code, I am printing out the values. Prox04 will give a number between 0 and 25, and it's suppose to give a number that corresponds to turning the servo to the left. That number should be between 65 and 95. After mapping, it prints a number between 99 and 108 for some reason. Am I inputting the numbers incorrectly in the map function?

In the full code, I am printing out the values.

But, you are not sharing them.

if ((Prox01 >15) && (Prox02 >15) && (Prox03 >15) && (Prox04 >15) && (Prox05 >15))
  Steering.write(95);
  else if (Prox04 <=25)
  {
    rightSide = Prox01;
    rightSide = map(rightSide, 5, 25, 65, 95);
    Steering.write(rightSide);
  }

Are you even getting to the else block?

Printing out rightSide and leftSide before computing new values hardly seems useful.

What do you mean I'm not sharing them?

The reason I printed out the right and left values at first is just so it prints along side the IR sensor values. It was something I thought of trying last night, and it wasn't meant for 100% efficiency.

I know that it gets to the else block because the values for leftside/rightside change once the values for that one IR sensor gets below 25 inches and the others are all above 15 inches.

Am I using the map function correctly?

What do you mean I'm not sharing them?

Perhaps I just missed it, but I scrolled back to the top and looked, and I can't see anywhere where you show the output to the serial monitor.

The reason I printed out the right and left values at first is just so it prints along side the IR sensor values. It was something I thought of trying last night, and it wasn't meant for 100% efficiency.

Printing the value before you compute it, just so the Serial.print() call has company is just about the silliest reason I have ever heard of for doing that.

I know that it gets to the else block because the values for leftside/rightside change once the values for that one IR sensor gets below 25 inches and the others are all above 15 inches.

If the value for Prox04 is less than 25 but greater than 15, it will never get to the else block. Without seeing your serial output, we can not be certain that the else block is ever executed. I don't see that you are, either.

Adding Serial.println("Prox04 IS less than 25"); (or Serial.println("PaulS is an idiot"); ;)) in the else block would tell you for certain that the else block is entered.

So would printing the value of rightSide and/or leftSide only after you compute them (in the block where they are computed).

The output to the Serial monitor? do you mean Serial.begin(9600);  //opens the serial monitor at 9600 baud

Printing the values first actually does tell me when the code jumps into the else block because when the code starts, the rightside and left side values are defaulted to 0. When that number changes, then I know it jumped into the else block. when it is not in the else block, the value doesn't change at all. In order for the first if statement to be true, ALL of the sensors (there are actually 5 total, but I don't really use the center one) must have a reading of above 15. And all of the values are printed, so I can see when the value falls below 25.

But besides that, am I using the map function correctly?? I can't find anything that specifies what values should go in the four spots of the map function.

Well, I figured out what the error was-- I didn’t change all the values to match each sensor…

This

 else if (Prox04 <=25)
  {
    rightSide = Prox01;
    rightSide = map(rightSide, 5, 25, 65, 95);
    Steering.write(rightSide);
  }

Should have been THIS

 else if (Prox04 <=25)
  {
    rightSide = Prox04;
    rightSide = map(rightSide, 5, 25, 65, 95);
    Steering.write(rightSide);
  }

Silly mistake…Thanks for all the help!

The output to the Serial monitor? do you mean Code:

Serial.begin(9600); //opens the serial monitor at 9600 baud

That comment is wrong. The Arduino can not force the Serial Monitor application to start up. You have to manually open it, which resets the Arduino. The Arduino then sends data to the serial port that the Serial Monitor application is reading.

You have not shown that output to us.

Silly mistake....Thanks for all the help!

No problem. Glad you got it figured out.

But, printing the value after computing it is still a better idea. You know when the value changes, because you only print it when it changes. It is easy to see what the inputs were that triggered it to be computed, rather than having to hunt back for the previous set of values.