From f31ea70e1b3341d31c552ac962186f91be9d5bcb Mon Sep 17 00:00:00 2001 From: UncleRus Date: Tue, 11 Oct 2016 09:28:16 +0500 Subject: [PATCH] Driver for ultrasonic range meters + example --- examples/ultrasonic/Makefile | 4 +++ examples/ultrasonic/main.c | 60 ++++++++++++++++++++++++++++++++++ extras/ultrasonic/component.mk | 9 +++++ extras/ultrasonic/ultrasonic.c | 58 ++++++++++++++++++++++++++++++++ extras/ultrasonic/ultrasonic.h | 48 +++++++++++++++++++++++++++ 5 files changed, 179 insertions(+) create mode 100644 examples/ultrasonic/Makefile create mode 100644 examples/ultrasonic/main.c create mode 100644 extras/ultrasonic/component.mk create mode 100644 extras/ultrasonic/ultrasonic.c create mode 100644 extras/ultrasonic/ultrasonic.h diff --git a/examples/ultrasonic/Makefile b/examples/ultrasonic/Makefile new file mode 100644 index 0000000..fd56901 --- /dev/null +++ b/examples/ultrasonic/Makefile @@ -0,0 +1,4 @@ +PROGRAM = ultrasonic +EXTRA_COMPONENTS = extras/ultrasonic + +include ../../common.mk diff --git a/examples/ultrasonic/main.c b/examples/ultrasonic/main.c new file mode 100644 index 0000000..b4b1ac4 --- /dev/null +++ b/examples/ultrasonic/main.c @@ -0,0 +1,60 @@ +/* + * Example of using ultrasonic rnaghe meter like HC-SR04 + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include +#include + +#define TRIGGER_PIN 5 +#define ECHO_PIN 4 + +#define MAX_DISTANCE_CM 500 // 5m max + +void delay_ms(uint32_t ms) +{ + for (uint32_t i = 0; i < ms; i ++) + sdk_os_delay_us(1000); +} + +void user_init() +{ + uart_set_baud(0, 115200); + printf("SDK version : %s\n", sdk_system_get_sdk_version()); + + ultrasonic_sensor_t sensor = { + .trigger_pin = TRIGGER_PIN, + .echo_pin = ECHO_PIN + }; + + ultrasoinc_init(&sensor); + + while (true) + { + int32_t distance = ultrasoinc_measure_cm(&sensor, MAX_DISTANCE_CM); + if (distance < 0) + { + printf("Error: "); + switch (distance) + { + case ULTRASONIC_ERROR_PING: + printf("Cannot ping (device is in invalid state)\n"); + break; + case ULTRASONIC_ERROR_PING_TIMEOUT: + printf("Ping timeout (no device found)\n"); + break; + case ULTRASONIC_ERROR_ECHO_TIMEOUT: + printf("Echo timeout (i.e. distance too big)\n"); + break; + } + } + else + printf("Distance: %d cm, %.02f m\n", distance, distance / 100.0); + + delay_ms(200); + } +} diff --git a/extras/ultrasonic/component.mk b/extras/ultrasonic/component.mk new file mode 100644 index 0000000..9b20df0 --- /dev/null +++ b/extras/ultrasonic/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/ultrasonic + +# expected anyone using this driver includes it as 'ultrasonic/ultrasonic.h' +INC_DIRS += $(ultrasonic_ROOT).. + +# args for passing into compile rule generation +ultrasonic_SRC_DIR = $(ultrasonic_ROOT) + +$(eval $(call component_compile_rules,ultrasonic)) diff --git a/extras/ultrasonic/ultrasonic.c b/extras/ultrasonic/ultrasonic.c new file mode 100644 index 0000000..f6a21f6 --- /dev/null +++ b/extras/ultrasonic/ultrasonic.c @@ -0,0 +1,58 @@ +/* + * Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 and so on + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * BSD Licensed as described in the file LICENSE + */ +#include "ultrasonic.h" +#include +#include +#include + +#define TRIGGER_LOW_DELAY 4 +#define TRIGGER_HIGH_DELAY 10 +#define PING_TIMEOUT 6000 +#define ROUNDTRIP 58 + +void ultrasoinc_init(const ultrasonic_sensor_t *dev) +{ + gpio_enable(dev->trigger_pin, GPIO_OUTPUT); + gpio_enable(dev->echo_pin, GPIO_INPUT); + gpio_write(dev->trigger_pin, false); +} + +int32_t ultrasoinc_measure_cm(const ultrasonic_sensor_t *dev, uint32_t max_distance) +{ + // Ping: Low for 2..4 us, then high 10 us + gpio_write(dev->trigger_pin, false); + sdk_os_delay_us(TRIGGER_LOW_DELAY); + gpio_write(dev->trigger_pin, true); + sdk_os_delay_us(TRIGGER_HIGH_DELAY); + gpio_write(dev->trigger_pin, false); + + // Previous ping isn't ended + if (gpio_read(dev->echo_pin)) + return ULTRASONIC_ERROR_PING; + + // Wait for echo + uint32_t timeout = sdk_system_get_time() + PING_TIMEOUT; + while (!gpio_read(dev->echo_pin)) + { + if (sdk_system_get_time() >= timeout) + return ULTRASONIC_ERROR_PING_TIMEOUT; + } + + // got echo, measuring + uint32_t echo_start = sdk_system_get_time(); + uint32_t time = echo_start; + timeout = echo_start + max_distance * ROUNDTRIP; + while (gpio_read(dev->echo_pin)) + { + time = sdk_system_get_time(); + if (time >= timeout) + return ULTRASONIC_ERROR_ECHO_TIMEOUT; + } + + return (time - echo_start) / ROUNDTRIP; +} diff --git a/extras/ultrasonic/ultrasonic.h b/extras/ultrasonic/ultrasonic.h new file mode 100644 index 0000000..6ade82d --- /dev/null +++ b/extras/ultrasonic/ultrasonic.h @@ -0,0 +1,48 @@ +/* + * Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 and so on + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * BSD Licensed as described in the file LICENSE + */ +#ifndef EXTRAS_ULTRASONIC_H_ +#define EXTRAS_ULTRASONIC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ULTRASONIC_ERROR_PING (-1) +#define ULTRASONIC_ERROR_PING_TIMEOUT (-2) +#define ULTRASONIC_ERROR_ECHO_TIMEOUT (-3) + +/** + * Device descriptor + */ +typedef struct +{ + uint8_t trigger_pin; + uint8_t echo_pin; +} ultrasonic_sensor_t; + +/** + * Init ranging module + * \param dev Pointer to the device descriptor + */ +void ultrasoinc_init(const ultrasonic_sensor_t *dev); + +/** + * Measure distance + * \param dev Pointer to the device descriptor + * \param max_distance Maximal distance to measure, centimeters + * \return Distance in centimeters or ULTRASONIC_ERROR_xxx if error occured + */ +int32_t ultrasoinc_measure_cm(const ultrasonic_sensor_t *dev, uint32_t max_distance); + +#ifdef __cplusplus +} +#endif + +#endif /* EXTRAS_ULTRASONIC_H_ */