Library 30- Measure distance with HC-SR04 and STM32F4
I have at least 10 HC-SR04 sensors at home so I decided to made a library for it. This sensor can measure distance between 2cm and 4meters. It can produce about 40 measurements per second. His working angle is about 15degrees,
On the start, you have to send 10us starting pulse at TRIGGER pin. After that, on ECHO pin high pulse is returned in relation to the distance. Large distance means large high signal.
You have to give sensor some time after you make a conversion. If not, some measurements may be currupted.
Sensor can be used in a lot of projects, like autonomous robot or something like that.
Library
Features
- Measure distance with HC-SR04 sensor
- Number of sensors depends on available GPIO pins on STM32F4 device package
- Checks if sensor is connected
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- TM
- TM DELAY
- TM GPIO
- defines.h
- TM DELAY
Functions and structure
Two simple functions are used to work with sensor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/** * @brief HC-SR04 working structure */ typedef struct { float Distance; /*!< Distance measured from sensor in centi meters */ GPIO_TypeDef* ECHO_GPIOx; /*!< Pointer to GPIOx PORT for ECHO pin. Meant for private use only */ uint16_t ECHO_GPIO_Pin; /*!< GPIO Pin for ECHO pin. Meant for private use only */ GPIO_TypeDef* TRIGGER_GPIOx; /*!< Pointer to GPIOx PORT for TRIGGER pin. Meant for private use only */ uint16_t TRIGGER_GPIO_Pin; /*!< GPIO Pin for ECHO pin. Meant for private use only */ } TM_HCSR04_t; /** * @brief Initializes HC-SR04 sensor * @param *HCSR04: Pointer to empty @ref TM_HCSR04_t structure to save initialization data * @param *ECHO_GPIOx: Pointer to GPIOx PORT for ECHO pin * @param ECHO_GPIO_Pin: GPIO Pin for ECHO pin * @param *TRIGGER_GPIOx: Pointer to GPIOx PORT for TRIGGER pin * @param TRIGGER_GPIO_Pin: GPIO Pin for ECHO pin * @retval HC-SR04 status: * - 0: Device not detected * - > 0: Device is ready to use */ uint8_t TM_HCSR04_Init(TM_HCSR04_t* HCSR04, GPIO_TypeDef* ECHO_GPIOx, uint16_t ECHO_GPIO_Pin, GPIO_TypeDef* TRIGGER_GPIOx, uint16_t TRIGGER_GPIO_Pin); /** * @brief Starts sensor measurement and read it's data * @param *HCSR04: Pointer to @ref TM_HCSR04_t structure to save initialization data * @retval Distance in float: * - > 0: Valid distance in cm (centi meters) * - -1: Error */ float TM_HCSR04_Read(TM_HCSR04_t* HCSR04); |
Example
Example was tested on my all 3 STM32F4 boards. Everytime same result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/** * Keil project for HC-SR04 Ultrasonic distance sensor * * Tested on STM32F4-, STM32F429- Discovery and Nucleo F401RE boards * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_hcsr04.h" #include <stdio.h> int main(void) { /* HCSR04 Instance */ TM_HCSR04_t HCSR04; /* Initialize system */ SystemInit(); /* Initialize delay functions */ TM_DELAY_Init(); /* Initialize LEDs on board */ TM_DISCO_LedInit(); /* Turn on LED red */ TM_DISCO_LedOn(LED_RED); /* Initialize distance sensor1 on pins; ECHO: PD0, TRIGGER: PC1 */ if (!TM_HCSR04_Init(&HCSR04, GPIOD, GPIO_PIN_0, GPIOC, GPIO_PIN_1)) { /* Sensor is not ready to use */ /* Maybe wiring is incorrect */ while (1) { TM_DISCO_LedToggle(LED_RED | LED_GREEN); Delayms(100); } } while (1) { /* Read distance from sensor 1 */ /* Distance is returned in cm and also stored in structure */ /* You can use both ways */ TM_HCSR04_Read(&HCSR04); /* Something is going wrong, maybe incorrect pinout */ if (HCSR04.Distance < 0) { TM_DISCO_LedOn(LED_RED); TM_DISCO_LedOff(LED_GREEN); } else if (HCSR04.Distance > 50) { /* Distance more than 50cm */ TM_DISCO_LedOn(LED_GREEN); TM_DISCO_LedOff(LED_RED); } else { /* Distance between 0 and 50cm */ TM_DISCO_LedOff(LED_GREEN | LED_RED); } /* Give some time to sensor */ Delayms(100); } } |
Project is available on my Github account, download library below.
Recent comments