Incorporate Obstacle avoidance in encoder ISR

I have the following piece of code, which is used to make my robot move a certain distance. How do I incoporate an obstacle avoidance check in it as well? I am using HCSR04 ultrasonic sensor but to check the distance it uses a delay, so how would I go about doing this?

int encoder_pin = 3;  // The pin the encoder is connected           
unsigned int rpm;     // rpm reading
volatile uint16_t pulses;  // number of pulses
unsigned long timeold; 
// The number of pulses per revolution
// depends on your index disc!!
//float pprev = 166.67;
float pprev = 83.33;
float distance;
float rev;
float dprev=18.84;
float ppcm=5.33;


//motor pins
const int Motor1Pin1 = 8;
const int Motor1Pin2 = 9;
const int Motor2Pin1 = 10;
const int Motor2Pin2 = 11;

int flag;
int led=5;


void setup()
 {
   Serial.begin(9600);
     //Use statusPin to flash along with interrupts
   pinMode(encoder_pin, INPUT);
   
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(1, counter, FALLING);
   // Initialize
   pulses = 0;
   rpm = 0;
   timeold = 0;

   //define Motor Pins
    pinMode(Motor1Pin1, OUTPUT);   
  pinMode(Motor1Pin2, OUTPUT);   
  pinMode(Motor2Pin1, OUTPUT);   
  pinMode(Motor2Pin2, OUTPUT); 
  
  pinMode(led,OUTPUT);
 }

 void loop()
 {
   
   while (flag!=1)
   {
     GoForward();
   }
  
   //Write it out to serial port
   Serial.print("PULSES = ");
   Serial.println(pulses);
//   distance = pulses/ppcm;
   Serial.print("DISTANCE = ");
   Serial.println(distance);
   Serial.print("DISTANCE2 = ");
   Serial.println(distance2);


  }

 void counter()
 {
    //Update count
      pulses++; 
  rev=pulses/pprev; 
//distance =rev*dprev;
distance=pulses/ppcm;
if (distance2>=30)
{
 digitalWrite(led,HIGH) ;
Stop();
flag=1;


}

  else {
  GoForward();
 
  digitalWrite(led,LOW) ;
}
}

 
 //                MOTOR FUNCTIONS

void GoForward(){
  digitalWrite(Motor1Pin2, LOW);
  digitalWrite(Motor1Pin1, HIGH);
  digitalWrite(Motor2Pin2, LOW);
  digitalWrite(Motor2Pin1, HIGH);
}

void GoBackward(){
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor1Pin2, HIGH);
  digitalWrite(Motor2Pin1, LOW);
  digitalWrite(Motor2Pin2, HIGH);
}

void GoLeft(){
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor1Pin2, HIGH);
  digitalWrite(Motor2Pin2, LOW);
  digitalWrite(Motor2Pin1, HIGH);
}

void GoRight(){
  analogWrite(Motor1Pin2, LOW);
  analogWrite(Motor1Pin1, HIGH);
  analogWrite(Motor2Pin1, LOW);
  analogWrite(Motor2Pin2, HIGH);
}


void Stop(){
  digitalWrite(Motor1Pin2, LOW);
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor2Pin1, LOW);
  digitalWrite(Motor2Pin2, LOW);
}

You should almost never do calculations inside an ISR. It should only collect relevant data and set a flag. Then the calcs should be done in the main program. You want to return as quickly as you can from the ISR.

I agree with @aarg.

Think of it like this...
You are never going to have to take avoiding action within 100 microsecs. You probably don't even need to do it within 100 millisecs. 100 microsecs would be a long time in an ISR.

Use your ISR only to update the pulses variable. Do everything else in your other code. You probably don't even need a flag variable if your code checks whether the value of pulses has changed.

...R

Thanks for the reply. so the distance calculation should be done in the main code? But the problem here is if the robot is moving it never returns from the ISR until the robot stops again. Also about my main question, how would i set up an obstacle distance check from my ultrasonic sensors while the robot is moving and still not lose information from the encoder pulses? is the only solution to stop the robot a given period of time to check for obstacles and then resume its path?

royal_flush:
Thanks for the reply. so the distance calculation should be done in the main code? But the problem here is if the robot is moving it never returns from the ISR until the robot stops again.

That can't happen if all the ISR does is increment the variable pulses

void counter() {
    pulses ++;
}

Also about my main question, how would i set up an obstacle distance check from my ultrasonic sensors while the robot is moving and still not lose information from the encoder pulses? is the only solution to stop the robot a given period of time to check for obstacles and then resume its path?

Your code does not seem to have any ultrasonic stuff in it so I don't know what you have tried. I don't think there is any reason why the pulse counting should be affected.

Post your latest code.

...R

ok thanks. yes I have not implemented the ultrasonic part into it yet, but the problem is the ultrasonic sensor uses a delay to measure the ping so wouldnt this cause loss of pulse readings?

#define trigPin 5
#define echoPin 6

void setup(){
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}

void loop(){
 int duration,distance;
digitalWrite(trigPin,HIGH);
delay(1);
digitalWrite(trigPin,LOW);
duration = pulseIn(echoPin,HIGH);
distance = (duration/2) /29.1;
Serial.print(distance);
Serial.println(" cm");
delay (500);
}

Ignore the delay at the end of course, that was used for testing purposes. but theres a 1 millisecond delay there, would it affect it?

Also a question regarding the ISR, if an interrupt is triggered and the code gets into the ISR, would it resume the code it was in at the point where the interrupt was triggered or resume from the beginning again?

I think that the ISR will continue to count during the PING interval. And, yes, the code continues where it left off when the ISR completes.

I think there is a non-blocking NewPing library - but I don't have a "pinger" so I have no experience of them.

...R