SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By The Crusher
#198256
Hi there!


I'm working on a project where I have multiple functions in different voids, where I'm using a "menu" with help of two buttons (sw3 and sw4 in code) to change a value, and a start button (sw1) to change to another void. So far I have 6 voids that has different delays, before it goes to another void and back to the menu.

The main components is a Arduino pro, 2004 lcd display from ebay, 2x2 button pad from sparkfun and different leds and relays.

What I would like to do, is use another switch (sw2 in code) to abort the delay, and take it back to the menu.

I have found out that the arduino can't do anything else during a delay. I have tried a for(); loop, just to test it out, with no luck. Tried millis(); too, but no matter how mutch I read about millis();, I still don't understand how I can inplant that to my code.

In the code below, it is in void program1(); to program6(); I need help with.

Anyone on the forum that can explain the millis(); function for me and maybe help me out with inplant it in my code? Or do I have to find something else than millis();?

Here is my code:
Code: Select all
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(14,15,16,17,18,19);
// (RS, EN, DB4, DB5, DB6, DB7)

//Defining pins for switches
const int sw1 = 2; //Start button
const int sw2 = 3; //Stop button
const int sw3 = 4; //Prog - button
const int sw4 = 5; //Prog + button

//Defining pins for LEDs in switches
const int led1 = 6; //Start button LED
const int led2 = 7; //Stop button LED
const int led3 = 8; //Prog - button LED
const int led4 = 9; //Prog + button LED

//Defining pins for output LEDs
const int relayG = 10; //Relay for green light
const int relayY = 11; //Relay for yellow light
const int relayR = 12; //Relay for red light

//Defining value for program selection
int value;

void setup() {
  //Defining pinMode's
  pinMode(sw1, INPUT);
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);
  pinMode(sw4, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(relayG, OUTPUT);
  pinMode(relayY, OUTPUT);
  pinMode(relayR, OUTPUT);

  //Starting a lamp test
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Lamp test");
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  digitalWrite(relayG, LOW);
  digitalWrite(relayY, LOW);
  digitalWrite(relayR, LOW);
  delay(10000);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, HIGH);
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, HIGH);
  lcd.setCursor(0,1);
  lcd.print("complete!");
  delay(2000);
  lcd.clear();
  //Lamp test complete

  //Setting value for program selection
  value = 1;

  //Turning red light on
  digitalWrite(relayR, LOW);
}

//Is the people ready to open FIRE?!? This part is NOT complete yet
void er_skytter_klar() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Er skytterene klare?");
  lcd.setCursor(0,1);
  lcd.print("Hvis nei, trykk rød");
  lcd.setCursor(0,2);
  lcd.print("knapp innen 15");
  lcd.setCursor(0,3);
  lcd.print("sekunder");
  if (digitalRead(sw2) == HIGH) {
    avbryt();
  } else if (digitalRead(sw2) == LOW ) {
    
  }
  
}

//Program 1, 6 sec
void program1() {
    delay(100);
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 1 kjorer");
    lcd.setCursor(0,1);
    lcd.print("6 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(4000);
    stans();
}

//Program 2, 8 sec
void program2() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 2 kjorer");
    lcd.setCursor(0,1);
    lcd.print("8 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(6000);
    stans();
}

//Program 3, 10 sec
void program3() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 3 kjorer");
    lcd.setCursor(0,1);
    lcd.print("10 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(8000);
    stans();
}

//Program 4, 20 sec
void program4() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 4 kjorer");
    lcd.setCursor(0,1);
    lcd.print("20 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(18000);
    stans();
}

//Program 5, 120 sec
void program5() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 5 kjorer");
    lcd.setCursor(0,1);
    lcd.print("120 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(118000);
    stans();
}


//Program 6 300 sec
void program6() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 6 kjorer");
    lcd.setCursor(0,1);
    lcd.print("300 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    delay(298000);
    stans();
}

//Program 7, ∞ sec
void program7() {
  if (digitalRead(sw2) == HIGH) { 
    stans();
  } else {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 7 kjorer");
    lcd.setCursor(0,1);
    lcd.print("Friskyting");
    delay(200);
    program7();
  } 
}

//Stop sequense
void stans() {
  digitalWrite(relayG, LOW);
  digitalWrite(relayY, LOW);
  digitalWrite(relayR, HIGH);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Staaaaaaaaaaaaaaaans");
  delay(2000);
  performCommand();
}

//Abort sequense
void avbryt() {
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, LOW);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  performCommand();
}

