Code works on a Micro, but not ATTiny85

I have created the following rather simple code to toggle an LED driver.
The serial commands are commented out on the ATTiny85 portion as there is not a serial output.
I can trigger all three options with serial feedback that is correct on the Micro, but on the Tiny85 I only get the flash routine, the long press never seems to trigger in order to latch the LED enable line on or off. This DOES work on the micro via the serial feedback.



static const int buttonPin = 3;                     // switch pin
static const int LED_Pin = 4;                                  // LED output Enable Pin
int buttonStatePrevious = LOW;                      // previousstate of the switch



unsigned long minButtonLongPressDuration = 1000;    // Time we wait before we see the press as a long press
unsigned long buttonLongPressMillis;                // Time in ms when we the button was pressed
bool buttonStateLongPress = false;                  // True if it is a long press
bool LEDState = false;
const int intervalButton = 50;                      // Time between two readings of the button state
unsigned long previousButtonMillis;                 // Timestamp of the latest reading

unsigned long buttonPressDuration;                  // Time the button is pressed in ms

//// GENERAL ////

unsigned long currentMillis;          // Variabele to store the number of milleseconds since the Arduino has started

void setup() {
//Serial.begin(9600);               // Initialise the serial monitor

  pinMode(buttonPin, INPUT);          // set buttonPin as input
  pinMode (LED_Pin, OUTPUT);          //set LED pin as output

//  Serial.println("Press button");

}

      
// Function for reading the button state
void readButtonState() {

  // If the difference in time between the previous reading is larger than intervalButton
  if(currentMillis - previousButtonMillis > intervalButton) {
    
    // Read the digital value of the button (LOW/HIGH)
    int buttonState = digitalRead(buttonPin);    

    // If the button has been pushed AND
    // If the button wasn't pressed before AND
    // IF there was not already a measurement running to determine how long the button has been pressed
    if (buttonState == LOW && buttonStatePrevious == HIGH && !buttonStateLongPress) {
      buttonLongPressMillis = currentMillis;
      buttonStatePrevious = LOW;
//      Serial.println("Button pressed");
      
    }

    // Calculate how long the button has been pressed
    buttonPressDuration = currentMillis - buttonLongPressMillis;

    // If the button is pressed AND
    // If there is no measurement running to determine how long the button is pressed AND
    // If the time the button has been pressed is larger or equal to the time needed for a long press
    if (buttonState == LOW && !buttonStateLongPress && buttonPressDuration >= minButtonLongPressDuration) {
      buttonStateLongPress = true;
//      Serial.println("Button long pressed");
      
      
      //led on code
 
            
//      Serial.println(LEDState);
      if (LEDState == HIGH){
//        Serial.println("LED ON");
          digitalWrite(LED_Pin, HIGH);
      } else {
//        Serial.println("LED OFF");
          digitalWrite(LED_Pin, LOW);
      }
           LEDState = !LEDState;
//           Serial.println(LEDState);
    }
      
    // If the button is released AND
    // If the button was pressed before
    if (buttonState == HIGH && buttonStatePrevious == LOW) {
      buttonStatePrevious = HIGH;
      buttonStateLongPress = false;

      digitalWrite (LED_Pin, HIGH);
      delay(100);
      digitalWrite (LED_Pin, LOW);
//      Serial.println("flash");
      }
    
    
    // store the current timestamp in previousButtonMillis
    previousButtonMillis = currentMillis;

  }

}

void loop() {

  currentMillis = millis();    // store the current time
  readButtonState();           // read the button state
  
}

