Go Down

Topic: run motor inside interrupt (Read 1 time) previous topic - next topic

bibi_efrat

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

dc42

What is it that is supposed to stop the motors rotating backwards when the tank has moved sufficiently far away from the wall?
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

MarkT

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..
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

bibi_efrat

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

Grumpy_Mike

#4
Jan 13, 2013, 06:50 pm Last Edit: Jan 13, 2013, 06:52 pm by Grumpy_Mike Reason: 1
Quote
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.

Quote
the motors are permanently rotating backwards.

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

bibi_efrat

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);
}


Grumpy_Mike

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.

bibi_efrat

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.

Grumpy_Mike

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

Quote
when no interrupt occurs and joystick is either idle or tilted

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

so as you said:-
Quote
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.

Go Up