Simple code that I cannot make to work

Hi folks, I'm new into programming and I'm trying to make this code work, which is part of a larger program that controls a couple of relays instead of LEDs.

What I need to do now is: when a button is pressed (i.e. a microswitch), the program should turn OFF an LED and wait some seconds to turn it on again.

I can't use the 'while' control structure since it will stop the running loop and therefore stop the whole code from controlling other stuff.

Check this out:

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;


int inmersionB1 = 3000;
unsigned long inicioInmersionB1;
unsigned long currentMillis = millis();

void setup()
{

  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT);
    digitalWrite(puls1Pin, HIGH);

}
void loop()
{
  puls1 = digitalRead(puls1Pin);
  if (puls1 == LOW) {
    led = LOW;
    inicioInmersionB1 = millis();
    program1;
  }

  digitalWrite(ledPin, led);

}
void program1() {

  if ((currentMillis - inicioInmersionB1) > inmersionB1) {
    if (led == HIGH)
      led = LOW;
  }
  digitalWrite(ledPin, led);
}

Hope some of you can help me. Thank you guys!!

A few things.

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;

int inmersionB1 = 3000;
unsigned long inicioInmersionB1;
unsigned long currentMillis = millis();

void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(puls1Pin, INPUT); <- Use INPUT_PULLUP instead
digitalWrite(puls1Pin, HIGH); Get rid of this, not needed if you use INPUT_PULLUP
}

void loop()
{
puls1 = digitalRead(puls1Pin);
if (puls1 == LOW) { <- No Debounce?
led = LOW;
inicioInmersionB1 = millis();
program1; <- Though this compiles, it is not doing what you want, try adding ( ) and take it out of that IF statement otherwise it will only check when the button is pressed.
}

digitalWrite(ledPin, led); Not really needed here, better if it is in the IF statement
}

void program1() {
if ((currentMillis - inicioInmersionB1) > inmersionB1) {
if (led == HIGH)
led = LOW; But the button turns the LED OFF, shouldn't this make it HIGH
HERE
}
digitalWrite(ledPin, led); <- Move this...
}

Alright, first of all thank you for your advice! I introduced the changes you suggested and a few more. Started using a library that stores the time elapsed. This one.

Here are the changes, now the led turns off alright, but it wont turn on after the specified time.

Any suggestions?

#include <elapsedMillis.h>
const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;


int inmersionB1 = 3000;
unsigned long inicioInmersionB1;
unsigned long currentMillis = millis();

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT_PULLUP);
  digitalWrite(ledPin, HIGH);  [b]//If i get rid of this, the led starts OFF  : :o [/b]

}

void loop()
{
  puls1 = digitalRead(puls1Pin);
  if (puls1 == LOW) { 
    delay(10); 
    led = LOW;
    elapsedMillis inicioInmersionB1;
    digitalWrite(ledPin, led);

  }
program1(); 
 
}

void program1() {
  if ((currentMillis - inicioInmersionB1) > inmersionB1) {
    if (led == LOW)
      led = HIGH; 
        digitalWrite(ledPin, led);
  }

}

Started using a library that stores the time elapsed.

Why?

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;


int inmersionB1 = 3000;
unsigned long inicioInmersionB1;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT_PULLUP);
}

void loop()
{
  puls1 = digitalRead(puls1Pin);
  if (puls1 == LOW) 
  {
    delay(10); // not a suitable debounce, but debounce actually might not be needed
    led = LOW;
    inicioInmersionB1 = millis();
    digitalWrite(ledPin, led);
  }
  program1();

}

void program1() 
{
  if ((millis() - inicioInmersionB1) >= inmersionB1) 
  {
    if (led == LOW)
      led = HIGH;
    digitalWrite(ledPin, led);
  }

}

HazardsMind:
Why?

Because I wasn't sure how to store millis() properly. Now It's clear, thank you again!

