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

Using Comparator as "Window" for potentiometer wake up.

I am trying to use the comparator to wake me up when a potentiometer is moved a certain amount.

Before I sleep I read the ADC value of the comparator and use this to set the upper and lower value of the comparator.

My issue is this only works when I move the POT down.  For some reason the UP direction is not working.

I am including the NRF_DRV_COMP_EVT_EN_UP_MASK in my nrf_drv_comp_start  command.  What else needs to be added to get an event when the voltage crosses the upper threshold?

This is using the nRF52832 , SDK14

#define COMPTH_MAX 63
#define COMPTH_INTERVAL 5

void zoom_comp_init(void)
{

    uint32_t err_code;

    nrf_saadc_value_t vdd, adcval;

    nrf_drv_comp_uninit();

    APP_ERROR_CHECK(nrf_drv_saadc_sample_convert(4, &vdd));

    APP_ERROR_CHECK(nrf_drv_saadc_sample_convert(0, &adcval));

    // hw_adc_disable();

    float frac = (float)adcval / (float)vdd;

    // ref_setting = frac*16.0;
    static uint8_t myrefval = 0; //(0-16)
    frac *= 64.0;
    myrefval = (uint8_t)frac;
    
    nrf_drv_comp_config_t myCompConfig = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0);

    myCompConfig.input = NRF_COMP_INPUT_0;
    myCompConfig.main_mode = NRF_COMP_MAIN_MODE_SE;
    myCompConfig.reference = NRF_COMP_REF_VDD;
    myCompConfig.speed_mode = NRF_COMP_SP_MODE_Normal;
    //myCompConfig.hyst = NRF_COMP_HYST_50mV;
    myCompConfig.isource = COMP_ISOURCE_ISOURCE_Off;
    myCompConfig.interrupt_priority = 6;

    if (myrefval > (COMPTH_MAX - COMPTH_INTERVAL) )
    {
	myCompConfig.threshold.th_down = COMPTH_MAX - COMPTH_INTERVAL*2;
	myCompConfig.threshold.th_up = COMPTH_MAX;
    }
    else if (myrefval < COMPTH_INTERVAL)
    {
	myCompConfig.threshold.th_down = 0;
	myCompConfig.threshold.th_up = COMPTH_INTERVAL*2;
    }
    else
    {
	myCompConfig.threshold.th_down = myrefval - COMPTH_INTERVAL;
	myCompConfig.threshold.th_up = myrefval + COMPTH_INTERVAL;
    }

    NRF_LOG_INFO("ZOOM |  Reference Value=%d", myrefval);
    NRF_LOG_INFO("ZOOM |  TH_DOWN=%d  TH_UP=%d", myCompConfig.threshold.th_down, myCompConfig.threshold.th_up);

    err_code = nrf_drv_comp_init(&myCompConfig, comp_event_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_comp_start( NRF_DRV_COMP_EVT_EN_DOWN_MASK | NRF_DRV_COMP_EVT_EN_UP_MASK ,
        NRF_DRV_COMP_SHORT_STOP_AFTER_UP_EVT | NRF_DRV_COMP_SHORT_STOP_AFTER_DOWN_EVT | NRF_DRV_COMP_SHORT_STOP_AFTER_CROSS_EVT);

static void comp_event_handler(nrf_comp_event_t event)
{

    asm("nop;");
    NRF_LOG_INFO("Comp Event.");
    switch (event)
    {
	case NRF_COMP_EVENT_CROSS:
	    NRF_LOG_INFO("Comp CROSS Event.");
	    sysEvents.zoom_change = 1;
	    break;
	case NRF_COMP_EVENT_DOWN:

	    // sysEvents.zoom_change = 1;
	    //if (update_zoom())
	    {
		NRF_LOG_INFO("Comp DOWN Event.");
		sysEvents.zoom_change = 1;
	    }
	    break;
	case NRF_COMP_EVENT_UP:

	    //if (update_zoom())
	    {
		NRF_LOG_INFO("Comp UP Event.");
		sysEvents.zoom_change = 1;
	    }
	    // sysEvents.zoom_change = 1;
	    break;
    }
}

Parents
  • I think your understanding should be correct. This is taken from the product specifications:

    Event generation on output changes

    • UP event on VIN- > VIN+
    • DOWN event on VIN- < VIN+
    • CROSS event on VIN+ and VIN- crossing
    • READY event on core and internal reference (if used) ready

    Use the PSEL register to select any of the AIN0-AIN7 pins as VIN+ input, irregardless of the operation mode selected for the comparator. The source of VIN- depends on which operation mode is used:

    • Differential mode: Derived directly from AIN0 to AIN7
    • Single-ended mode: Derived from VREF. VREF can be derived from VDD, AIN0-AIN7 or internal 1.2 V, 1.8 V and 2.4 V references.

    The events should be generated on output changes (OUTPUT: 0 = BELOW (VIN+ < VIN-), 1 = ABOVE (VIN+ > VIN-)). When the events will be generated will depend on the initial value of VIN+. Please study the diagram in Figure 5 in the single-ended mode chapter.

  • So, the end conclusion of this would then mean I cannot set the upper and lower thresholds above and below my current input voltage and interrupt when the potentiometer is moved up or down correct?  If VIN has to cross both thresholds to get an event then I would have to pick one direction for the POT to move in order to get an event.

    Are there any other means to do this?  The only other option i can think of is to wake periodically and read the input as an ADC to see if the user changed the POT position.  This seems like it would cause much worse battery life and average power consumption.

Reply
  • So, the end conclusion of this would then mean I cannot set the upper and lower thresholds above and below my current input voltage and interrupt when the potentiometer is moved up or down correct?  If VIN has to cross both thresholds to get an event then I would have to pick one direction for the POT to move in order to get an event.

    Are there any other means to do this?  The only other option i can think of is to wake periodically and read the input as an ADC to see if the user changed the POT position.  This seems like it would cause much worse battery life and average power consumption.

Children
No Data
Related