On an Arduino it is easy to get an HC-SR04 ultrasonic sensor getting to work. However, on my STM32(F103C8T6) I get strange values.

I assumed I connect it correctly, since I get values on the trigger pin. I checked the voltage on the 5V pin going to VCC of the HC-SR04 is 4.87 V.

The following program I used (only most important parts and with generated comments removed):

// PA10 US1 Trigger
#define US1_Trigger_Port GPIOA
#define US1_Trigger_Pin  GPIO_PIN_10
// PA9 US1 Echo
#define US1_Echo_Port GPIOA
#define US1_Echo_Pin  GPIO_PIN_9

uint32_t us1_duration;
uint32_t us1_distance;

uint32_t raw_values[1024];
uint32_t n = 0;

And for the loop (default part, auto generated by CubeMX):

int main(void)

  while (1)
    HAL_GPIO_WritePin(US1_Trigger_Port, US1_Trigger_Pin, SET);
    HAL_GPIO_WritePin(US1_Trigger_Port, US1_Trigger_Pin, RESET);

    uint8_t state;
      state = HAL_GPIO_ReadPin(US1_Echo_Port, US1_Echo_Pin);
    } while (state == RESET);
    uint32_t us1_start = HAL_GetTick();

      state = HAL_GPIO_ReadPin(US1_Echo_Port, US1_Echo_Pin);
    } while (state == SET);

    uint32_t us1_end = HAL_GetTick();
    us1_duration = us1_end - us1_start;

    us1_distance = (us1_duration / 2) / 29.1; // cm (?)
    raw_values[n] = us1_duration;

    if (n == 1024)


I put a breakpoint in the break statement to stop the program to check values. I moved my hand between 10 and 20 cm (4-8 inches) away from the sensor but the raw values I get are:

Name : raw_values
Details:{195, 196, 1, 1, 196, 1, 4, 1, 1, 1, 197, 0 <repeats 1013 times>}
Default:0x20001070 <raw_values>

The raw values I expect would be in 10-20cm range (at least most of them), which would result according to the datasheet in raw values of 10 * 58 to 20 * 58 which is 580 to 1060. Especially not around 0's and not all same values around a certain value (this time 200).

The data sheet info I used can be found here: datasheet

Update I checked it with a logic analyzer, and noticed the high parts of the echo durations are less than 1 ms. I don't know why I still get values of 200 sometimes, maybe when there is no echo.

  • \$\begingroup\$ what raw values are you expecting? \$\endgroup\$
    – jsotola
    Commented Feb 10, 2018 at 20:45
  • \$\begingroup\$ @jsotola I updated my question ... I would expect values to be in 580-1060 range. \$\endgroup\$ Commented Feb 10, 2018 at 20:49
  • 1
    \$\begingroup\$ This is what counters are for. Your interrupts should be starting and stopping counters. \$\endgroup\$ Commented Feb 10, 2018 at 22:18
  • \$\begingroup\$ @ScottSeidman I was hoping to manually start a timer (since I only need it for measuring time). I'm reading some more documentation :-) \$\endgroup\$ Commented Feb 10, 2018 at 22:54
  • 1
    \$\begingroup\$ You're measuring very short times, and you're trying for accuracy. It's hard to know your needs, but polling for a change is often wrong for this type of thing. A timer hooked by interrupts to your echo pulse is dead simple, and the most accurate you can get. \$\endgroup\$ Commented Feb 10, 2018 at 23:42

1 Answer 1


I found out the HAL_getTick returns milliseconds, and the echos are less than 1 ms (sometimes).

However, I changed it just by counting the loop iterations and I get much better values:

Name : raw_values
    Details:{118, 233, 797, 971, 268, 15, 290, 854, 455, 62, 258, 525, 867, 865, 866, 581, 576, 576, 587, 588, 581, 0 <repeats 1003 times>}

The last 8 values (except the 0) I got when I placed a box steadily in front of the sensor.

I think if I calculate the exact duration (in ms) of one loop it should be ok and I forget about the bad resolution of the HAL ticks. Or I should use some hardware timer that I start and check.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.