Autonomous Car - Interrupt not working

I want to make a self-guided car using the stored waypoints as reference for travel.

This is the simple logic:
a) Read GPS coordinates → travel based on bearing and distance w.r.t next (stored) Waypoint
b) Read HC-SR04; if obstacle is too close, turn left and travel for x seconds. Then go to Step a (above)

It continuously reads GPS and HC-SR04 inputs and outputs/ controls 2 DC motors

I plan to use an INTERRUPT for avoiding obstacles as that is high priority task. For now, I have written a dummy code lighting Green LED in loop() and RED in interrupt when obstacles are met.

#include <NewPing.h> //library for UltraSonic Sensor

//============== HC-SR04  variables ===========
int TRIGGER_PIN_FRONT = 6;
int ECHO_PIN_FRONT = 2;
int MAX_DISTANCE = 200;
int thresholdDistance = 5;
int hurdleDistance = 0;
NewPing frontUSS(TRIGGER_PIN_FRONT, ECHO_PIN_FRONT, MAX_DISTANCE);

//============== TIMERS ================
int CYCLE_PERIOD = 500;
long lastCYCLE_TIME = 0;

//============== Indicator LEDs ======================
int greenLED = 5;
int redLED = 4;
bool resetLEDs = true;


void setup() {
  pinMode(greenLED, OUTPUT);
  pinMode(redLED, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2),subroutine_MeasureHurdleDistance, CHANGE); //
}

void loop() {

  //In normal loop, blink GREEN LED - to be substitued with Motor Navigation code
  if (resetLEDs) {
    digitalWrite(redLED, LOW);
    blinkLED(greenLED);
  }
  else {
    digitalWrite(greenLED, LOW);
  }
}

void blinkLED(int pinNo) {
  digitalWrite(pinNo, LOW);
  //using delayMicroseconds as it works inside interrupt (will be used to let car complete the turn)
  delayMicroseconds(10000000);
 
  digitalWrite(pinNo, HIGH);
  delayMicroseconds(10000000);
 
}

void subroutine_MeasureHurdleDistance() {
  if ((millis() - lastCYCLE_TIME) > CYCLE_PERIOD) 
  {
    resetLEDs = false;
    unsigned int uS = frontUSS.ping();
    
    if ((uS / US_ROUNDTRIP_CM) <= thresholdDistance){ 
      digitalWrite(greenLED, LOW);
      blinkLED(redLED);
      
    }
    lastCYCLE_TIME = millis();
    resetLEDs = false;  
  }
  else {
    resetLEDs = true;  
  }
}

Above code is not working for me - the GREEN LED stays HIGH and the RED led flickers continuously - as a function of CYCLE_PERIOD variable.

Also, the articles/ blogs I read seem to fire interrupt only when input on pin 2 changes from 0 to 1 or vice versa - which is not so in my pin 2’s continuous input. It reads some voltage value as a function of obstacle distance

So, I request guidance on below questions:
1- Where am I going wrong in my current code
2- Is my Interrupt definition wrong? If so, how can I correct it
3- Is the thought process - inputs/ sensors - correct

Would appreciate your guidance.
Regards

I don't fully understand your code, but you haven't explained where this interrupt is coming from. If you have an on-board distance sensor, which is read by the Arduino, then how do you use that to do an interrupt? Interrupts normally come from external hardware, which is not being simultaneously controlled by the arduino program.

If you are pinging for distance within the software, then you can't get to processing the distance information any faster by somehow generating an interrupt from within your code.

jrdoner,

I have connected Echo pin to pin 2 on Arduino. It is here that I need an interrupt only if obstacle is within certain distance.

From your response I understand that nothing new has happened to generate INTERRUPT - pin 2 had been receiving input from SR04.

And That’s the challenge I am facing: How to Generate and Interrupt.

Since main flow will be large chunk of Code (Read GPS > calculate bearing and distance > send output to motors; it’ll consume time and motor flow needs to be smooth), I want to park Obstacle checking logic in an interrupt since I am interested in values only if obstacle is near.

BTW current code is supposed to do following(in bold, italics). There are 2 Flows:
1- read GPS → calculations for direction and distance → control motors
if no obstacles → set Green led HIGH, Red led LOW