This code isn't working properly yet though, I need program1() to be called only if the button is pressed. Otherwise the LED starts OFF after 3 seconds it turns on for itself. However moving it into the 'if' statement doesn't do the trick.

I need the program to wait while the button is pressed, for 3 seconds and then turn the LED back ON.

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;


int inmersionB1 = 3000;
unsigned long inicioInmersionB1;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT_PULLUP);
}

void loop()
{
  puls1 = digitalRead(puls1Pin);
  if (puls1 == LOW) 
  {
    delay(10); 
    led = LOW;
    inicioInmersionB1 = millis();
    digitalWrite(ledPin, led);
    program1(); //Now i put it into the 'if' statement, but looks like the program1() is not called at all since the led doesnt turn back on!
  }

}

void program1() 
{
  if ((millis() - inicioInmersionB1) >= inmersionB1) 
  {
    if (led == LOW)
      led = HIGH;
    digitalWrite(ledPin, led);
  }

}

How is your button wired? Right now it is set to go LOW when pressed, otherwise it is HIGH.

The code worked when I posted it. The LED was on and when I brought pin 30 to ground, the LED went off, 3 seconds passed and it went back on again.

inicioInmersionB1 = millis();
when you do the above, you call
your program1() function a few uS later.
therefore:
if ((millis() - inicioInmersionB1) >= inmersionB1)
will never be true.

Start thinking about how the code executes and the time that things happen.

You can use:
Serial.println(" I got here ");
at strategic locations, to prove if the sketch gets to where you think it gets to.

.

HazardsMind:
How is your button wired? Right now it is set to go LOW when pressed, otherwise it is HIGH.

The code worked when I posted it. The LED was on and when I brought pin 30 to ground, the LED went off, 3 seconds passed and it went back on again.

Thank you once more, button is wired as yours. But when I bring pin 30 to ground, the program turns the LED OFF indefinitely. When I release it, it stays OFF for 3 more seconds, then it turns ON.

Think of the button as a microswitch for some motor. When the switch is activated (the motor touches it and brings it to ground), it should turn the motor OFF and then after 3 seconds, turn it back ON so the switch is released. Do I make myself more clear?

LarryD:
inicioInmersionB1 = millis();
when you do the above, you call
your program1() function a few uS later.
therefore:
if ((millis() - inicioInmersionB1) >= inmersionB1)
will never be true.

Start thinking about how the code executes and the time that things happen.

You can use:
Serial.println(" I got here ");
at strategic locations, to prove if the sketch gets to where you think it gets to.

.

Hi! thank you for your reply. I fail to see why

 if ((millis() - inicioInmersionB1) >= inmersionB1)

would never be true.

Can you elaborate please?

If someone else doesn't answer you, then I will do it in the morning. It is 1:03 AM here and I don't want to get back out of bed right now.

HazardsMind:
If someone else doesn't answer you, then I will do it in the morning. It is 1:03 AM here and I don't want to get back out of bed right now.

Thank you very much man, very appreciated! Good night.

In your post #4 you run this line as long as the switch is low:
inicioInmersionB1 = millis();
You then call program1() a few uS later so:
if ((millis() - inicioInmersionB1) >= inmersionB1)
Will not be true as inmersionB1 is 3000 or 3seconds.

The next time through loop() if the switch is still closed you again:
inicioInmersionB1 = millis();
So once again:
if ((millis() - inicioInmersionB1) >= inmersionB1)
is not true.
If the switch opens and goes HIGH there is no way to get to program1().

LarryD:
In your post #4 you run this line as long as the switch is low:
inicioInmersionB1 = millis();
You then call program1() a few uS later so:
if ((millis() - inicioInmersionB1) >= inmersionB1)
Will not be true as inmersionB1 is 3000 or 3seconds.

The next time through loop() if the switch is still closed you again:
inicioInmersionB1 = millis();
So once again:
if ((millis() - inicioInmersionB1) >= inmersionB1)
is not true.
If the switch opens and goes HIGH there is no way to get to program1().

