How to exit loop on value change

Hey,

First off I’ve not programmed in C in a long time so my code is a mess and probably not the most elegant. Please don’t hate me :smiley:

Anyway I’m building an RC car as a school project. I’m working on the code for the auto-braking system (using an ultrasonic sensor) I’ve not added any of the code for operating the motor. I’m using an LED signal in place of that; stay on when it can run, blink when autostop is engaged.

Once autostop is engage I’m running a comparison every 1 second to determine if the vehicle has stopped so that I can override the autobrake system so after the car stop I can still run it forward, until it clears the obstruction and resets the override. Unfortunately the override isn’t working.

Any help here would be much appreciated.

//SETTINGS
const byte stopdistance = 50;             //Car stop distance

// defines pin numbers
const int trigPin = 2;                   //Sensor - TRIG pin
const int echoPin = 8;                   //Sensor - ECHO pin
const int StopledPin = 13;               //LED - Stop led

// defines constants
const long blinkInterval = 300;          // Stopled Blink Interval
unsigned long previousMillis = 0;        // will store last time LED was updated

const long SCinterval = 1000;            // time between stop checks
unsigned long SCprevMillis = 0;          // will store last time stopcheck occured in during autobrake



// defines variables
long duration;                           //duration of received pulse
int distance;                            //distance from sensor in cm
bool StopledState = 1;                    //ledState used to set the LED
bool autostop = 0;                        //signals start of autobrake
bool autostopOverride = 0;                //autobraking system override
bool autostopFlash  = 0;                  //flash led to signal autostop engaged

void setup() {
  pinMode(StopledPin, OUTPUT);          //Set ledPin as Output
  pinMode(trigPin, OUTPUT);             // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);              // Sets the echoPin as an Input
  Serial.begin(9600);                   // Starts the serial communication

}
void loop() {

//AUTOBRAKE SYSTEM

  //Sensor Pulse/Distance
    // Clears the trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);
    // Calculating the distance
    distance= duration*0.034/2;


        

  //Distance Trigger
  


    //routine logic
    if (distance <= stopdistance && autostopOverride == 0)             //if distance is equal or less than set distance
    {
      autostop = 1;
    }
    else
    {
      autostop = 0;
    }

  //Autobraking

  
    if (autostop == 1 && autostopOverride == 0) //if autostop engaged and override disengaged
    {
      //Blink AutoStopLED
         //vars
         unsigned long currentMillis = millis();   //var for StopledBlink
      
        if (currentMillis - previousMillis >= blinkInterval) {
          previousMillis = currentMillis;
          if (StopledState == 1) {
          StopledState = 0;
          } else {
          StopledState = 1;
        }
        digitalWrite(StopledPin, StopledState);
      }
      //Blink AutoStopLED


      //StopCheck
        //vars
        unsigned long SCcurrentMilis = millis();  //var for StopCheck
        int prevdist;                             //distance captured every 1s
        int prevdist2;                            //distance captured every 1s
        
        if (SCcurrentMilis - SCprevMillis >= SCinterval)
        {
          SCprevMillis = SCcurrentMilis;

          prevdist = distance;
          Serial.print("Prev Distance: ");
          Serial.println(prevdist);  
        }
        
          Serial.print("Distance: ");
          Serial.println(distance); 

        if (prevdist - distance == 0)
        {
          autostopOverride == 1;
        }

      
    }
       
    
    else
    {
        digitalWrite(StopledPin,1);   //turn on LED
        autostopOverride == 0;
    }
    
    
}

Your code would benefit from a little decomposition. If you think about it, every program has Five Steps:

  1. Initialization -- sets the operating environment, as in setup()
  2. Input -- data from sensors?
  3. Process -- algorithm to determine what's done with the data
  4. Output -- stop car, start care, etc.
  5. Termination -- clean up and undo what you did in step one, release resources. Arduino's don't often
    need this.

Write functions for these steps can call from within loop...don't put all the code in loop(). Also, look for ways to clean up the code. Use Ctrl-T in IDE to format you code. Then, this

          if (StopledState == 1) {
             StopledState = 0;
          } else {
             StopledState = 1;
          }

could also be written as:

   StopedState = !StopedState;

Thank you for the help on program flow. I will divy up the code into subroutines before I return with more questions

Okay, I redivided everything into subroutines so it’s cleaner. I’m still not sure how I can run the timed override though. I’ve tried using while and if statements around “brakingtrigger();” in the main loop and in the conditions for the IF in the breaking trigger routine. I still can’t seem to find a way to override the braking routine when the distance value doesn’t change compared to the previous value

//SETTINGS
const byte stopdistance = 50;             //Car stop distance

// defines pin numbers
const int trigPin = 2;                   //Sensor - TRIG pin
const int echoPin = 8;                   //Sensor - ECHO pin
const int StopledPin = 13;               //LED - Stop led

// defines constants
const long blinkInterval = 300;          // Stopled Blink Interval
unsigned long previousMillis = 0;        // will store last time LED was updated

const long SCinterval = 1000;            // time between stop checks
unsigned long SCprevMillis = 0;          // will store last time stopcheck occured in during autobrake



// defines variables
long duration;                           //duration of received pulse
int distance;                            //distance from sensor in cm
bool StopledState = 1;                    //ledState used to set the LED
bool autostopOverride = 0;                //autobraking system override
bool autostopFlash  = 0;                  //flash led to signal autostop engaged

void setup() {
  pinMode(StopledPin, OUTPUT);          //Set ledPin as Output
  pinMode(trigPin, OUTPUT);             // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);              // Sets the echoPin as an Input
  Serial.begin(9600);                   // Starts the serial communication

}

void loop()
{
  distancecheck();
  brakingtrigger();
}

void distancecheck()
{
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2;
}

void brakingtrigger()
{
  if (distance <= stopdistance)             //if distance is equal or less than set distance
  {
    autostop();                                                      //call autostop
  }
  else
  {
    digitalWrite(StopledPin, 1);  //turn on LED
  }
}

void autostop()
{
  blinkLED();
  stopcheck();
}


void stopcheck()
{
  //vars
  unsigned long SCcurrentMilis = millis();  //var for StopCheck
  int prevdist;                             //distance captured every 1s
  int prevdist2;                            //distance captured every 1s

  if (SCcurrentMilis - SCprevMillis >= SCinterval)
  {
    SCprevMillis = SCcurrentMilis;

    prevdist = distance;
    Serial.print("Prev Distance: ");
    Serial.println(prevdist);
  }
  if (prevdist - distance == 0)
  {
    autostopOverride = 1;
  }


}

void blinkLED()
{
  unsigned long currentMillis = millis();   //var for StopledBlink

  if (currentMillis - previousMillis >= blinkInterval)
  {
    previousMillis = currentMillis;
    StopledState = !StopledState;
    digitalWrite(StopledPin, StopledState);
  }
}

This is much easier to read. As to the breaking trigger routine, ask yourself at what point in the program flow do I need to ask the question about the distance compared to earlier values. Sometimes it helps to actually draw the situation on paper with arrows drawn between boxes that represent the movement from the current status (or state) of the object being measured to the next state. if statements often mean two arrows from one state to the next of two states. Below each arrow, write in English what causes it to proceed to the next box or to loop back to a previous box. That should help you write the code.