[SOLVED] Pushbutton controlling second pushbutton behaviour on Attiny85

Hi all.

My projects include: 2 leds, A and B; 2 pushbuttons: X and Y.

It starts with ledA on and led B off. When you press X it turns off ledA and lits ledB, and if you press X again it turns B off and A on. (mode on/off)

If you press once the Y pushbutton, it will change the way X controls the leds: now when X is pressed A is off and B is on, and when it's released B is off and A is on. (mode hold)

If you press Y again, X will act again as in mode on/off.

I got it working perfectly so far, till I realized I needed a way to tell the user which mode was on without having to try the button.

So I deciced to make ledA blinking while "mode hold" was active.

And here comes the problem: if I use a millis function to blink the led it's going to mess with the timing of "on/off mode" and I have to keep X pressed for 1-2 sec to make ledA and B switch.

I hope I was clear, I'll add some code to show how I handled this project.

LOOP SECTION:

/* LOOP
 ******************************************************************* */
void loop() {

  toggleMode(); //Y pressed
  FSWpressed(); //B pressed
  channelCtrl(); //led control

  digitalWrite(led1, ledState1);
  digitalWrite(led2, ledState2);
 
}

and the 3 functions I've used:

/* Toggle Mode - Pushbutton Y
  ******************************************************************* */

void toggleMode() {
  /* read the state of the switch into a local variable: */
  int reading = digitalRead(toggle);

  /* check to see if you just pressed the button
     (i.e. the input went from LOW to HIGH),  and you've waited
     long enough since the last press to ignore any noise:

     If the switch changed, due to noise or pressing: */
  if (reading != lastToggleState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    /* whatever the reading is at, it's been there for longer
       than the debounce delay, so take it as the actual current state:

       if the button state has changed:*/
    if (reading != toggleState) {
      toggleState = reading;

      // only toggle if the new button state is HIGH
      if (toggleState == HIGH) 

        tempState = !tempState; /* change mode */ //temp state is var that stores current mode

      }
    }
  }
  /* save the reading.  Next time through the loop,
     it'll be the lastButtonState: */
  lastToggleState = reading;
}


/* Channel Switch - Footswitch X
  ******************************************************************* */
void FSWpressed() {
  /* read the state of the switch into a local variable: */
  int reading = digitalRead(Fswitch);

  /* check to see if you just pressed the button
     (i.e. the input went from LOW to HIGH),  and you've waited
     long enough since the last press to ignore any noise:

     If the switch changed, due to noise or pressing:*/
  if (reading != lastSwitchState) {
    // reset the debouncing timer
    lastDebounceTime2 = millis();
  }

  if ((millis() - lastDebounceTime2) > debounceDelay2) {
    /* whatever the reading is at, it's been there for longer
       than the debounce delay, so take it as the actual current state:

       if the button state has changed: */
    if (reading != switchState) {
      switchState = reading;

      /* check for tempState. 0: ON-OFF mode; 1: Temp mode */
      if (tempState == 0) {

        if (switchState == HIGH) {
          channel = !channel; /* change channel ON */ //channel stores which led should be on
          
        }
      }
      if (tempState == 1) {
        if (switchState == HIGH) {
          channel = 1;
        } else {
          channel = 0;
        }
      }
    }
    /* save the reading.  Next time through the loop,
       it'll be the lastButtonState: */
    lastSwitchState = reading;
  }
}

/* Channel Switch - Control leds and relay
  ******************************************************************* */
void channelCtrl() {
if (tempState == ){
  switch (channel) { 
    case 0:
      ledState1 = 1;
      ledState2 = 0;
      break;

    case 1:
      ledState1 = 0;
      ledState2 = 1;
      break;
  }

}

This way it works but if I add the blinking led like this, on/off mode stops working smooth:

void channelCtrl() {
  if (tempState == 0) {
    switch (channel) {
      case 0:
        ledState1 = 1;
        ledState2 = 0;
        relayState = 0;
        break;

      case 1:
        ledState1 = 0;
        ledState2 = 1;
        relayState = 1;
        break;
    }
  }
  if (tempState == 1) {
    switch (channel) {
      case 0:
        ledState2 = 0;
        relayState = 0;
        // ledState1 = 1;
        if (millis() - prevLedOn >= 100) {
          // save the last time you blinked the LED
          prevLedOn = millis();
          ledState1 = !ledState1; //change led state
        }
        break;

      case 1:
        ledState1 = 0;
        ledState2 = 1;
        break;
    }
  }
}

Probably there were more easy ways to have the same results, but this the one who worked smoothest for me.

Posting code like that is most unhelpful also you haven't included the setup and global variable definitions.

The problem can be solved much simpler than that, to flash an LED then at the start of the loop function simply put:-

if(mode) digitalWrite(ledToFlashPin,millis() & 0x200);

Change the 0x200 to any other exact power of two to change the flashing rate, like 0x400, 0x800, 0x1000 and so on.

Grumpy_Mike:
Posting code like that is most unhelpful also you haven't included the setup and global variable definitions.

The problem can be solved much simpler than that, to flash an LED then at the start of the loop function simply put:-

if(mode) digitalWrite(ledToFlashPin,millis() & 0x200);

Change the 0x200 to any other exact power of two to change the flashing rate, like 0x400, 0x800, 0x1000 and so on.

Thanks for your answer!
I've omitted the first part because I didnt want to make an huge post.
I'll edit it asap and meanwhile I'll try your solution!
Thanks again.

---EDIT:

I've changed your line to:

if(mode) digitalWrite(ledToFlashPin,!(millis() & 0x200));

and now it blinks continously in "mode hold" without interfering with the pushbutton!!
Thanks a lot I have never seen that kind if statement!