Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: ISR / Millis or alternative

  1. #1

    ISR / Millis or alternative

    Hi Guys,

    I'm trying to figure out which method might be the best, or the most effective, and how I might go about this.

    I'm going to build a little test circuit involving a button and an encoder. My goal is to be able to hold down the button (indefinitely) whilst increasing or decreasing the encoder's value. Upon release of the button, the value of the encoder would then be stored to the variable of the button.

    I'm wondering how I would achieve something like this? Would an ISR be suitable, or perhaps the millis function or a while loop.

    Any guidance would be great here

    Thanks
    M

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,929
    Does anything else need to happen while the button is pushed to change the value? Updating a display or any other processing

  3. #3
    At this stage, it would just be assigning the midi note value for the button held with the encoder. I'm just trying to conceptulise the best practice for such a function.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,929
    I suppose the td_libs_Bounce.html is the standard answer. If you keep looping without delays you can catch changes and when held down pick a time interval to change the value by some amount. When released stop doing that. You can update the midi note in loop or just after the button is released. Use an elapsedMillis variable to set to zero when pressed and when 100 or 1000 as desired change the value and set that back to zero and repeat until released. Repeat for multiple buttons if there is an up and down.

  5. #5
    Ok, thanks for that.

    Currently I would be using the button in a midi step sequencer configuration. So I press the step button to toggle it on, and then if I press it again, it toggles the step off.

    How would I allow the ability to hold and edit the steps value with the encoder? As if when I press and hold, it would toggle the step off instead of allowing me to press and hold to edit.

  6. #6
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,385
    just a thought, have you tried teensythreads?

    drop your encoder in one thread, leave all your other stuff in loop(), and set your timeslices to 1ms

  7. #7
    Just had a look at your suggestion, Teensythreads. Not exactly sure how that would help

  8. #8
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    Similar approach of what defragster said, but step value is only set upon release. See comments for what happens where:
    Code:
    #include <Bounce.h>
    
    const int buttonPin = 1;
    Bounce button = Bounce(buttonPin, 10);
    bool down;
    elapsedMillis startMillis;
    
    void setup() {
      pinMode(buttonPin, INPUT_PULLUP);
    }
    
    void loop() {
      if (button.update()) {
        if (button.fallingEdge()) {
          startMillis = 0;
          //handle your step_on logic here
          down = true;
        } else if (button.risingEdge()) {
           if (startMillis < 1000) {
            //handle your step_off logic here
          } else {
            //handle your set_midi_value here
          }
          down = false;
        }
      } else if(down) {
        //handle your encoder logic here
      }
    }

  9. #9
    Thanks, I'm trying not to use pre-existing libraries to help me better understanding the logic behind it all.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,929
    Cool, post what you try.

    The bounce page indicates the trouble reading a button opening or closing... I.e. Chatter or bounce of multiple transitions in the short term. Detecting a short or long press will need attention

  11. #11
    Ok, this is what I have so far (which unfortunately doesn't work as first thought)

    Code:
    int buttonPin = 14;
    boolean holdState = false;
    
    int stepState = 0;
    
    uint64_t currentMillis = 0;
    uint8_t buttonState = 0;
    uint8_t buttonLastState = 0;
    
    void setup() {
      Serial.begin(9600);
    
      pinMode(buttonPin, INPUT);
    
    }
    
    void loop() {
      int reading = digitalRead(buttonPin);
    
      if (reading != buttonLastState)
        currentMillis = millis();
      if ((millis() - currentMillis) > 25) { //SHORT PRESS
        if (reading != buttonState) {
          buttonState = reading;
          if (stepState == 0) {
            if (buttonState == HIGH) {      //RISING EDGE
              stepState = 1;
              Serial.println(stepState);
    
            }
          } else if (stepState == 1) {
            if (buttonState == LOW) {        //FALLING EDGE
              stepState = 0;
              Serial.println(stepState);
            }
          } else if (buttonState == HIGH) {
            if ((millis() - currentMillis) > 500) {
              if (holdState == false) {
                holdState = true;
                currentMillis = millis();
                Serial.println("B");
              }
            }
          }
        }
      }
      buttonLastState = reading;
    }
    The logic:
    stepState - toggle the step on or off.

    On the rising edge (HIGH) I want to turn on the step (1), and then the button is released. On the falling edge (LOW) I then want to turn off the step (0). Assuming turning off the step on the falling edge would allow me to go into a timed state if stepState = 1.

    Pressing and holding the button in stepState (1) , which would allow me to then use the encoder to select the value. Upon released, the stepState still remains active, until I press it again and it turns off on the falling edge.

    Hope that makes more sense of what I'm trying achieve.
    Last edited by mtiger; 01-11-2018 at 03:37 AM.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,929
    Your first posts seem clear in what you wanted - I think I could write it. Notes above say that is tricky with the way closing switches typically cycle the pin state on and off multiple times on for each intended change in state for some short time.

    Post #4 links to Bounce - it shows a test program before showing bounce use. Working with that will show the behavior to work with and around that will be aggravating the code in post #11.

    Even with Bounce it will take some clear stepping through states based on time and chosen action. Without Bounce handling the initial layer of pin noise that needs to be addressed first.

  13. #13
    Ok I'll work further on it, thanks for your help though

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,929
    Quote Originally Posted by mtiger View Post
    Thanks, I'm trying not to use pre-existing libraries to help me better understanding the logic behind it all.
    Quote Originally Posted by mtiger View Post
    Ok I'll work further on it, thanks for your help though
    Well - you said you wanted to 'not use pre-existing ...'

    Start with a simple example - with nothing but one button being tested - make that work - then if help is needed your code can be used on any teensy with a button. Once you have that part worked out - single detection recorded for any press or release - add the logic to wait for ongoing repeat adjustment time while held.

    If you hook an interrupt it will be called multiple times on most presses - or releases. And a tight while watching it will see HIGH and LOW return multiple times on most changes. The Bounce library has the coding to detect that for a selected interval where it is expected.

  15. #15
    Defragster, an update.... been working on it using multiple states and booleans and getting close. Will post the code soon once I have it working the way I intend.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •