Maker Pro
Maker Pro

Sketch question

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
I found this on youtube and tried it out. It works but I am confused as to why I can't activate both pushbuttons at the same time. How can this sketch be modified to do this?

Code:
// constnts that won't change. They're used here to set pin numbers
const int button1 = 2;      // the number of the pushbutton pin
const int button2 = 3;      // the number of the pushbutton pin
const int relay1 = 11;     // the number of the relay1 pin
const int relay2 = 12;     // the number of the relay2 pin

// variables that will change
int buttonState1 = 0;       // variable for reading the pushbutton1 status
int buttonState2 = 0;       // variable for reading the pushbutton2 status
void setup()

{
  // initialize the relay pin as an output
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);

  // initialize the pushbutton pin as an input
  pinMode(button1, INPUT_PULLUP);   // PULLUP for add 5v to pin without hardware prevent pin from floating between HIGH and LOW
  pinMode(button2, INPUT_PULLUP);   // PULLUP for add 5v to pin without hardware prevent pin from floating between HIGH and LOW
}

void loop()
{
  // read the state of the pushbutton value
  buttonState1 = digitalRead(button1);

  // check if the pushbutton is pressed. If it is, the buttonState is LOW.
  if (buttonState1 == LOW)
  {
    digitalWrite(relay1, LOW);      // pin 2 is pressed and connected to GND so it will be LOW
    delay (1000);                   // remove 5v from pin 11 so relay in1 will be 0v and this will make relay on
  }                                 // wait 1 sec.
  else
  {
    digitalWrite(relay1, HIGH);     // add 5v to arduino pin 11 so relay in1 will be 5v and this will make the relay turn off.
  }

  // read the state of the pushbutton value
  buttonState2 = digitalRead(button2);

  // check if the pushbutton is pressed
  // if it is, the buttonState is LOW
  if (buttonState2 == LOW)          // pin 3 is pressed and connected to GND so it will be LOW
  { // remove 5v from pin 12 so relay in2 will be 0v and this will make the relay turn on
    digitalWrite(relay2, LOW);      // and wait 5 seconds.
    delay (5000);
  }
  else
  {
    digitalWrite(relay2, HIGH);     // add 5v to arduino pin 12 so relay in2 will be 5v and this will make the relay turn off.
  }
}
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,722
Joined
Nov 17, 2011
Messages
13,722
why I can't activate both pushbuttons at the same time.
PLeas ego into mor edetail. There is no fundamental issue reading both pushbuttons immediately one after the other and peforming the consequent actions. Rading two buttons one after the other is almost identical to reading them at the same time. The very short delay is much less than a possible delay by your finers when pushing he two buttons. Reading one button right after the other is froma users's perspective identical to reading both buttons at the same time.

Wahzt exactly do you want to achieve?
 

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
I want to be able to activate both relays at the same time. With the current sketch, this doesn't happen. I have to wait for the delay to transpire before activating the other.
 

kellys_eye

Jun 25, 2010
6,514
Joined
Jun 25, 2010
Messages
6,514
Put (move) the buttonstate2 line directly below the buttonstate1 line

Put the if (buttonstate2) line below the if (buttonstate1) line

Put the digitalWrite(relay2) line below the digitalwrite(relay1) line

etc

Basically you are 'combining' the two statement lines to be run successively and BEFORE the delay is implemented.
 

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
Put (move) the buttonstate2 line directly below the buttonstate1 line

Put the if (buttonstate2) line below the if (buttonstate1) line

Put the digitalWrite(relay2) line below the digitalwrite(relay1) line

etc

Basically you are 'combining' the two statement lines to be run successively and BEFORE the delay is implemented.
This causes the relays to activate and stay that way. Cannot deactivate them.
 

Doug3004

Sep 5, 2014
119
Joined
Sep 5, 2014
Messages
119
You can also use the pushbutton checks to set a state indicator variable (each button having a separate variable), and then further on down, have two more (if) statements that turn either relay on if their state is set to [true].

The problem with turning both relays on in the current sketch is that it calls a delay() statement after turning each relay on. That blocks the other relay from being able to turn on at the same time.

You can also program separate event timers in code to handle that too--and then both can turn on and then turn off after 5 seconds each.

In practice I don't use delay() much as it stops everything else from happening. Normally I will write my own software timing code because you can simultaneously have several "delay" periods running for different things at the same time.

I do use delayMicroseconds() to help with external chip interface timing, but only in short amounts like 20 ~ 100 microseconds.

