samples: servo_motor: cleanups and changes
Align the sample with changes made to other basic samples. Move away from 'pwm-0' as a devicetree alias, requiring applications to define a 'pwm-servo' alias. We are getting rid of the aliases that just bounce through to node labels as soon as we can, might as well get the applications ready now. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
a0f940ae04
commit
e959386bd2
@ -1,20 +1,47 @@
|
||||
.. _servo-motor-sample:
|
||||
|
||||
PWM: Servo motor
|
||||
################
|
||||
Servomotor
|
||||
##########
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This is a sample app which drives a servo motor using PWM.
|
||||
This is a sample app which drives a servomotor using PWM.
|
||||
|
||||
This app is targeted for servo motor ROB-09065. With the PWM control signal, the
|
||||
servo motor can rotate to any angle between 0 and 180 degrees. The corresponding
|
||||
PWM pulse width is between 700 micro seconds and 2300 micro seconds. The motor
|
||||
is programmed to rotate back and forth in the 180 degree range.
|
||||
The sample rotates a servomotor back and forth in the 180 degree range with a
|
||||
PWM control signal.
|
||||
|
||||
Since different servo motors may require different PWM pulse width, you may need
|
||||
to modify the pulse width in the app if you are using a different servo motor.
|
||||
This app is targeted for servomotor ROB-09065. The corresponding PWM pulse
|
||||
widths for a 0 to 180 degree range are 700 to 2300 microseconds, respectively.
|
||||
Different servomotors may require different PWM pulse widths, and you may need
|
||||
to modify the source code if you are using a different servomotor.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
The servomotor must be connected via PWM. The PWM device must be configured
|
||||
using the ``pwm-servo`` :ref:`devicetree <dt-guide>` alias. Usually you will
|
||||
need to set this up via a :ref:`devicetree overlay <set-devicetree-overlays>`
|
||||
like so:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
pwm-servo = &foo;
|
||||
};
|
||||
};
|
||||
|
||||
Where ``foo`` is the node label of a PWM device in your system.
|
||||
|
||||
You will see this error if you try to build this sample for an unsupported
|
||||
board:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Unsupported board: pwm-servo devicetree alias is not defined
|
||||
|
||||
The sample uses PWM channel 0.
|
||||
|
||||
Wiring
|
||||
******
|
||||
@ -28,6 +55,9 @@ ground and the white wire to pad 0 on the edge connector.
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
The sample has a devicetree overlay for the :ref:`bbc_microbit` which uses
|
||||
``pwm0``.
|
||||
|
||||
This sample can be built for multiple boards, in this example we will build it
|
||||
for the bbc_microbit board:
|
||||
|
||||
|
||||
@ -5,4 +5,4 @@ tests:
|
||||
tags: drivers pwm
|
||||
depends_on: pwm
|
||||
harness: motor
|
||||
filter: dt_alias_exists("pwm-0")
|
||||
filter: dt_alias_exists("pwm-servo")
|
||||
|
||||
@ -5,9 +5,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Sample app to demonstrate PWM.
|
||||
*
|
||||
* This app uses PWM[0].
|
||||
* @file Sample app to demonstrate PWM-based servomotor control
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
@ -15,54 +13,57 @@
|
||||
#include <device.h>
|
||||
#include <drivers/pwm.h>
|
||||
|
||||
#if !DT_NODE_HAS_STATUS(DT_ALIAS(pwm_0), okay)
|
||||
#error "Choose supported board or add new board for the application"
|
||||
#define PWM_NODE DT_ALIAS(pwm_servo)
|
||||
|
||||
#if !DT_NODE_HAS_STATUS(PWM_NODE, okay)
|
||||
#error "Unsupported board: pwm-servo devicetree alias is not defined or enabled"
|
||||
#define PWM_LABEL ""
|
||||
#else
|
||||
#define PWM_LABEL DT_LABEL(PWM_NODE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unlike pulse width, period is not a critical parameter for
|
||||
* motor control. 20ms is commonly used.
|
||||
* Unlike pulse width, the PWM period is not a critical parameter for
|
||||
* motor control. 20 ms is commonly used.
|
||||
*/
|
||||
#define PERIOD (USEC_PER_SEC / 50U)
|
||||
|
||||
/* all in micro second */
|
||||
#define STEPSIZE 100
|
||||
#define MINPULSEWIDTH 700
|
||||
#define MAXPULSEWIDTH 2300
|
||||
#define PERIOD_USEC (20U * USEC_PER_MSEC)
|
||||
#define STEP_USEC 100
|
||||
#define MIN_PULSE_USEC 700
|
||||
#define MAX_PULSE_USEC 2300
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct device *pwm_dev;
|
||||
u32_t pulse_width = MINPULSEWIDTH;
|
||||
struct device *pwm;
|
||||
u32_t pulse_width = MIN_PULSE_USEC;
|
||||
u8_t dir = 0U;
|
||||
|
||||
printk("PWM demo app-servo control\n");
|
||||
printk("Servomotor control\n");
|
||||
|
||||
pwm_dev = device_get_binding(DT_LABEL(DT_ALIAS(pwm_0)));
|
||||
if (!pwm_dev) {
|
||||
printk("Cannot find PWM device!\n");
|
||||
pwm = device_get_binding(PWM_LABEL);
|
||||
if (!pwm) {
|
||||
printk("Error: didn't find %s device\n", PWM_LABEL);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (pwm_pin_set_usec(pwm_dev, 0, PERIOD, pulse_width, 0)) {
|
||||
printk("pwm pin set fails\n");
|
||||
if (pwm_pin_set_usec(pwm, 0, PERIOD_USEC, pulse_width, 0)) {
|
||||
printk("Error %d: failed to set pulse width\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dir) {
|
||||
if (pulse_width <= MINPULSEWIDTH) {
|
||||
if (pulse_width <= MIN_PULSE_USEC) {
|
||||
dir = 0U;
|
||||
pulse_width = MINPULSEWIDTH;
|
||||
pulse_width = MIN_PULSE_USEC;
|
||||
} else {
|
||||
pulse_width -= STEPSIZE;
|
||||
pulse_width -= STEP_USEC;
|
||||
}
|
||||
} else {
|
||||
pulse_width += STEPSIZE;
|
||||
pulse_width += STEP_USEC;
|
||||
|
||||
if (pulse_width >= MAXPULSEWIDTH) {
|
||||
if (pulse_width >= MAX_PULSE_USEC) {
|
||||
dir = 1U;
|
||||
pulse_width = MAXPULSEWIDTH;
|
||||
pulse_width = MAX_PULSE_USEC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user