Code ignored after 'delay' - yet another case

Good morning! Yet another newbie.

First the question, code to follow:

I have started a little bot obstacle avoidance routine. I was very pleased to see most of the code work just as I had hoped. One small glitch that more or less echoes another problem I've seen posted. In the section of the code where I use the 'speedPin' to switch the enable on one side of the H-Bridge or the other (with an IR sensor) I have not been successful adding any other code to these lines. The argument ends with a 'delay' but any effort to continue the code from here is ignored. It is interesting to note that I have had no problem doing this later in the code, just this one spot. One more request, in that this is the first program I have written, I would appreciate any advice. Now for the code:

int IRPin2 = 1;          // select input pin for the second IR sensor
int IRPin2Value = 0;    //store value from IR sensor 2
int IRPin = 2;         //select the input pin for the IR sensor
int IRPinValue = 0;   //store value from IR sensor
int switchPin = 2;   //first bumper switch, digital return
int switchPin2 = 5; //second bumper switch, digital return
int motorPin1 = 3;   //h-bridge L1
int motorPin2 = 4;    //h-bridge L2
int motorPin3 = 7;     //h-bridge L3
int motorPin4 = 6;      //h-bridge L4
int speedPin = 9;        //enable 1 (E on the L1/L2 side)
int speedPin2 = 10;       //enable 1 (E on the L3/L4 side)


void setup() {
  
  pinMode(switchPin, INPUT);  //set the bumper switch  as an input
  pinMode(switchPin2, INPUT); //set the bumper switch 2 as an input
  
  //pinMode(IRPin, INPUT); // IRpin (right) as input
  //pinMode(IRPin2, INPUT);// IRpin2 (left) as input
  //apparently the analog in does not need to be called
  
  //set the following pins as outputs:
  
  pinMode(motorPin1 , OUTPUT);
  pinMode(motorPin2 , OUTPUT);
  pinMode(motorPin3 , OUTPUT);
  pinMode(motorPin4 , OUTPUT);
  
  
  pinMode(speedPin , OUTPUT);  //this is setting one enable pin
  pinMode(speedPin2 , OUTPUT); //this is setting the other
  
  
  //set speedPin high so motors will run at start
  
  digitalWrite(speedPin, HIGH);
  digitalWrite(speedPin2, HIGH);
  
                             
}

void loop(){
  
  //Threshold info and instructions for both IR sensors
  
  int threshold = 200;
  if(analogRead(IRPin) > threshold) {
    digitalWrite(speedPin2, HIGH);             //right IR sensor
    digitalWrite(speedPin, LOW); 
    delay(2500);
    

  }
    
  else if(analogRead(IRPin2) > threshold) {  
    digitalWrite(speedPin2, LOW);             
    digitalWrite(speedPin, HIGH);               //left IR sensor
    delay(2500);
}            
    
   
  else{digitalWrite(speedPin2, HIGH);  
       digitalWrite(speedPin, HIGH);
}

{
  }
    
  //first bumper switch
  
  if (digitalRead(switchPin) == HIGH) {
    digitalWrite(motorPin1, LOW);     //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, LOW);     //set L3 low
    digitalWrite(motorPin4, HIGH);    //set L4 high
    delay(2000);
    digitalWrite(motorPin1, HIGH);   //set L1 low
    digitalWrite(motorPin2, LOW);    //set L2 high
    digitalWrite(motorPin3, LOW);    //set L3 low
    digitalWrite(motorPin4, HIGH);   //set L4 high
    delay(1500);
    
    
     }
  
  //second bumper switch
    
 else if (digitalRead(switchPin2) == HIGH) {
    digitalWrite(motorPin1, LOW);  //set L1 low
    digitalWrite(motorPin2, HIGH); //set L2 high
    digitalWrite(motorPin3, LOW);  //set L3 low
    digitalWrite(motorPin4, HIGH); //set L4 high
    delay(2000);
    digitalWrite(motorPin1, HIGH); //set L1 low
    digitalWrite(motorPin2, LOW);  //set L2 high
    digitalWrite(motorPin3, LOW);  //set L3 low
    digitalWrite(motorPin4, HIGH); //set L4 high
    delay(1500);
    
     }
  
  //instructions given these conditions at either bumper
  
  else {
    digitalWrite(motorPin1, HIGH); //set L1 high
    digitalWrite(motorPin2, LOW);  //set L2 low
    digitalWrite(motorPin3, HIGH); //set L3 high
    digitalWrite(motorPin4, LOW);  //set L4 low
    
  }

  }