2- continuously check obstacles; ACTION needed ONLY IF obstacle too near <*generate interrupt>
obstacle met → set Red led HIGH, Green led LOW

Only reason for introducing (millis() - lastCYCLE_TIME) > CYCLE_PERIOD is to ensure that regular flow is not locked inside “subroutine_MeasureHurdleDistance()”.

Also, the articles/ blogs I read seem to fire interrupt only when input on pin 2 changes from 0 to 1 or vice versa - which is not so in my pin 2's continuous input. It reads some voltage value as a function of obstacle distance

Then you have misunderstood the concept of an interrupt. An interrupt can only respond to a digital signal. "Is the pin HIGH?" is a digital signal. You can't do "attachInterrupt(2.3metres)". You could have an external comparator which has been set up to look for a particular analog voltage and have that control your interrupt pin HIGH or LOW.

But this is not an application that needs an interrupt. Interrupts are only necessary when you need to time or count an incoming digital signal accurately or you need to clear an incoming buffer so the next data arriving in a few milliseconds has a place to go. You should structure your program to read all the relevant inputs, make decisions and then drive the outputs and it should do that several thousand times per second.

Santoshk:
I plan to use an INTERRUPT for avoiding obstacles as that is high priority task.

No it isn't and you do not know what an interrupt is.

Please just forget about interrupts and work out your code properly.

Yes, we can give advice if you start from the beginning and plan out your project. Trying to fix a badly thought out code is pretty much a waste of time.

If you don’t use delay (or delayMicroseconds) as you do in your blinkLED, you more than likely don’t need interrupts. Have a look at blink without delay.

If there is any chance that both LEDs need to blink at the same time, you need two variables to store the previous millis().

The below code demonstrates the above and measures the loop duration. For this simple example, the loop duration has a max of 12 microseconds (average 8). Fast enough to avoid an obstacle?

//============== Indicator LEDs ======================
#define FIRSTLED 4
#define REDLED FIRSTLED
#define GREENLED FIRSTLED + 1
bool resetLEDs = true;


void setup() {
  pinMode(GREENLED, OUTPUT);
  pinMode(REDLED, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  // loop timing measurement
  static unsigned long prevMicros = 0;
  unsigned long currentMicros = micros();

  // delay timing
  static unsigned long prevMillis = 0;
  unsigned long currentMillis = millis();

  if (prevMicros == 0)
    prevMicros = currentMicros;

  if (prevMillis == 0)
    prevMillis = currentMillis;

  //In normal loop, blink GREEN LED - to be substitued with Motor Navigation code
  if (resetLEDs) {
    digitalWrite(REDLED, LOW);
    blinkLED(GREENLED);
  }
  else {
    digitalWrite(GREENLED, LOW);
  }

  // read ECHO_PIN_FRONT and take action
  //  ...
  //  ...

  // do other stuff
  //  ...
  //  ...
  // simulate change of resetLEDs
  if (currentMillis - prevMillis > 5000)
  {
    resetLEDs ^= 1;
    prevMillis = currentMillis;
  }
  // do more other stuff
  //  ...
  //  ...
  Serial.print(F("Loop duration: "));
  Serial.println(currentMicros - prevMicros);
  prevMicros = micros();
}

void blinkLED(int pinNo) {
  static unsigned long prevMillis[2] = {0LU, 0LU};
  unsigned long currentMillis = millis();
  if (prevMillis[pinNo - FIRSTLED] == 0)
  {
    prevMillis[pinNo - FIRSTLED] = currentMillis;
  }
  if (currentMillis - prevMillis[pinNo - FIRSTLED] > 1000)
  {
    digitalWrite(pinNo, digitalRead(pinNo) ^ 1);
    prevMillis[pinNo - FIRSTLED] = currentMillis;
    Serial.println(digitalRead(pinNo), DEC);
  }
}

Only requirement for blinkLed is that the LEDs are consecutive (4 and 5 acceptable, 4 and 6 will possibly cause a crash).

Thanks all for the Course correction.

I will re-think and prepare a simple flow chart first. I need to get the understanding of logic/ code meta-model validated - if forum protocol permits - and then head deep into coding.

Regards