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

2 Timers as counter with external input capture pin

Hi. I have to make mesuring impulses quantity of two external low freq signals without interrupts.

I tried to use GPIOTE EVENTS_IN[0] and 1 with PPI ch 0 and 1 to timer 2 and 3 TASKS_COUNT generate. it works, but when the event on pins polarity change occure simultaneously one of the timers counts twice. 

How to make it write to be timers counted independently of each other?

Parents Reply Children
  • Delay between signals 1 - 1.5 ms/

    Code (next i remake without ppi)

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    
    		if( pin == 4 )
    		{	
    			counter1++;
    			SEGGER_RTT_WriteString(0,"CNT1\r\n");
    		}
    		else if( pin == 5 )
    		{			
    			counter2++;
    			SEGGER_RTT_WriteString(0,"CNT2\r\n");
    		}
    }
    
    static void buttons_leds_init(bool * p_erase_bonds)
    {
    	nrf_gpio_cfg_output(17);
    	nrf_gpio_cfg_output(18);
    	nrf_gpio_cfg_output(19);
    	nrf_gpio_cfg_output(20);
    	nrf_gpio_pin_set(17);
    	nrf_gpio_pin_set(18);
    	nrf_gpio_pin_set(19);
    	nrf_gpio_pin_set(20);
    
    	err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    	
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
        in_config.pull = NRF_GPIO_PIN_PULLUP;
        nrf_drv_gpiote_in_init(4, &in_config, in_pin_handler);
        nrf_drv_gpiote_in_event_enable(4, true);
        nrf_drv_gpiote_in_init(5, &in_config, in_pin_handler);
        nrf_drv_gpiote_in_event_enable(5, true);
        
        NVIC_SetPriority(2, GPIOTE_IRQn);
        NVIC_DisableIRQ(GPIOTE_IRQn);
    }
    

    cnt2 sets twice

  • Your code does not use PPI. Do you still see double-events with this code? Have you scoped pin 5 to see if there are any glitches or pulses that might account for this double increment?

    Is your counter values declared as volatile? This is important when variables are used in interrupt vectors.

     

    Best regards,

    Håkon

  • With PPi or not, it has double event. There is no pulses (i use cap 0.1 uf on input pins). Variables are volatile but SEGGER_RTT_WriteString(0,"CNT2\r\n"); prints twice

  • I assume your inputs should then alternate between CNT1 and CNT2, ie: the input signal phase is 0/180 degrees.

    Could you try to omit RTT, and do something like this to see if this might be a RTT polling/buffering issue?

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
            static nrf_drv_gpiote_pin_t last_pin;
    		if( pin == 4 )
    		{	
    			counter1++;
    			//SEGGER_RTT_WriteString(0,"CNT1\r\n");
    		}
    		else if( pin == 5 )
    		{			
    			counter2++;
    			//SEGGER_RTT_WriteString(0,"CNT2\r\n");
    		}
    		if (pin == last_pin)
    		{
    		  // Same evt happen twice in a row.
    		  static uint32_t double_count;
    		  double_count++;
    		}
    		last_pin = pin;
    }
    

     

    Best regards,

    Håkon

Related