if else with map

I am having a bit of trouble on my first arduino project. I am trying to use two IR sensors to drive a motor in either direction until the readings balance. Fairly simple on the circuit side (as you can tell from the code below I am sure). I can get one sensor to work at a time to drive the motor with the following code; however, the motor will not change direction. I have included debugging scripts to print the inputs via serial interface and the sensor portion appears to be working as I envisioned. I feel there is a problem with my if else statement chain. I have also tried switch case with the same problem. Any help to what I know is a simple problem would be greatly appreciated!!! Code follows:

#include <AFMotor.h>

AF_DCMotor motor(4);

const int sensorMin = 610;
const int sensorMax = 599;

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps

}

void loop() {
int right = analogRead(A1); // setting up inputs
int left = analogRead(A0);
int x = map(right, sensorMin, sensorMax, 1, 2); //mapping sensor range
int y = map(left, sensorMin, sensorMax, 1, 2);
Serial.println(right);
Serial.print("left ir = "); //debugging stuff
Serial.print(left);
Serial.print(" right ir =");

Serial.println(x);
Serial.print("left ir = "); //more debugging info
Serial.print(y);
Serial.print(" right ir =");

if (y > x) {motor.setSpeed(200); //something here only lets one statement
motor.run(BACKWARD);} //run???- I am guessing but I suspect this is

else if (x > y) {motor.setSpeed(200); //where the flaw is??
motor.run(FORWARD);}

else {motor.run(RELEASE);}

if (x > y) {motor.setSpeed(200);
motor.run(FORWARD);}

else if (y > x) {motor.setSpeed(200);
motor.run(BACKWARD);}

else {motor.run(RELEASE);}

delay(10); //for stability

}

The code looks like it would work even though the debug output is a little wonky and you have the IF chain twice in different order. Try this:

#include <AFMotor.h>

AF_DCMotor motor(4);

const int sensorMin = 610;
const int sensorMax = 599; 

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
}

void loop() {
  int right = analogRead(A1);
  int left = analogRead(A0);
  int x = map(right, sensorMin, sensorMax, 1, 2);    //mapping sensor range
  int y = map(left, sensorMin, sensorMax, 1, 2);
  
  //debugging stuff
  Serial.print(F("raw left ir = ")); 
  Serial.print(left);
  Serial.print(F("   raw right ir ="));
  Serial.println(right);

  //more debugging info
  Serial.print(F("mapped left ir = "));
  Serial.print(y);
  Serial.print(F("     mapped right ir ="));
  Serial.println(x);

  if (y > x) {
    motor.setSpeed(200); 
    motor.run(BACKWARD);
  }
  else if (x > y) {
    motor.setSpeed(200);
    motor.run(FORWARD);
  }
  else {
    motor.run(RELEASE);
  }

  delay(10);     //for stability
}

The debugging is much cleaner. Thanks!!!! :slight_smile: ;however, the motor is still functioning the same. The inputs change correspondingly with proximity to the IR transmitter (increase in intensity for mapped function - except mapped values range from 1 - 5 instead of 1-2 ????) but the motor will only turn in one direction when close to the right sensor. I had tried only one if chain originally and added the opposing one when I could not get it to work - still doesn't. In any case your code looks much cleaner than mine :wink: I am still experimenting with what will work I will clean it up so it looks more like yours in the future. Any other Ideas on the motor?? It will turn forwards and backward with a simple command and delay program??? I am thinking about just turning states high and low to drive relays with a separate power supply and forgetting the motor shield - but it should work I think :~ Any help would be greatly appreciated!!

Your original code has at least one semicolon at the end of an "if".
Don't do this.

parkmeadows9720:
The inputs change correspondingly with proximity to the IR transmitter (increase in intensity for mapped function - except mapped values range from 1 - 5 instead of 1-2 ????)

The output range of the map() function is only valid for the specified input range (610-599). If the input is outside that range the output will be outside the specified range.

If you want to constrain outputs you can use the constrain(value, limit1, limit2) function.

I don't really understand why you are using the map() function anyway.

I had actually used the map function to try and use switch case i.e. case 1: case 2: etc. you are correct XD it is not necessary with the if statement; however, I believe the problem I am experiencing is unrelated (I already tried with just sensor values < and >) with the same problem??? We can remove it for simplification to see if the issue becomes more evident. Any ideas on any other code to get around the motor problem?? Any help is greatly appreciated :slight_smile: !!!

Subtract the two sensor readings to get a (signed) difference.

Scale the signed difference to get a signed speed.

If the speed is negative, move the motor backwards at that speed. If the speed is positive, move the motor forward at that speed.

forgive me I am new - have only been programming the arduino for a couple of days now - but I believe the code you refer to would look something like the following (this would give a constant speed of course), please advise if this is not what you meant :):

#include <AFMotor.h>

AF_DCMotor motor(4);

const int sensorMin = 610;
const int sensorMax = 599;

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
}

void loop() {
int right = analogRead(A1);
int left = analogRead(A0);
int x = (right - left)

//debugging stuff
Serial.print(F("raw left ir = "));
Serial.print(left);
Serial.print(F(" raw right ir ="));
Serial.println(right);

Serial.print(F(" difference ="));
Serial.println(x);

if (x > 0) {
motor.setSpeed(200);
motor.run(BACKWARD);
}
else if (x < 0) {
motor.setSpeed(200);
motor.run(FORWARD);
}
else {
motor.run(RELEASE);
}

delay(10); //for stability
}

That's the sort of thing I had in mind, although I see you're using constant values for speed rather than making it proportional to your difference signal. I suspect that'll make it tend to bounce back and forth about the central position rather than settle at the center. But you can always play around with the thresholds if you do prefer to stick with a constant speed:

const int Threshold = 30;
...
  if (x > Threshold ) {
    motor.setSpeed(200);
    motor.run(BACKWARD);
  }
  else if (x < -Threshold ) {
    motor.setSpeed(200);
    motor.run(FORWARD);
  }
  else {
    motor.run(RELEASE);
  }

I assume you will work out left / right / forward / reverse so that the movement is in the correct direction.

Yes I would. Except that I am still having the same problem :frowning: I loaded the code I sent on the previous post and can watch the reading sweep from +45 to -45 ; however, the motor only turns when the value is negative and does not turn at all when the value is positive??? Perhaps something in the forward backward commands? I can give it a simple forward delay 1000 backward delay 1000 and watch it repeatedly reverse direction - just not with commands in my if statement. It is as if only one direction will work for some reason??? :~

If you write a test sketch that does nothing but run the motor in the forward direction, does it succeed?

#include <AFMotor.h>

AF_DCMotor motor(4);

void setup(){}

void loop () {
motor.setSpeed(200);
motor.run(FORWARD);
}

//will run the motor forward

however placing BACKWARD in place of FORWARD does not turn the motor. I suspect a problem with the shield now.

uhhhhhhhhhhhhh never mind I have to apologize to everyone I had the motor wired into the ground instead of the other terminal to the motor so of course it would only turn one way!???!!!. All of my previous sketches (and yours) did work to some degree :blush: Thank you for all your help though - and an intense learning experience!! After I finish this robot I will be back to learn some more.

THANKS