Onebutton Long press change mode set time and press Once to change time

Hi, im doing my project menu interface ,(ONEBUTTON PIN_3) the first menu is the clock shown below i wanted to change the mode of the clock, if it's short press it will change to second page Menu.When i't is Long press(Change MODE) on clock menu the arrow will pointed at HOURS and one press to pointed at MINUTE Then press one to bck CLOCK then (PIN_2) press one to change value .

(The point is when i (Long Press)change mode Then use same button press once it did't show any thing ) i'm new to this ,learning how to do a menu...
im using (Onebutton.h) ,it did't pointed on Hours when i long press change mode. :thinking:

> Blockquote
#include <Arduino.h>
#include <U8g2lib.h>
#include <OneButton.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

// Variables to store the time
volatile byte hours = 0;
volatile byte minutes = 0;
volatile byte seconds = 0;

// Constants for the button pins
// The FALLING interrupt is only available at pin 2 and 3 on the Arduino UNO 
const int BUTTON_MODE = 3;
const int BUTTON_SET = 2;

OneButton button( BUTTON_MODE , true);

const int BUTTON_MODE_DEBOUNCE_TIME = 250;
const int BUTTON_SET_DEBOUNCE_TIME = 25;

const int MODE_SET_TIMEOUT = 5000;
      
const int MODE_SET_TIME = 0;
const int MODE_SET_MINUTES = 2;
const int MODE_SET_HOURS = 1;

// Button state variables
unsigned long elapsedButtonModeMs = 0;
unsigned long previousButtonModeMs = 0;

unsigned long elapsedButtonSetMs = 0;
unsigned long previousButtonSetMs = 0;

// Char array for the time being showed on the display
char timeString[9];

// Variables to store the time
unsigned long currentMs = 0;

// Int is enough to store the elapsed time
unsigned long elapsedTimeUpdateMs = 0;
unsigned long previousTimeUpdateMs = 0;

float percentageOfSecondElapsed = 0;

byte currentMode = MODE_SET_TIME;

volatile boolean buttonModePressed = false;
volatile boolean buttonSetPressed = false;
bool isLongPressed = false;

// A complete list of all displays is available at: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {

  u8g2.setFont(u8g2_font_logisoso16_tf);
  u8g2.begin();
  
  button.attachLongPressStart(longPressStart);
  button.attachClick(Click);
  
  // Empty the interrupt queue. This makes sure there are 
  // no old pending interrupts in the queue which are processed on startup
  // More info: https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards
  EIFR = bit (INTF0);  // clear flag for interrupt 0
  EIFR = bit (INTF1);  // clear flag for interrupt 1

  digitalWrite(BUTTON_MODE, HIGH);
  digitalWrite(BUTTON_SET, HIGH);

  // Configure the pins of the buttons with the internal PULLUP resistor
  pinMode(BUTTON_MODE, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_MODE), longPressStart, FALLING);

  pinMode(BUTTON_SET, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_SET), setButtonPressedInterrupt, FALLING);

}

void loop(void) {
  // millis() itself takes 1.812 micro seconds that is 0.001812 milli seconds
  // https://arduino.stackexchange.com/questions/113/is-it-possible-to-find-the-time-taken-by-millis
     button.tick();
     Clock();
   
            

}

void Clock (){
  
  currentMs = millis();

  elapsedButtonModeMs = currentMs - previousButtonModeMs;
  elapsedButtonSetMs = currentMs - previousButtonSetMs;

  checkTime();
  button.tick();
  
    if (currentMode == MODE_SET_TIME) {
      increaseSeconds();
      } 
    
  else {
    if (elapsedButtonModeMs > MODE_SET_TIMEOUT && elapsedButtonSetMs > MODE_SET_TIMEOUT) {
      currentMode = MODE_SET_TIME;
      buttonModePressed = false ;  
      }
     previousTimeUpdateMs = currentMs;     
}

  if (buttonModePressed) {
     modeButtonHandler();
     }

  if (buttonSetPressed) {
    buttonSetHandler();
    }
    drawScreen1();
  
  }
  