See here:
https://pastebin.com/Y70kuYT1
(I didn't test this but anyway)
 

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
You can also use the pushbutton checks to set a state indicator variable (each button having a separate variable), and then further on down, have two more (if) statements that turn either relay on if their state is set to [true].

The problem with turning both relays on in the current sketch is that it calls a delay() statement after turning each relay on. That blocks the other relay from being able to turn on at the same time.

You can also program separate event timers in code to handle that too--and then both can turn on and then turn off after 5 seconds each.

In practice I don't use delay() much as it stops everything else from happening. Normally I will write my own software timing code because you can simultaneously have several "delay" periods running for different things at the same time.

I do use delayMicroseconds() to help with external chip interface timing, but only in short amounts like 20 ~ 100 microseconds.

See here:
https://pastebin.com/Y70kuYT1
(I didn't test this but anyway)

This sketch works as I was wanting. I'll study it and see what is going on. Thanks for your help!
 

dorke

Jun 20, 2015
2,342
Joined
Jun 20, 2015
Messages
2,342
void loop()
{
// read the state of the pushbuttons value
buttonState1 = digitalRead(button1);
buttonState2 = digitalRead(button2);

// check if at least one push-button is pressed
if ((buttonState1 == LOW) || (buttonState2 == LOW) )
{
digitalWrite(relay1, buttonState1); // if pin 2 is pressed, relay1 is set to ON
digitalWrite(relay2, buttonState2); // if pin 3 is pressed, relay2 is set to ON

delay (1000); // wait 1 sec.
digitalWrite(relay1, HIGH); // pin 11 will be 5v and this will make relay1 turn off.

if (buttonState2 == LOW) // if button2 was pressed,add 4sec and then deactivate relay2
{ delay (4000);
digitalWrite(relay2, HIGH); // pin 12 will be 5v and this will make relay2 turn off.
}
}
}


The above code will allow you to activate both relays at the same time.
Note:
If no.1 is pushed and activated,the code will wait for 1 sec before "re-checking" the buttons.
If no.2 was pushed the total wait time will be 1+4 =5sec.

To eliminate this "problem" you will have to run in an "interrupt mode of operation".
 

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
You can also use the pushbutton checks to set a state indicator variable (each button having a separate variable), and then further on down, have two more (if) statements that turn either relay on if their state is set to [true].

The problem with turning both relays on in the current sketch is that it calls a delay() statement after turning each relay on. That blocks the other relay from being able to turn on at the same time.

You can also program separate event timers in code to handle that too--and then both can turn on and then turn off after 5 seconds each.

In practice I don't use delay() much as it stops everything else from happening. Normally I will write my own software timing code because you can simultaneously have several "delay" periods running for different things at the same time.

I do use delayMicroseconds() to help with external chip interface timing, but only in short amounts like 20 ~ 100 microseconds.

See here:
https://pastebin.com/Y70kuYT1
(I didn't test this but anyway)
I have been playing around with this. I notice when I change the delays for both relays, or just one relay, after I upload the sketch, both relays activate. I have to press the buttons to cycle the timer out and then it works fine. What could be going on?
 

dorke

Jun 20, 2015
2,342
Joined
Jun 20, 2015
Messages
2,342
I have been playing around with this. I notice when I change the delays for both relays, or just one relay, after I upload the sketch, both relays activate. I have to press the buttons to cycle the timer out and then it works fine. What could be going on?

You have to set the initial state of the buttons variable and relays to be not activated at boot , before and outside the above code like so:

buttonState1 = high);
buttonState2 = high);
digitalWrite(relay1, buttonState1); // relay1 is set to off
digitalWrite(relay2, buttonState2); // relay2 is set to off
 

Doug3004

Sep 5, 2014
119
Joined
Sep 5, 2014
Messages
119
Try what dorke says above, and init the button states and digitalwrite the relay pins high. I forgot that bit...

Also I just guessed what you meant with the "use both buttons at once" question.
When people learn how to use delay() to cause one sketch pause, then they try to use it for multiple pauses (for different things) that can start and stop at any time and not interfere with each other,,, and there isn't any practical way to do that.
So the solution is to just not use delay() entirely.
-Or to use the hardware timers, but then you only have so many of them... You can have twenty of these 'software timers' going all at once, without any problems. They may not be perfectly accurate, but they will be really, really close.
 

BobK

Jan 5, 2010
7,682
Joined
Jan 5, 2010
Messages
7,682
I think what you want is this:

You can press button 1 at any time and the first relay will stay energized for 1 second.
You can also press button 2 at any time and the second relay will stay energized for 5 seconds.

In order to do that the loop has to be structured very differently. The buttons must be checked at a much higher rate and the relays have to stay activated while it goes through many loops of checking the buttons.

I will look at writing the correct code a later.

Bob
 

bigone5500

Apr 9, 2014
712
Joined
Apr 9, 2014
Messages
712
You have to set the initial state of the buttons variable and relays to be not activated at boot , before and outside the above code like so:

buttonState1 = high);
buttonState2 = high);
digitalWrite(relay1, buttonState1); // relay1 is set to off
digitalWrite(relay2, buttonState2); // relay2 is set to off
So would these lines to above the void loop()? Would they have int before them or would they simply be (buttonState1 = high); , with or without parentheses? There is already 'int buttonState1 = 0; in the setup. So I'm thinking that maybe it should be replaced?
 

Doug3004

Sep 5, 2014
119
Joined
Sep 5, 2014
Messages
119
So would these lines to above the void loop()? Would they have int before them or would they simply be (buttonState1 = high); , with or without parentheses? There is already 'int buttonState1 = 0; in the setup. So I'm thinking that maybe it should be replaced?
I would guess:
1. both of the buttonState variables should be initialized to 1 instead of zero,,, since you are using input pullup on the pin, with HIGH as the "off" condition.
2. Also, in the setup() sub after you declare the relay pins as outputs, then you should probably have two more statements that use digitalWrite() to set them both high so that the relays start off being turned off.

It drives me nuts how they made those relay boards...
Whenever I use the relays I will wire them so that a high signal = turning on.
The relays are SPDT so even though they say that low = on, you can wire them the opposite way.
Then the LED on the relay board goes off when the relay is activated instead of turning on, but it still tells you if it's getting a signal or not.
Or you can buy the relay boards that have a jumper to set them to work either way (either low or high can be 'on') and then the activity LED works right both ways.
 
Top