Is this a possible application?

Hi, I was referred here from and was told this microcontroller could be what Im looking for. What Im looking to do is by using a standard spst normally open mom switch is as so

from OFF

STEP 1) press and release switch and pin x goes hi

STEP 2) press and release switch a second time and pin x stays hi and pin y goes hi

STEP 3) press and HOLD switch third time pin x goes lo, pin y stays hi and pin z goes hi

STEP 4) release switch pin x goes hi, pin y stays hi and pin z goes lo

STEP 5) press and release switch and all pins go lo

then start over


press and hold switch for 2 seconds from off and program starts at STEP 3 and goes to STEP 4 then STEP 5

I also need to be able to debounce the switch used

I must explain that I have very little experience with programming language but I do understand the hardware side of things. I asked in the other forum for something fairly user friendly for someone that doesnt understand programming and I was referred here. Im only looking to do this one thing with a microcontroller. Ive looked through the tutorials and other than one about debouncing a switch I didnt see anything I thought would help me with my particular application. If anyone can help me with this Id appreciate it, thanks

That should be a pretty straight forward task to perform. A 'state machine' is probably the best model to utilize. Each transistion of the input switch, both low to high and high to low would increment a state counter variable. On reading your detailed sequence there seems to be 8 states including the off state (0-7 states). A case statement would decide which outputs to turn on or off depending on which state the counter has moved to. Step 1 would also need to start a timer to jump to step 3 if 2 seconds has elapsed without moving to step 1. That make sense?


Although a state machine would certainly work, there are other approaches that will also work. Your application is similar to something I am working on so here are some ideas that may be of help.

You could use a routine that returns how long a switch is pressed to drive your logic as well as debounce the switch. swPressed() is a function that returns the duration in milliseconds that a switch has been pressed. It returns 0 if a switch is not pressed for at least the debounce period.

I have outlined some code that uses this function to implement logic similar to your application. I hope its of some help.

 #define swPin 2  // the switch pin to monitor

#define DEBOUNCE_TIME  40 // switch must be pressed at least this number of ms
#define NO_SWITCH  255  

void loop(){
  unsigned int dur,prevDur;

  dur = prevDur = swPressed(swPin);
  if(dur > 0){
    // here if switch pressed for the first time
      if(dur >= prevDur){     
        // still wating for first release
        prevDur = dur;
        dur = swPressed(swPin); // update duration so we can tell if its been held for over 2000ms         
      else{  // switch released 
        if(prevDur < 2000){
          // only do steps 1 and 2 if switch held less than 2000ms    
          // do step 1
          while(swPressed(swPin) == 0) ; // wait for switch to be pressed
          while(swPressed(swPin) != 0) ; // wait for switch to be released
          // do step 2        
        while(swPressed(swPin) == 0) ; // wait for switch to be pressed
        // do step 3
        while(swPressed(swPin) != 0) ; // wait for switch to be released
        while(swPressed(swPin) == 0) ; // wait for switch to be pressed
        while(swPressed(swPin) != 0) ; // wait for switch to be released
        // do step 4
        while(swPressed(swPin) == 0) ; // wait for switch to be pressed 
        while(swPressed(swPin) != 0) ; // wait for switch to be released
        // do step 5   
unsigned int swPressed(byte sw){
  // returns duration button pressed in ms, returns 0 if not pressed for DEBOUNCE period 
  // this logic only supports one button pressed at a time
  static byte prevswitch = NO_SWITCH;
  static unsigned long startTime;
  unsigned int dur;

  dur = 0;
  if(digitalRead(sw) == LOW){
    if(sw != prevswitch ){  
      startTime = millis();
      prevswitch = sw;     
      if(digitalRead(sw) == LOW)
        dur = DEBOUNCE_TIME;
    else if (sw == prevswitch ){
      Serial.println(millis() - startTime);
      if( millis() - startTime > 60000)
        dur = 60000; // this prevents overflowing return value
        dur = millis() - startTime;     
        if( dur < DEBOUNCE_TIME)
          dur = 0;  // return 0 if duration less than debounce time
  else if (sw == prevswitch ){  // was previous switch released?  
    prevswitch = NO_SWITCH;  // yes, so clear switch indicator
  return dur;