Delay issue between "if/else if" statements

Hello guys,

I tried a very simple line follower project with the following code uploaded on Arduino uno rev3 :

//set the position of IR detectors
int IR_ext_left = 8;
int IR_mid_left = 9;
int IR_mid_right = 10;
int IR_ext_right = 11;

//include servo library and sets left and right servo
#include <Servo.h>
Servo ServoL;
Servo ServoR;

void setup() {
pinMode(IR_ext_left, INPUT);
pinMode(IR_mid_left, INPUT);
pinMode(IR_mid_right, INPUT);
pinMode(IR_ext_right, INPUT);
ServoL.attach(6); 
ServoR.attach(5); 
}

void loop() {

if (digitalRead(IR_ext_left)== HIGH) //beaucoup trop à gauche donc tourne fort à droite
{  
   ServoL.write(76);
   ServoR.write(76);
   delay(500);
  }

 else if (digitalRead(IR_ext_right)== HIGH) //beaucoup trop à droite donc tourne fort à gauche
{  
   ServoL.write(111);
   ServoR.write(111);
   delay(500);
  }
  
else if (digitalRead(IR_mid_left)== HIGH || digitalRead(IR_mid_right)== HIGH)
  {  
   ServoL.write(111);
   ServoR.write(76);
   delay(500);
  }
   
  else 
  {    
    ServoL.write(94); 
    ServoR.write(94);  
             }
}

It kinda works, meaning the bot does follow black trail.
However, every time it switches from any "if/else if" condition to another, there is a 1-2 sec delay during which the L-led on arduino board is blinking, then only do the motors start.
When switching between the last "else" statement and any "if/else if" there is no such delay, everything goes smoothly.
Do you have an explanation why does this occur and how to solve it so that there is no "loading" delay when switching between the different statements? (apart from the 500 ms to ensure a minimum movement)

Thank you!

Sounds like maybe the Uno is resetting?

Try putting delay(5000); in setup(). If the 1-2 second delay becomes 6-7 seconds, that would confirm it is resetting.

If that's the case, please post a schematic showing types and values of all components and give links to the specs of major components, including the power source. I have a horrible feeling this might include a PP3 size 9V battery.

how are you powering the 2 servos and the motor ?

@J-M-L I use 4x1.5V batteries. I read that Arduino should ideally be powered with 9V however it was supposedly bad to connect 4x1.5V and 2x1.5V battery holders in serie.

@PaulRB You were right, the delay increased proportionally, so it is resetting.
Below is an approx. scheme of the circuit


IR sensors specs are here
servos specs are here

you could be drawing too much current from your battery pack when the 2 motors are in play and the voltage drops to a point where your arduino crashes.

Also Powering the arduino through the Jack requires at least 7V so you are already under specs.

that's what the doc states:

The board can operate on an external supply from 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may become unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.

could you do a test where you just join the grounds of the battery pack and Arduino but not the + and power the Arduino through USB ?

What happens if you use some Serial.prints for troubleshooting?

//set the position of IR detectors
int IR_ext_left = 8;
int IR_mid_left = 9;
int IR_mid_right = 10;
int IR_ext_right = 11;

//include servo library and sets left and right servo
#include <Servo.h>
Servo ServoL;
Servo ServoR;

void setup() {
Serial.begin(115200);
pinMode(IR_ext_left, INPUT);
pinMode(IR_mid_left, INPUT);
pinMode(IR_mid_right, INPUT);
pinMode(IR_ext_right, INPUT);
ServoL.attach(6); 
ServoR.attach(5); 
Serial.println("I'm exiting setup()");
}

void loop() {

if (digitalRead(IR_ext_left)== HIGH) //beaucoup trop à gauche donc tourne fort à droite
{  
   ServoL.write(76);
   ServoR.write(76);
   delay(500);
  }

 else if (digitalRead(IR_ext_right)== HIGH) //beaucoup trop à droite donc tourne fort à gauche
{  
   ServoL.write(111);
   ServoR.write(111);
   delay(500);
  }
  
else if (digitalRead(IR_mid_left)== HIGH || digitalRead(IR_mid_right)== HIGH)
  {  
   ServoL.write(111);
   ServoR.write(76);
   delay(500);
  }
   
  else 
  {    
    ServoL.write(94); 
    ServoR.write(94);  
             }
}

Serial.println("I'm exiting setup()"); should only print one time after a reboot. Does it print more then one time, such as after a long pause?

@J-M-L powering the arduino through USB the code works fine, there are no delay nor resets between new directions. So I guess you are right, it is a powering issue.
Then should I get an additional battery holder with 2 slots and make a serie specifically for the arduino?

@Idahowalker when powering through USB it is printed only once. I do not know how to print it on my monitor without having the arduino powered by the USB.

Clearly, as is mentioned, a power issue if powering the thing through USB is all good.

Post an actual image of your project.

if you provide more than 7V on the Jack of your UNO, the power will be taken from the Jack and the USB will just be used for Serial.

but if you provide more than 7V you'll probably have solved your issue as well

there are battery holder with 6 slots. that probably would do. But separating the electronics power from the motors power is also always a good idea.

@falrhen, your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project :wink: See About the Installation & Troubleshooting category.

I notice that you are not using any decoupling capacitors at all.

You should alway put at least a 100uF and 0.1uF ceramic capacitor between power and ground of every servo you use as close to the servo as possible. This helps reduce the interference the servos generate.

Even better if the servos have they're own power supply, separate from the Arduino's supply. You still need to connect the grounds together.

@Grumpy_Mike
Thanks for the tip! This bot was inspired from the beginner's instructable tutorials and they never mentionned capacitors required for servos. Do you have a link or anything that would explain why servos generate interferences (with what?)

Not surprising the instructables web site is full of crap projects written by people with an inflated sense of their skills.

All motors brushed motors generate interference, this is such a fundamental piece of information but it seem to be missing in the bulk of tutorials on the web.

In fact all digital circuits generate interference and the way you get rid of it is by using decoupling techniques. This page describes the fundamental of how it works.
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Not what, everything. Interference is short for electromagnetic interference and it is radio waves that are generated .

No, that's not true. Uno is a 5V device, so ideally should be powered with 5V. But to do that you have 2 options. 1) supply 6.5V~12V to the Vin pin or barrel socket, both of which connect to the Uno's onboard regulator. If you supply a higher voltage or draw a high current, the regulator can easily overheat and shut down or fail. 2) supply 5V direct to the 5V and GND pins, bypassing the onboard regulator. In practice, anything between 4.5~5.5V is ok. Below that and the Uno may behave strangely. Over that, the main chip will be damaged, so 4x1.5V is too high. However, 4x1.2V rechargeable AA should be ok for connecting to the 5V pin.

I don't understand why that would be bad.

Current: < 1000 mA.

Not a very helpful or precise spec! I guess that means the stall current could be up to but not exactly 1A. If both servos start up at the same time, there could be a total demand of almost 2A for a moment.

AA batteries can supply 2A, but that is near the limit for them, so I expect their output voltage will drop significantly and this is why the Uno is resetting

Do you know you can get battery holders with place for three AA or AAA batteries?

I sometimes use them to power the Arduino direct to the 5V pin when using none rechargeable batteries.

First thing first, as you all said it was a power supply issue. So I separated the Arduino's and servo's supply and now everything work smoothly, so thank you all for your kind help.

@Grumpy_Mike I will read through your link and consider de-coupling in my future projects. I still need to improve my knowledge of electronics.

@PaulRB @Grumpy_Mike Thank you for the explanation. I did not even know that the 5V pin could be used to power the Arduino. I thought the 3.3 and 5V pins were used on the contrary to power other devices through the Arduino, such as the IR sensors connected here.

I think I misunderstood the advice that same batteries of the same voltage should be used to assemble batteries pack of higher performances. Guess blocks of 1.5V batteries with unequal slots are still perfectly fine.

Half correct. The 3.3V pin can provide power for components needing 3.3V. The Uno cannot be powered through the 3.3V pin, it is never an input.

The 5V pin can be either power input or output. When using Vin or barrel socket, 5V pin is an output. Otherwise it is an input.

This applies to all 5V Arduino. Many newer Arduino models run at 3.3V. you can supply them with 3.3V using the 3.3V pin as an input, or supply 5V or maybe more to their Vin or 5V pin and use the 3.3V pin as an output to power external circuits.

But always remember, when drawing power from Uno or any other arduino, at 5V or 3.3V, it is not meant to be a power supply, it is only meant to be a controller. It can only ever supply small currents. Ok for sensors, a few single colour LEDs etc but not motors, relays, solenoids, RGB led strips. They need a lot of current. An adequate, external supply is needed. Often that supply can also power the Arduino.

That is generally true.

The point is that the two battery packs will see different current draw and will therefore discharge at different rates. You will essentially need to replace both packs when either drops to an unusable voltage in order to avoid problems, which feels somewhat wasteful.

If you use a buck converter to change > 5V to == 5V, you get more current than a linear regulator will. The DC converter gets over 95% efficiency.. it converts what 7805 dumps to heat. Convert 6V to 5V, no problem. Converted 5V goes in the 5V pin, NOT VIN!

Your battery will last longer. There are also boost converters that trade current for voltage.

I did mean to suggest that, but with a potential 2+ Amp stall current of the servos, you need to use a decent "buck" converter. :face_with_raised_eyebrow: