Can arduino run multiple loops for 4 different things?

Hello,

I have a question about my project table and if the arduino mega would be able to handle it one way or another.
The table consists of 3 different sections that do different things using the arduino. At the moment I have code for all 3 seperatly and they work individually but I was not able to bring them together yet so they can work seperatly but into one code for the arduino.

Part 1 and 2 do seperatly for 2 different drawers: press touch sensor, arduino converts the signal into press on, press off and makes a motor run one way or another and control some RGB strips

Part 3 is a reed switch that if on controls a x10 module for my lights etc. and a different motorsetup for a beamerlift.

Code for part 1 and 2 is twice like this(but with different pins offcourse)

int i=0;
int a=0;

void setup()
{
  
  pinMode(4, INPUT);
  pinMode(6, OUTPUT);
  pinMode(8, OUTPUT)
}

void loop()
{
  if (i == 0){ digitalWrite(6, LOW);digitalWrite(8, LOW);}  else{digitalWrite(6, HIGH);digitalWrite(8, HIGH);}

  if (i == 0 && digitalRead(4) == HIGH && a == 1){i = 1;} else{} // LED moet aan
  if (i == 1 && digitalRead(4) == HIGH && a == 0){i = 0;} else{} // LED moet uit
 
  if (i == 0 && digitalRead(4) == LOW){a = 1;} else{} // Test LED=uit en S4 is losgelaten
  if (i == 1 && digitalRead(4) == LOW){a = 0;} else{} // Test LED=aan en S4 is losgelaten
 
}

The other piece of code for part 3 is like this:

int switchPin = 2;              // reed switch is connected to pin 2
int X10Pin = 12;
int MotorPin = 11;
int ledPin = 10;


int val;                        // variable for reading the pin status
int val2;                       // variable for reading the delayed/debounced status
int buttonState;                // variable to hold the button state

int EntertainmentMode = 0;              

