Skip to content

Commit

Permalink
Get started example update for addressable LED compatibility.
Browse files Browse the repository at this point in the history
 Added the RMT/addr LED blink to the example and more detailed README.md
 Moved component/led_strip to common_components
 Added missing README file to common_components/led_strip
 README file update
 Makefile and Kconfig fixed for led_strip component
 Fixing end-of-line on main/blink.c
 Component updated to handle multiple instances
 Added note on the RMT channel number (ESP32 and ESP32-S2)
 Removed components folder from rmt/led_strip example and README updated
 Changed the led_strip_denit function and added ESP32-C3 RMT info on channel configuration
 Updates on README, Kconfig default settings and configure_led() function added
  • Loading branch information
pedrominatel committed Feb 15, 2021
1 parent 2c0962f commit cccdb3e
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 34 deletions.
4 changes: 4 additions & 0 deletions examples/common_components/led_strip/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(SRCS "led_strip_rmt_ws2812.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES "driver"
)
16 changes: 16 additions & 0 deletions examples/common_components/led_strip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# LED Strip Component

This directory contains an implementation for addressable LEDs using the RMT peripheral.

It's compatible with:

* [WS2812](http://www.world-semi.com/Certifications/WS2812B.html)
* SK68XX

This component is used as part of the following ESP-IDF examples:
- [Blink Example](../../get-started/blink).
- [LED Strip Example](../../peripherals/rmt/led_strip).

To learn more about how to use this component, please check API Documentation from header file [led_strip.h](./include/led_strip.h).

Please note that this component is not considered to be a part of ESP-IDF stable API. It may change and it may be removed in the future releases.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,27 @@ typedef struct {
*/
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config);

/**
* @brief Init the RMT peripheral and LED strip configuration.
*
* @param[in] channel: RMT peripheral channel number.
* @param[in] gpio: GPIO number for the RMT data output.
* @param[in] led_num: number of addressable LEDs.
* @return
* LED strip instance or NULL
*/
led_strip_t * led_strip_init(uint8_t channel, uint8_t gpio, uint16_t led_num);

/**
* @brief Denit the RMT peripheral.
*
* @param[in] strip: LED strip
* @return
* - ESP_OK
* - ESP_FAIL
*/
esp_err_t led_strip_denit(led_strip_t *strip);

#ifdef __cplusplus
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "led_strip.h"
#include "driver/rmt.h"

#define RMT_TX_CHANNEL RMT_CHANNEL_0

static const char *TAG = "ws2812";
#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \
do \
Expand Down Expand Up @@ -169,3 +171,37 @@ led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config)
err:
return ret;
}

led_strip_t * led_strip_init(uint8_t channel, uint8_t gpio, uint16_t led_num)
{
static led_strip_t *pStrip;

rmt_config_t config = RMT_DEFAULT_CONFIG_TX(gpio, channel);
// set counter clock to 40MHz
config.clk_div = 2;

ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));

// install ws2812 driver
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(led_num, (led_strip_dev_t)config.channel);

pStrip = led_strip_new_rmt_ws2812(&strip_config);

if ( !pStrip ) {
ESP_LOGE(TAG, "install WS2812 driver failed");
return NULL;
}

// Clear LED strip (turn off all LEDs)
ESP_ERROR_CHECK(pStrip->clear(pStrip, 100));

return pStrip;
}

esp_err_t led_strip_denit(led_strip_t *strip)
{
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
ESP_ERROR_CHECK(rmt_driver_uninstall(ws2812->rmt_channel));
return strip->del(strip);
}
2 changes: 2 additions & 0 deletions examples/get-started/blink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/led_strip)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(blink)
2 changes: 2 additions & 0 deletions examples/get-started/blink/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

PROJECT_NAME := blink

EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/led_strip

include $(IDF_PATH)/make/project.mk
62 changes: 60 additions & 2 deletions examples/get-started/blink/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
# Blink Example

Starts a FreeRTOS task to blink an LED
(See the README.md file in the upper level 'examples' directory for more information about examples.)

See the README.md file in the upper level 'examples' directory for more information about examples.
This example demonstrates how to blink a LED using GPIO or RMT for the addressable LED, i.e. [WS2812](http://www.world-semi.com/Certifications/WS2812B.html).

See the RMT examples in the [RMT Peripheral](../../peripherals/rmt) for more information about how to use it.

## How to Use Example

Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.

### Hardware Required

* A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for Power supply and programming

Some development boards use an addressable LED instead of a regular one. These development boards include:

| Board | LED type | Pin |
| -------------------- | -------------------- | -------------------- |
| ESP32-C3-DevKitC-1 | Addressable | GPIO8 |
| ESP32-C3-DevKitM-1 | Addressable | GPIO8 |
| ESP32-S2-DevKitM-1 | Addressable | GPIO18 |
| ESP32-S2-Saola-1 | Addressable | GPIO18 |

See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it.

### Configure the Project

Open the project configuration menu (`idf.py menuconfig`).

In the `Example Configuration` menu:

* Select the LED type in the `Blink LED type` option.
* * Use `GPIO` for regular LED blink.
* * Use `RMT` for addressable LED blink.
* * * Use `RMT Channel` to select the RMT peripheral channel.
* Set the GPIO number used for the signal in the `Blink GPIO number` option.
* Set the blinking period in the `Blink period in ms` option.


### Build and Flash

Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.

(To exit the serial monitor, type ``Ctrl-]``.)

See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.

## Example Output

As you run the example, you will see the LED blinking, according to the previously defined period. For the addressable LED, you can also change the LED color by setting the `pStrip_a->set_pixel(pStrip_a, 0, 16, 16, 16);` (LED Strip, Pixel Number, Red, Green, Blue) with values from 0 to 255 in the `blink.c` file.

Note: The color order could be different according to the LED model.

The pixel number indicates the pixel position in the LED strip. For a single LED, use 0.

## Troubleshooting

* If the LED isn't blinking, check the GPIO or the LED type selection in the `Example Configuration` menu.

For any technical queries, please open an [issue] (https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
38 changes: 35 additions & 3 deletions examples/get-started/blink/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
menu "Example Configuration"

choice BLINK_LED
prompt "Blink LED type"
default BLINK_LED_RMT if IDF_TARGET_ESP32C3
default BLINK_LED_RMT if IDF_TARGET_ESP32S2
default BLINK_LED_GPIO
help
Defines the default peripheral for blink example

config BLINK_LED_GPIO
bool "GPIO"
config BLINK_LED_RMT
bool "RMT - Addressable LED"
endchoice

config BLINK_LED_RMT_CHANNEL
depends on BLINK_LED_RMT
int "RMT Channel"
range 0 7
default 0
help
Set the RMT peripheral channel.
ESP32 RMT channel from 0 to 7
ESP32-S2 RMT channel from 0 to 3
ESP32-C3 RMT channel from 0 to 1

config BLINK_GPIO
int "Blink GPIO number"
range 0 34
default 8 if IDF_TARGET_ESP32C3
default 18 if IDF_TARGET_ESP32S2
default 5
help
GPIO number (IOxx) to blink on and off.

GPIO number (IOxx) to blink on and off or the RMT signal for the addressable LED.
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink.

GPIOs 35-39 are input-only so cannot be used as outputs.

config BLINK_PERIOD
int "Blink period in ms"
range 10 3600000
default 1000
help
Define the blinking period in milliseconds.

endmenu
76 changes: 59 additions & 17 deletions examples/get-started/blink/main/blink.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,74 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"

/* Can use project configuration menu (idf.py menuconfig) to choose the GPIO to blink,
static const char *TAG = "example";

/* Use project configuration menu (idf.py menuconfig) to choose the GPIO to blink,
or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO

void app_main(void)
static uint8_t s_led_state = 0;

#ifdef CONFIG_BLINK_LED_RMT
static led_strip_t *pStrip_a;

static void blink_led(void)
{
/* If the addressable LED is enabled */
if (s_led_state) {
/* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
pStrip_a->set_pixel(pStrip_a, 0, 16, 16, 16);
/* Refresh the strip to send data */
pStrip_a->refresh(pStrip_a, 100);
} else {
/* Set all LED off to clear all pixels */
pStrip_a->clear(pStrip_a, 50);
}
}

static void configure_led(void)
{
ESP_LOGI(TAG, "Example configured to blink addressable LED!");
/* LED strip initialization with the GPIO and pixels number*/
pStrip_a = led_strip_init(CONFIG_BLINK_LED_RMT_CHANNEL, BLINK_GPIO, 1);
/* Set all LED off to clear all pixels */
pStrip_a->clear(pStrip_a, 50);
}

#elif CONFIG_BLINK_LED_GPIO

static void blink_led(void)
{
/* Set the GPIO level according to the state (LOW or HIGH)*/
gpio_set_level(BLINK_GPIO, s_led_state);
}

static void configure_led(void)
{
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/
ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
gpio_reset_pin(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
while(1) {
/* Blink off (output low) */
printf("Turning off the LED\n");
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
/* Blink on (output high) */
printf("Turning on the LED\n");
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}

#endif

void app_main(void)
{

/* Configure the peripheral according to the LED type */
configure_led();

while (1) {
ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
blink_led();
/* Toggle the LED state */
s_led_state = !s_led_state;
vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
}
}
2 changes: 2 additions & 0 deletions examples/peripherals/rmt/led_strip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/led_strip)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(led_strip)
2 changes: 2 additions & 0 deletions examples/peripherals/rmt/led_strip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

PROJECT_NAME := led_strip

EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/led_strip

include $(IDF_PATH)/make/project.mk
4 changes: 2 additions & 2 deletions examples/peripherals/rmt/led_strip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ GPIO18 +-----------------+---|>| (WS2812)

Open the project configuration menu (`idf.py menuconfig`).

In the `Example Connection Configuration` menu:
In the `Example Configuration` menu:

* Set the GPIO number used for transmitting the IR signal under `RMT TX GPIO` optin.
* Set the GPIO number used for transmitting the IR signal under `RMT TX GPIO` option.
* Set the number of LEDs in a strip under `Number of LEDS in a strip` option.

### Build and Flash
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit cccdb3e

Please sign in to comment.