El propósito de este artículo es demostrar como se controla via el módulo de modulación de ancho de pulso conocido como PWM a un servo conectado a el kit IoT Nordic nRF54L15-DK,
Antes de proceder con estre demo, por favor sigua los pasos del previo artículo de los pasos a seguir para instalar el Nordic nRF54L15-DK Zephyr Linux
La siguiente table del Nordic kit nRF54L15-DK fue usada para derivar cual PIN en el kit de Nordic nRF54L15-DK se puede usar para conectar la señal del modula de PWM para controlar un servo externo,
| P1 signal | Function | Default connected on P1 |
|---|---|---|
| P1.00 | 32.768 kHz, XL1 | No. Solder bridges must be configured. |
| P1.01 | 32.768 kHz, XL2 | No. Solder bridges must be configured. |
| P1.02 | NFC1 | No. 0R resistors must be configured. |
| P1.03 | NFC2 | No. 0R resistors must be configured. |
| P1.04 | UART1_TXD | Yes. |
| P1.05 | UART1_RXD | Yes. |
| P1.06 | UART1_RST | Yes. |
| P1.07 | UART1_CTS | Yes. |
| P1.08 | Button 2 | Yes. |
| P1.09 | Button 1 | Yes. |
| P1.10 | LED 1 | Yes. |
| P1.11 | Yes. | |
| P1.12 | Yes. | |
| P1.13 | Button 0 | Yes. |
| P1.14 | LED 3 | Yes. |
Como el P1.11 esta disponible, se va a utilizar en este demo de control de servo. En el previo artículo IoT Nordic nRF54L15-DK Zephyr PWM LED P1.10 se uso para conectar la señal PWM a el LED1 en el kit IoT de Nordic nRF54L15-DK. Ahora se crea el siguiente archivo de configuración de Zephyr llamado proj.conf en el directorio de su preferencia,
CONFIG_LOG=y
CONFIG_LED=y
CONFIG_LED_PWM=y
Por el proceso standard de desarollo de Zephyr, se incluye el archivo llamado CMakeLists.txt dentro del directorio del projecto,
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(spi)
target_sources(app PRIVATE src/main.c)
También se incluye el siguiente archivo overlay de Zephyr llamado nrf54l15dk_nrf54l15.overlay
/{
pwmleds {
compatible = "pwm-leds";
pwm_led0: pwm_led_0 {
pwms = <&pwm20 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
};
};
};
&pwm20 {
status = "okay";
pinctrl-0 = <&pwm20_custom>;
pinctrl-1 = <&pwm20_csleep>;
pinctrl-names = "default", "sleep";
};
&pinctrl {
pwm20_custom: pwm20_custom {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 11)>;
nordic,invert;
};
};
pwm20_csleep: pwm20_csleep {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 11)>;
low-power-enable;
};
};
};
Aquí en DigiKey se desarrollo una version para ilustrar como se controla un servo externo con el siguiente código main.c,
/* DigiKey Coffee Cup Servo Control Version **/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/drivers/pwm.h>
LOG_MODULE_REGISTER(DigiKey_Coffee_Cup, LOG_LEVEL_INF);
#define PWM_PERIOD PWM_MSEC(20)
#define PWM_SERVO_MIN_PULSE_WIDTH PWM_USEC(100)
#define PWM_SERVO_MAX_PULSE_WIDTH PWM_USEC(1100)
#define PWM_LED0 DT_ALIAS(pwm_led0)
static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(PWM_LED0);
int set_motor_angle(uint32_t pulse_width_ns)
{
int err;
err = pwm_set_dt(&pwm_led0, PWM_PERIOD, pulse_width_ns);
if (err) {
LOG_ERR("pwm_set_dt_returned %d", err);
}
return err;
}
int main(void)
{
int err;
if (!pwm_is_ready_dt(&pwm_led0)) {
LOG_ERR("Error: PWM device %s is not ready", pwm_led0.dev->name);
return 0;
}
err = pwm_set_dt(&pwm_led0, PWM_PERIOD, PWM_SERVO_MIN_PULSE_WIDTH );
if (err) {
LOG_ERR("Error in pwm_set_dt(), err: %d", err);
return 0;
}
while(1)
{
err = set_motor_angle(PWM_SERVO_MIN_PULSE_WIDTH);
if (err) {
LOG_ERR("Error: couldn't set duty cycle, err %d", err);
}
k_msleep(1000);
err = set_motor_angle(PWM_SERVO_MAX_PULSE_WIDTH);
if (err) {
LOG_ERR("Error: couldn't set duty cycle, err %d", err);
}
k_msleep(1000);
}
return 0;
}
El directorio del projecto de Zephyr es como se muestra a continuación,
|-- CMakeLists.txt
|-- nrf54l15dk_nrf54l15.overlay
|-- prj.conf
`-- src
|-- main.c
Ahora se procede a construir el projecto de Zephyr así,
digikey_coffee_cup (venv) $ west build -p always -b nrf54l15dk/nrf54l15/cpuapp -- -DEXTRA_DTC_OVERLAY_FILE=nrf54l15dk_nrf54l15.overlay
Finalmente se conecta el Nordic IoT nRF54L15-DK vía la interfaz de USB para programarlo así,
digikey_coffee_cup (venv) $ west flash
Antes de conectar el servo a el Nordic nRF54L15-DK kit, el Sparkfun 8-channel USB Logic Analyzer fue conectado a el Port 1 - Pin 11 en la plataforma para observar la señal de PWM. Los aspectos importantes de la señal de PWM signal relevantes a este demo de control del servo fueron previamente definidas en el código main.c son,
#define PWM_PERIOD PWM_MSEC(20)
#define PWM_SERVO_MIN_PULSE_WIDTH PWM_USEC(100)
#define PWM_SERVO_MAX_PULSE_WIDTH PWM_USEC(1100)
Estos parámetros (para propósitos de ilustración solamente) definen un periodo de 20 ms de la señal de PWM con un máximo ancho de pulso de 1.1 ms y un ancho mínimo de 100 us. Estos dos anchos son las señales de PWM que se usan para controlar el servo en este demo. La próxima captura del Analizador Lógico USB de 8-canales de Sparkfun muestra que las características de la señal de PWM estan de acuerdo con las especificaciones del código main.c, un periodo de 20 ms de la señal de PWM para ambos estados (1.1 ms y 100 us) como se muestra aquí,
Caso de 1.1 ms con un periodo de 20 ms
Caso de 100 us con un periodo de 20 ms
acercando la captura de estos eventos con el Analizador Lógico USB de 8-canales de Sparkfun se muestran a continuación,
(Acercamiento) Caso de ancho de pulso de 1.1 ms con un periodo de 20 ms
(Acercamiento) Caso de ancho de pulso de 100 us con un periodo de 20 ms
El Analizador Lógico USB de 8-canales de Sparkfun se puede usar para medir los anchos de estos pulsos como se demonstro anteriormente. Estos dos estados del módulo de PWM fueron definidos en el código main.c usando las siguientes llamadas a la función de establecer el ángulo del servo, uno para el mínimo ancho del pulso y otro para el máximo ancho de pulso, correspondientes a el “duty cycle” mínimo y otro para el “duty cycle” máximo ,
set_motor_angle(PWM_SERVO_MIN_PULSE_WIDTH);
set_motor_angle(PWM_SERVO_MAX_PULSE_WIDTH);
Estos parámetros fueron usados para propósitos ilustrativos solamente, se pueden optimizar y cambiar como sea necesario, dependiendo del servo usado en la aplicación. Hemos demostrado como controlar un servo usando el sistema operativo Zephyrcon el kit IoT Nordic nRF54L15-DK. El kit IoT Nordic nRF54L15-DK de es una excelente plataforma para desarollar aplicaciones IoT.
y está disponible en DigiKey. Que tenga buen día.
This article is also available in english here.
Este artículo está disponible en inglés aquí.




