help with interrupt

Hi,

I’m attempting to build an obstacle avoiding car using both IR and ultrasonic sensing. Having sorted out issues with individual sensing I’d like to combine the two codes. My plan is to run the ultrasonic code primarily and add an interrupt attached to the ir sensors. My interrupt, however, doesn’t seem to work very well - -meaning that I can see it called on the serial monitor however the car resumes moving shortly thereafter.

Not really sure what to do to keep the car stopped while the obstacle is present.

Also curious about multiple ir sensors on one pin. Since there is only INT0 and INT1, I like to connect 2 sensors to pin2 and 2 sensors to pin 3. Any experience doing this would be appreciated. JD

#include <Servo.h>  //servo library
Servo myservo;      // create servo object to control servo

#define ledPin 13
#define interruptPin 2
#define interruptPinalso 3
#define Echo 9  
#define Trig 8
#define ENA 5
#define ENB 6
#define IN1 17
#define IN2 16
#define IN3 15
#define IN4 14
#define carSpeed 150
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

void emergstop(){
  while (interruptPin == LOW || interruptPinalso == LOW);
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
  digitalWrite(ledPin, HIGH);
  Serial.println("Emerg_Stop!");
  delay (1000);
    
}

 
void forward(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("Forward");
}
 
void back() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("Back");
}
 
void left() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("Left");
}
 
void right() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("Right");
}
 
void stop() {
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
  Serial.println("Stop!");
}
 
//Ultrasonic distance measurement Sub function
int Distance_test() {
  digitalWrite(Trig, LOW);  
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);  
  delayMicroseconds(20);
  digitalWrite(Trig, LOW);  
  float Fdistance = pulseIn(Echo, HIGH)/ 58;  
  return (int)Fdistance;
}  
 
void setup() {
  myservo.attach(11);  // attach servo on pin 11 to servo object
  Serial.begin(9600);    
  pinMode(Echo, INPUT);    
  pinMode(Trig, OUTPUT);  
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT);
  pinMode(interruptPinalso, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), emergstop, FALLING);
  attachInterrupt(digitalPinToInterrupt(interruptPinalso), emergstop, FALLING);
  stop();
}
 
void loop() {
    digitalWrite(ledPin, LOW);
    myservo.write(90);  //setservo position according to scaled value
    delay(500);
    middleDistance = Distance_test();
 
    if(middleDistance <= 50) {    
      stop();
      delay(500);                        
      myservo.write(0);          
      delay(1000);      
      rightDistance = Distance_test();
      
        
      delay(1000);                                                  
      myservo.write(180);              
      delay(1000);
      leftDistance = Distance_test();
      
      delay(500);
      myservo.write(90);              
      delay(1000);
      if(rightDistance > leftDistance) {
        right();
        delay(180);
      }
      else if(rightDistance < leftDistance) {
        left();
        delay(180);
      }
      else if((rightDistance <= 30) || (leftDistance <= 30)) {
        back();
        delay(180);
      }
      else {
        forward();
      }
    }  
    else {
        forward();
    }                    
}

You can only connect two sensors to a single pin if both sensors have open-collector outputs. Even then, you will be unable to tell WHICH sensors was triggered, so what's the point? If they are NOT open-collector, then you stand an excellent chance of blowing up one or both when they are triggered.

Regards, Ray L.

I see a problem...

delay(500);

And another...

delay(500);

And a bigger one...

delay(1000);

Need I say more?

RayLivingston: You can only connect two sensors to a single pin if both sensors have open-collector outputs. Even then, you will be unable to tell WHICH sensors was triggered, so what's the point? If they are NOT open-collector, then you stand an excellent chance of blowing up one or both when they are triggered.

Regards, Ray L.

How do I tell if my ir sensor has open collector outputs?

I am not concerned with differentiating between which sensor is triggered. I only want the vehicle to stop until the object is removed or the ultrasonic sensor has time to rescan.

MorganS: I see a problem... And another... And a bigger one... Need I say more?

I have removed the delay from the isr. What is wrong with the other delays?

jdsbalancebot:
How do I tell if my ir sensor has open collector outputs?

Start with the datasheet.

You are printing in the ISR Interrupts are disabled whilst in an ISR Printing uses interrupts

Can you see a possible problem ?

You are using delay() in the ISR Interrupts are disabled whilst in an ISR delay() uses interrupts

Can you see a possible problem ?

UKHeliBob: You are printing in the ISR Interrupts are disabled whilst in an ISR Printing uses interrupts

Can you see a possible problem ?

You are using delay() in the ISR Interrupts are disabled whilst in an ISR delay() uses interrupts

Can you see a possible problem ?

Thank you, Bob. I didn't know that printing is not allowed in an isr. Delays - I knew but ignored (duh.)

I want to stay in the interrupt while the sensor is detecting an obstacle. Is that possible?

jdsbalancebot:
I want to stay in the interrupt while the sensor is detecting an obstacle. Is that possible?

It may be possible, but it’s wrong. You need to get in and out of an ISR ASAP. Just set a flag in the ISR to indicate an obstacle and deal with it in you main (non-ISR) code. Be sure to declare the flag as ‘volatile’.

Delays in the main part of loop() are blinding your sensors. The Arduino literally closes its eyes and counts up to 500.

Remember, even the slow Arduinos can do 16,000 things in one millisecond.

With the help of a watch on your wrist, can you tell me when 60 minutes have passed? Can you walk and avoid obstacles during that time?

In the Arduino, millis() is that watch.