Delays without delay [solved]

Hi guys

I am new to this whole coding thing but I have an application where it comes in handy.

I have a welder without gas feed control.

I want to have a push button which opens a NC solenoid valve. But when I let go of the button I want the valve to keep open for like a second or so.

I have tried the delay function but realised that it will also take a second to open the valve then.

I have looked at millis but haven't got it to work.

Hope you will help eventhough it's proberly obviously how it's done.

Thanks in advance

Have a look at Timer libraries pulse function.

Hi Sony

I just looked at it. Do you have an example of how the code could look like? I can't get it to work.

Thanks

Unfortunately I dont have any simple code right now.

Probably you can post your test code and we can take it from there. Please post the code inside code tag.

Hi Sony

I came across this on the forum. It does what I need only in the wrong order. It waits 0,5 seconds before switching on. Can I modify this so it waits before switching off?

void setup()
{
 pinMode(10, INPUT); // button
 pinMode(11, OUTPUT); // LED
 digitalWrite(11, LOW);
}

int pinState = HIGH;
const int x = 500; // 500ms delay

void loop()
{
 int newState = digitalRead(10);
 if (pinState != newState) // button state differs from last recorded state?
 {
   pinState = newState;
   if (pinState == LOW) // button newly pressed?
     delay(x);
   digitalWrite(11, !pinState); // set LED HIGH if button LOW and vice versa
 }
}
   if (pinState == LOW){ // button newly pressed?
      digitalWrite(11, HIGH); // set LED HIGH if button LOW and vice versa[color=#222222][/color]
     delay(x);
     digitalWrite(11, LOW);
    }

If you do the above approach, the pin state will change from HIGH to LOW after 500ms delay.

Hi Sony

My code look like this then.

But it only works if I push the button and release. I need PIN 13 to be on while i hold the button and stay on for 1 second when I release.

Do you have any ideas?

void setup()
{
 pinMode(2, INPUT); // button
 pinMode(13, OUTPUT); // LED
 digitalWrite(13, LOW);
}

int pinState = HIGH;
const int x = 1000; // 1000ms delay

void loop()
{
 int newState = digitalRead(2);
 if (pinState != newState) // button state differs from last recorded state?
 {
   pinState = newState;
   if (pinState == LOW){ // button newly pressed?
      digitalWrite(13, HIGH); // set LED HIGH if button LOW and vice versa[color=#222222][/color]
     delay(x);
     digitalWrite(13, LOW);
    }
 }
}
 int newState = digitalRead(2);
 if (pinState != newState) // button state differs from last recorded state?[color=#222222][/color]
 {
   pinState = newState;
   if(buttonPinState==HIGH) //button is pressed
       digitalWrite(13, HIGH); //pin will be high till the button is pressed.
    if(buttonState==LOW){ //button released
       delay(1000); //delay for a second and write low to pin 13
       digitalWrite(13, LOW);
    }
}

I havent tested the above code.

@sarouje: the stated aim of the thread (read the title) is to delay without using the delay() function.

Right @AWOL but in between, he wanted to try with Delay and questions are based on that.

If the delay functions does so it dosen't instantly switch on, then I would like to avoid it.

I am looking on different posts but can't seem to get a code that will do this for me. Is it really that complicated?

Thanks so far

Is it really that complicated?

To write a program that does not use delay()? No.

To convert a program that is riddled with delay()s to not use delay()? Yes, it can be extremely complicated.

PaulS:
To convert a program that is riddled with delay()s to not use delay()? Yes, it can be extremely complicated.

No doubt about that :), I experienced that when I started with Arduino.
Seems like OP is moving from Non Delay to Delay again.

Hi Paul

That's a bit out of context. It wasn't even the question you answered.

I am in no way locked in on using delay, I don't care how the code looks if it just switches on when the button is pressed and wait for 1 second to switch off when the button is released.

If you have some solutions for this please let me know.

Trying to ridiculing me dosen't really help anything?

Thanks in advance

@BS92, Paul is not trying to ridicule you in anyway, he saying his view point about converting code that uses delay to millis. It's complicated and difficult to understand the flow of programming at first.

I would suggest you try with delay() approach and later can refactor and move with non delay approach.

Hi Sony

Then I must have misunderstood his intent.

Anyway the delay dosen't help me in my specific project if the delay function causes a delay in the whole program making it also delay the switching ON function.

I find it odd that it is so complicated to make what seems to me an easy function into code. But it is probably me underestimeting the complicity of this.

BS92:
Anyway the delay dosen't help me in my specific project if the delay function causes a delay in the whole program making it also delay the switching ON function.

Yes delay causes the whole program to delay. Can you please try the below approach? I havent tested with any button press, it just a quick code to try the approach, later you can refactor it if it works.

unsigned long previousMillis = 0;
byte started = 0;
byte pinState=0;

void setup() {
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

void loop() {
  int newState = digitalRead(2);
  if (pinState != newState) 
  {
    pinState = newState;
    if (pinState == HIGH){ //button is pressed
      stop();
      digitalWrite(13, HIGH); //pin will be high till the button is pressed.
    }
    if (pinState == LOW) { //button released
      start();
    }
  }
  performAction();
}

void start() {
  started = 1;
  previousMillis = millis();
}

void stop() {
  started = 0;
}

void performAction() {
  if (started == 1) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= 1000) {
      digitalWrite(13, LOW);
      started=0;
    }
  }
}

Your program can be in a number of states - the switch has not been pressed and the LED is off, the switch has been pressed and the LED is on but has not been on long, the switch has been pressed and the LED is on and has been on long enough, the LED has been turned back off, etc.

You need to keep track of which state you are in, so that, on any given pass through loop(), you can determine if it is necessary to change state, because the user pressed the switch, because enough time has passed, or just because the voices told you to change state.

Once you know that a state change is needed, there is some code that is needed to make the change happen. For instance, if a state change is needed because the user pressed the switch, you need to record when that happened and turn the LED on. If a state change is needed because the LED has been on for long enough, you need to turn the LED off.

If you approach the design of the program with this "state machine" approach in mind, you'll never need to use delay().

Changing from using delay() to not using it means that you need to completely rethink the design.

Hi Sony

Worked as a charm:)

Thank you very much!

I hope to be in a position were I can figure these things out myself.

But again thanks

And to Paul

Sorry for assuming you made fun of me...

Best wishes

Good to hear that your issue resolved. Go through @Paul response (#17) as well.

Please append [solved] to the title.