{"id":4445,"date":"2017-01-09T02:40:54","date_gmt":"2017-01-09T01:40:54","guid":{"rendered":"https:\/\/playembedded.org\/?p=4445"},"modified":"2024-02-19T08:35:05","modified_gmt":"2024-02-19T07:35:05","slug":"detecting-obstacles-hc-sr04","status":"publish","type":"post","link":"https:\/\/playembedded.org\/blog\/detecting-obstacles-hc-sr04\/","title":{"rendered":"Detecting obstacles using an ultrasonic sensor HC-SR04"},"content":{"rendered":"<h3 id=\"1_HC_SR04_a_cheap_ultrasonic_sensor\" class=\"level_1\">HC-SR04: a cheap ultrasonic sensor<\/h3>\n<h4 id=\"2_Description\" class=\"level_2\">Description<\/h4>\n<figure id=\"attachment_4452\" aria-describedby=\"caption-attachment-4452\" style=\"width: 250px\" class=\"wp-caption alignright\"><a href=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/11\/HC_SR04-front.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-4452\" src=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/11\/HC_SR04-front.jpg\" alt=\"HC-SR04 front view\" width=\"250\" height=\"123\" srcset=\"https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC_SR04-front.jpg 600w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC_SR04-front-150x74.jpg 150w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC_SR04-front-300x148.jpg 300w\" sizes=\"auto, (max-width: 250px) 100vw, 250px\"><\/a><figcaption id=\"caption-attachment-4452\" class=\"wp-caption-text\">An HC-SR04 seen from front side.<\/figcaption><\/figure>\n<p>HC-SR04 is a commonly used ultrasonic sensor which is capable to detect obstacles in a range of 2-300cm. The sensor looks like a small PCB having two metal cylinders&nbsp;on the front-side and a small circuit on the back-side (see Fig.1).<\/p>\n<h4 id=\"3_Documentation\" class=\"level_2\">Documentation<\/h4>\n<p>In this article we will provide a simple demo to use HC-SR04. This requires a preliminary read of the sensor user manual:<br><a href=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/11\/HCSR04.pdf\">HC-SR04 User Manual<\/a><\/p>\n<h4 id=\"4_Pinmap_description\" class=\"level_2\">Pinmap description<\/h4>\n<p>The sensor has 4 PIN:<\/p>\n<ol>\n<li><strong>VCC<\/strong>, which must be connected to 5V;<\/li>\n<li><strong>Trig<\/strong>, which is an input PIN to trigger the measurement;<\/li>\n<li><strong>Echo<\/strong>, which is an output PIN which sent out a square wave;<\/li>\n<li><strong>GND<\/strong>, which must be connected to ground.<\/li>\n<\/ol>\n<blockquote>\n<p>Note that user manual specifies which GND must be connected first since a floating 5V could permanently damage the sensor.<\/p>\n<\/blockquote>\n<h3 id=\"5_How_it_works\" class=\"level_1\">How it works<\/h3>\n<p>The two cylinders are actually an ultrasonic receiver (R) and an ultrasonic transmitter (T) which are driven by the circuitry. The working principle is quite simple: when triggered the transmitter shoots some pulses. When sound encounters an obstacle it is echoed back and detected by the receiver.<!--more--><\/p>\n<figure id=\"attachment_4451\" aria-describedby=\"caption-attachment-4451\" style=\"width: 1328px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/11\/HC-SR04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4451 size-full\" src=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/11\/HC-SR04.jpg\" alt=\"HC-SR04 obstacle\" width=\"1328\" height=\"1000\" srcset=\"https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC-SR04.jpg 1328w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC-SR04-150x113.jpg 150w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC-SR04-300x226.jpg 300w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC-SR04-1024x771.jpg 1024w, https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/11\/HC-SR04-1200x904.jpg 1200w\" sizes=\"auto, (max-width: 1328px) 100vw, 1328px\"><\/a><figcaption id=\"caption-attachment-4451\" class=\"wp-caption-text\">An example of obstacle detection using an HC-SR04<\/figcaption><\/figure>\n<p>Since the speed of sound is almost constant, the information about the distance is strictly related the elapsed time from the shoot to the receiving. Indeed, sound has to travel twice the distance (roundtrip). Known the elapsed time the distance to obstacle is<\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Ctext%7Bd%7D+%3D+%5Cfrac%7B%5Ctext%7Bv%7D+%5Ccdot+%5Ctext%7Bt%7D%7D%7B%5Ctext%7B2%7D%7D&amp;bg=ffffff&amp;fg=000&amp;s=2&amp;c=20201002\" alt=\"\\text{d} = \\frac{\\text{v} \\cdot \\text{t}}{\\text{2}}\" class=\"latex\"><\/p>\n<p>where<\/p>\n<ul>\n<li style=\"text-align: left;\"><strong>d<\/strong> is distance between the obstacle and the sensor<\/li>\n<li style=\"text-align: left;\"><strong>v<\/strong> is the speed of sound (about 340 m\/s)<\/li>\n<li style=\"text-align: left;\"><strong>t<\/strong> is time elapsed<\/li>\n<\/ul>\n<p>Note that, here we are not discussing about accuracy of the measurement which is affected from from different factors:<\/p>\n<ul>\n<li>speed of sound is not constant: it depends on&nbsp;material medium, temperature, pressure and humidity.<\/li>\n<li>time measurement accuracy: the measure is made by on board circuit and we don&rsquo;t have control on this.<\/li>\n<li>the obstacle may not have a flat surface and there could be multiple diffraction or spurious echo.<\/li>\n<\/ul>\n<h3 id=\"6_How_to_use_it\" class=\"level_1\">How&nbsp;to use it<\/h3>\n<p>If&nbsp;<strong>Trig<\/strong>&nbsp;is set as high for at least 10us the sensor will shoot 8 pulses of sound. For the the whole time required by the sound to made the road trip&nbsp;<strong>Echo<\/strong>&nbsp;will be high.<\/p>\n<p>The logical steps to get a measure would be:<\/p>\n<ol>\n<li>Set the Input Capture Unit to measure the high period of a square wave on the <strong>Echo<\/strong> pin;<\/li>\n<li>Pull up <strong>Trig<\/strong> signal for at least 10 us;<\/li>\n<li>Convert the measured time in a distance using the previous formula.<\/li>\n<\/ol>\n<h3 id=\"7_A_simple_demo\" class=\"level_1\">A simple demo<\/h3>\n<p>In this first demo we will use a STM32 Nucleo-64 F401RE and ChibiOS in order to detect an obstacle and print the distance to it on the ST-Link virtual COM port. To do this we will use <em>chprintf()<\/em> already explained in <a href=\"https:\/\/playembedded.org\/en\/2015\/02\/10\/hello-chibios\/\">Hello ChibiOS<\/a>&nbsp;and the ICU driver already used with <a href=\"https:\/\/playembedded.org\/en\/2015\/06\/23\/using-dht11-with-chibiosrt\/\">DHT11<\/a>&nbsp;and <a href=\"https:\/\/playembedded.org\/en\/2015\/08\/08\/ir-remote-and-stm32-using-chibios\/\">IR Remote<\/a>.<\/p>\n<h4 id=\"8_Connections\" class=\"level_2\">Connections<\/h4>\n<p>The PINs are connected as follow:<\/p>\n<ol>\n<li><strong>VCC<\/strong>, to 5V;<\/li>\n<li><strong>Trig<\/strong>, to PB10;<\/li>\n<li><strong>Echo<\/strong>, to PA8;<\/li>\n<li><strong>GND<\/strong>, to ground.<\/li>\n<\/ol>\n<h4 id=\"9_Demo_explained\" class=\"level_2\">Demo explained<\/h4>\n<p>Taking a look to <em>main.c<\/em> we can see how this demo works. After few initializations the code starts to capture square waves on PA8.<\/p>\n<pre class=\"lang:c decode:true\">#define ICU_TIM_FREQ                1000000\n#define M_TO_CM                     100.0f\n#define SPEED_OF_SOUND              343.2f\n\nstatic float lastdistance = 0.0;\n\nstatic void icuwidthcb(ICUDriver *icup) {\n\n  icucnt_t width = icuGetWidthX(icup);\n  lastdistance = (SPEED_OF_SOUND * width * M_TO_CM) \/ (ICU_TIM_FREQ * 2);\n}\n\n\nstatic ICUConfig icucfg = {\n ICU_INPUT_ACTIVE_HIGH,\n ICU_TIM_FREQ, \/* 1MHz ICU clock frequency. *\/\n icuwidthcb,\n NULL,\n NULL,\n ICU_CHANNEL_1,\n 0\n};<\/pre>\n<p>As said, the information in encapsulated in the width of the squarewave: computing the previous explained formula it is possible to get distance starting from width. The distance will be&nbsp;stored in a variable&nbsp;which is used by main.<\/p>\n<pre class=\"lang:c decode:true \">  while (true) {\n    \/* Triggering *\/\n    palWriteLine(LINE_TRIGGER, PAL_HIGH);\n    chThdSleepMicroseconds(10);\n    palWriteLine(LINE_TRIGGER, PAL_LOW);\n#if ANSI_ESCAPE_CODE_ALLOWED\n    chprintf(chp, \"\\033[2J\\033[1;1H\");\n#endif\n    chprintf(chp, \"Distance: %.2f cm\\n\\r\", lastdistance);\n    chThdSleepMilliseconds(100);\n  }<\/pre>\n<p>The main loop triggers the measurement providing a rising-edge on <strong>Trig<\/strong> and&nbsp;prints the last measure on the STLink&nbsp;Virtual COM port.<\/p>\n<h3 id=\"10_HC_SR04_and_HD44780_mixing_two_demos\" class=\"level_1\">HC-SR04 and HD44780: mixing two demos<\/h3>\n<p>In the article <a href=\"https:\/\/playembedded.org\/en\/2017\/01\/08\/hd44780-backpack-stm32\/\">How to drive a HD44780 with I2C backpack with a STM32<\/a>&nbsp;we have shown how to use an LCD 16&times;2 based on HD44780 provided of an I2C backpack. It is possible to create a more interesting demo including the LCD library in order to print the distance on the display instead of the Virtual COM port.<\/p>\n<h4 id=\"11_Connections\" class=\"level_2\">Connections<\/h4>\n<p>The PINs are connected as follow:<\/p>\n<ol>\n<li><strong>VCC<\/strong> (HC-SR04) and <strong>VCC<\/strong> (HD44780), to 5V;<\/li>\n<li><strong>GND <\/strong>(HC-SR04) and <strong>GND <\/strong>(HD44780), to Ground;<\/li>\n<li><strong>Trig <\/strong>(HC-SR04), to PB10;<\/li>\n<li><strong>Echo<\/strong> (HC-SR04), to PA8;<\/li>\n<li><strong>SDA&nbsp;<\/strong>(HD44780), to PB9;<\/li>\n<li><strong>SCL<\/strong>&nbsp;(HD44780), to PB8.<\/li>\n<\/ol>\n<h4 id=\"12_Demo_explained\" class=\"level_2\">Demo explained<\/h4>\n<p>Lets take a look to the main loop<\/p>\n<pre class=\"lang:c decode:true\">  lcdStart(&amp;LCDD1, &amp;lcdcfg);\n  lcdWriteString(&amp;LCDD1, \"Distance\", 0);\n\n  while (true) {\n    \/* Triggering *\/\n    palWriteLine(LINE_TRIGGER, PAL_HIGH);\n    chThdSleepMicroseconds(10);\n    palWriteLine(LINE_TRIGGER, PAL_LOW);\n\n    chsnprintf(string, sizeof(string), \"%.2f cm       \", lastdistance);\n    lcdWriteString(&amp;LCDD1, string, 40);\n    chThdSleepMilliseconds(200);\n  }<\/pre>\n<p>We can note few things:<\/p>\n<ul>\n<li><em>chprintf()<\/em> is replaced by a <em>lcdWriteString()<\/em>;<\/li>\n<li>first line is printed only once before the loop since it doesn&rsquo;t changes;<\/li>\n<li><em>chsnprintf()<\/em> is a custom implementation of <em>snprintf()<\/em>;<\/li>\n<li>printing the last distance we add some spaces to avoid&nbsp;misprints when the string size decrease.<\/li>\n<\/ul>\n<h3 id=\"13_Project_download\" class=\"level_1\">Project download<\/h3>\n\n\n<p>The project can be found directly in ChibiStudio under the workspace PLAY Embedded with the name &ldquo;<a href=\"https:\/\/github.com\/PLAY-Embedded\/pe_demos\/tree\/master\/RT-STM32F401RE-NUCLEO64-HC-SR04%2BHD44780-PCF8574\">RT-STM32F401RE-NUCLEO64-HC-SR04+HD44780-PCF8574<\/a>&ldquo;.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>HC-SR04: a cheap ultrasonic sensor Description HC-SR04 is a commonly used ultrasonic sensor which is capable to detect obstacles in a range of 2-300cm. The sensor looks like a small PCB having two metal cylinders&nbsp;on the front-side and a small circuit on the back-side (see Fig.1). Documentation In this article we will provide a simple [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":4648,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1225],"tags":[],"coauthors":[241],"class_list":["post-4445","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interfacing-externals","red"],"views":19192,"jetpack_featured_media_url":"https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2017\/01\/HD44780HC-SR04.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/4445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/comments?post=4445"}],"version-history":[{"count":0,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/4445\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media\/4648"}],"wp:attachment":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media?parent=4445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/categories?post=4445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/tags?post=4445"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/coauthors?post=4445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}