1

I have a problem. I want to make a car with a motor, front lights and rear lights. I want to run them at the same time but in different loops.

This is my code.

const int red1 = 10;
const int red2 = 11;
const int blue1 = 12;
const int blue2 = 13;
const int front1 = 3;
const int front2 = 4;
const int back1 = 5;
const int back2 = 6;
const int enablePWMPin = 9;
const int controlPinA = 8;
const int controlPinB = 7;
int buzzer = A0;

void setup() {
  pinMode(red1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(blue1, OUTPUT);
  pinMode(blue2, OUTPUT);
  pinMode(front1, OUTPUT);
  pinMode(front2, OUTPUT);
  pinMode(back1, OUTPUT);
  pinMode(back2, OUTPUT);
  pinMode(enablePWMPin, OUTPUT);
  pinMode(controlPinA, OUTPUT);
  pinMode(controlPinB, OUTPUT);

  digitalWrite(enablePWMPin, LOW);
  digitalWrite(front1, LOW);
  digitalWrite(front2, LOW);
  digitalWrite(back1, LOW);
  digitalWrite(back2, LOW);
  digitalWrite(red1, LOW);
  digitalWrite(red2, LOW);
  digitalWrite(blue1, LOW);
  digitalWrite(blue2, LOW);
  noTone(buzzer);
}

void loop() {
  digitalWrite(enablePWMPin, HIGH);
  digitalWrite(controlPinA, HIGH);
  digitalWrite(controlPinB, LOW);
  delay(3000);
  digitalWrite(controlPinA, LOW);
  digitalWrite(controlPinB, HIGH);
  delay(3000);
} 

void loop() {
  digitalWrite(red1, HIGH);
  digitalWrite(red2, HIGH);
  digitalWrite(blue1, LOW);
  digitalWrite(blue2, LOW);
  delay(250);
  digitalWrite(red1, LOW);
  digitalWrite(red2, LOW);
  digitalWrite(blue1, HIGH);
  digitalWrite(blue2, HIGH);
  delay(250);
}

void loop() {
  int directionA = digitalRead(controlPinA);
  int directionB = digitalRead(controlPinB);
  if (directionA == HIGH && directionB == LOW) {
    digitalWrite(front1, HIGH);
    digitalWrite(front2, HIGH);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  } else if (directionA == LOW && directionB == HIGH) {
    digitalWrite(back1, HIGH);
    digitalWrite(back2, HIGH);
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
  } else {
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  }
}

I'm using an Arduino Uno. Can I start all the loop() functions at the same time?

2

5 Answers 5

9

As the others have stated, no you can't have multiple loop functions. What you need to do is modify your approach so that each thing you are trying to do can be done sequentially without blocking (ie: remove the delay function usage). Expanding on some suggestions by JRobert, Here is how I would make these functions "run at the same time":

void loop() {

    lights1(); 
    lights2();
    motor();

}

void lights1() {

  static unsigned long lastTime = 0;
  const long interval = 3000;
  static bool state = 0;

  unsigned long now = millis();

  if ( now - lastTime > interval && state == 0) {
    state = 1;
    lastTime = now;
    digitalWrite(enablePWMPin, HIGH);
    digitalWrite(controlPinA, HIGH);
    digitalWrite(controlPinB, LOW);
  }

  if ( now - lastTime > interval && state == 1) {
    state = 0;
    lastTime = now;
    digitalWrite(controlPinA, LOW);
    digitalWrite(controlPinB, HIGH);
  }
}

void lights2() {

  static unsigned long lastTime = 0;
  const long interval = 250;
  static bool state = 0;

  unsigned long now = millis();

  if ( now - lastTime > interval && state == 0) {
    state = 1;
    lastTime = now;
    digitalWrite(red1, HIGH);
    digitalWrite(red2, HIGH);
    digitalWrite(blue1, LOW);
    digitalWrite(blue2, LOW);
  }

  if ( now - lastTime > interval && state == 1) {
    state = 0;
    lastTime = now;
    digitalWrite(red1, LOW);
    digitalWrite(red2, LOW);
    digitalWrite(blue1, HIGH);
    digitalWrite(blue2, HIGH);
  }

}

void motor() {
  int directionA = digitalRead(controlPinA);
  int directionB = digitalRead(controlPinB);
  if (directionA == HIGH && directionB == LOW) {
    digitalWrite(front1, HIGH);
    digitalWrite(front2, HIGH);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  } else if (directionA == LOW && directionB == HIGH) {
    digitalWrite(back1, HIGH);
    digitalWrite(back2, HIGH);
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
  } else {
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  }
}

This approach will simulate running all three functions at the same time. Each function runs one at a time. But, since the delay has been removed from the light1/2 functions, they will end quickly during the 'waiting' period instead of pausing execution. This will allow the motor(s) to run and lights to blink all at the same time.

3

No you cannot.

Not only is it no proper C/C++ to have multiple identical functions, i.e. it will not compile (as jfpoilpret's comment suggests). It is also not in accordance with the idea of programm flow in the Arduino world - the sketches - where you have two methods on the highest (user accessible) level: void setup() and void loop(). setup is run exactly once at the beginning of your program. Following that loop is looped (hence the name) forever. You need to properly restructure your code to implement your intended program flow, i.e. call your own functions from loop. Read more on www.arduino.cc with tutorials worth studying.

2

What are you trying to accomplish? Are these loops meant to run simultaneously (not possible)? Or one after the other? You could get pretty close to "simultaneous" if "real fast" is good enough. You'd need to

  • Give each loop function a new, unique name;
  • Split each of the first two loops at the delay()s for a total of 5 functions;
  • Use a timer library such as SimpleTimer to run each of the functions at the rate you need them to.
  • and from the only loop() function, keep calling SimpleTimer's '.run()' function to keep the whole thing going.

You could improve the speed of the individual functions by replacing the digitalRead() and digitalWrite() calls with direct reads and writes to port and bit you want read or set.

2

I want to run them at the same time but in a different loop.

First of all, you can only do one thing at a time. So that's out.

Secondly, to run multiple loops sequentially (one at a time), it is fairly easy:

void loop1(void) {...}
void loop2(void) {...}
...

void loop(void) {
  loop1(); //run loop1
  loop2(); //run loop2
  ...
  loopn(); //run loopn
}

Whether it works will depend on how you have coded those loops.

2

To use multiple loops at the same time you need a Arduino Due Board. It is the only board compatible with library #include <Scheduler.h>

See Examples > Scheduler Library > Multiple Blinks

// Include Scheduler since we want to manage multiple tasks.
#include <Scheduler.h>

int led1 = 13;
int led2 = 12;
int led3 = 11;

void setup() {
  Serial.begin(9600);

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Add "loop2" and "loop3" to scheduling.
  // "loop" is always started by default.
  Scheduler.startLoop(loop2);
  Scheduler.startLoop(loop3);
}

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

// Task no.2: blink LED with 0.1 second delay.
void loop2() {
  digitalWrite(led2, HIGH);
  delay(100);
  digitalWrite(led2, LOW);
  delay(100);
}

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c=='0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c=='1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}
2
  • void is not a verb.
    – gre_gor
    Oct 5, 2018 at 15:24
  • 2
    @gre_gor: Using that word as a verb may void its warranty ;-) Oct 5, 2018 at 15:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.