//Lamp test
void lamptest() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Lampe test");
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(relayG, LOW);
    digitalWrite(relayY, LOW);
    digitalWrite(relayR, LOW);
    delay(10000);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(relayG, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayR, HIGH);
    lcd.setCursor(0,1);
    lcd.print("complete!");
    delay(2000);
    performCommand();
}

//Program selector
void performCommand() {
  lcd.clear();
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, LOW);
  lcd.setCursor(0,0);
  lcd.print("Lismarken pk");
  lcd.setCursor(0,1);
  lcd.print("Velg program:");
  lcd.setCursor(0,2);
  lcd.print("Program:");
  lcd.setCursor(10,2);
  lcd.print(value);
 
//Magic that changes value with buttons!
  if (digitalRead(sw3) == HIGH) {
    value--;
    digitalWrite(led3, LOW);
    delay(350);
    digitalWrite(led3, HIGH);
    if (value == 0) value = 8;
  }
  if (digitalRead(sw4) == HIGH) {
    value++;
    digitalWrite(led4, LOW);
    delay(350);
    digitalWrite(led4, HIGH);
    if (value == 9) value = 1;
  }

//Showing text on line 4 on lcd, according to withc program to be selected
  if (value == 1) {
    lcd.setCursor(0,3);
    lcd.print("6 sekunder skyting");
  } else if (value == 2) {
    lcd.setCursor(0,3);
    lcd.print("8 sekunder skyting");
  } else if (value == 3) {
    lcd.setCursor(0,3);
    lcd.print("10 sekunder skyting");
  } else if (value == 4) {
    lcd.setCursor(0,3);
    lcd.print("20 sekunder skyting");
  } else if (value == 5) {
    lcd.setCursor(0,3);
    lcd.print("120 sekunder skyting");
  } else if (value == 6) {
    lcd.setCursor(0,3);
    lcd.print("300 sekunder skyting");
  } else if (value == 7) {
    lcd.setCursor(0,3);
    lcd.print("Friskyting");
  } else if (value == 8) {
    lcd.setCursor(0,3);
    lcd.print("Lampe test");
  }

//This makes the hole **** go in a loop, untill start button is pressed
  if (value == 1 && digitalRead(sw1) == HIGH) {
    program1();
  } else if (value == 2 && digitalRead(sw1) == HIGH) {
    program2();
  } else if (value == 3 && digitalRead(sw1) == HIGH) {
    program3();
  } else if (value == 4 && digitalRead(sw1) == HIGH) {
    program4();
  } else if (value == 5 && digitalRead(sw1) == HIGH) {
    program5();
  } else if (value == 6 && digitalRead(sw1) == HIGH) {
    program6();
  } else if (value == 7 && digitalRead(sw1) == HIGH) {
    program7 ();
  } else if (value == 8 && digitalRead(sw1) == HIGH) {
    lamptest ();
  }
  delay(200);
}

void loop() {
  performCommand();
}
By jremington
#198259
So far I have 6 voids
No, you have six functions. The keyword "void" before a function name signifies that the function does not return a value.

To learn how to do things on a timed basis without using the function named delay(), carefully study the "blink without delay" example that comes with the Arduino IDE. There, you will learn to use the millis() function.
By The Crusher
#198264
Yes, that is what i ment. Sorry for the misunderstanding.

I have studyed the "blink without delay" example, and tried to use what I understod from it in my code (posting what I added below) and it did not work as I hoped for, BUT, it is a step in the right direction. Right now, When i press my start button (sw1), it changes function, but goes back to performCommand() function right after. When I hold down sw1 and then press stop button (sw2), it goes over to the stans() function.
If I hold down my start button, it goes back and fourt from program4() to performCommand(), but after the "timer" i made have gone, it goes over to stans.

So my problem right now, will be to run the function program4() for 18000 millisecounds and then go to stans(), without holding down the start button, and have a constant loop between program4() and performCommand()

this is what I have added above void setup():
Code: Select all
unsigned long prevMillisprog4;

unsigned long currentMillis;
unsigned long sw2pressMillis;

const long intervalprog4 = 18000;
const long intervalprog4off = 1000;

bool stansready = false;
bool stansstate = false;
Tis is the changes I made in program4():
Code: Select all
void program4() {
  if (digitalRead(sw2) == HIGH) {
    stans();
  } else {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Program 4 kjorer");
    lcd.setCursor(0,1);
    lcd.print("20 sekunder");
    lcd.setCursor(0,2);
    lcd.print("skyting");
    unsigned long currentMillis = millis();

    if (digitalRead(sw2) == HIGH) {
      sw2pressMillis = currentMillis;
      stansready = true;
    }
    
    if (currentMillis - prevMillisprog4 == intervalprog4) {
      stans();
      stansstate = true;
      prevMillisprog4 = currentMillis;
      stansready = false;
    }
    
      
  }
}
I think I'm on to something here, and I'm starting to understand how millis() works, but I've not managed to create a millis() function that works in my code yet.
By jremington
#198265
There are a couple of problems with the following line:
Code: Select all
if (currentMillis - prevMillisprog4 == intervalprog4)
1. You should almost always be testing the value of millis() (the current time), not the value of a variable named currentMillis, as it is valid for only 1 millisecond.

2. The difference between two times is almost never equal to a particular constant.

I don't know exactly what your program is supposed to do, but I suggest that you go back and look at the "blink without delay" example to understand why you should probably be using something like this instead:
Code: Select all
if (millis() - prevMillisprog4 >= intervalprog4)
#198267
like Jremington, I am still struggling what you want to do exactly. Next to that you should try to avoid duplicated code as much as possible and break up in smaller subroutines to solve an issue on a single place. Hence I propose a bit of different setup, but it is UNTESTED code and you should expect some errors.
Code: Select all
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(14,15,16,17,18,19);
// (RS, EN, DB4, DB5, DB6, DB7)

//Defining pins for switches
const int sw1 = 2; //Start button
const int sw2 = 3; //Stop button
const int sw3 = 4; //Prog - button
const int sw4 = 5; //Prog + button

//Defining pins for LEDs in switches
const int led1 = 6; //Start button LED
const int led2 = 7; //Stop button LED
const int led3 = 8; //Prog - button LED
const int led4 = 9; //Prog + button LED

//Defining pins for output LEDs
const int relayG = 10; //Relay for green light
const int relayY = 11; //Relay for yellow light
const int relayR = 12; //Relay for red light

//Defining value for program selection
int value;

void setup() {
  //Defining pinMode's
  pinMode(sw1, INPUT);
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);
  pinMode(sw4, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(relayG, OUTPUT);
  pinMode(relayY, OUTPUT);
  pinMode(relayR, OUTPUT);

  //Starting a lamp test
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Lamp test");
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  digitalWrite(relayG, LOW);
  digitalWrite(relayY, LOW);
  digitalWrite(relayR, LOW);
  delay(10000);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, HIGH);
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, HIGH);
  lcd.setCursor(0,1);
  lcd.print("complete!");
  delay(2000);
  lcd.clear();
  //Lamp test complete

  //Setting value for program selection
  value = 1;

  //Turning red light on
  digitalWrite(relayR, LOW);
}

//Is the people ready to open FIRE?!? This part is NOT complete yet
void er_skytter_klar() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Er skytterene klare?");
  lcd.setCursor(0,1);
  lcd.print("Hvis nei, trykk rød");
  lcd.setCursor(0,2);
  lcd.print("knapp innen 15");
  lcd.setCursor(0,3);
  lcd.print("sekunder");
  if (digitalRead(sw2) == HIGH) {
    avbryt();
  } 
  else if (digitalRead(sw2) == LOW ) {
    
  }
  
}

/* update LEDs and LCD display 
 * line1 : text for first line
 * line2 : text for second line
 * line3 : text for third line
 */
void set_display(char *line1, char *line2, char *line3)
{
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(line1);
    lcd.setCursor(0,1);
    lcd.print(line2);
    lcd.setCursor(0,2);
    lcd.print(line3);
}

/*
 * check regularly if SW2 was pressed.
 * 
 * DelayTime : number of milliseconds to wait
 * return  
 *      1 if SW2 was pressed
 *      0 if timed out
 */
int wait_untill( unsigned long DelayTime)
{
  unsigned long repeat = (DelayTime/500);
  
  // in case Delaytime was less that 500mS
  if (repeat == 0)  repeat = 1;
  
  // as long as we have not timed out  
  while(repeat--)
  {
      delay(500);
      if (digitalRead(sw2) == HIGH) return(1);
  }  

  return(0);
}

//Program 1, 6 sec
void program1() {
    set_display("Program 1 kjorer", "6 sekunder", "skyting")
    
    // if SW2 was NOT pressed go to stans()
    if (wait_untill(4000) == 0) stans();
}

