0

I'm trying to change the state of a relay according to the state of a digital input in an Arduino with an ethernet shield. It works sometimes and some other times it doesn't work.

My code:

const int led1 = 2;
const int enable1 = 4;
boolean led1_OnOff;

void setup() {
  led1_OnOff = false;
  pinMode(enable1, INPUT);
  digitalWrite(enable1, LOW);
  pinMode(led1, OUTPUT);
}

void loop() {
  if(digitalRead(enable1) == HIGH) {
    if(led1_OnOff == true) {
      led1_OnOff = false;
    } else {
      led1_OnOff = true;
    }
  }

  if(led1_OnOff == true)
    digitalWrite(led1, HIGH);
  else
    digitalWrite(led1, LOW);
}

My schematics:

Relay 5v -> arduino 5v Relay gnd -> arduino gnd Relay in -> digital pin 2 Relay com -> 220 AC Relay NC -> 220 AC Push button pin 1 -> Arduino 5v Push button pin 2 -> digital pin 4

Pin 2 is connected to the relay enable pin and pin 4 is connected to a push button and the boolean is used for saving the state.

Can anyone tell me what the problem is, and why the relay doesn't work most of the time?

  • Your "My Schematics" is a description, not a schematic. Please make a schematic showing how the Arduino drives your relay. Is it directly connected? How much current does your relay's coil draw? An Arduino pin is only meant to supply 20ma with an absolute maximum of 40ma. It may just not have enough drive. You'll also need a diode to across the coil to quench the inductive kickback when you release the coil, to stop it reaching and destroying the Arduino pin. – JRobert Jan 30 '17 at 19:00
  • Thanks for stopping by...I already answered my question so no need to tell you more about my schematic as it is already right and there is nothing wrong about it...have a good day. – Kareem Essam Gaber Jan 30 '17 at 19:31
0

Assuming your circuit is correct (and perhaps it is, since you imply that it works some of the time), the first obvious problem is that when you press the button, the code will repeatedly toggle the output, very very fast. It may seem to you like you're only pressing the button for a moment, but the code will loop many many times. When you release the button, it's a 50/50 chance whether it leaves the relay on or off.

To solve this, you can wait until the button is released before checking again.

In addition to this, you may have switch bounce. There are nicer ways of fixing this, but for your stated purpose, waiting 0.1s after a releae before checking the button again is probably sufficient.

....
void loop() {
  if(digitalRead(enable1) == HIGH)
  {
    if(led1_OnOff == true)
    {
      led1_OnOff = false;
      //+digitalWrite(led1, LOW);
    }
    else
    {
      led1_OnOff = true;
      //digitalWrite(led1, HIGH);
    }

    // Wait for the button to be released
    while(digitalRead(enable1) == HIGH)
    {
      // do nothing, just wait
    }
    // Poor-man's debounce
    delay(100);
  }

  if(led1_OnOff == true)
    digitalWrite(led1, HIGH);
  else
    digitalWrite(led1, LOW);
}
  • that's a little bit steadier but still doesn't work always – Kareem Essam Gaber Jan 30 '17 at 14:48
  • Perhaps you have switch bounce. Code modified to address that. – Mark Smith Jan 30 '17 at 14:52
  • I tried something else and it works now, but thanks for the help. – Kareem Essam Gaber Jan 30 '17 at 15:11
0

First, how you are set a pin as input and write in this pin?

pinMode(enable1, INPUT);

digitalWrite(enable1, LOW);

You dont need compare a boolean with true

if(digitalRead(enable1) == HIGH)

is the same as:

if(digitalRead(enable1))

use a debbounce with a button state flag to change the button state

if( digitalRead(enable1))
       ena_deb++;
       if(ena_deb > 5){
            change_en_state
       }
}else{
    change_en_state = 0
}

if(change_en_state == X)
    change_output_value;
  • Thanks for your answer...I already figuered out the answer. – Kareem Essam Gaber Jan 30 '17 at 19:32
  • And by the way it's ok to define a pin as input and intialize it at start up...and I already know that trick you said about booleans but it's a programing habit. – Kareem Essam Gaber Jan 30 '17 at 19:35
  • When you define a pin as input you can not intialize it, is physically Impossible. The best way for do a debbounce is use a timer for that. count the debbounce in the timer and set a flag, so you only need read a flag – rodrigo Jan 30 '17 at 19:42
0

I modified my code and added some code for button debounce and added 10k ohm pull down resistor to my hardware and it works like a charm now.

my new code :

const uint8_t led1 = 6;
const uint8_t enable1 = 7;
const uint16_t buttonConfidenceLevel = 500;
boolean led1_OnOff;

uint16_t pressedConfidenceLevel;
uint16_t releasedConfidenceLevel;
boolean pressed;

void setup() {
    led1_OnOff = false;
    pinMode(enable1, INPUT);
    pinMode(led1, OUTPUT);

    pressedConfidenceLevel = 0;
    releasedConfidenceLevel = 0;
    pressed = false;
}

void loop() {
    if(isButtonPressed()) {
        // Button is pressed
        led1_OnOff = !led1_OnOff;

        if(led1_OnOff == true)
          digitalWrite(led1, LOW);
        else
          digitalWrite(led1, HIGH);
    }

}

boolean isButtonPressed() {
    if(digitalRead(enable1) == HIGH) // button is sensed pushed down
    {
        releasedConfidenceLevel = 0;

        if(pressed == false)
        {
            pressedConfidenceLevel++;

            if(pressedConfidenceLevel > buttonConfidenceLevel)
            {
                pressedConfidenceLevel = 0;
                pressed = true;

                // Button is pressed
                return true;
            }
        }
    }
    else // button is sensed released
    {
        pressedConfidenceLevel = 0;

        if(pressed == true)
        {
            releasedConfidenceLevel ++;

            if(releasedConfidenceLevel > buttonConfidenceLevel)
            {
                releasedConfidenceLevel = 0;
                pressed = false;
            }
        }
    }

    return false;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.