run motor inside interrupt

hi all
need help:
I built a tank with infra-red detector. I’ve implemented it in such a way that - when the detector (which is connected to external INT0 - pin2) - is switching from 1 → 0 - an interrupt occurs.
inside the ISR (interrupt service routine) - i’ve just rotated the motors backwards (so the tank won’t hit the wall…).

but i get strange results - the motors are permanently rotating backwards…

please advice

thanks

What is it that is supposed to stop the motors rotating backwards when the tank has moved sufficiently far away from the wall?

Is the interrupt routine also telling the rest of the program what its done? If not then the two parts of the code
could end up fighting each other, so to speak…

but while inside the ISR - no other code is running (there is only one processor). so why should i tell synchronize the code inside the ISR with the rest of the code.

btw - the code is : running the tank using xbee (with joystick).

thanks

but while inside the ISR - no other code is running (there is only one processor). so why should i tell synchronize the code inside the ISR with the rest of the code.

Because using an ISR to change something the main code doesn't know about is like pulling the rug from underneath it.

the motors are permanently rotating backwards.

So what tells your motor to stop. I think it is time to post your code.

hi

hereby attached the code of the receiver (the tank):

the tank get x and y values from the Joystick.
but should be interrupted when InfraRed which is connected to pin2 is getting LOW and should go reverse.

#include <XBee.h>
#include <math.h>
#include <avr/interrupt.h>

#define motor1Dir 8
#define motor2Dir 7
#define motor1PWM 6
#define motor2PWM 5
#define ir_sensor 2
int sensorpin = 0;
//#define motor1Enable 11
//#define motor2Enable 12
/*
This example is for Series 1 XBee (802.15.4)
Receives either a RX16 or RX64 packet and sets a PWM value based on packet data.
Error led is flashed if an unexpected packet is received
*/

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle
Rx16Response rx16 = Rx16Response();
Rx64Response rx64 = Rx64Response();
uint8_t option = 0;
uint8_t data = 0;

int xx_new;
int yy_new;
int xx_old;
int yy_old;
int flush_counter ;
int sensor_val;

void initMotorDriver()
{
pinMode(motor1Dir, OUTPUT);
pinMode(motor2Dir, OUTPUT);
pinMode(motor1PWM, OUTPUT);
pinMode(motor2PWM, OUTPUT);

}

void Car_Init()
{
go_forward(255);
delay(1000);
stop_go_forward();
go_reverse(255);
delay(1000);
stop_go_reverse();
}

void setup()
{
// start serial communications:
Serial.begin(57600);
//Serial.println(“Robot Setup”);
xbee.setSerial(Serial);
//Serial1.begin(9600);

// prints title with ending line break
/*
Serial.println(“Line Sensor boar Sensor test”);
Serial.println(“Enter to show sensor value: 0=Sensor0, 1=Sensor1, 2=Sensor2, 3=Sensor3, 4=Sensor4, 5=Sensor5”);
Serial.println(“Enter to move: s= stop, f = forward, r = right, l = left”);
*/
initMotorDriver();
Car_Init();
flush_counter = 0;
pinMode(ir_sensor, INPUT);
digitalWrite(ir_sensor, HIGH); // Enable pullup resistor
attachInterrupt(0,pin2ISR, LOW);
//sei(); // Enable global interrupts
//EIMSK |= (1 << INT0); // Enable external interrupt INT0
//EICRA |= (0 << ISC01); // Trigger INT0 on falling edge

}

void loop()
{
//get_ir_sensor();
get_location();
performCommand();
delay(50);

}
/*
void get_ir_sensor()
{
sensor_val = digitalRead(ir_sensor);
if (sensor_val == 0)
{
go_reverse(255);
delay(1000);
stop_go_reverse();

}
}

*/

