Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turned library into a ESP-IDF component. Added application example. #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions Makefile

This file was deleted.

52 changes: 27 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ This library can be used to drive addressable LED strips from the ESP32 using th
The library currently uses double buffering to seperate the LED strip that's being currently displayed and the LED strip that is currently being updated. There are two buffers, 1 and 2, which contain the colors for the LED strip. When the driver is showing buffer 1, any calls to led_strip_set_pixel_color will update buffer 2. When a call to led_strip_show is made, it will switch out the buffers, so buffer 2 is currently being displayed and buffer 1 is the one that is written to when calls to led_strip_set_pixel_color are made.

## How to use

Clone this component to [ESP-IDF](https://github.com/espressif/esp-idf) project (as submodule):
```
git submodule add https://github.com/tmedicci/ESP32_LED_STRIP components/ESP32_LED_STRIP
```

Or run a sample (make sure you have installed the [toolchain](http://esp-idf.readthedocs.io/en/latest/get-started/index.html#setup-toolchain)):

```
git clone https://github.com/tmedicci/ESP32_LED_STRIP
cd ESP32_LED_STRIP/examples/example_basic
make menuconfig
```
### Change settings in `menuconfig`

```
make menuconfig
-> ESP32 LED Strip Basic Example
```
###Library Functions

All functions for initializing and setting colors are located in led_strip.h. Right now the library supports:

Initialization of an led strip which initializes the RMT peripheral and starts a task for driving LEDs
Expand All @@ -29,43 +50,24 @@ Get the color of a pixel on the strip **currently being shown**. For instance, i
bool led_strip_get_pixel_color(struct led_strip_t *led_strip, uint32_t pixel_num, struct led_color_t *color);
```

Clear the led strip
Function that sets a task for manipulating LED effects. Check led_strip_effect at led_strip.h for more details (it contains a pointer to an already initilized led_strip_t struct).
```c
bool led_strip_clear(struct led_strip_t *led_strip)
led_strip_set_effect(struct led_strip_effect_t *led_strip_effect, effect_type_t effect_type, struct led_color_t *effect_color, uint8_t effect_speed);
```

Below is simple configuration
Clear the led strip and
```c
#define LED_STRIP_LENGTH 17U
#define LED_STRIP_RMT_INTR_NUM 19U

static struct led_color_t led_strip_buf_1[LED_STRIP_LENGTH];
static struct led_color_t led_strip_buf_2[LED_STRIP_LENGTH];

struct led_strip_t led_strip = {
.rgb_led_type = RGB_LED_TYPE_WS2812,
.rmt_channel = RMT_CHANNEL_1,
.rmt_interrupt_num = LED_STRIP_RMT_INTR_NUM,
.gpio = GPIO_NUM_21,
.led_strip_buf_1 = led_strip_buf_1,
.led_strip_buf_2 = led_strip_buf_2,
.led_strip_length = LED_STRIP_LENGTH
};
led_strip.access_semaphore = xSemaphoreCreateBinary();

bool led_init_ok = led_strip_init(&led_strip);
bool led_strip_clear(struct led_strip_t *led_strip)
```

Expect more examples in main.c in the near future for use cases excercising all functionality of the library.

## Limitations
1. Right now the library only supports the timing for WS2812/WS2812B LED strips. I believe most of the Adafruit Neopixel strips use these LED drivers. The ability to add drivers for other LEDs like the SK6812 and WS2811 is implemented, but I don't have any to test on.
1. Right now the library only supports the timing for WS2812/WS2812B, SK6812 and APA106 LED strips. Tested with WS2812 and APA106.
2. Only supports 30ms refresh period. Will add functionality to make this configurable in the future.

## Future Goals of Library (in somewhat prioritized order)
1. Add higher level functions for generating rainbows, bouncing effects, etc.
1.1. Add other effects like rainbows, fade-in/out, in-out...
2. Somehow clean up led strip c file. This may involve seperating the waveform generation of each kind of LED.
3. Add support for "LED rooms". An LED room may contain one or more strips covering multiple walls and multiple corners. This would allow very cool LED shows for different setups, such as LEDs bouncing off walls, LEDs mirroring what the other strip is doing parallel or perpendicular to it, etc.
4. Add support for other LED strips (WS2811, SK6812, etc.)
5. Add ESP supported logging and ESP checks at the beginning and end of function
6. Add notes about memory limitations. Right now depending on how its done, there are two buffers that are either stack allocated or statically allocated and another buffer for the rmt items that's malloc'd on the heap.
10 changes: 10 additions & 0 deletions component.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Component Makefile
#
# This Makefile should, at the very least, just include $(SDK_PATH)/make/component.mk. By default,
# this will take the sources in this directory, compile them and link them into
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
# please read the SDK documents if you need to do this.
#
COMPONENT_ADD_INCLUDEDIRS := . inc

4 changes: 0 additions & 4 deletions components/led_strip/component.mk

This file was deleted.

13 changes: 13 additions & 0 deletions examples/example_basic/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := example_basic_ESP32_led_strip
EXTRA_COMPONENT_DIRS += $(PROJECT_PATH)/../../../

include $(IDF_PATH)/make/project.mk

40 changes: 40 additions & 0 deletions examples/example_basic/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
menu "ESP32 LED Strip Basic Example"

choice RGB_LED_TYPE
prompt "LED Strip Model"
default WS2812
help
CPU frequency to be set on application startup.
config WS2812
bool "WS2812"
config SK6812
bool "SK6812"
config APA106
bool "APA106"
endchoice

config RGB_LED_TYPE
int
default 0 if WS2812
default 1 if SK6812
default 2 if APA106

config LED_STRIP_LENGTH
int "LED Strip Length"
default 10
help
Length of LED Strip.

config RMT_CHANNEL
int "RMT Channel from 0 to 7"
default 0
help
Choose RMT Channel from 0 to 7. Defaults to 0.

config GPIO_NUM
int "GPIO to use as LED Strip TX"
default 25
help
GPIO number from 0 to 32 to use as TX for the LED Strip.

endmenu
File renamed without changes.
95 changes: 95 additions & 0 deletions examples/example_basic/main/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* ----------------------------------------------------------------------------
File: main.c
Author(s): Tiago Medicci Serrano <[email protected]>
Date Created: 06/02/2018
Last modified: 06/02/2018

------------------------------------------------------------------------- */

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_system.h"
#include "esp_task.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "led_strip.h"
#include "sdkconfig.h"

#include <stdio.h>

#define LED_STRIP_LENGTH 6U

struct led_strip_t led_strip;
struct led_strip_effect_t led_strip_effect;
struct led_color_t led_effect_color;

extern void main_led_task(void *args);

/**
* @brief Initialize WS2812 LED Interface
*
* @param None
*
* @return
* -ESP_OK On success
* -ESP_FAIL Generic code indicating failure
*
**/
esp_err_t initialize_LED(void)
{

static struct led_color_t led_strip_buf_1[CONFIG_LED_STRIP_LENGTH];
static struct led_color_t led_strip_buf_2[CONFIG_LED_STRIP_LENGTH];

led_strip.rgb_led_type = CONFIG_RGB_LED_TYPE;
led_strip.rmt_channel = CONFIG_RMT_CHANNEL;
led_strip.gpio = CONFIG_GPIO_NUM;
led_strip.led_strip_buf_1 = led_strip_buf_1;
led_strip.led_strip_buf_2 = led_strip_buf_2;
led_strip.led_strip_length = LED_STRIP_LENGTH;
led_strip.access_semaphore = xSemaphoreCreateBinary();

led_strip_effect.led_strip = &led_strip;

//TODO: turn led_strip_init return into a esp_err_t indicating ESP-IDF error code
if(!led_strip_init(led_strip_effect.led_strip)){
return ESP_FAIL;
}
return ESP_OK;
}

void main_led_task(void *pv)
{
ESP_ERROR_CHECK( initialize_LED() );
led_effect_color.red = 0;
led_effect_color.green = 0;
led_effect_color.blue = 0;
while(true){
ESP_ERROR_CHECK( led_strip_set_effect(&led_strip_effect, RGB, &led_effect_color, 255) ); //Set RGB rounding effect at max speed
vTaskDelay(6000 / portTICK_PERIOD_MS); //Wait for 6s
led_strip_clear(led_strip_effect.led_strip); //Clear LED Strip
vTaskDelay(6000 / portTICK_PERIOD_MS); //Wait for 6s
//Set white color (RGB=[255,255,255])
led_effect_color.red = 55;
led_effect_color.green = 55;
led_effect_color.blue = 55;
ESP_ERROR_CHECK( led_strip_set_effect(&led_strip_effect, COLOR, &led_effect_color, 200) ); //Set white color
vTaskDelay(6000 / portTICK_PERIOD_MS); //Wait for 6s
}
}

void app_main(void)
{
nvs_flash_init();
TaskHandle_t main_task_handle;
BaseType_t task_created = xTaskCreate(main_led_task,
"main_led_task",
ESP_TASK_MAIN_STACK,
NULL,
ESP_TASK_MAIN_PRIO,
&main_task_handle);
(void)task_created;
vTaskDelete(NULL);
}

Loading