Go Down

Topic: press+hold with Milli help [SOLVED] (Read 141 times) previous topic - next topic

anishkgt

Jan 11, 2017, 12:15 pm Last Edit: Jan 13, 2017, 12:02 am by anishkgt
I am trying to add a second push button+hold but can't seem to get it rite !


the first press works, second push+hold for 800ms works and when it comes to the third Push+hold for 1500ms actually goes through the second and then starts the third action.

The second pulse(continousWeld) has break command that exists the loop and when existing it starts the third action also.

Here is what i intent to do
first press and release does one action
Press+hold for 800ms starts ContinousWeld
Press+hold for 2000 starts another action.

Code: [Select]
void loop()
{
  while (!zeroCrossingFlag) //As a ZC error detect, Set Ready light ON when zero cross detected else OFF.
  {
    digitalWrite(rdy, LOW);
  }
  digitalWrite(rdy, HIGH);

  // Start debug
  if (OldWeldStepValue != WeldStep())
  {
    WeldStepVal();
    OldWeldStepValue = WeldStep();
  }
  //end debug

  PulseSetLed();
  //myServo.write(SrvStartSet());
  //myServo.write(SrvEndSet());
  btnState = digitalRead(btn);
  if (btnState == LOW && buttonLast == HIGH && (millis() - btnUpTime) > long(debounce)) // Test for button pressed and store the down time
  {
    btnDnTime = millis();
  }
  if (btnState == HIGH && buttonLast == LOW && (millis() - btnDnTime) > long(debounce)) // Test for button release and store the up time
  {
    if (ignoreUp == false) Weld(100, 400);
    else ignoreUp = false;
    btnUpTime = millis();
  }
  if (btnState == LOW && (millis() - btnDnTime) > long(holdTime)) // check hold time
  {
    continousWeld();
    ignoreUp = true;
    btnUpTime = millis();
  }
  if (btnState == LOW && (millis() - btnDnTime) > long(holdTime2)) // Test for button held down for longer than the hold time
  {
    SetWeldHead();
    ignoreUp = false;
    btnDnTime = millis();
  }
  buttonLast = btnState;
  zeroCrossingFlag = false;
}

septillion

#1
Jan 11, 2017, 02:27 pm Last Edit: Jan 12, 2017, 02:19 am by septillion
Please post ALL your code next time. See http://snippets-r-us.com/

Problem is, for the 2000ms long press to work correct you can only check if the 800ms pressed happened WHEN the button is released.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

anishkgt

Yea i did try to post the whole code but it was way to long. Will use the snippets here on.


So how do i check if the 800ms was actually pressed. sorry, am trying to understand this milli() thing. been a little confusing to me.

CrossRoads

Reply, then scroll down and use the Attach button if it's a longer program.

millis() just returns the number of mS since the last reset. Same as you looking at your watch to see how many hours:minutes:seconds since midnight. Note the time, note the time again, if enough time has elapsed do some action, like take the cookies out of the oven.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

septillion

#4
Jan 11, 2017, 02:54 pm Last Edit: Jan 11, 2017, 02:55 pm by septillion
Will use the snippets here on.
No don't! Then the help will stop right here.

Next time, instead of a snippet, make a new simpilied sketch with the same problem. So instead of calling complex other functions like continousWeld(), go back to the basics and just do a Serial.print() like Serial.println("Button held for 800ms")

So how do i check if the 800ms was actually pressed. sorry, am trying to understand this milli() thing. been a little confusing to me.
The problem is not the fact you don't understand millis() ;) It's the problem you don't understand logic and/or switches ;)

You can only determine how low a button was long pressed (was it 800 < time < 2000, or was it time > 2000?)  AFTER you RELEASED the button. While the button is still pressed you can't tell.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

anishkgt

i was trying this bit of the original code
Code: [Select]
const byte servoPin = 5;
const byte btn = 6 ;
const byte bzr = 7;
const byte L8   = 9; // First LED
const byte L1   = A4; // Last LED
const byte ServoPot = A1; // Servo height preset
int SrvPotMap = 0 ;
int SrvPotValue = 0;
const int debounce = 10; // ms debounce period to prevent flickering when pressing or releasing the button
const int holdTime = 800; // ms hold period: how long to wait for press+hold event
const int holdTime2 = 1200;
int i = 0;
int counter1 = 0;
int counter2 = 0;
int btnState = LOW; // value read from button
int buttonLast = HIGH; // buffered value of the button's previous state
long btnDnTime; // time the button was pressed down
long btnUpTime; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered

void setup()
{
  pinMode(L1, OUTPUT);
  pinMode(L8, OUTPUT);
  pinMode(bzr, OUTPUT);
  pinMode(btn, INPUT_PULLUP);
  pinMode(ServoPot, INPUT);
  pinMode(servoPin, OUTPUT);
  btnState = digitalRead(btn);
  Serial.begin(9600);
}

void SetWeldHead()
{
  while (counter2 < 10)
  {
    delay(1000);
    btnState = digitalRead(btn);
    if(btnState == LOW)
    {
      Serial.println("SetWeldHead_BREAK");
      break;
    }
  }
  Serial.println("End Adjust");
  counter2 = 0;
}

