State code for two functions on on switch

Trying to make a simple code so on a simple push a relay is activated but if button held then the second relay is held for as long as the button is held keeping first relay activated until another press of the button.

#include <SM.h>

const int Switch = 3;
const int ARelay = 9;
const int BRelay = 8;

SM btnCtrl(Waiting);

void setup(){
  Serial.begin(115200);
  pinMode(ARelay, OUTPUT);
  pinMode(BRelay, OUTPUT);
}//setup()

void loop(){
  EXEC(btnCtrl);
}//loop()

State Waiting(){
  if(digitalRead(Switch)) btnCtrl.Set(Pressed);
  {digitalWrite(BRelay, 0); digitalWrite(ARelay,0);}
}//Waiting()

State Pressed(){
  digitalWrite(ARelay, 1);
  if(btnCtrl.Timeout(200)) btnCtrl.Set(Holding);
  if(!digitalRead(Switch)) btnCtrl.Set(Waiting);
}//Pressed()

State Holding(){
  {digitalWrite(ARelay, 1); digitalWrite(BRelay, 1);}
  if(!digitalRead(Switch)) btnCtrl.Set(Pressed);
}//Holding()

This is what ive started with?

Do i need to do a case for the first button push to see if relay is being held? Just beginning and sort of understand bits but more i try to read up the more i doubt what i know.

First thing I would need to know is what is the "SM" library? I guess it is State Machine library, but where from?

It's not very clear from your description. The way I do state machines is first list the events for each state, and what actions and state transitions to perform. If there is a situation where it needs to "remember" a previous event then add a new state.

It also helps a lot to draw a diagram.

But, I think you would benefit from a new state "relay on".

1 Like

when the button is pressed, capture a timestamp and start a timer.

if the button is released before the timer expires, stop the timer.

if the timer expires, recognize that the button is being held.

there are 4 possible events

  1. button initially pressed
  2. button released before timer expires
  3. timer expires
  4. button release after timer expires

decide what to do for each possible event. sounds like

  1. energize 1st relay
  2. do nothing
  3. energize 2nd relay
  4. de-energize 2nd relay
2 Likes

GitHub - e-Gizmo/SM: for e-Bot (Mobile Robot) State Machine library to arduino 1.0.6 and below is the state library that i have been testing with

Still not sure of the required sequence, is it :

Scenario #1

Button press -> relay 1 on
Button held -> both relays on
Button release -> both relays off ??

then repeats.

Or

Scenario #2

Button press -> relay 1 on
Button held -> both relays on
Button release -> relay(s) stay on

Button press -> both relays off?

Scenario 3

Button press -> relay 1 on
Button held -> both relays on
Button release -> relay 2 off

another Button press -> relay 1 off

Does holding down the press that turns off relay 1 turn on relay 2 until the button is released?

FWIW I do not know this state machine library but this is a case where I would switch to just learning how to make a state machine using simple C code.

See

and/or google

arduino state machine

Reading a variety of approaches will be beneficial. And time better spent than aligning your thinking with what one person thought best and wrote a library to do

a7

1 Like

Button Press relayA on
Button hold relayA&B on
Button release keep A on until button pressed again

look this over

const byte PinRlys [] = { 12, 11 };
const int  Nrly       = sizeof(PinRlys);

enum { RlyOff = HIGH, RlyOn = LOW };

const byte PinBut = A1;
byte       butState;

// -----------------------------------------------------------------------------
void
loop (void)
{
    byte but = digitalRead (PinBut);
    if (butState != but)  {
        butState = but;
        delay (10);     // debounce

        if (LOW == but)  {
            digitalWrite (PinRlys [0], !  digitalRead (PinRlys [0]));
            digitalWrite (PinRlys [1], RlyOn);
        }
        else
            digitalWrite (PinRlys [1], RlyOff);
    }
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin (9600);

    pinMode  (PinBut, INPUT_PULLUP);
    butState = digitalRead (PinBut);

    for (int n = 0; n < Nrly; n++)  {
        Serial.println (n);
        pinMode      (PinRlys [n], OUTPUT);
        digitalWrite (PinRlys [n], RlyOff);
    }
}

I'm still not clear on the second and subsequent button press... is it

First Button Press relayA on
First Button hold relayA&B on
First Button release relay B OFF if was on

Second button press turn relay A OFF
Second button press hold??
Second button release (does nothing)

Next button press - repeat from first?

Since eveyone else is still trying to figure out what the OP actually wants, you might spend a few of your limited life time supply of words to say what your code does, or which if any of the suggested scenarios it might be coded to.

Or is this just another thing to consider and mine for how to do things in the way you like?

a7

...

Right so not explained anything well here i want a momentary press of the button to turn relay a on (and stay on) and a hold to turn on relay b also a on while held ( b off on release only on for hold) and for a to stay on until another momentary press of the button.

You'll have to define momentary versus held if you don't want relay 2 to energize always you press the button, however briefly.

And say whether when the button action turns off relay 1 whether that action, momenetary or held, should energize relay 2.

@gcjr's sketch makes relay 2 follow the button, no matter what it is doing to relay 1.

a7

how often is it easier to post code and ask, "is this what you want"

Almost never. Isn't part of learning how to accomplish anything with computers figuring out how to tell other ppl what the desired functionality might be?

Something like this allowing for multiple interpretations only gets worse as the number of ambiguously described features increases.

Life is too short to take the approach of throwing stuff at the wall to see what sticks.

a7

1 Like

What should happen to relayB?

The description is incomplete.

Look at it from the other direction and list all the different behaviors (states) first, then consider how you change between them (button events, timing?)

States:
Aoff Boff
Aon Boff
Aon Bon
Aoff Bon?

Transitions?

(I find it easiest to draw a diagram instead of spelling it out)

From what you’ve written I have a question: If you do several long presses, does A turn on and stay on continuously, while B turns on and off as the button is long-pressed?

does this need a state machine?

Judging by your code, which is hard to follow, and also does not do what the OP wanted, I would say yes.

Your code will still have states, even if you don't use a formal state machine.

1 Like