Thank you LarryD, now I understand perfectly why that approach won't work. Then how can I set the time stored on inicioInmersionB1 to be the one when the button is just pushed? I need to set that time once, not at every loop...

Let me get something straight.
Your motor runs. May be driving a threaded rod?
At some point a switch is closed. Do to the position of a traveler on the rod?
When the switch first closes you want the motor to stop. The switch stays closed?
After 3 seconds the motor starts. Does the switch open?

Remember there is something called switch bounce.

.

Also have you looked at the StateChangeDetection sketch for switches?

LarryD:
Let me get something straight.
Your motor runs. May be driving a threaded rod?
At some point a switch is closed. Do to the position of a traveler on the rod?
When the switch first closes you want the motor to stop. The switch stays closed?
After 3 seconds the motor starts. Does the switch open?

Remember there is something called switch bounce.

.

Thank you LarryD, that is exactly what is happening here. Should work like this: Motor runs until some traveler attached to it closes a switch and makes the motor stop. Then after 3 seconds, the motor runs again, opening the switch.

Check this out! I think I figured out how to solve it! This code works -almost- perfect, it doesn't work every time I push the button, most of the times, but not every time.
It seems like I need to debounce the switch. I'm trying to find out how to fix it. Any suggestions??

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1;


int inmersionB1 = 3000;
unsigned long inicioInmersionB1;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT_PULLUP);
  digitalWrite(ledPin, HIGH);
}

void loop()
{
  puls1 = digitalRead(puls1Pin);
  if (puls1 == HIGH && led == HIGH)
  {
    button();
  }
  else if (puls1 == LOW && led == LOW)
  {
    program1();
  }
}

int button()
{

  puls1 = digitalRead(puls1Pin);
  if (puls1 == LOW)
  {
    delay(10);
    led = LOW;
    inicioInmersionB1 = millis();
    digitalWrite(ledPin, led);

  }


}
void program1()
{
  if ((millis() - inicioInmersionB1) >= inmersionB1)
  {
    if (led == LOW)
      led = HIGH;
    digitalWrite(ledPin, led);
  }

}

Unfortunately time has caught up to me too.
It is bed time here also.

I'll check in tomorrow.

:sleeping:

LarryD:
Unfortunately time has caught up to me too.
It is bed time here also.

I'll check in tomorrow.

:sleeping:

Hahaha don't worry man, thank you for your help, I'm about to get it right. Good night!!

Solved guys! Thank you very much for your help! This is the way I solved. I followed LarryD's advice and researched about StateChangeDetection, found this and figured out how to make my code work. Thank you both, LarryD and HazardsMind, you pointed me in the right direction.
Here's the code:

const int ledPin = 13;
int led = HIGH;
const int puls1Pin = 30;
int puls1 = 0;
int ultpuls1 = 0;

int inmersionB1 = 3000;
unsigned long inicioInmersionB1;

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers


void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(puls1Pin, INPUT_PULLUP);
  digitalWrite(ledPin, HIGH);
}

void loop()
{

  button();
  program1();
}

int button()
{
  puls1 = digitalRead(puls1Pin);
  delay(10);
  // compare the buttonState to its previous state
  if (puls1 != ultpuls1) {
    if (puls1 == LOW) {
      led = LOW;
      inicioInmersionB1 = millis();
      digitalWrite(ledPin, led);

    }
  }
  // save the current state as the last state,
  //for next time through the loop
  ultpuls1 = puls1;


}


void program1()
{
  if ((millis() - inicioInmersionB1) >= inmersionB1)
  {
    if (led == LOW)
      led = HIGH;
    digitalWrite(ledPin, led);
  }

}

If you have it working the way you need, congratulations.

You may want to look at a programming technique called "State Machine".
It can be used to handle all kinds of problem programs.

Not sure how or if your motor reverses direction.