//Program 2, 8 sec
void program2() {
    set_display("Program 2 kjorer", "8 sekunder", "skyting")
    
    // if SW2 was NOT pressed go to stans()
    if (wait_untill(6000) == 0) stans();
}

//Program 3, 10 sec
void program3() {
    set_display("Program 3 kjorer", "10 sekunder", "skyting")
    
    // if SW2 was NOT pressed go to stans()
    if (wait_untill(8000) == 0) stans();
}

//Program 4, 20 sec
void program4() {
    set_display("Program 4 kjorer", "20 sekunder", "skyting")

    // if SW2 was NOT pressed go to stans()
    if (wait_untill(18000) == 0) stans();
}

//Program 5, 120 sec
void program5() {
    set_display("Program 5 kjorer", "120 sekunder", "skyting")
    
    // if SW2 was NOT pressed go to stans()
    if (wait_untill(118000) == 0) stans();
}

//Program 6 300 sec
void program6() {
    set_display("Program 6 kjorer", "300 sekunder", "skyting")

    // if SW2 was NOT pressed go to stans()
    if (wait_untill(298000) == 0) stans();
}

//Program 7, ∞ sec
void program7() {
    set_display("Program 7 kjorer", "Friskyting", "        ")

    // if SW2 was pressed go to stans()
    if (wait_untill(1000)) stans();
 
    program7();
  } 
}

//Stop sequense
void stans() {
  digitalWrite(relayG, LOW);
  digitalWrite(relayY, LOW);
  digitalWrite(relayR, HIGH);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Staaaaaaaaaaaaaaaans");
  delay(2000);
  performCommand();
}

//Abort sequense
void avbryt() {
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, LOW);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  performCommand();
}

//Lamp test
void lamptest() {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Lampe test");
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(relayG, LOW);
    digitalWrite(relayY, LOW);
    digitalWrite(relayR, LOW);
    
    wait_untill(10000);
    
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(relayG, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayR, HIGH);
    lcd.setCursor(0,1);
    lcd.print("complete!");
    delay(2000);
    performCommand();
}

//Program selector
void performCommand() {
  lcd.clear();
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(relayG, HIGH);
  digitalWrite(relayY, HIGH);
  digitalWrite(relayR, LOW);
  lcd.setCursor(0,0);
  lcd.print("Lismarken pk");
  lcd.setCursor(0,1);
  lcd.print("Velg program:");
  lcd.setCursor(0,2);
  lcd.print("Program:");
  lcd.setCursor(10,2);
  lcd.print(value);
 
//Magic that changes value with buttons!
  if (digitalRead(sw3) == HIGH) {
    value--;
    digitalWrite(led3, LOW);
    delay(350);
    digitalWrite(led3, HIGH);
    if (value == 0) value = 8;
  }
  
  if (digitalRead(sw4) == HIGH) {
    value++;
    digitalWrite(led4, LOW);
    delay(350);
    digitalWrite(led4, HIGH);
    if (value == 9) value = 1;
  }

//Showing text on line 4 on lcd, according to withc program to be selected
  if (value == 1) {
    lcd.setCursor(0,3);
    lcd.print("6 sekunder skyting");
  } else if (value == 2) {
    lcd.setCursor(0,3);
    lcd.print("8 sekunder skyting");
  } else if (value == 3) {
    lcd.setCursor(0,3);
    lcd.print("10 sekunder skyting");
  } else if (value == 4) {
    lcd.setCursor(0,3);
    lcd.print("20 sekunder skyting");
  } else if (value == 5) {
    lcd.setCursor(0,3);
    lcd.print("120 sekunder skyting");
  } else if (value == 6) {
    lcd.setCursor(0,3);
    lcd.print("300 sekunder skyting");
  } else if (value == 7) {
    lcd.setCursor(0,3);
    lcd.print("Friskyting");
  } else if (value == 8) {
    lcd.setCursor(0,3);
    lcd.print("Lampe test");
  }

//This makes the hole **** go in a loop, untill start button is pressed
  if (digitalRead(sw1) == HIGH)
  {
      switch(value)
      {
          case 1: 
                program1();
                break;
          case 2: 
                program2();
                break;                
          case 3: 
                program3();
                break;
          case 4: 
                program4();
                break; 
          case 5: 
                program5();
                break;
          case 6: 
                program6();
                break;                
          case 7: 
                program7();
                break;
          case 8: 
                lamptest();
                break; 
        }
  }
  
  delay(200);
}