void setup() {
  pinMode(switchPin, INPUT);    // Set the switch pin as input

  pinMode(X10Pin, OUTPUT);
  pinMode(MotorPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  buttonState = digitalRead(switchPin);   // read the initial state
}

void loop(){
  val = digitalRead(switchPin);      // read input value and store it in val
  delay(10);                         // 10 milliseconds is a good amount of time
  val2 = digitalRead(switchPin);     // read the input again to check for bounces
  if (val == val2) {                 // make sure we got 2 consistant readings!
    if (val != buttonState) {          // the button state has changed!
      if (val == LOW) {                // check if the button is pressed
        if (EntertainmentMode == 0) {          
          EntertainmentmodeMode = 1;               
          digitalWrite(X10Pin, HIGH);
          digitalWrite(MotorPin, HIGH);
          digitalWrite(ledPin, HIGH);
          
        } else {
          EntertainmentMode = 0;              
          digitalWrite(X10Pin, LOW);
          digitalWrite(MotorPin, LOW);
          digitalWrite(ledPin, LOW);
         
        }
      }
    }
    buttonState = val;                 // save the new state in our variable
  }
}

So now my question is how can I put all those things together so they can all work on one arduino? just throwing them together does not work i've noticed :~

Yes it can. As KE7GKP said you need to make sure your different bits of code have not used the same variable names for different things. Assuming they don't; if you have three bits of code that work, then don't throw them all together - join them slowly one at a time.

You will need to initialize all your global variables, but for the rest think of aiming for;

void setup()
{
    setupPart1();
    setupPart2();
    setupPart3();
}
void loop()
{
    loopPart1();
    loopPart2();
    loopPart3();
}

Once that works you will see parts 1 and 2 are the same apart from the pins. That means it makes sense to replace them with with one setup and one loop function and just pass the pin numbers as parameters. Then when your requirements change (as they will) you don't have to change two lots of code, just one function which does parts 1 and 2.

What is a beamerlift?

a beamerlift is a scissor lift i've build myself so when my home entertainment system is active, the beamer(projector) rises out of the floor.

Now thanks to you i've sucessfully integrated all parts of my code into one but now i've ran into another problem I can't figure out:

In this part of code:

void magneetLoop(){
  val3 = digitalRead(reedsensorPin);      // read input value and store it in val
                  
    if (val3 == HIGH) {          // reedsensor actief
                   
               
         digitalWrite(led3Pin, LOW);
         digitalWrite(led4Pin, HIGH);
         
          
          
          digitalWrite(schaarliftPin, LOW);
          digitalWrite(sm10Pin, LOW);
            delay (10000);
            digitalWrite(led4Pin, LOW);
          
    }
         if (val3 == LOW) {
          
          
          digitalWrite(led4Pin, LOW);
          digitalWrite(led3Pin, HIGH),
          
          
          digitalWrite(schaarliftPin, HIGH);
          digitalWrite(sm10Pin, HIGH);
          delay (10000);
          digitalWrite(led3Pin, LOW);
          
         
    }
      
   }

My intentions are: once the reedsensor is active(HIGH) the GREEN led string(led4Pin) should go on together with the rest BUT it should also go off again after 10 seconds(same when,LOW but with a RED string), and here is my problem because this is a loop so it keeps going on again after it goes off. I think this should be a simple issue and quick to fix but i can not find it immediatly on google so I am asking it here :slight_smile:

What I do in cases where I want something to happen in a few seconds is that I set a timer to do it for me. Something like:

#include <Time.h>
#include <TimeAlarms.h>

void loop(){
  turnTheLedOn();
  Alarm.timerOnce(howLongToWait,turnTheLedOff());
  Alarm.delay(0); // you have to have this somewhere in the loop.
}

The Time and TimeAlarms libraries are available in the playground, just do search. You write a little routine to turn the led on and another to turn them off and vary the time to your taste. You have to have the Alarm.delay() call so the various timers you may be using get updated. This way you don't have to have obscure code to handle counts or anything.

Have fun.

It sounds like what you want to do is only execute the code in magneetloop if the reed switch has changed state. If so, keep the prior state in a global (or local static) lastval3 and check it in magneetloop after you read val3. If they're different, proceed as you do now, else do nothing. If they were different, set lastval3=val3 afterwards.

here is my problem because this is a loop so it keeps going on again after it goes off

You have almost answered your own question here, as @wildbill suggested you can have a global variable that is initialised outside the loop.
You might also base something on Alarms as suggested by @draythomp. The code he suggested though creates the alarm in the loop so it will generate lots of alarms. Here is some code you can run if you download the time library, open the monitor after you upload it. It shows a global variable "doneOnce" being used, it also shows the function "OnceOnly" being called once by an alarm. The function "NotSoGood" will be called after 10s, but then also every 1s after that.

#include <Time.h>
#include <TimeAlarms.h>

boolean doneOnce=false;

void setup()
{
  Serial.begin(9600);
  Serial.println("In Setup");
  Alarm.timerOnce(10,OnceOnly); // called once after 10 seconds
  return;
}

void  loop()
{
  Alarm.delay(1000); // this function MUST be called repeatedly for the alarms/timers to work
  if(!doneOnce)
  {
    doneOnce=true;
    Serial.println("This message will only get printed one time");
  }
  Alarm.timerOnce(10,NotSoGood); // alarm setup repeatedly
  return;
}

void OnceOnly()
{
  Serial.println("This timer only triggers once");
  return;
}

void NotSoGood()
{
  Serial.println("Alarm set in loop and so called repeatedly");
  return;
}

Here is the output;

In Setup
This message will only get printed one time
This timer only triggers once
Alarm set in loop and so called repeatedly
Alarm set in loop and so called repeatedly
Alarm set in loop and so called repeatedly
Alarm set in loop and so called repeatedly
Alarm set in loop and so called repeatedly

It is worth learning to use Serial because printing output makes it much easier to debug code.

The beamer sounds very impressive, good luck with it :slight_smile:

Hello,

I've not been able to find time to try the above suggestions but i've already ran into another problem

the magneetloop is supposed to do this in real life:

reed switch on:
-turn the beamer elevator up
-once it is up, send a signal to my sm10 x10 module so my home entertainment system turns on

reed switch off:
-turn of the sm10 module
-wait 10 seconds(so the infrared sender can reach the beamer before it goes away into the floor)
-turn the beamer elevator off

so i wrote this code for it

void magneetLoop(){
  val3 = digitalRead(reedsensorPin);      // read input value and store it in val
                  
    if (val3 == HIGH) {          // reedsensor actief
                   
               
        // digitalWrite(led3Pin, LOW);
       //  digitalWrite(led4Pin, HIGH);
         
          
          
          digitalWrite(schaarliftPin, HIGH);
          delay(5000);
          digitalWrite(sm10Pin, LOW);
          //  delay (10000);
          //  digitalWrite(led4Pin, LOW);
          
    }
         if (val3 == LOW) {
          
          
        //  digitalWrite(led4Pin, LOW);
        //  digitalWrite(led3Pin, HIGH),
          
          
          
          digitalWrite(sm10Pin, HIGH);
          delay (10000);
          digitalWrite(schaarliftPin, LOW);
        //  digitalWrite(led3Pin, LOW);
          
         
    }
      
   }

but since i've added the delays into the code, my other two loops do not function anymore. I think this is because the loops run constantly so the arduino is almost constantly busy on the delays in the magneetloop

But how can I solve this?
Also about the led's that have to be turned on for a few seconds everytime the reed switch of the magneetloop, I prefer to do this with a seperate global variable like wildbill said but at the moment I don't see how I could do this.

Thanks in advance

I've not been able to find time to try the above suggestions but i've already ran into another problem

You need to find time to play with the TimeAlarms because that will solve all your current problems.

When you go into Delay for 10s or so your other loops are not running. The processor is just sitting there waiting for the 10s to elapse.
Instead you want to put the code you want to happen after a delay into a function, then use the TimeAlarms to call the function after 10s. That way your processor is still running around executing your other code while the timer ticks.

There are no real shortcuts you have to try things out.

how can i loop multiple events with blink wo delay example? if i want 2 different interval? can it work like this?

// set pin numbers:
const int ledPin = 4; // the number of the LED pin
const int ledPin2 = 3; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
int ledState2 = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
long interval2 = 3000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT); }
void loop(){
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState); }

