{"id":4339,"date":"2019-01-09T20:00:03","date_gmt":"2019-01-09T19:00:03","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4339"},"modified":"2025-12-27T20:02:26","modified_gmt":"2025-12-27T19:02:26","slug":"inexpensive-hc-sr04-ultrasonic-rangefinder","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/inexpensive-hc-sr04-ultrasonic-rangefinder\/","title":{"rendered":"Inexpensive HC-SR04 Ultrasonic Rangefinder"},"content":{"rendered":"\n<p>Distance measurement is used in everyday life, for example in parking sensors in cars. For robots, distance sensors help them survive a thicket of obstacles, e.g., so that a drone doesn\u2019t smash its propellers against a pole or a wall. Let\u2019s take a look at a very cheap HC-SR04 ultrasonic rangefinder \u2013 how it works and how to use it optimally.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h1 class=\"wp-block-heading\">Ultrasonic&nbsp; rangefinder HC-SR04<\/h1>\n\n\n\n<p>The HC-SR04 ultrasonic sensor is powered by 5 V with a current draw of about 15 mA in the active state. The distance it can measure is in the range of 2\u00f7400 cm. The measurement cone is 15\u00b0, hence the best results at maximum distance are obtained with an object larger than 0.5 m\u00b2. The closer the object is, the smaller it can of course be.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/produkt\/hc-sr04-dalmierz-ultradzwiekowy\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=hcsr04&amp;utm_content=Text\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"341\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-1024x341.jpg\" alt=\"\" class=\"wp-image-948\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-768x256.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-24x8.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-36x12.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner-160x53.jpg 160w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/01\/HC-SR04_baner.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The distance measurement module uses 40 kHz ultrasound, which is far beyond the human hearing range. The sensor is built from two ultrasonic elements \u2013 a transmitter and a receiver. The operation scheme of each measurement is as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>To start a measurement, a high state lasting at least 10\u00a0\u00b5s must be applied to the TRIG pin.<\/li>\n\n\n\n<li>The module starts a timer and sends 8 ultrasonic pulses.<\/li>\n\n\n\n<li>It waits until the reflected beam returns to the receiver, which is right next to the transmitter.<\/li>\n\n\n\n<li>When it detects the reflected signal, it stops the counter.<\/li>\n\n\n\n<li>The total time of flight of the ultrasonic pulse is reflected by the pulse length on the ECHO pin.<\/li>\n<\/ol>\n\n\n\n<p>This is what it looks like on the analyzer.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"139\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-1024x139.jpg\" alt=\"\" class=\"wp-image-606\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-1024x139.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-300x41.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-768x104.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-24x3.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-36x5.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot-160x22.jpg 160w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_plot.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>How to calculate the distance? The formula is quite simple:&nbsp;<em>Distance = Wave propagation speed * time.&nbsp;<\/em>We have time measured with a counter. Remember that this is the time the ultrasonic wave needs to travel to the object and back. The propagation speed in air is 343 m\/s, i.e., 34300 cm\/s if you want the result in centimeters. The time reported by the sensor is in&nbsp;\u00b5s. To obtain seconds, simply divide by 1,000,000. Ultimately&nbsp;<strong><em>Distance[cm]= Time[\u00b5s] \/ 2 * 0.0343[cm\/\u00b5s]<\/em><\/strong>. You can also compute it more simply by starting from how long it takes the wave to travel one centimeter, which is about 29&nbsp;\u00b5s\/cm. The formula will then be:&nbsp;<strong><em>Distance[cm]= Time[\u00b5s] \/ 58[\u00b5s\/cm]<\/em><\/strong><em>. In this case we won\u2019t know decimal parts of a centimeter, but we avoid float in the calculations because <a href=\"http:\/\/msalamon.pl\/ile-kosztuje-uzywanie-float-i-co-daje-fpu\/\">How much does using float cost and what does FPU give?<\/a>. In the library I provided the option to choose the calculation method via the definition #define HCSR04_HIGH_PRECISION<\/em> which, when uncommented, selects float calculations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schematic and Cube<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic.jpg\" alt=\"\" width=\"960\" height=\"530\" class=\"aligncenter wp-image-604 size-full\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic-300x166.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic-768x424.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic-24x13.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic-36x20.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_schematic-145x80.jpg 145w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\"><\/a><\/figure><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube.jpg\" alt=\"\" width=\"960\" height=\"573\" class=\"aligncenter wp-image-605 size-full\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube-300x179.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube-768x458.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube-24x14.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube-36x21.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_cube-134x80.jpg 134w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\"><\/a><\/figure><\/h2>\n\n\n\n<p>For the tests I chose the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/nucleo-l476rg\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=hcsr04&amp;utm_content=Text\">Nucleo STM32L476RG<\/a> from one of my kits. <strong>Since the sensor operates at 5 V, you must be careful how you connect it!<\/strong> Especially the Echo pin, which is the output from the module and will be at 5 V in the high state. STM32 works in the 3.3 V domain, but fortunately some of its pins are <em>5 V tolerant<\/em>, which I wrote about in the post&nbsp;<a href=\"http:\/\/msalamon.pl\/dlaczego-stm32\/\">Why STM32?<\/a>. You should check in the documentation which ones you can safely connect to. I chose pins PA6 (5 V tolerant) for ECHO and PB0 (3.6 V tolerant) for TRIG. A 3.3 V level driven from a GPIO will be sufficient to drive the Trigger.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=hcsr04&amp;utm_content=nucleo\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>First, let\u2019s check a simple blocking approach. For this we need some&nbsp;<em>timer<\/em> that we can use at microsecond resolution. The maximum response from the HC-SR04 can be about 4 ms, so a 16-bit TIM3 counter will be more than enough, and that\u2019s what I\u2019ll take. I set the main HCLK frequency to 48 MHz. To obtain a microsecond tick of the&nbsp;<em>timer<\/em>&nbsp; it is enough to divide this frequency by 48. For this, I set the prescaler to 47. I also change the maximum value to which the counter can count. I set it to the largest possible \u2013 65535. Counting is left at the default \u2013 up. I do not enable any interrupts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Blocking measurement<\/h2>\n\n\n\n<p>In the \u201cbudget edition\u201d, as in most examples for popular Arduino, the microcontroller will wait for the ECHO signal from the sensor to finish to provide the pulse length.<\/p>\n\n\n\n<p>The initialization function takes a pointer to a <em>timer&nbsp;<\/em>configured earlier for a microsecond tick&nbsp;<em>.<\/em><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HCSR04_STATUS HCSR04_Init(TIM_HandleTypeDef *htim);<\/pre>\n\n\n\n<p>This function is responsible for starting the counter and setting the TRIG pin low.<\/p>\n\n\n\n<p>The second useful function is the distance measurement, which returns the measured distance in centimeters through a pointer to a float.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HCSR04_STATUS HCSR04_Read(float *Result);<\/pre>\n\n\n\n<p>This function sets the TRIG pin high for 10&nbsp;\u00b5s and then waits for a high state to appear on the ECHO pin. When it appears, it zeros the&nbsp;<em>timer<\/em> and in a loop waits for a low state on ECHO. After the echo signal ends, the conversion is performed and the result is written to the indicated variable. As you can see, the operation is simple. Unfortunately, the microcontroller actually waits idly for changes in the ECHO pin state. This may not be much time, but it depends on the measured distance. For small distances the total handling time will be about a millisecond, but for larger ones it will be much longer, as can be seen in the waveforms below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"162\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long.jpg\" alt=\"\" class=\"wp-image-608\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long-300x51.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long-768x130.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long-24x4.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long-36x6.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings_long-160x27.jpg 160w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"298\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings.jpg\" alt=\"\" class=\"wp-image-607\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings-300x93.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings-768x238.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings-24x7.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings-36x11.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_blocking_timings-160x50.jpg 160w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>How to do it better?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Non-blocking handling of the HC-SR04<\/h2>\n\n\n\n<p>For non-blocking handling of the sensor I will use the modes that&nbsp;<em>timers<\/em> in STM32 offer. To trigger the measurement I will use PWM at a frequency of about 15 Hz (period = 65535 microseconds) with a high-state duration of 11 \u00b5s (0.022%). Some sources state that 20 Hz is the maximum&nbsp;<em>refresh rate<\/em> for this sensor. I couldn\u2019t find this in official documents, so I accept that value as correct. However, for convenience of using a single counter (1 \u00b5s tick) for the complete handling of the measurement, I will use the aforementioned 15 Hz.<\/p>\n\n\n\n<p>To capture the ECHO signal I will use the&nbsp;<em>Input Capture<\/em> mode, which will capture both edges on the ECHO pin. The signal from this pin will be physically routed to TIM3 CH1. This channel will latch the counter value when it detects a rising edge on pin PA6, i.e., it will capture the counter value at the start of the measurement pulse. The falling edge, i.e., the end of the measurement, will be detected by TIM CH2 and will latch the counter value in the appropriate register. In the STM32 configuration it will be internally connected to the physical CH1 pin, i.e., PA6. Thanks to this I can distinguish and handle two different events on a single pin.<\/p>\n\n\n\n<p>I trigger an interrupt only after latching the value on the falling edge. In the interrupt handler I subtract the value of the register responsible for the end of the measurement from the register holding the value from the beginning of the measurement. By using the full 16-bit range of the timer I do not have to worry about a possible counter overflow between the start and the end. 16-bit arithmetic elegantly handles such cases on uint16_t numbers. I put this difference into the equation from the beginning of the post and I already have the calculated distance to the obstacle from the sensor.<\/p>\n\n\n\n<p>The CPU time now needed to handle the sensor is almost negligible. See for yourself.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"161\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings.jpg\" alt=\"\" class=\"wp-image-609\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings-300x50.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings-768x129.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings-24x4.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings-36x6.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_timings-160x27.jpg 160w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The measurement, as I said, is performed at about 15 Hz.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"160\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate.jpg\" alt=\"\" class=\"wp-image-610\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate.jpg 960w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate-300x50.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate-768x128.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate-24x4.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate-36x6.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_nonblocking_freshrate-160x27.jpg 160w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>To maintain compatibility with the blocking library, the read simply returns the library variable into which the interrupt places the result of its operation.<\/p>\n\n\n\n<p>I added the definitions of the <em>timer<\/em> channels configured for the sensor to the header file. If you use others \u2013 change them.<\/p>\n\n\n\n<p>Also remember to add interrupt handling to the HAL _weak function.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* USER CODE BEGIN 4 *\/\nvoid HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)\n{\n  HCSR04_TIM_IC_CaptureCallback(htim);\n}\n\/* USER CODE END 4 *\/\n<\/pre>\n\n\n\n<p>With the sensor facing a wall there are some fluctuations. You could eliminate them with some filtering. A simple moving average of the last few measurements would be enough which, as you remember, we have at about 15 per second.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"441\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement.jpg\" alt=\"\" class=\"wp-image-616\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/12\/hcsr04_measurement-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>As you can see, it\u2019s worth using the hardware capabilities that STM32s offer. Thanks to this, the microcontroller can deal with something more sensible than idly waiting for the measurement to finish. You could also try implementing a filter, e.g., Kalman, to eliminate measurement fluctuations with such frequent measurements, although from my observations on the terminal it wasn\u2019t that bad.<\/p>\n\n\n\n<p>If you liked the sensor, you can buy it <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/hc-sr04-dalmierz-ultradzwiekowy\/\">in my store<\/a>.<\/p>\n\n\n\n<p>Projects with the blocking and non-blocking versions can be found on my GitHub: <a href=\"https:\/\/github.com\/lamik\/HCSR04_blocking_STM32\" target=\"_blank\" rel=\"noopener\">blocking<\/a>, <a href=\"https:\/\/github.com\/lamik\/HCSR04_nonblocking_STM32\" target=\"_blank\" rel=\"noopener\">non-blocking<\/a><\/p>\n\n\n\n<p><span>If you noticed any error, disagree with something, would like to add something important or simply want to discuss this topic, write a comment. Remember that the discussion should be polite and in accordance with the rules of the Polish language.<\/span><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4339&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Inexpensive HC-SR04 Ultrasonic Rangefinder&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Distance measurement is used in everyday life, for example in parking sensors in cars. For robots, distance sensors help them survive a thicket of obstacles, e.g., so that a drone doesn\u2019t smash its propellers against a pole or a wall. Let\u2019s take a look at a very cheap HC-SR04 ultrasonic [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3087,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[175,176,174],"class_list":["post-4339","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-electronics","tag-programming","tag-stm32"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4339"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4339\/revisions"}],"predecessor-version":[{"id":4449,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4339\/revisions\/4449"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3087"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4339"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4339"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}