diff --git a/drivers/Makefile b/drivers/Makefile index f2a580dff343b109f223c4ade19eccd680c87893..fbe4236691846e18533bfeeb40c117f5aca982f3 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -34,5 +34,8 @@ endif ifneq (,$(filter rgbled,$(USEMODULE))) DIRS += rgbled endif +ifneq (,$(filter servo,$(USEMODULE))) + DIRS += servo +endif include $(RIOTBASE)/Makefile.base diff --git a/drivers/include/servo.h b/drivers/include/servo.h new file mode 100644 index 0000000000000000000000000000000000000000..0e398c13f1f7277938519914d21b8ead9cfb40ae --- /dev/null +++ b/drivers/include/servo.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup driver_servo Servo Motor Driver + * @ingroup drivers + * @brief High-level driver for servo motors + * @{ + * + * @file + * @brief High-level driver for easy handling of servo motors + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + */ + +#ifndef __SERVO_H +#define __SERVO_H + +#include "periph/pwm.h" + + +/** + * @name Descriptor struct for a servo + */ +typedef struct { + pwm_t device; /**< the PWM device driving the servo */ + int channel; /**< the channel the servo is connected to */ + unsigned int min; /**< minimum pulse width, in us */ + unsigned int max; /**< maximum pulse width, in us */ +} servo_t; + +/** + * @brief Initialize a servo motor by assigning it a PWM device and channel + * + * Digital servos are controlled by regular pulses sent to them. The width + * of a pulse determines the position of the servo. A pulse width of 1.5ms + * puts the servo in the center position, a pulse width of about 1.0ms and + * about 2.0ms put the servo to the maximum angles. These values can however + * differ slightly from servo to servo, so the min and max values are + * parameterized in the init function. + * + * The servo is initialized with fixed PWM values: + * - frequency: 100Hz (10ms interval) + * - resolution: 10000 (1000 steps per ms) + * + * Caution: When initializing a servo, the PWM device will be reconfigured to + * new frequency/resolution values. It is however fine to use multiple servos + * with the same PWM device, just on different channels. + * + * @param[out] dev struct describing the servo + * @param[in] pwm the PWM device the servo is connected to + * @param[in] pwm_channel the PWM channel the servo is connected to + * @param[in] min minimum pulse width in us + * @param[in] max maximum pulse width in us + * + * @return 0 on success + * @return <0 on error + */ +int servo_init(servo_t *dev, pwm_t pwm, int pwm_channel, unsigned int min, unsigned int max); + +/** + * @brief Set the servo motor to a specified position + * + * The position of the servo is specified in the pulse width that controls the + * servo. A value of 1500 means a pulse width of 1.5 ms, which is the center + * position on most servos. + * + * In case pos is larger/smaller then the max/min values, pos will be set to + * these values. + * + * @param[in] dev the servo to set + * @param[in] pos the position to set the servo in us + * + * @return 0 on success + * @return -1 on invalid configured channel + * @return -2 on invalid position + */ +int servo_set(servo_t *dev, unsigned int pos); + +#endif /* __SERVO_H */ +/** @} */ diff --git a/drivers/servo/Makefile b/drivers/servo/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2ff3f9dcb1578f659c8a4f9e9490a2ce64deef53 --- /dev/null +++ b/drivers/servo/Makefile @@ -0,0 +1,3 @@ +MODULE = servo + +include $(RIOTBASE)/Makefile.base diff --git a/drivers/servo/servo.c b/drivers/servo/servo.c new file mode 100644 index 0000000000000000000000000000000000000000..a3265c451c3e19550e8a37bfa7f9dc04eb041771 --- /dev/null +++ b/drivers/servo/servo.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup driver_servo + * @{ + * + * @file + * @brief Servo motor driver implementation + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + * + * @} + */ + +#include "servo.h" +#include "periph/pwm.h" + +#define FREQUENCY (100U) +#define RESOLUTION (10000U) + +int servo_init(servo_t *dev, pwm_t pwm, int pwm_channel, unsigned int min, unsigned int max) +{ + dev->device = pwm; + dev->channel = pwm_channel; + dev->min = min; + dev->max = max; + + return pwm_init(dev->device, PWM_LEFT, FREQUENCY, RESOLUTION); +} + +int servo_set(servo_t *dev, unsigned int pos) +{ + if (pos > dev->max) { + pos = dev->max; + } + else (pos < dev->min) { + pos = dev->min; + } + return pwm_set(dev->device, dev->channel, pos); +}