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

Button interrupt , gpiote

HEllo;
I'm working with nrf52832 and sdk15 , and for interrupt button i chose to work with the example "/nRF5_SDK_15.0.0_a53641a/examples/peripheral/pin_change_int/"
, so my question is how we can know its pushed button(push the button two time)  and long press.
and how we can add : three configuration nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);/and LOTOHI and toggle , all together. thank you for your help .
and what about consume of the energy is it better to work wirh nrf_gpio_pin_read(30) or this methode of interupt.

  • A huge portion of the support team is currently on Christmas vacation and you may experience delayed answers. Most of the staff will be back 6 of January 2020 and you can be sure to get an answer shortly after that.

    Best regards,

    Simon

  • Okey no probleme ; I'll be waiting for the reply , happy vacation for all 

  • so my question is how we can know its pushed button(push the button two time)

     In the pin change int example, you know that button 1 is pushed (a transition happens) when a GPIOTE event is triggered. In the pin_change_int example, the function in_pin_handler() will run in response to this event.

    and long press

     Check out this ticket.

     

    and how we can add : three configuration nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);/and LOTOHI and toggle , all together

     I am not sure if I understand what you are asking about here, can you explain it in more details?

     

    and what about consume of the energy is it better to work wirh nrf_gpio_pin_read(30) or this methode of interupt

     It depends on how you use nrf_gpio_pin_read(). If you put it in a while(1) it will definitely use more power than the method using GPIOTE events and interrupt.

    However, if you create a timer that will trigger an interrupt handler periodically and run nrf_gpio_pin_read() in the handler, then the current consumption will be low. The drawback of this method is that it will most definitely loose some pin transitions. I think the initial method is the best one.

    Best regards,

    Simon

  • Hello Simon thank you for your answer.
    I contiue working with the example (examples/peripheral/pin_change_int), and I made this code :

    #include <stdbool.h>
    #include "nrf.h"
    #include "nrf_drv_gpiote.h"
    #include "app_error.h"
    #include "boards.h"
    #include "nrf_delay.h"
    
    #define PIN_IN 30
    #define PIN_OUT 26
    bool HL_state;
    bool LH_state;
    bool First_state;
    bool up_state;
    int HL_counter=0;
    int LH_counter=0;
    int count ;
    int push_counter;
    int up_counter;
    
    
    void in_pin_handlerHL(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        //nrf_drv_gpiote_out_toggle(PIN_OUT);
        NRF_GPIOTE->EVENTS_IN[0] = 0;
    
    
            if (nrf_gpio_pin_read(30)==0)
            {
                HL_counter ++;
                HL_state=true;
                LH_state=false;
                LH_counter=0;
            }else{
                LH_counter ++;
                LH_state=true;
                HL_state=false;
                HL_counter=0;
            }
    
    }
    // void in_pin_handlerLH(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    // {
    //     //nrf_drv_gpiote_out_toggle(PIN_OUT);
    //     NRF_GPIOTE->EVENTS_IN[0] = 0;
    //     LH_counter ++;
    
    //         if (nrf_gpio_pin_read(30)==1)
    //         {
    //             LH_state=true;
    //             HL_state=false;
    //             HL_counter=0;
    //         }else{
    //             LH_state=false;
    //         }
    // }
    /**
     * @brief Function for configuring: PIN_IN pin for input, PIN_OUT pin for output,
     * and configures GPIOTE to give an interrupt on pin change.
     */
    static void gpio_init(void)
    {
        ret_code_t err_code;
    
    
        if (!nrf_drv_gpiote_is_init())
        {
            err_code = nrf_drv_gpiote_init();
            APP_ERROR_CHECK(err_code);
        }
    
        nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
        // err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
        // APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_config_t in_configHL = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
        // nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
        in_configHL.pull = NRF_GPIO_PIN_PULLUP;
    
        nrf_drv_gpiote_in_config_t in_configLH = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
        in_configLH.pull = NRF_GPIO_PIN_PULLUP;
    
        err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_configHL, in_pin_handlerHL);
        APP_ERROR_CHECK(err_code);
    
        // err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_configLH, in_pin_handlerLH);
        // APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        gpio_init();
    
        //printf("HL_state%d\n", HL_state );
        //printf("LH_state%d\n", LH_state );
           // printf("start");
        while (true)
        {
    
            if (HL_state==true)
            {
                //printf("yes\n");
                First_state=true;
                count=0;
    
                push_counter ++;
            }else
            {
                count ++;
                //printf("counter : %d\n", count);
                push_counter=0;
                up_counter ++;
            }
    
            if (1<count && count <5 && First_state==true )
            {
                printf("UP\n");
                up_state=true;
                First_state=false;
                up_counter=0;
    
            }else{
                up_state==false;
    
            }
    
            if (HL_state==true && up_state==true && up_counter < 10)
            {
                printf("double\n");
                up_state=false;
                First_state=false;
                count=0;
                up_counter=0;
    
            }else{
    
            }
    
            if(20<push_counter && push_counter<50 && HL_state==true){
    
                printf("hold_press\n");
                up_state=false;
                First_state=false;
    
    
            }else if(push_counter>50 && HL_state==true){
                printf("long_press\n");
                up_state=false;
                First_state=false;
                push_counter=0;
    
            }else{
    
            }
    
            nrf_delay_ms(100);
    
        }
    
    }
    
    
    /** @} */
    


    is it right ? , my question is can we do the high to lo and lo to high configuration as i commented in my code , cause it dosnt work for me , but for the moment i made it , I think it's right, please give me your feed back about my code. and i hope it will not consume a lot of energy 

  • Before continuing, I would like to ask why you don't use the solution already provided in this thread? That solution is based on a timer, which makes it more accurate and energy-efficient. 

    Best regards,

    Simon

Related