Controlling more LEDs from a blinky

Hello,

From the blinky example, how would I go about blinking LED0 to LED1 or LED0 to LED2 like a knight rider circuit?

This is what I have done so far that works for LED0 and LED1:

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <drivers/gpio.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   500

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
#define LED1_NODE DT_ALIAS(led1)
/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led_0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec led_1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
void main(void)
{
	int ret0;
	int ret1;
	if (!device_is_ready(led_0.port)) {
		return;
	}
	if (!device_is_ready(led_1.port)) {
		return;
	}
	ret0 = gpio_pin_configure_dt(&led_0, GPIO_OUTPUT_ACTIVE);
	if (ret0 < 0) {
		return;
	}
	ret1 = gpio_pin_configure_dt(&led_1, GPIO_OUTPUT_ACTIVE);
	if (ret1 < 0) {
		return;
	}

	while (1) {
		ret0 = gpio_pin_toggle_dt(&led_0);
		if (ret0 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);
		ret0 = gpio_pin_toggle_dt(&led_0);
		ret1 = gpio_pin_toggle_dt(&led_1);
		if (ret1 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);
		ret1 = gpio_pin_toggle_dt(&led_1);
		// ret0 = gpio_pin_toggle_dt(&led_0);
		// if (ret0 < 0) {
		// 	return;
		// }
		// k_msleep(SLEEP_TIME_MS);
		// ret1 = gpio_pin_toggle_dt(&led_1);
		// if (ret1 < 0) {
		// 	return;
		// }
		// k_msleep(SLEEP_TIME_MS);
	}
}

and code below is for LED0 to LED3

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <drivers/gpio.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   80

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
#define LED1_NODE DT_ALIAS(led1)
#define LED2_NODE DT_ALIAS(led2)
#define LED3_NODE DT_ALIAS(led3)
/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led_0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec led_1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
static const struct gpio_dt_spec led_2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);
static const struct gpio_dt_spec led_3 = GPIO_DT_SPEC_GET(LED3_NODE, gpios);
void main(void)
{
	int ret0;
	int ret1;
	int ret2;
	int ret3;
	if (!device_is_ready(led_0.port)) {
		return;
	}
	if (!device_is_ready(led_1.port)) {
		return;
	}
	if (!device_is_ready(led_2.port)) {
		return;
	}
	if (!device_is_ready(led_3.port)) {
		return;
	}
	/* Sets all the LEDs to OFF state */
	ret0 = gpio_pin_configure_dt(&led_0, GPIO_OUTPUT_INACTIVE);
	if (ret0 < 0) {
		return;
	}
	ret1 = gpio_pin_configure_dt(&led_1, GPIO_OUTPUT_INACTIVE);
	if (ret1 < 0) {
		return;
	}
	ret2 = gpio_pin_configure_dt(&led_2, GPIO_OUTPUT_INACTIVE);
	if (ret2 < 0) {
		return;
	}
	ret3 = gpio_pin_configure_dt(&led_3, GPIO_OUTPUT_INACTIVE);
	if (ret3 < 0) {
		return;
	}

	while (1) {
		/* Turns on LED0 */
		ret0 = gpio_pin_toggle_dt(&led_0);
		if (ret0 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);

		/* Turns off LED0 and turns on LED1*/
		ret0 = gpio_pin_toggle_dt(&led_0);
		ret1 = gpio_pin_toggle_dt(&led_1);
		if (ret1 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);

		/* Turns off LED1 and turns on LED3*/
		ret1 = gpio_pin_toggle_dt(&led_1);
		ret3 = gpio_pin_toggle_dt(&led_3);
		if (ret3 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);

		/* Turns off LED3 and turns on LED2*/
		ret3 = gpio_pin_toggle_dt(&led_3);
		ret2 = gpio_pin_toggle_dt(&led_2);
		if (ret2 < 0) {
			return;
		}
		k_msleep(SLEEP_TIME_MS);

		/* Turns off LED2*/
		ret2 = gpio_pin_toggle_dt(&led_2);

		// ret0 = gpio_pin_toggle_dt(&led_0);
		// if (ret0 < 0) {
		// 	return;
		// }
		// k_msleep(SLEEP_TIME_MS);
		// ret1 = gpio_pin_toggle_dt(&led_1);
		// if (ret1 < 0) {
		// 	return;
		// }
		// k_msleep(SLEEP_TIME_MS);
	}
}

I'd like to also ask any way to improve my code? optimize? that would be appreciated.

board: nrf52840dk

Parents
  • Hello,

    Here is a slightly more condensed version of your code:

    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS 80
    
    /* The devicetree node identifier for the "led0" alias. */
    #define LED0_NODE DT_ALIAS(led0)
    #define LED1_NODE DT_ALIAS(led1)
    #define LED2_NODE DT_ALIAS(led2)
    #define LED3_NODE DT_ALIAS(led3)
    
    
    static const struct gpio_dt_spec led[] = {
    	GPIO_DT_SPEC_GET(LED0_NODE, gpios),
    	GPIO_DT_SPEC_GET(LED1_NODE, gpios),
    	GPIO_DT_SPEC_GET(LED2_NODE, gpios),
    	GPIO_DT_SPEC_GET(LED3_NODE, gpios)
    };
    
    void main(void)
    {
    	int ret;
    	int led_num = ARRAY_SIZE(led);
    
    	/* No need to check all pins if they are all on the same Port/device */
    	if (!gpio_is_ready_dt(&led[0])) {
    		printk("GPIO port is not ready.\n");
    		return;
    	}
    
    	/* Initialize LED pins as outputs */
    	for (int i=0; i < led_num; i++) {
    		ret = gpio_pin_configure_dt(&led[i], GPIO_OUTPUT_INACTIVE);
    		if (ret < 0) {
    			printk("gpio_pin_configure_dt() failed for pin %d(err %d)\n", led[i].pin, ret);
    		};
    	}
    
    	while(1) {
    		for (int i = 0; i < led_num; i++) {
    			(void)gpio_pin_set_dt(&led[i], 1);
    			k_msleep(SLEEP_TIME_MS);
    			(void)gpio_pin_set_dt(&led[i], 0);
    		}
    
    		for (int k = led_num - 2; k > 0; k--) {
    			(void)gpio_pin_set_dt(&led[k], 1);
    			k_msleep(SLEEP_TIME_MS);
    			(void)gpio_pin_set_dt(&led[k], 0);
    		}
    	}
    }

    Best regards,

    Vidar

  • Hello Vidar

    It seems I ran into a roadblock of sorts.

    if (!gpio_is_ready_dt(&led[0])) {
    		printk("GPIO port is not ready.\n");
    		return;
    	}

    Looks like a similar issue to:  gpio_is_ready_dt not found in nRF Connect SDK

    if (!device_is_ready(led[0].port)) {
    		printk("GPIO port is not ready.\n");
    		return;
    	}

    This code above allowed the program to build.

    Just curious, why isn't gpio_is_ready_dt not part of the sdk? is there a way we can get it?

  • It seems like you are using an older version of the nRF Connect SDK.

    Commit that introduced this function:

    https://github.com/nrfconnect/sdk-zephyr/commit/016f0d4fbe93dfe6a5b51ac565faf17981bf29ab 

Reply Children
Related