This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Button long press functionality using nrf52840

I'm using nrf52840  and SDK VR 15.0.0

I want to apply the long press button functionality and short press button functionality to change the screens in OLED SSD1306.

How can I perform that?

Thank you!

Parents
  • Hello,

    This is implemented as part of the bsp module, and you may see its implementation in SDK/components/libraries/bsp/bsp.c, specifically the bsp_button_event_handler function.

    /**@brief Function for handling button events.
     *
     * @param[in]   pin_no          The pin number of the button pressed.
     * @param[in]   button_action   Action button.
     */
    static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
        bsp_event_t        event  = BSP_EVENT_NOTHING;
        uint32_t           button = 0;
        uint32_t           err_code;
        static uint8_t     current_long_push_pin_no;              /**< Pin number of a currently pushed button, that could become a long push if held long enough. */
        static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */
    
        button = bsp_board_pin_to_button_idx(pin_no);
    
        if (button < BUTTONS_NUMBER)
        {
            switch (button_action)
            {
                case APP_BUTTON_PUSH:
                    event = m_events_list[button].push_event;
                    if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
                    {
                        err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);
                        if (err_code == NRF_SUCCESS)
                        {
                            current_long_push_pin_no = pin_no;
                        }
                    }
                    release_event_at_push[button] = m_events_list[button].release_event;
                    break;
                case APP_BUTTON_RELEASE:
                    (void)app_timer_stop(m_bsp_button_tmr);
                    if (release_event_at_push[button] == m_events_list[button].release_event)
                    {
                        event = m_events_list[button].release_event;
                    }
                    break;
                case BSP_BUTTON_ACTION_LONG_PUSH:
                    event = m_events_list[button].long_push_event;
            }
        }
    
        if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
        {
            m_registered_callback(event);
        }
    }


    Based on this, you could either make a similar implementation yourself, or you may use the BSP module directly - this is up to you.

    Please let me know if anything still should be unclear, or if you have any other questions.

    Best regards,
    Karl

  • Thanks for your reply, Karl!

    From forums, I got to know about this bsp_button_event_handler.

    While calling this API how the argument " action " defined.

    ex: bsp_button_event_handler(12,2)

    12 means button_2 pin number

    2  means the BSP_BUTTON_ACTION_LONG_PUSH

    Is this the right way or any different approach for using that API please let me know sir !!

    Thank you

  • Hello again,

    manoj97 said:
    can you explain the line 7 in your example code?

    That was an oversight by me, sorry. I have updated the code now to the correct parameter.

    manoj97 said:
    why the BTN_ACTION_DISCONNECT is given instead of that we can give this one "BSP_BUTTON_ACTION_LONG_PUSH" will it work for long press?

    You are correct that you may instead just supply BSP_BUTTON_ACTION_LONG_PUSH as the argument directly - but I would recommend that you create a forwarding macro that matches the naming of the action you are connecting the action to. This way, your code readability will increase.

    manoj97 said:
    Correct me where i have gone wrong?

    Could you elaborate why you are wrong? Are you getting an error - if so, which error are you getting, and which function call returns the error?
    If you are not getting an error, what is the behavior you are seeing - and how does it differ from what you were expecting?

    Best regards,
    Karl

  • According to my code which I have shared with you ,

    Is when I press and hold button 2  for  5 sec it has to trigger the screen_9().

    But it is not happing. That is my point so I asked where I have mistaken

  • This is understood from your previous reply, but in order to be able to help you I will need to know more about the behavior you are seeing.

    What tests have you conducted to identify what is happening? Have you used the debugger to step through your code, to see where it might go wrong? Or, have you tested if the button press causes the bsp_event_handler to be called at all?
    In the case that the bsp_event_handler is called, which event is it called with?

    The more info you provide about what you have done to identify your issue, the easier it will be to help you resolve the issue.
    It is very hard to help you when you only provide a code snippet and "it is not happening", because I have no way to run the little code you have provided and you may have programmed something else somewhere else in your code that will prevent the execution of the code you have provided. I have no way of knowing, and thus I rely on your accurate description of the behavior you are seeing.

    Please check the things I mention above - is the bsp_event_handler called at all when you press your button, and what event is it called with - and get back to me with the result.

    Best regards,
    Karl

  • By using the app_button, nrfx gpiote, and app timers. I read the status of a button based on that start and stop the timers.

    It worked fine.

    thank you!!!

  • manoj97 said:

    By using the app_button, nrfx gpiote, and app timers. I read the status of a button based on that start and stop the timers.

    It worked fine.

    thank you!!!

    I am happy to hear that your issue is resolved, and that it is now working as intended, great!
    It is no problem at all, I am happy to help.

    Please do not hesitate to open a new ticket if you should encounter any issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl

Reply
  • manoj97 said:

    By using the app_button, nrfx gpiote, and app timers. I read the status of a button based on that start and stop the timers.

    It worked fine.

    thank you!!!

    I am happy to hear that your issue is resolved, and that it is now working as intended, great!
    It is no problem at all, I am happy to help.

    Please do not hesitate to open a new ticket if you should encounter any issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl

Children
No Data
Related