void loop() {
  performCommand();
}
By The Crusher
#198278
Thanks for the replies.

I can try to explain what I'm trying to do:

Each program works like a traffic light. The only difference on the programs is the time the green light is on. Ather that time has passed, ig goes over to a 2 sec stop function, witch means green and yellow light for 2 sec, before moving over to the red light and back to the menu.

The project is a test project for fun, for a shooting range I'm a member off. It is for competishion shooting, therefore different timers on different programs.

All my buttons is LOW when not pressed, and HIGH when pressed. The leds and relays are HIGH when off, and LOW when on.

Function performCommand() changes the value if sw3 or sw4 is pressed. The display shows witch program to start if sw1 is pressed. So I call performCommand() for a menu. It basically changes value, each value has a program, and when sw1 is pressed, it moves to that function.

Eacn program then activates the green light (relayG and led1, led1 is the led in the start button), waits the specificed time, and then goes over to the stop function.

What I want to do with my code, is to have a function that aborts the timer, and go back to either stop function or the abort function (avbryt();) that I'm still working on. This is just a function I want just in case something happens on the shooting range and I want to stop the green light.

@paulvha: I must say, that code setup seems very interesting! I will look more into that, try to understand how it's put togetter and understand how it works.

@jremington:
1: Ok, so if I write currentMillis = millis(); straigt above the if(currentMillis - prevMillisprog4 >= intervalprog4) it won't help? I'll give it a try.

2: The == instead of >= was a test to check if it fixed my problem, witch it didn't. And I will look more into the "blink without delay" function. For me it seems like using millis() to change a state, witch then goes in a digitalWrite() seems easier to do than change to another function. I'll do some more testing and research.

Hope I explained what I'm trying to do a bit better now :) thanks for the help so far
By jremington
#198279
1: Ok, so if I write currentMillis = millis(); straigt above the if(currentMillis - prevMillisprog4 >= intervalprog4) it won't help?
You can do that, but I don't see the point. currentMillis is not "current" 1 millisecond later.

A state machine would be a much better approach to solving your problem than a bunch of if statements. Here is one of many tutorials on how to write a state machine http://www.programmingbasics.org/en/beginner/fsm.html
By The Crusher
#198295
jremington wrote: Fri Feb 09, 2018 1:19 pm A state machine would be a much better approach to solving your problem than a bunch of if statements. Here is one of many tutorials on how to write a state machine http://www.programmingbasics.org/en/beginner/fsm.html
Seems interesting. I will check it out, have made a couple of test codes there, seems like a very nice tool to work with. It's like doing it "graphically" and understandable with blocks witch generates a code. Thanks
paulvha wrote: Fri Feb 09, 2018 9:57 am like Jremington, I am still struggling what you want to do exactly. Next to that you should try to avoid duplicated code as much as possible and break up in smaller subroutines to solve an issue on a single place. Hence I propose a bit of different setup, but it is UNTESTED code and you should expect some errors.
As I wrote, interesting code setup. I looked into it, and merged a part from your code into mine, and it actually works now.

I copied this part:
Code: Select all
//Check regulary if SW2 was pressed, thanks to paulvha @sparkfun forums!
int wait_untill( unsigned long DelayTime)
{
  unsigned long repeat = (DelayTime / 500);

  // in case Delaytime was less that 500mS
  if (repeat == 0)  repeat = 1;

  // as long as we have not timed out
  while (repeat--)
  {
    delay(500);
    if (digitalRead(sw2) == HIGH) return (1);
  }

  return (0);
}
and also copied a part of a function, so a function looks like this now:
Code: Select all
//Program 4, 20 sec
void program4() {
  if (digitalRead(sw2) == HIGH) {
    stansready = true;
  } else if (digitalRead(sw2) == LOW) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(relayR, HIGH);
    digitalWrite(relayY, HIGH);
    digitalWrite(relayG, LOW);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Program 4 kjorer");
    lcd.setCursor(0, 1);
    lcd.print("20 sekunder");
    lcd.setCursor(0, 2);
    lcd.print("skyting");
    //Replacing delay(18000)
    if (wait_untill(18000) == 0) {
      stans();
    }
  }
}
And now I can abort a function and go back to performCommand() with pressing SW2 during the countdown.

Thanks a lot for the help everyone!