if(currentMillis - previousMillis > interval2) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState2 == LOW)
ledState2 = HIGH;
else
ledState2 = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin2, ledState2); } }

can it work like this?

What does your testing tell you?

Please, please use code tags when posting code.

like this its working fine with 2different interval 2 leds are blinking :slight_smile:
long interval = 5234; // interval at which to blink (milliseconds)
long interval2 = 1356; // interval at which to blink (milliseconds)

in my case i use relays that drive an air blower to work once a day ..

const int ledPin =  4;      // the number of the LED pin
const int ledPin2 =  3;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
int ledState2 = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long previousMillis2 = 0;        // will store last time LED was updated
long interval = 5234;           // interval at which to blink (milliseconds)
long interval2 = 1356;           // interval at which to blink (milliseconds)
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);  
   pinMode(ledPin2, OUTPUT);    }
void loop(){
   unsigned long currentMillis = millis();
    unsigned long currentMillis2 = millis();
            if(currentMillis2 - previousMillis2 > interval2) {
       previousMillis2 = currentMillis2;   
         ledState2 = HIGH;
           digitalWrite(ledPin2, ledState2);  
  delay(500);
 ledState2 = LOW;
     digitalWrite(ledPin2, ledState2);
    if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
    // if the LED is off turn it on and vice-versa:
       ledState = HIGH;
      // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState); 
 delay(500);
 ledState = LOW;
         digitalWrite(ledPin, ledState);  }}    }
 unsigned long currentMillis = millis();
    unsigned long currentMillis2 = millis();

The chances of those two values being different are pretty slim (and probably unimportant even if they are different) - just use one of them.

Have a look at my state machine library here: Arduino Playground - SMlib

Example 4 is about concurrency.

mortenx:
how can i loop multiple events with blink wo delay example?

The key is to design your code so that it is non-blocking. In other words your code is designed to be run repeatedly; each time it runs it checks whether it needs to do anything (yet) - if so it does it, if not it doesn't. Your code doesn't ever stop to wait for something to happen, it just checks whether it has happened yet and assumes that it will be called again in the near future to check again.