PS, I noted another posting with a similar problem but not quite the same. Hope it was correct to send up another posting.

You're aware that delay halts the whole microcontoller for the required delay and not just the bit with the H bridge ?

No I wasn't aware of that ('delay' stopping the processor). I'm not sure how that would be a problem at this juncture. I don't expect anything other than a delay in action equivalent to the time indicated. I guess you're saying that if there were other things that it (the processor) should be doing at that same time, they also would also be delayed.

I'm not sure if this answers my question, but perhaps I'm not focusing.

Is 'delay' acting correctly then? Am I using it incorrectly? Is there a more effective way to get the bot (or that one half of the bridge) to stop? Why doesn't 'delay' cause the same issues in the other places I've used it?

Thank you for you assistance. I look forward to hearing from you again.

Given this code in your loop function:

  //Threshold info and instructions for both IR sensors

  int threshold = 200;
  if(analogRead(IRPin) > threshold) {
    digitalWrite(speedPin2, HIGH);             //right IR sensor
    digitalWrite(speedPin, LOW);
    delay(2500);


  }

  else if(analogRead(IRPin2) > threshold) {
    digitalWrite(speedPin2, LOW);
    digitalWrite(speedPin, HIGH);               //left IR sensor
    delay(2500);
}


  else{digitalWrite(speedPin2, HIGH);
       digitalWrite(speedPin, HIGH);
}

[glow]{
  }[/glow]

The hilighted { and } immediately above this does nothing. Is this what you intended?

Onward... In this code, also:

  int threshold = 200;
  if(analogRead(IRPin) > threshold) {
    digitalWrite(speedPin2, HIGH);             //right IR sensor
    digitalWrite(speedPin, LOW);
    delay(2500);


  }

  else if(analogRead(IRPin2) > threshold) {
    digitalWrite(speedPin2, LOW);
    digitalWrite(speedPin, HIGH);               //left IR sensor
    delay(2500);
}


  [glow]//else{[/glow]
                 digitalWrite(speedPin2, HIGH);
       digitalWrite(speedPin, HIGH);
  [glow]//}[/glow]

I commented out the two hilighed lines to allow the bot to theoretically return going forward. If this fixes the problem, remember that the else only happens if the first two conditions are false. So, the bot would continue to spin (if that is what it is doing) so long as either right or left IR was greater than your threshold, and never return to driving forward.

If that isn't the problem, then.... I guess I need more information. Could you describe what it is doing at what stage in the code and exactly where you need it to do something else? I am kind of guessing at this point.

Interesting project!

Thanks SpinLock!

First, regarding the brackets ‘{}’, they are no doubt residue from previous cutting and pasting. This is, as you might suspect, a little bit of this and little bit of that I borrowed from other sources(largely what I found in “Interactivity”). Thank you for that. I have noticed brackets ‘{}’ floating around with nothing between them before. Is there any good reason for this? (I removed mine after you pointed it out)

Next, what I was hoping to do was to add instructions after the delay in the ‘if’ and ‘else if’ statements. By removing the last else statement in that group I got to were I was going but don’t quite understand why.

//Threshold info and instructions for both IR sensors

int threshold = 200;
if(analogRead(IRPin) > threshold) {
digitalWrite(speedPin2, HIGH); //right IR sensor
digitalWrite(speedPin, LOW);
delay(2500);

I wanted to add instructions Here…

}

else if(analogRead(IRPin2) > threshold) {
digitalWrite(speedPin2, LOW);
digitalWrite(speedPin, HIGH); //left IR sensor
delay(2500);

and Here

}

else{digitalWrite(speedPin2, HIGH);
digitalWrite(speedPin, HIGH);
}

so I removed the line above and all is well

Thank you very much for putting me on the right track. And thank you also for your explanation. I’m learning slowly, but I’m learning (oh and having fun). As far as this being an interesting project, thank you!

I have noticed brackets ‘{}’ floating around with nothing between them before. Is there any good reason for this?

In the middle of code normally no, there is no reason.

However, they can be used as reminders that there’s an empty loop, e.g.while (analogRead (potPin) < THRESHOLD) { }

which could also be written while (analogRead (potPin) < THRESHOLD) ;
though here sometimes the semicolon is simply “lost” or missed out in an edit, and so the next statement becomes the body of the “while” loop, which can make for interesting debugging.

Thank you AWOL.

So they (curly brackets) work much like </end stuff> in HTML

Very good of all of you to get back to me so quickly and help so much.

Yes, they work like brackets in algebra, grouping things together. It's a matter of personal preference, but whilst it is possible to write single statements as conditional clauses:

if (someCondition) 
   a = b + 6;
else
   a = b + 7;

many prefer to always use braces:

if (someCondition) {
   a = b + 6;
} else {
   a = b + 7;
}

Gotcha.

And thank you. The more of this stuff the better!

The C++ language (used by Arduino) does not care how you indent your code, but you will find it a LOT easier to maintain your programs if you start to get neater about the layout of your code. It can avoid this kind of mistake, as well as make it clearer for you and other people to read in six months when your memory is not so fresh.

Make your braces match indentation with the beginning of the statement that needs them. Some people do this:

while (condition)
[glow]{[/glow]
    do_something();
[glow]}[/glow]

Other people prefer this:

[glow]w[/glow]hile (condition) {
    do_something();
[glow]}[/glow]

That’s a personal choice, but nest the indentation consistently and neatly.

while (condition)
{
[glow] [/glow]   do_something();
[glow] [/glow]   for (i = 0; i < 10; i++)
[glow] [/glow]   {
[glow] [/glow]   [glow] [/glow]   if (!circumstance)
[glow] [/glow]   [glow] [/glow]   [glow] [/glow]   do_something_else();
[glow] [/glow]   }
}

As for loops that have no bodies, I try to make it quite clear to the reader that it is not a mistake, by doing the following. Putting a bare semicolon between the brackets makes it appear intentional. Putting the braces indented on the next line also draws attention to it, so that it is clear that the lines following this code are not the body of the loop.

while (check_condition())
    [glow]{ ; }[/glow]
do_something_else_afterwards();

Whatduino,

Yes I read that (somewhere), but sadly can't remember if examples were given. Thank you for the clear examples of improvement. I will neaten up my code, in fact I'm doing that right now. You guys are nice enough to help, the least I could do would be to make it legible.

Thanks Again! The more advice the better.

BTW, I have abandon the enable pin / IR sensor aspect of that code as it was too limiting (I can after all only stop one side or the other that way, not turn the wheels in reverse). I am using the same code for the IR as I did the bumper switches. So far, so good

Whatduino,

More like this then?:

int IRPin2 = 1;          // select input pin for the second IR sensor
int IRPin2Value = 0;    //store value from IR sensor 2
int IRPin = 2;         //select the input pin for the IR sensor
int IRPinValue = 0;   //store value from IR sensor
int switchPin = 2;   //first bumper switch, digital return
int switchPin2 = 5; //second bumper switch, digital return
int motorPin1 = 3;   //h-bridge L1
int motorPin2 = 4;    //h-bridge L2
int motorPin3 = 7;     //h-bridge L3
int motorPin4 = 6;      //h-bridge L4
int speedPin = 9;        //enable 1 (E on the L1/L2 side)
int speedPin2 = 10;       //enable 1 (E on the L3/L4 side)


void setup() 

{
  
  pinMode(switchPin, INPUT);  //set the bumper switch  as an input
  pinMode(switchPin2, INPUT); //set the bumper switch 2 as an input
  
  //pinMode(IRPin, INPUT); // IRpin (right) as input
  //pinMode(IRPin2, INPUT);// IRpin2 (left) as input
  //apparently the analog in does not need to be called
  
  //set the following pins as outputs:
  
  pinMode(motorPin1 , OUTPUT);
  pinMode(motorPin2 , OUTPUT);
  pinMode(motorPin3 , OUTPUT);
  pinMode(motorPin4 , OUTPUT);
  
  
  pinMode(speedPin , OUTPUT);  //this is setting one enable pin
  pinMode(speedPin2 , OUTPUT); //this is setting the other
  
  
  //set speedPin high so motors will run at start
  
  digitalWrite(speedPin, HIGH);
  digitalWrite(speedPin2, HIGH);
  
                             
}

void loop()

{
  
  //Threshold info and instructions for both IR sensors
  
  int threshold = 200;
  if(analogRead(IRPin) > threshold) 
  {
    digitalWrite(motorPin1, LOW);     //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, LOW);     //set L3 low
    digitalWrite(motorPin4, HIGH);    //set L4 high
    delay(2000);                                     //right IR
    digitalWrite(motorPin1, HIGH);   //set L1 low
    digitalWrite(motorPin2, LOW);    //set L2 high
    digitalWrite(motorPin3, LOW);    //set L3 low
    digitalWrite(motorPin4, HIGH);   //set L4 high
    delay(1500);
  }
    
  else if(analogRead(IRPin2) > threshold) 
  
  {  
    digitalWrite(motorPin1, LOW);     //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, LOW);     //set L3 low
    digitalWrite(motorPin4, HIGH);    //set L4 high
    delay(2000);                                         //left IR
    digitalWrite(motorPin1, LOW);   //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, HIGH);    //set L3 low
    digitalWrite(motorPin4, LOW);   //set L4 high
    delay(1500);
  }            
    
   
  else
  
  {
    digitalWrite(motorPin1, HIGH); //set L1 high
    digitalWrite(motorPin2, LOW);  //set L2 low
    digitalWrite(motorPin3, HIGH); //set L3 high
    digitalWrite(motorPin4, LOW);  //set L4 low
  }


    
  //first bumper switch
  
  if (digitalRead(switchPin) == HIGH) 
  
  {
    digitalWrite(motorPin1, LOW);  //set L1 low
    digitalWrite(motorPin2, HIGH); //set L2 high
    digitalWrite(motorPin3, LOW);  //set L3 low
    digitalWrite(motorPin4, HIGH); //set L4 high
    delay(2000);                                  //left switch
    digitalWrite(motorPin1, LOW);   //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, HIGH);    //set L3 low
    digitalWrite(motorPin4, LOW);   //set L4 high
    delay(1500);
    
  }
  
  //second bumper switch
    
 else if (digitalRead(switchPin2) == HIGH) 

  {
    digitalWrite(motorPin1, LOW);     //set L1 low
    digitalWrite(motorPin2, HIGH);    //set L2 high
    digitalWrite(motorPin3, LOW);     //set L3 low
    digitalWrite(motorPin4, HIGH);    //set L4 high
    delay(2000);                                    //right switch
    digitalWrite(motorPin1, HIGH);   //set L1 low
    digitalWrite(motorPin2, LOW);    //set L2 high
    digitalWrite(motorPin3, LOW);    //set L3 low
    digitalWrite(motorPin4, HIGH);   //set L4 high
    delay(1500);
  }
  
  //instructions given these conditions at either bumper
  
  else 
  
  {
    digitalWrite(motorPin1, HIGH); //set L1 high
    digitalWrite(motorPin2, LOW);  //set L2 low
    digitalWrite(motorPin3, HIGH); //set L3 high
    digitalWrite(motorPin4, LOW);  //set L4 low
  }

}

Much better - you have one "else" that's sticking out a little bit, but otherwise, it reads much more clearly! You will appreciate it when you go back to see your own code months later.

I guess you're saying that if there were other things that it (the processor) should be doing at that same time, they also would also be delayed.

If you don't mind the in-productive delay, there isn't an issue, but if you're just waitng for something to catch up and it can be doing something else in the meantime, there are ways around it.

Take a look at the "Blink without delay" example in the IDE for one way. Personally I like to give a variable the millis() value in the main loop and then use a if then loop to branch if its above a value I get by adding x to the variable. eg

  // main loop
  time = millis();
  if (time >= loop1 ){ 
     loop1 = time + 1000;  // 1 second - alter to suit
     // put stuff you want running every 1 second here
    }

I've stopped using delay altogether, its literally just a waste of time. :)

Halley,

Thanks, and yup I see that 'else'. It is much easier to read.

Pluggy,

I understand now. I will try that tonight and post tomorrow. Thank you for helping me see what you were saying. I am a novice and from time to time need a little guidance. It is a little more difficult to follow (from a human standpoint), but I understand why it works more efficiently.

Sorry it took so long to get back to you all, 'Internal Server Error'. I guess there were to many of us in the pool ;-)