///----------CheckTime------------
void checkTime() {
  // Check if a minutes has been elapsed
  if (seconds > 59) {
    seconds = 0;
    minutes++;
  }

  // Check if an hour has been elapsed
  if (minutes > 59) {
    minutes = 0;
    hours++;
  }

  // Check if a day has been elapsed
  if (hours > 23) {
    hours = 0;
  }
}

void longPressStart(){
  
         previousButtonModeMs = currentMs;
     if (currentMode==MODE_SET_TIME &&buttonModePressed == false){
         buttonModePressed = true;
         currentMode=1 ; 
     }
     
     else{ 
      if(currentMode == 2){ 
     }
          Click() ;
     }
      previousTimeUpdateMs = currentMs;  
 
}
 
void Click(){
     if(buttonModePressed ==true &&currentMode==1){
        if(elapsedButtonModeMs > BUTTON_MODE_DEBOUNCE_TIME){
           previousButtonModeMs = currentMs;
           currentMode++;
        }
     }
         
      else{
        if(currentMode == 2 ) {
           currentMode = 0;
         } 
       buttonSetPressed = false ;
     }   
}

void setButtonPressedInterrupt() {
  buttonSetPressed = true;
}

void modeButtonHandler() {
      Click();
}

void buttonSetHandler() {
  if (elapsedButtonSetMs > BUTTON_SET_DEBOUNCE_TIME) {
    previousButtonSetMs = currentMs;
    if (currentMode == MODE_SET_MINUTES) {
      minutes++;
    }
    if (currentMode == MODE_SET_HOURS) {
      hours++;
    }
  }
  buttonSetPressed = false;
}

void increaseSeconds() {
  elapsedTimeUpdateMs = currentMs - previousTimeUpdateMs;
  
  // Check if 1000ms, 1 second, has been elapsed
  if (elapsedTimeUpdateMs > 1000) {
    seconds++;
    // It might be possible that more than 1000ms has been elapsed e.g. 1200ms 
    // Then there are already 200ms elapsed of the next second. We need to
    // substract these on the "last time". So the next second will be updated 200ms earlier. 
    // This reduces the amount of time drift.
    previousTimeUpdateMs = currentMs - (elapsedTimeUpdateMs - 1000);
  }
}
///------------------Display---------------
void drawScreen1() {
  
  u8g2.firstPage();

  do {

    if (currentMode != MODE_SET_TIME) {
      u8g2.drawTriangle((currentMode - 1) * 21 + 28, 0, currentMode * 21 - 15, 0, (currentMode - 1) * 21 + 18, 10);
    }
    drawAnimation();
    drawTime();

  } while (u8g2.nextPage());
}

void drawTime() {
  // Found at https://forum.arduino.cc/index.php?topic=371117.0
  // sprintf_P uses the Program Memory instead of RAM, more info at http://gammon.com.au/progmem
  // Here we format the minutes and seconds with a leading zero: e.g. 01, 02, 03 etc.
  sprintf_P(timeString, PSTR("%2d:%02d"), hours, minutes);

  // Draw the timeString
  u8g2.drawStr(5, 30, timeString);
}

void drawAnimation() 
 {
  // Calculate the percentage elapsed of a second
  percentageOfSecondElapsed = elapsedTimeUpdateMs / 1000.0;

  if (currentMode == MODE_SET_TIME) {
    // Draw the yellow lines
    //u8g2.drawBox(5,127 - (127 * percentageOfSecondElapsed) , 2 , 127);
    u8g2.drawBox(2,(127 * percentageOfSecondElapsed) ,2 , 127);
  }
 }

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project :wink: See About the Installation & Troubleshooting category.

ok thkss, my first time post.

I think is the Intterupt problem ..i'll do some researched see...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.