void ContinousWeld()
{
  while (counter1 < 6)
  {
    delay(1000);
    btnState = digitalRead(btn);
    if(btnState == LOW)
    {
      Serial.println("Continous Weld_BREAK");
      break;
    }
    delay(500);
    Serial.println("Continous Weld");
    counter1++;
  }
  counter1 = 0;
  Serial.println("End Weld");
}

void loop()
{
  btnState = digitalRead(btn);
  if (btnState == LOW && buttonLast == HIGH && (millis() - btnUpTime) > long(debounce)) // Test for button pressed and store the down time
  {
    btnDnTime = millis();
  }
  if (btnState == HIGH && buttonLast == LOW && (millis() - btnDnTime) > long(debounce)) // Test for button release and store the up time
  {
    if (ignoreUp == false) Serial.println("Single Weld");
    else ignoreUp = false;
    btnUpTime = millis();
  }
  if (btnState == LOW && (millis() - btnDnTime) > long(holdTime)) // Test for button held down for longer than the hold time
  {
    ContinousWeld();
    ignoreUp = true;
    btnDnTime = millis();
  }
  if (btnState == LOW && (millis() - btnDnTime) > long(holdTime2)) // Test for button held down for longer than the hold time
  {
    SetWeldHead();
    //delay(500);
    ignoreUp = true;
    btnDnTime = millis();
  }
  buttonLast = btnState;
}
The third action does not seem to be working here.

cattledog

Quote
Here is what i intent to do
first press and release does one action
Press+hold for 800ms starts ContinousWeld
Press+hold for 2000 starts another action.
As septillion says, you need to determine the press duration before knowing it to short/long/longer

Here's some button code which does that, but puts a timeout on the longer press.
Code: [Select]

#define noEvent     0
#define shortPress 1
#define longPress  2
#define longerPress 3

#define buttonPin 5
#define shortTime 800 //if equal longTime there is no unrecorded press
#define longTime 800
#define longerTime 2000

unsigned long buttonPressStartTimeStamp;
unsigned long buttonPressDuration;

boolean startTimeout = false;

byte previousButtonState = HIGH;
byte buttonState = HIGH;

void setup() {

  Serial.begin(115200);
  Serial.println("Long/Short Button Press");

  // Setup the button with an internal pull-up
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {

  switch (checkButton())
  {
    case shortPress:
      Serial.println("short press");
      //do short press code
      break;

    case longPress:
      Serial.println("long press");
      //do long press code
      break;

    case longerPress:
      Serial.println("longer press");
      //do longer press code
      break;
  }
}

byte checkButton()
{
  byte event = noEvent;
  buttonState = digitalRead(buttonPin);

  //button pressed
  if (buttonState == LOW && previousButtonState == HIGH)
  {
    delay(20);//blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == LOW && previousButtonState == HIGH)
    {
      buttonPressStartTimeStamp = millis();
      startTimeout = true;
    }
  }

  //button released
  if (buttonState == HIGH && previousButtonState == LOW)
  {
    delay(20);//blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == HIGH && previousButtonState == LOW)
    {
      buttonPressDuration = (millis() - buttonPressStartTimeStamp);
      startTimeout = false;//duration determined no timeout required
    }
  }

  if (buttonPressDuration > 0 && buttonPressDuration <= shortTime)
  {
    event = shortPress;
    buttonPressDuration = 0;
  }

  if (buttonPressDuration > longTime && buttonPressDuration <= longerTime)
  {
    event = longPress;
    buttonPressDuration = 0;
  }

  //button not released and still timing
  if (buttonState == LOW && startTimeout == true && (millis() - buttonPressStartTimeStamp) > longerTime)
  {
    event = longerPress;
    startTimeout = false;
    buttonPressDuration = 0;
  }

  previousButtonState = buttonState;
  return event;
}

anishkgt

Thanks CattleDog, but the short press does not seem to be working. I wish to have the event happen while the button is pressed and not released when it reaches the predefined time. Just like in my previous post. here the event happens only after release the button.

septillion

Instead of trying different pieces of code like mad, try to understand why it doesn't work.

You check to see if it's a long press(800<time<2000) or a longlong press (time>2000) while the button is still being pressed. But if the button now is checked, and press time is 900, how will it know the difference between you keeping the button pressed for another 3 seconds of you releasing it 1ms later. It can't look into the future.

Aka, you can only tell which of the two it was AFTER the button is released.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

anishkgt

cattleDog's code worked. just clearing a doubt
Code: [Select]
int const shortTime = 800; //if equal longTime there is no unrecorded press

what does the comment mean and is it necessary that the short time and longerTime be same ?

cattledog

Quote
what does the comment mean and is it necessary that the short time and longerTime be same ?
No, they do not have to be the same. If,  for example the duration of a short press is <300ms, and the duration of a long press is between 800ms and 1500ms then any press with a duration between 300 and 800 will not register as either.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy