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

HCSR04 with nRF52 (PCA10040)

Hi developer, sorry to interrupt and ask. How to use an ultrasonic sensor with nRF52? Since I search a code for nRF52 are not exist and see ultrasonic sensor can connect with nRF51. Hope that is some solution to use ultrasonic with nRF52.

Parents
  • Hi

    If I am not mistaken, to use this sensor you have to generate a short pulse from the nRF5x, and measure the time it takes until you receive a pulse in return from the sensor?

    To do that you can use the TIMER, PPI and GPIOTE peripherals in the nRF52, which allow you to generate the pulse and measure the delay without having to run a lot of code in the CPU.

    The code for this could look something like this (not tested!):

    #define SENSOR_PIN_OUT      2
    #define SENSOR_PIN_IN       3
    #define PPI_CH_A            0
    #define PPI_CH_B            1
    #define PPI_CH_C            2
    #define GPIOTE_CH_A         0
    #define GPIOTE_CH_B         1
    #define PULSE_LENGTH_MS     10
    #define TIMEOUT_LENGTH_MS   500
    
    void sensor_init(void)
    {
        // Timer configuration
        NRF_TIMER0->PRESCALER   = 4; // (16M / (2^4)) = 1MHz timer frequency
        NRF_TIMER0->CC[0]       = 1;
        NRF_TIMER0->CC[1]       = PULSE_LENGTH_MS * 1000 + 1;
        NRF_TIMER0->CC[2]       = 0;
        NRF_TIMER0->CC[3]       = TIMEOUT_LENGTH_MS * 1000;
        NRF_TIMER0->SHORTS      = TIMER_SHORTS_COMPARE3_STOP_Msk | TIMER_SHORTS_COMPARE3_CLEAR_Msk;
        NRF_TIMER0->INTENSET    = TIMER_INTENSET_COMPARE3_Msk;
        
        // GPIOTE configuration
        NRF_GPIOTE->CONFIG[GPIOTE_CH_A] = GPIOTE_CONFIG_MODE_Task   << GPIOTE_CONFIG_MODE_Pos |
                                          SENSOR_PIN_OUT            << GPIOTE_CONFIG_PSEL_Pos |
                                          GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;
        NRF_GPIOTE->CONFIG[GPIOTE_CH_B] = GPIOTE_CONFIG_MODE_Event  << GPIOTE_CONFIG_MODE_Pos |
                                          SENSOR_PIN_IN             << GPIOTE_CONFIG_PSEL_Pos |
                                          GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos;
        
        // PPI configuration    
        NRF_PPI->CH[PPI_CH_A].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[GPIOTE_CH_B];
        NRF_PPI->CH[PPI_CH_A].TEP = (uint32_t)&NRF_TIMER0->TASKS_CAPTURE[2];
        NRF_PPI->CHENSET = (1 << PPI_CH_A);
        NRF_PPI->CH[PPI_CH_B].EEP = (uint32_t)&NRF_TIMER0->EVENTS_COMPARE[0];
        NRF_PPI->CH[PPI_CH_B].TEP = (uint32_t)&NRF_GPIOTE->TASKS_SET[GPIOTE_CH_A];
        NRF_PPI->CHENSET = (1 << PPI_CH_B);    
        NRF_PPI->CH[PPI_CH_C].EEP = (uint32_t)&NRF_TIMER0->EVENTS_COMPARE[1];
        NRF_PPI->CH[PPI_CH_C].TEP = (uint32_t)&NRF_GPIOTE->TASKS_CLR[GPIOTE_CH_A];
        NRF_PPI->CHENSET = (1 << PPI_CH_C);
    
        // Interrupt configuration
        NVIC_SetPriority(TIMER0_IRQn, 7);
        NVIC_EnableIRQ(TIMER0_IRQn);
    }
    

    And then to start a reading you would simply have to start the timer:

    NRF_TIMER0->TASKS_START = 1;
    

    Best regards
    Torbjørn

  • Have you been through the nRF52 Getting Started tutorial on devzone?

    You should definitely start there if you don't have previous Nordic experience. Once you have been able to complete that you can start extending the examples with more code, to read your sensor.

Reply Children
No Data
Related