I have the following options selected for the ATTiny85 in my IDE via the ATTiny Core board profile,
![image|483x189](upload://vC5sxPV9OFwAsPWX3hQeR58gm5V.png)


My IDE tools for the ATTiny85 are as follows
ATTiny Core
ATTiny85 chip selected
Clock Source 8MHz internal
Timer 1 Clock: CPU Frequency
LTO Disabled
Millis() Enabled
Save EEPROM: EEPROM retained
BOD; Disabled
Programmer: USBTinyISP

And what are the three options, exactly?

I modified the code from a previous post of mine to remove the blinking LED and added the on-off logic.

/*  Pushbutton Example with On/Off with soft off
    by @Perehama
*/

class IntervalTimer {
  public:
    IntervalTimer(unsigned long i);
    void synchronizeTimer();
    bool intervalComplete();
    void setInterval(unsigned long i);
    unsigned long elapsedTime();
  private:
    unsigned long _interval;
    unsigned long _timestamp;
};

class PushButton {
  public:
    PushButton(int pinNumber, unsigned long debounceTime);
    void inputPullup() const;
    bool isPushed();
    unsigned long durationHeld();
    void setDebounce(unsigned long i);
  private:
    IntervalTimer _timer;
    int _preState = HIGH;
    unsigned char _debounceFlag = 0;
    const int _ButtonPin;
    const static int _RisingEdge = HIGH - LOW;
    const static int _FallingEdge = LOW - HIGH;
};

IntervalTimer::IntervalTimer(const unsigned long i) : _interval(i) {}

void IntervalTimer::synchronizeTimer() {
  _timestamp = millis();
}
bool IntervalTimer::intervalComplete() {
  if (millis() - _timestamp >= _interval) {
    _timestamp += _interval;
    return true;
  }
  return false;
}

void IntervalTimer::setInterval(unsigned long i) {
  _interval = i;
}

unsigned long IntervalTimer::elapsedTime() {
  unsigned long x = millis() - _timestamp;
  return x;
}

PushButton::PushButton(int pinNumber, unsigned long debounceTime) : _timer(debounceTime), _ButtonPin(pinNumber) { }

void PushButton::inputPullup() const {
  pinMode(_ButtonPin, INPUT_PULLUP);
}

bool PushButton::isPushed() {
  bool b = false;
  if (_debounceFlag == 1) {
    if (_timer.intervalComplete()) _debounceFlag = 0;
  }
  else {
    int sample = digitalRead(_ButtonPin);
    int state = sample - _preState;
    if (state == _FallingEdge) {
      _timer.synchronizeTimer();
      b = true;
      _debounceFlag = 1;
    }
    else if (state == _RisingEdge) {
      _timer.synchronizeTimer();
      _debounceFlag = 1;
    }
    _preState = sample;
  }
  return b;
}

unsigned long PushButton::durationHeld() {
  unsigned long u = 0;
  if (_preState == LOW) {
    u = _timer.elapsedTime();
    if (u == 0) u = 1;
  }
  return u;
}

void PushButton::setDebounce(unsigned long i) {
  _timer.setInterval(i);
}

static const int buttonPin = 3;  // switch pin
static const int LED_Pin = 4;  // LED output Enable Pin
const unsigned long MinButtonLongPressDuration = 1000UL;  // Time we wait before we see the press as a long press
unsigned char onOffFlag;

PushButton Button(buttonPin, 50UL);

void setup() {
  Button.inputPullup();
  pinMode(LED_Pin, OUTPUT);
}

void loop() {
  if (Button.isPushed()) onOffFlag ^= 1;
  if (Button.durationHeld() >= MinButtonLongPressDuration) onOffFlag = 0;
  (onOffFlag > 0) ? digitalWrite(LED_Pin, HIGH) : digitalWrite(LED_Pin, LOW);
}

The flash, when briefly pressed, or latched on/ off when held

I don't see that behaviour when the sketch is programmed into an Uno or into an ATtiny85. I see a flash when the button is released, and (occasionally) the LED staying on for the duration of a long press. But the latter is not consistent on either.

The intent of the sketch is a multi function response from a single button with external pullup. A brief press should result in a 50ms activation of the led enable.
A long press of the button should toggle the led enable on or off until anoter long press is encountered

That may be the intent, but I'm not seeing that behaviour on either an Uno or ATtiny85.

If the serial lines are uncommented, it responds properly on my micro. But it doesn't work on the tiny, only the flash bit. That's what I'm asking. I know it doesn't work, why does it not work m

I'll give this a try, thanks!

One button isn't going to be able to tell the difference between a long press and a momentary press, so it will trip the briefly (50ms) state while waiting for the long press.

EDIT: Code Corrected. See Below...

I am saying that I don't see it working anywhere. Not on an Uno, not on an ATtiny85. And it makes no difference on the Uno whether the Serial lines are commented or not. It doesn't work.

I can handle that, it's for a flashlight. I need both a flash and latch on/off..
As I said, by the serial feedback responses, I am getting to the appropriate locations in the code. Since the tiny doesn't have serial, I comment those serial print lines, and only get the flash.

Try my second code.... and behavior... it should teach you a lot, if you are learning to code... You declare some stuff as const when it's already global and assign a 0 value (LOW is also 0) when again it's a global. This shows some broken fluency with the language. Also, you declare your 50 ms constant as an int, but likely use it as a unsigned long. I don't know what "works/doesn't" looks like in either case, so you will have to explain exactly the behaviour of the non-working code. "working" is only relevant to explain how the functionality breaks from one chip to the next. If it doesn't compile, for example, that's not the same as not working (or it is, depending on your definition).

Ok, I think I figured this out, the flash routine is running after the latch part. so I need to jump out of the function at the end of the latch so the flash doesn't run

this is the console output when using the micro:

Button pressed
flash
Button pressed
Button long pressed
LED OFF
1
flash

console output is not the same as LED ON/OFF

If you are using an Arduino Uno, swap the pin number to LED_BUILTIN.

This will give you are more accurate picture from one to the other.

I am using a Pro Micro for the serial to debug. The actual target is an ATTiny 85. I do not have an UNO

ok, your code is forever evaluating the on/off routine in the loop portion, even though the button is inactive high via pullup

That's correct. This is a polling method.