void get_location()
{
xbee.readPacket();

if (xbee.getResponse().isAvailable()) {
// got something

if (xbee.getResponse().getApiId() == RX_16_RESPONSE || xbee.getResponse().getApiId() == RX_64_RESPONSE) {
// got a rx packet

if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
xx_old = xx_new;
yy_old = yy_new;
xbee.getResponse().getRx16Response(rx16);

//READ VALUE1
uint8_t analogHigh = rx16.getData(0);
uint8_t analogLow = rx16.getData(1);
int value1 = analogLow + (analogHigh * 256);

//READ VALUE2
uint8_t analogHigh2 = rx16.getData(2);
uint8_t analogLow2 = rx16.getData(3);
int value2 = analogLow2 + (analogHigh2 * 256);
xx_new = map(value1, 0, 1023, -255, 255) ;
yy_new = map(value2, 0, 1023, -255, 255) ;
if (flush_counter == 50)
{
//xbee.flush();
Serial.flush();
flush_counter = 0;
}
else
flush_counter += 1;

} else {
xbee.getResponse().getRx64Response(rx64);
}

} else {
// not something we were expecting

}
}
}

void performCommand()
{

if ((xx_old != xx_new) || (yy_old != yy_new))
{
if ((xx_new > 7 && yy_new > 7))
{
go_right_F(abs(xx_new));
return;
}

else if ((xx_new < -7 && yy_new > 7))
{
go_left_F(abs(xx_new));
return;
}
else if ((xx_new > 7 && yy_new < -7))
{
go_right_B(abs(xx_new));
return;
}
else if ((xx_new < -7 && yy_new < -7))
{
go_left_B(abs(xx_new));
return;
}
else if (((xx_new < 7 && xx_new > -7) && yy_new > 7))
{
go_forward(255);
return;
}
else if (((xx_new < 7 && xx_new > -7) && yy_new < -7))
{
go_reverse(255);
return;
}

else if (((yy_new < 7 && yy_new > -7) && xx_new > 7))
{
go_right_F(255);
return;
}
else if (((yy_new < 7 && yy_new > -7) && xx_new < -7))
{
go_left_F(255);
return;
}
else if (((xx_new < 7 && xx_new > -7) && (yy_new < 7 && yy_new > -7)))
{
stop_go_forward();
return;
}
xx_new = 0;
yy_new = 0;

}
}

//Action code******************************************//
void go_forward(int speed) // ???
{
digitalWrite(motor1Dir,LOW);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,LOW);
digitalWrite(motor2PWM,speed);
}

void stop_go_forward() // ???
{
//digitalWrite(12,HIGH);
//digitalWrite(8,HIGH);
digitalWrite(motor1PWM,LOW);
digitalWrite(motor2PWM,LOW);
}

void go_reverse(int speed) // ???
{
digitalWrite(motor1Dir,HIGH);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,HIGH);
digitalWrite(motor2PWM,speed);
}

void stop_go_reverse() // ???
{
digitalWrite(motor1PWM,LOW);
digitalWrite(motor2PWM,LOW);
//digitalWrite(12,HIGH);
//digitalWrite(8,HIGH);
}

void go_right_F(int speed) // ???
{
digitalWrite(motor1Dir,LOW);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,HIGH);
digitalWrite(motor2PWM,speed);
}

void go_left_F(int speed) // ???
{
digitalWrite(motor1Dir,HIGH);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,LOW);
digitalWrite(motor2PWM,speed);
}

void go_right_B(int speed) // ???
{
digitalWrite(motor1Dir,HIGH);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,LOW);
digitalWrite(motor2PWM,speed);
}

void go_left_B(int speed) // ???
{
digitalWrite(motor1Dir,LOW);
digitalWrite(motor1PWM,speed);
digitalWrite(motor2Dir,HIGH);
digitalWrite(motor2PWM,speed);
}

void pin2ISR()
{
go_reverse(255);
}

You should have used the correct code tags when posting code.

As I said before once you set the motor turning backwards in the ISR what makes it stop?
I can’t see anything in the code that would lead me to believe it should stop. It looks like it is working exactly how it is written.

10x for the fast reply

when infrared sensor is no longer=0 (the tank went enough distance from the wall) - no more interrupt will occur since pin2 value=1 (as long as the sensor is not sensing anything ---> 1 is the default sensor value) - when no interrupt occurs and joystick is either idle or tilted - a new value is set to xx_new,yy_new and the tank will move as desired.

The ISR will do the same thing over and over and over again to no real effect after the first one.

when no interrupt occurs and joystick is either idle or tilted

Yes.

a new value is set to xx_new,yy_new and the tank will move as desired.

so as you said:-

but i get strange results - the motors are permanently rotating backwards

That means you are not reading the new value of a joystick command or you are not changing the command from last time. How about using the ISR to clear the value of xx_old,yy_old to a value that will never be received. Declare these values as volatile.