When you structure your code like this it becomes very easy to control multiple things concurrently. For example, serial input could be handled by a function that checks whether there is new input available, reads it if so, checks whether the new input means that a complete message has been received, and if so does whatever is needed to handle that message. Timed actions can be handled by checking whether it is time to do the next action yet, and if so doing it, 'Blink without delay' demonstrates how to do that using the results of millis(). Then your main loop() just becomes a sequence of calls to handle each possible type of event. As long as none of your event handlers takes so long that the other handlers are delayed excessively, you can scale this up as far as you want (subject to the hardware constraints of your Arduino ) and the various things being controlled are kept independent of each other.

Hi! I'd like to use this space to ask a question similar to what LouisG has asked in the first post. I've built a circuit that resembles a traffic signal system also making a provision for the pedestrians to control the traffic lights. So, there are two independent circuits - one for the cars and one for the pedestrians. I've created two separate functions for the two systems to work independently but I'm unable to make both work together at the same time. For the pedestrians, I've included a PushButton which when pressed executes a function which works if I just want the pedestrians to control the traffic lights. The other function controls the traffic lights using a timer and this function also works fine if I just want only this function to control the traffic lights. However, I'm visualizing it to be like this - The traffic lights will operate normally following the timer function as it is but if the PushButton is pressed it will change the lights following the other function defined for it. The code is as follows:

int carRed = 5; // assign the car lights
int carYellow = 4;
int carGreen = 3;
int pedRed = 13; // assign the pedestrian lights
int pedGreen = 12;
int pushButton = 8; // pushbutton pin
int crossTime = 5000; // time allowed to cross
int trafficDelay = 10000;

void setup() {
pinMode(carRed, OUTPUT);
pinMode(carYellow, OUTPUT);
pinMode(carGreen, OUTPUT);
pinMode(pedRed, OUTPUT);
pinMode(pedGreen, OUTPUT);
pinMode(pushButton, INPUT); // pushButton on pin 2
digitalWrite(carGreen, HIGH);
digitalWrite(pedRed, HIGH);
}

void loop() {
int buttonState = digitalRead(pushButton);
if (buttonState == HIGH) {
changeLights();
}
else {
normalMode();
}
}

This code doesn't seem to work the way I expected. I'd like some help on this issue soon.

If you want to do several things at a time maybe the demo several things at a time which is a Sticky at the top of this section of the Forum would be a good place to start.

...R

u can test my code for multi-loop

/*
*
*
*

  • multi independent blink program for Arduino UNO,mega, nano, pro mini support all 8-bit microcontroller

*/
unsigned long d1,d2,d3,d4,d5,d6;
int delay1 = 1000;//put delay value of loop1 in ms
int delay2 = 1001;//put delay value of loop2 in ms
int delay3 = 1002;//put delay value of loop3 in ms
int delay4 = 1003;//put delay value of loop4 in ms
int delay5 = 1004;//put delay value of loop5 in ms
int delay6 = 1005;//put delay value of loop6 in ms
int i1,i2,i3,i4,i5,i6 = 0;

void setup() {
pinMode(13,OUTPUT);
pinMode(12,OUTPUT);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
d1 = delay1;
d2 = delay2;
d3 = delay3;
d4 = delay4;
d5 = delay5;
d6 = delay6;
}
/do not use delay() inside the program/
void loop() {
loop1();
loop2();
loop3();
loop4();
loop5();
loop6();
}
void loop1() {
if(millis()-d1>=delay1)
{
d1 = millis();
digitalWrite(13,i1);
i1++;
}
i1 = i1%2;
}
void loop2() {
if(millis()-d2>=delay2)
{
d2 = millis();
digitalWrite(12,i2);
i2++;
}
i2 = i2%2;
}
void loop3() {
if(millis()-d3>=delay3)
{
d3 = millis();
digitalWrite(11,i3);
i3++;
}
i3 = i3%2;
}
void loop4() {
if(millis()-d4>=delay4)
{
d4 = millis();
digitalWrite(10,i4);
i4++;
}
i4 = i4%2;
}
void loop5() {
if(millis()-d5>=delay5)
{
d5= millis();
digitalWrite(9,i5);
i5++;
}
i5 = i5%2;
}
void loop6() {
if(millis()-d6>=delay6)
{
d6 = millis();
digitalWrite(8,i6);
i6++;
}
i6 = i6%2;
}