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.

Reply
  • 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.

Children
Related