Announcement

Collapse
No announcement yet.

tactile switch to toggle through menu, press only, press and hold

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • tactile switch to toggle through menu, press only, press and hold

    I would like to use a tactile switch to toggle through menu: for example if the user presses the switch it goes to menu one, if they press and hold switch for 1s it goes into menu 2, if they press and hold switch for 3s it goes to menu 3

    I am not sure how to program could recognize for press and hold versus a simple press. Would anyone be able to help me the coding.


    This is the code I would use in C program:
    first pull up SWITCH HIGH, then

    while (digitalRead (SWITCH) == LOW)
    {
    if (millis() >= (unsigned long)(CurrentTime + 1000))
    {
    do something useful
    }
    }

    Can something be similar be done in 4D IDE? how can I record time? or perhaps use something like the switch case for different options?

  • #2
    Hi,

    I haven't been able to test this code but it compiles ok.

    var tch;
    var timenow;
    var t;

    pin_Set(PIN_INP_HI, PA4);

    repeat

    tch := pin_Read(PA4);
    timenow := sys_T();
    while(tch == 0x0000)
    t := sys_T();
    if(t > timenow + 3000)
    // do something
    break;
    endif
    wend

    forever

    I hope this helps

    Best regards

    Paul

    Comment


    • mazmazak
      mazmazak commented
      Editing a comment
      Thanks I tried the code and it seems to work only if tch is not defined and pin_Read(PA1) is inside the while statement:

      timenow := sys_T();
      while (pin_Read(PA1) == 0x0000)
      if(sys_T() > timenow + 1000)
      menu :=!menu; //do something
      break;
      endif
      wend

      Now the question is how to distinguish a single press from a press and hold.

    • pauleilio
      pauleilio commented
      Editing a comment
      Hi,

      My apologies, yes the input status of PA1 should be checked in the while statement. Glad you managed to fix it.

      Best regards

      Paul

  • #3
    i would count in the while loop, the moment it breaks (you letting go), the time counted goes to the proper function

    < 1500 secs menu 1
    > 1500 && < 2500 menu 2
    > 2500 menu 3

    Comment


    • #4
      Thansk Tonton, I dont think I can achieve 3 menu with one switch. it will be too complected for the user. Now I am focusing my effort on 2 menus: menu 1 = press once, menu 2 = press and hold for 1s

      unfortunate you can not add 2-3 event in the loop and break the loop at the latter time this is because event one (< 1500 mSec) happens always and will break the loop before even two (> 1500 && < 2500). You have to look before and after and see what happens.

      Comment


      • #5
        Code:
            sys_SetTimer(TIMER0,3000) ;
            while (pin_Read(PA1) == 0x0000) ;
            if (sys_GetTimer(TIMER0))
                // Short press
            else
                // Long press
            endif
        Mark

        Comment


        • mazmazak
          mazmazak commented
          Editing a comment
          Hi Mark,

          I tried your code:
          sys_SetTimer(TIMER0,2000) ;
          while (pin_Read(PA1) == 0x0000)
          if (sys_GetTimer(TIMER0))
          if (menu == 1 || menu == 2) // go to menu 3 if in menu 1 or 2
          menu := 3;
          else
          menu := 1; // if in menu 3 go back to menu 1
          endif
          pause (200); // Debouncing
          else
          if (menu == 1) // if in menu 1 goto menu 2
          menu := 2;
          else // if in menu 2 goto menu 1
          menu := 1;
          endif
          pause (200);
          break;
          endif
          wend


          But its seems I have to release the switch to get to the menu with long press. there is no feedback to the user indicating the switch is held for required time.

          If I were to add a break to the long press, then when the menu appear the user releases the finger from the switch but the reaction time is not fast enough and the MCU see this a short press and enters another menu right way. do you have a suggestion to fix this problem?

      • #6
        Thanks,

        is was my code:

        but looks like the code you posted is a lot simpler, I'll try to see if it work.

        timenow := sys_T();
        if(pin_Read(PA1) == 0x0000) // look for switch press
        pause(200); // debouncing
        if (pin_Read(PA1)!= 0x0000) // look for switch release
        if (menu == 1) // if in menu 1 goto menu 2
        menu := 2;
        else // if in menu 2 goto menu 1
        menu := 1;
        endif
        else
        while (pin_Read(PA1) == 0x0000) // look for switch is held
        if(sys_T() > timenow + 1500) // if switch is held for 1500ms
        if (menu == 1 || menu == 2) // go to menu 3 if in menu 1 or 2
        menu := 3;
        else
        menu := 1; // if in menu 3 go back to menu 1
        endif
        break;
        endif
        wend
        pause (200); // give user some time to release the switch
        endif
        endif

        Comment


        • #7
          Well, that's because you have coded it that way. Why not try something like

          Code:
              sys_SetTimer(TIMER0,2000) ;
              while (pin_Read(PA1) == 0x0000) && (sys_GetTimer(TIMER0))) ;
              if (sys_GetTimer(TIMER0))
                  if (menu == 1 || menu == 2) // go to menu 3 if in menu 1 or 2
                      menu := 3;
                  else
                      menu := 1; // if in menu 3 go back to menu 1
                  endif
                  pause (200); // Debouncing
              else
                  if (menu == 1) // if in menu 1 goto menu 2
                      menu := 2;
                  else // if in menu 2 goto menu 1
                      menu := 1;
                  endif
                  pause (200);
                  break;
              endif
          That won't wait more than 2 seconds
          Mark

          Comment


          • mazmazak
            mazmazak commented
            Editing a comment
            Hi Mark, I am not sure why that code doesn't work. it seams that by adding "&& (sys_GetTimer(TIMER0))" it never get inside the else statement.

          • ESPsupport
            ESPsupport commented
            Editing a comment
            Are you sure? Try a few print statements (and maybe pauses, or just write a log to COM0) to see what is going on
        Working...
        X