Need Help with ON/OFF ! [SOLVED]

Hi

I need to write a code with a relay to on every hour for 1 min and off ,so I thought its a simple code as below ,

void setup() {
pinMode(10, OUTPUT);// output to the relay

}
void loop() {
digitalWrite (10,HIGH);
delay(60000); // On for one minute
digitalWrite (10,LOW);off for one hour
delay(3600000);
}

Now I need to use a push button so when button press (HIGH)the relay should ON when release (LOW)run the previous loop(Relay On for 1 min and OFF for 1 hour).I try to use a IF/ELSE statement as below and it doesn't work .Appreciate if someone can help me with this .

const int buttonPin = 8; // Button pin

const int RelyPin = 10; // Relay pin

int buttonState = 0;

void setup() {

pinMode(RelyPin, OUTPUT);
pinMode(buttonState, INPUT);
}
void loop() {

buttonState = digitalRead(buttonPin);

if (buttonState == HIGH) {

digitalWrite(RelyPin, HIGH);

}

else {

digitalWrite(RelyPin, HIGH);
delay(60000); // On for one minute
digitalWrite(RelyPin, LOW);
delay(3600000);// off for 1 hour
}}

You really need to read this.

Follow the advice I gave you. When you re-post your code, with all the delay() functions removed, we can talk more. I'm not going to write your code for you. When you've read, and understood, the reference I linked you to, you'll know heaps more than you do now. You need to learn and you do that by doing, not by somebody doing for you. See you in 30 minutes (it's n0w 2038UTC).

With the delays in the code your button will be checked only every 61 minutes.

You need to use a variation of the BlinkWithoutDelay example to have your relay turn ON for 1 minute and OFF for 59 minutes. Since the two delays are not the same, you have to use a variable for the time interval and change it depending on if the relay is ON or OFF.

When I press the relay on forever.

Is it "forever" or for one hour and two minutes?

Your first button press turns the relay on, but you you do not set the relay state to HIGH from the default initialization of LOW.

Therefore, this block of off time code is active even though the relay is HIGH.

 else if ((RelyState == LOW) && (currentMillis - previousMillis >= OffTime))

Well yes it is ON for one hour .Sorry im still confuse with what you are trying to explain.I never though its going to be this hard :frowning: btw thanks for helping.

I want to the relay to go off once i released the button and work according to the timer.Any ideas of how to do that ? Thanks!!

I'm not sure what you exactly want, but if you want to press the button, have the relay on for one on time cycle, and then go off (and run on the timer after that), then you need to make the relay state consistent with the actual condition. Also, if you don't press the button right at the start and millis() becomes larger than the on time, it will turn immediately off, so you need to set the previous millis() = millis() when the button is first pressed.

if (buttonState == HIGH) {
  digitalWrite(RelyPin, HIGH);
  RelayState = HIGH;
  previousMillis = currentMillis;   
}

Now when I press the button The led attached to the relay will turn on but not the relay also the led attached to the relay flicker sometimes .

This sounds like some sort of hardware/wiring issue.

Please provide (use an attachment) a hand drawn sketch of your wiring schematic. How is the button wired? How is the relay wired and powered? Is the relay active HIGH or LOW? Does the buttonPin have a pullup or pulldown resistor?

Please read this guide on how to use the forum and learn how to post your code in code tags. If you can't figure out how to do this, then you probably won't be able to figure out your problem.

 pinMode(buttonState, INPUT);

This is wrong, you are setting pin 0 as an input, not the buttonPin 8.

  unsigned long currentMillis = millis();

Do not redeclare this variable in loop(). It is fine as a global.

int RelayPin =  10;      
int RelayState = LOW;             
unsigned long previousMillis = 0;   
unsigned long currentMillis = millis();     
long OnTime = 1200;           // milliseconds of on-time
long OffTime = 3000000 ;          // milliseconds of off-time
int buttonpin = 8; // Relay pin 
int buttonState = 0;
void setup() 
{
  // set the digital pin as output:
  pinMode(RelyPin, OUTPUT);    
  //pinMode(buttonState, INPUT);
  pinMode(buttonpin, INPUT);  
}
 
void loop()
{
  buttonState = digitalRead(buttonpin);

if (buttonState == HIGH) {
  digitalWrite(RelyPin, HIGH);
  RelyState = HIGH;
  previousMillis = currentMillis;   
}

else {
}
  //unsigned long currentMillis = millis();
  currentMillis = millis();
 
  if((RelyState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    RelyState = LOW;   // turn it Off
    previousMillis = currentMillis;  
    digitalWrite(RelyPin, RelyState);  
  }
  else if ((RelyState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    RelyState = HIGH;  // turn it on
    previousMillis = currentMillis;   
    digitalWrite(RelyPin, RelyState);    
  }
}

Instead of

pinMode(buttonPin, INPUT)

and

if (buttonState == HIGH)

Try

pinMode(buttonPin,INPUT_PULLUP);

and

if (buttonState == LOW)

Move

currentMillis = millis();

to the top of your loop() function.

RE :evanmars

I did the changes now when i press the button the relay stays on again not turning off ,

int RelyPin = 10;
int RelyState = LOW;
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
long OnTime = 1200; // milliseconds of on-time
long OffTime = 50000 ; // milliseconds of off-time
int buttonpin = 8; // Relay pin
int buttonState = 8;
void setup()
{
// set the digital pin as output:
pinMode(RelyPin, OUTPUT);
pinMode(buttonState, INPUT_PULLUP);
}

void loop()
{
previousMillis = currentMillis;
buttonState = digitalRead(buttonpin);

if (buttonState == LOW) {
digitalWrite(RelyPin, HIGH);
RelyState = HIGH;

}
else {
}

if((RelyState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
RelyState = LOW; // turn it Off
previousMillis = currentMillis;
digitalWrite(RelyPin, RelyState);
}
else if ((RelyState == LOW) && (currentMillis - previousMillis >= OffTime))
{
RelyState = HIGH; // turn it on
previousMillis = currentMillis;
digitalWrite(RelyPin, RelyState);
}
}

long OnTime = 1200;           // milliseconds of on-time
long OffTime = 3000000 ;          // milliseconds of off-time

OnTime == 1.2 seconds
OffTime == 50 minutes

If you've wired the button with a pullup resistor (which we didn't know in the original post), then you need pinMode(buttonPin, INPUT);and buttonState = digitalRead(buttonPin);as you had.

I did the changes

No you did not.

Move
Code: [Select]
currentMillis = millis();
to the top of your loop() function.

No code tags = no hope.

Post ALL of your code in code tags.

You have

previousMillis = currentMillis;

Not

currentMillis = millis();

Seriously, read cattledog's posts #11 and #17 and mine in #20.

Post. Your. Code. In. Code. Tags.

If you can't be bothered to do that, I can't be bothered to help any more.

Sorry evanmars I was confuse with what is code tag n now i figured out .Hope I did it right this time .The code I posted below is modified (only the button press relay working not the timer loop )

int RelyPin =  10;      
int RelyState = LOW;             
unsigned long previousMillis = 0;   
long OnTime = 10000;           // milliseconds of on-time
long OffTime = 600000 ;          // milliseconds of off-time
int buttonpin = 8; // Relay pin 
int buttonState = 0;
void setup() 
{
  // set the digital pin as output:
  pinMode(RelyPin, OUTPUT);    
  pinMode(buttonpin, INPUT);  
}
 
void loop()
{
  buttonState = digitalRead(buttonpin); //Button input value

if (buttonState == HIGH) { //If button input High 
  digitalWrite(RelyPin, HIGH); // Relay ON

}

else {
 digitalWrite(RelyPin, LOW);}
 unsigned long currentMillis = millis();  
  if((RelyState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    RelyState = LOW;   // turn it Off
    previousMillis = currentMillis;  
    digitalWrite(RelyPin, RelyState);  
  }
  else if ((RelyState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    RelyState = HIGH;  // turn it on
    previousMillis = currentMillis;   
    digitalWrite(RelyPin, RelyState);    
  }
  

}

This is the code for the push button to ON/OFF relay

int RelPin = 10; // choose the pin for the Relay
int inPin =8;   // choose the input pin (for a pushbutton)
int val = 0;     // variable for reading the pin status

void setup() {
  pinMode(RelPin, OUTPUT);  // declare Relay as output
  pinMode(inPin, INPUT);    // declare pushbutton as input
}

void loop(){
  val = digitalRead(inPin);  // read input value
  if (val == HIGH) {         // check if the input is HIGH (button released)
    digitalWrite(RelPin, HIGH);  // turn RELAY ON
  } else {
    digitalWrite(RelPin, LOW);  // turn RELAY OFF
  }
}

This is the code for the timer to on off relay

int RelyPin =  10;      
int RelyState = LOW;             
unsigned long previousMillis = 0;        
long OnTime = 60000;           // milliseconds of on-time
long OffTime = 600000 ;          // milliseconds of off-time

void setup() 
{
  // set the digital pin as output:
pinMode(RelyPin, OUTPUT);    
    
}
 
void loop()
{
 
  unsigned long currentMillis = millis();  
  if((RelyState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    RelyState = LOW;   // turn it Off
    previousMillis = currentMillis;  
    digitalWrite(RelyPin, RelyState);  
  }
  else if ((RelyState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    RelyState = HIGH;  // turn it on
    previousMillis = currentMillis;   
    digitalWrite(RelyPin, RelyState);    
  }

}

I was trying to combine both to one code so the timing loop to relay ON 1 min every hour will run while the button press it interrupt and turn on the relay until the button released .Once release it will go back to the timing loop.

Define a boolean variable, say buttonWasPressed.

Then change

if (buttonState == HIGH) { //If button input High 
  digitalWrite(RelyPin, HIGH); // Relay ON

}

else {
 digitalWrite(RelyPin, LOW);}

to

if (buttonState == HIGH) { //If button input High 
   digitalWrite(RelyPin, HIGH); // Relay ON
   buttonWasPressed = 1;
}

else if(buttonWasPressed && !buttonState) {
   buttonWasPressed = 0;
   digitalWrite(RelyPin, LOW);}

WOW ! Looks like its working fine now . Thank you so much for the help evanmars ! u r a life saver :slight_smile:

The final code is this after i did the changes according to your instructions .

int RelyPin =  10;      
int RelyState = LOW;               
//unsigned long currentMillis = millis(); //current time    
long OnTime = 12000;           // milliseconds of on-time
long OffTime = 60000 ;          // milliseconds of off-time
int buttonpin = 8; // Relay pin 
boolean buttonWasPressed = true;
void setup() 
{
  // set the digital pin as output:
  pinMode(RelyPin, OUTPUT);    
  pinMode(buttonpin, INPUT);  
}
 
void loop()
{
  buttonState = digitalRead(buttonpin); //Button input value

if (buttonState == HIGH) { //If button input High 
   digitalWrite(RelyPin, HIGH); // Relay ON
   
}

else if(buttonWasPressed && !buttonState) {
   buttonWasPressed = 0;
   digitalWrite(RelyPin, LOW);}

 unsigned long currentMillis = millis();  
  if(RelyState == HIGH )
 
    
    digitalWrite(RelyPin, RelyState);  
  }
  else if (RelyState == LOW )
  {
     
    digitalWrite(RelyPin, RelyState);    
  }
  

}

Thanks again for ur time!

You're welcome. Just remember in the future, always post allof your code and use code tags. Makes it much easier to help.

One thing more. Can you edit your original post and add [SOLVED] to the subject line please. Saves myself (and others) from checking back periodically to see how you're progressing.