Go Down

Topic: Momentary switch with latching code (Read 20 times) previous topic - next topic

krk5

Hello,

I've been doing simple things with the arduino but I'm having a few problems some code for a momentary switch and I'm not sure how to "latch" the code so it doesn't continue switching a relay when the switch is held.

Here is what I'm trying to achieve:

When the momentary switch is pressed, I need the LED to light (uno led on pin 13) and the relay to switch.  When pressed again the LED should turn off and the relay switch back.  I'm using a dual latching relay that has a current pulse requirement of around 20mA @5V.  WIth the code I posted below the relay is switching via a short pulse on a high and low pin and the led is lighting.  The problem is that the LED and relay continue to change status when the switch is held.  I need it to stop switching and retain the status if the switch is held by accident.  Right now it will flip a few times on one short push.  It's also slightly erratic, sometimes it doesn't register the switch.  Also, I'm using an external pull up resistor, not the uno's internal pull up.

Thanks for any assistance!

Code: [Select]
/*
Alternating LED and relay switching
*/

#include <Bounce.h>

const int inputPin = 2;      // momentary switch
const int ledPin =  13;      // the number of the LED pin
const int relayPin1 =  12;   // relay +
const int relayPin2 = 11;    // relay -

int ledState = LOW;           // the current state of the output pin
int lastbuttonState = LOW;   // the previous reading from switch

Bounce bouncer = Bounce(inputPin,75);   //setting up debounce for the push button

void setup()
{
  pinMode(inputPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
}

void loop() {

  bouncer.update ( );    // Update the debouncer for the push button

  int value = bouncer.read();     // Get the update value

  int reading = value == HIGH;

  if (lastbuttonState == LOW && reading == HIGH)
  {
    digitalWrite (ledPin, HIGH);
    digitalWrite (relayPin2, LOW);
    digitalWrite (relayPin1, HIGH);
    delay (100);
    digitalWrite (relayPin1, LOW);
  }
bouncer.update ( );    // Update the debouncer for the push button

int val = bouncer.read();     // Get the update value

  int read = val == HIGH;
 
if (lastbuttonState == LOW && read == HIGH)
  {
    digitalWrite (ledPin, LOW);
    digitalWrite (relayPin1, LOW);
    digitalWrite (relayPin2, HIGH);
    delay (100);
    digitalWrite (relayPin1, LOW);
  }
}

astrofrostbyte

#1
Mar 02, 2013, 08:32 pm Last Edit: Mar 02, 2013, 08:36 pm by astrofrostbyte Reason: 1
I Haven't read the full code but the following pops out:


  • The following line is bit strange:     int reading = value == HIGH;

  • in the second block i see two times in a row : digitalWrite (relayPin1, LOW);

  • When is 'lastbuttonState' made high in the code

Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

krk5

Thanks, it should have been     digitalWrite(relayPin2, LOW)  but it's still acting the same.

The switch sometimes switches the led and relay and sometimes it does not.  I don't know if it's the way I have the debounce code/library written or not.  But if I hold the switch it cycles the relay and LED.  I need it to "latch"

Without     int reading = value == HIGH;  the code does not work

Here is the updated code

Code: [Select]
/*
Alternating LED's
*/

#include <Bounce.h>

const int inputPin = 2;    // momentary switch
const int ledPin =  13;      // the number of the LED pin
const int relayPin1 =  12;
const int relayPin2 = 11;

int ledState = LOW;           // the current state of the output pin
int lastbuttonState = LOW;   // the previous reading from first push button pin

Bounce bouncer = Bounce(inputPin,75);   //setting up debounce for the first push button

void setup()
{
  pinMode(inputPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
}

void loop() {

  bouncer.update ( );    // Update the debouncer for the push button

  int value = bouncer.read();     // Get the update value

  int reading = value == HIGH;

  if (lastbuttonState == LOW && reading == HIGH)
  {
    digitalWrite (ledPin, HIGH);
    digitalWrite (relayPin2, LOW);
    digitalWrite (relayPin1, HIGH);
    delay (500);
    digitalWrite (relayPin1, LOW);
  }
bouncer.update ( );    // Update the debouncer for the push button

int val = bouncer.read();     // Get the update value

  int read = val == HIGH;
 
if (lastbuttonState == LOW && read == HIGH)
  {
    digitalWrite (ledPin, LOW);
    digitalWrite (relayPin1, LOW);
    digitalWrite (relayPin2, HIGH);
    delay (500);
    digitalWrite (relayPin2, LOW);
  }
}



astrofrostbyte

#3
Mar 02, 2013, 09:36 pm Last Edit: Mar 02, 2013, 09:39 pm by astrofrostbyte Reason: 1
See if you can follow the following,  it has a statemachine (switch-case) that 'walks' through the stages of how the system should behave.
Its a common way to code these types of things

State/Case 0:  the system is OFF and in rest, we are waiting for someone to push a button.  
                     If someone pushes button we switch on Relay and led and go to the next state
State/case 1:  here we wait untill the button is released
                     if button is released we go to the next state.
State/case 2:  here the system is ON and we are in rest,  we are waiting for someone to push button

...etc....

Code: [Select]

/*  Alternating LED's  */
#include <Bounce.h>

const int inputPin = 2;    // momentary switch
const int ledPin =  13;      // the number of the LED pin
const int relayPin1 =  12;
const int relayPin2 = 11;

byte mode = 0;

Bounce bouncer = Bounce(inputPin,75);   //settup debounce for first push button

void setup()
{ pinMode(inputPin, INPUT);
 pinMode(ledPin, OUTPUT);
 pinMode(relayPin1, OUTPUT);
 pinMode(relayPin2, OUTPUT);
}

void loop() {
 bouncer.update ( );    // Update the debouncer for the push button
 switch( mode )
 {
   case 0://------------------------ I'm off and in restmode
     if ( bouncer.read() == HIGH )
     { // switch relay ON
       // switch LED ON
       mode = 1;
     }
     break;
   case 1://------------------------ I'm in ON mode, w8 4 keyrelease
     if ( bouncer.read() == LOW )
       mode = 2;
     break;
   case 2://------------------------ I'm ON and in restmode
     if ( bouncer.read() == HIGH )
     { // switch relay OFF
       // switch LED OFF
       mode = 3;
     }
     break;
   case 3://------------------------ I'm in OFF mode, w8 4 keyrelease
     if ( bouncer.read() == LOW )
       mode = 0;
     break;
 }//switch


}//loop


Code is untested and the case gives you the framework, still need to fill in the Relay ON/OFF and LED On/OFF
Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

krk5

Thanks so much for the help.  I'll plug in the missing pieces and try it out!

:)

Go Up