Skip to content

Commit

Permalink
example: add led indicator example
Browse files Browse the repository at this point in the history
  • Loading branch information
lijunru-hub committed Jan 25, 2024
1 parent 996917b commit 640d3d9
Show file tree
Hide file tree
Showing 35 changed files with 1,328 additions and 8 deletions.
11 changes: 11 additions & 0 deletions .gitlab/ci/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,17 @@ build_example_gprof_gprof_simple:
variables:
EXAMPLE_DIR: examples/gprof/gprof_simple

build_example_lighting_indicator:
extends:
- .build_examples_template
- .rules:build:example_lighting_indicator
parallel:
matrix:
- IMAGE: espressif/idf:release-v5.1
- IMAGE: espressif/idf:release-v4.4
variables:
EXAMPLE_DIR: examples/lighting/indicator

build_example_lighting_lightbulb:
extends:
- .build_examples_template
Expand Down
15 changes: 15 additions & 0 deletions .gitlab/ci/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@
.patterns-example_get_started_button_power_save: &patterns-example_get_started_button_power_save
- "examples/get-started/button_power_save/**/*"

.patterns-example_lighting_indicator: &patterns-example_lighting_indicator
- "examples/lighting/indicator/**/*"

.patterns-example_lighting_lightbulb: &patterns-example_lighting_lightbulb
- "examples/lighting/lightbulb/**/*"

Expand Down Expand Up @@ -683,6 +686,18 @@
- <<: *if-dev-push
changes: *patterns-example_gprof_gprof_simple

.rules:build:example_lighting_indicator:
rules:
- <<: *if-protected
- <<: *if-label-build
- <<: *if-trigger-job
- <<: *if-dev-push
changes: *patterns-build_system
- <<: *if-dev-push
changes: *patterns-components_led_led_indicator
- <<: *if-dev-push
changes: *patterns-example_lighting_indicator

.rules:build:example_lighting_lightbulb:
rules:
- <<: *if-protected
Expand Down
6 changes: 6 additions & 0 deletions components/led/led_indicator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@

# ChangeLog

## v0.9.1 - 2024-1-17

* Resolve the issue of calling preempt_stop with a specified blink_type that is not running, causing the current preemptive blink to stop.
* Resolve the issue of the RGB ring not functioning.
* Ensure that preempt_start stops the previous preemptive blink.

## v0.9.0 - 2023-11-28

### BUG FIX
Expand Down
4 changes: 3 additions & 1 deletion components/led/led_indicator/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "0.9.0"
version: "0.9.1"
description: LED indicator driver
url: https://github.com/espressif/esp-iot-solution/tree/master/components/led/led_indicator
dependencies:
Expand All @@ -7,3 +7,5 @@ dependencies:
version: ">=2.5.2"
public: true
cmake_utilities: "0.*"
examples:
- path: ../../../examples/lighting/indicator
1 change: 0 additions & 1 deletion components/led/led_indicator/include/led_ledc.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#pragma once

#include "driver/ledc.h"
// #include "led_common.h"

#ifdef __cplusplus
extern "C" {
Expand Down
14 changes: 9 additions & 5 deletions components/led/led_indicator/src/led_indicator.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -276,8 +276,7 @@ static void _blink_list_runner(TimerHandle_t xTimer)

led_indicator_hsv2rgb(p_led_indicator->current_fade_value.value, &r, &g, &b);
led_indicator_ihsv_t irgb_value = {
.value = (r << 16) | (g << 8) | b,
.i = p_blink_step_value.i,
.value = SET_IRGB(p_blink_step_value.i, r, g, b),
};
p_led_indicator->hal_indicator_set_rgb(p_led_indicator->hardware_data, irgb_value.value);

Expand Down Expand Up @@ -701,6 +700,9 @@ esp_err_t led_indicator_preempt_start(led_indicator_handle_t handle, int blink_t
LED_INDICATOR_CHECK(p_led_indicator->blink_lists[blink_type] != NULL, "undefined blink_type", return ESP_ERR_INVALID_ARG);

xSemaphoreTake(p_led_indicator->mutex, portMAX_DELAY);
if (p_led_indicator->preempt_blink != NULL_PREEMPT_BLINK) {
p_led_indicator->p_blink_steps[p_led_indicator->preempt_blink] = LED_BLINK_STOP; // Maker sure the last preempt blink is stopped
}
p_led_indicator->p_blink_steps[blink_type] = 0;
p_led_indicator->preempt_blink = blink_type;
_blink_list_switch(p_led_indicator); //stop and switch to next blink steps
Expand All @@ -720,8 +722,10 @@ esp_err_t led_indicator_preempt_stop(led_indicator_handle_t handle, int blink_ty
LED_INDICATOR_CHECK(blink_type >= 0 && blink_type < p_led_indicator->blink_list_num, "blink_type out of range", return ESP_FAIL);
LED_INDICATOR_CHECK(p_led_indicator->blink_lists[blink_type] != NULL, "undefined blink_type", return ESP_ERR_INVALID_ARG);
xSemaphoreTake(p_led_indicator->mutex, portMAX_DELAY);
p_led_indicator->p_blink_steps[blink_type] = LED_BLINK_STOP;
p_led_indicator->preempt_blink = NULL_PREEMPT_BLINK;
if (p_led_indicator->preempt_blink == blink_type) {
p_led_indicator->p_blink_steps[blink_type] = LED_BLINK_STOP;
p_led_indicator->preempt_blink = NULL_PREEMPT_BLINK;
}
_blink_list_switch(p_led_indicator); //stop and switch to next blink steps
xSemaphoreGive(p_led_indicator->mutex);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ TEST_CASE("TEST LED RGB control Real time ", "[LED RGB][Real time]")
{
led_strip_config_t strip_config = {
.strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line
.max_leds = MAX_LED_NUM, // The number of LEDs in the strip,
.max_leds = MAX_LED_NUM, // The number of LEDs in the strip,
.led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
.led_model = LED_MODEL_WS2812, // LED strip model
.flags.invert_out = false, // whether to invert the output signal
Expand Down
8 changes: 8 additions & 0 deletions examples/.build-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ examples/get-started/button_power_save:
enable:
- if: INCLUDE_DEFAULT == 1

examples/lighting/indicator:
enable:
- if: INCLUDE_DEFAULT == 1

examples/lighting/indicator/ws2812_strips:
enable:
- if: SOC_RMT_SUPPORTED == 1

examples/lighting/lightbulb:
enable:
- if: INCLUDE_DEFAULT == 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "."
REQUIRES console)
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <string.h>
#include "cmd_led_indicator.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "esp_log.h"
#include "esp_check.h"

static struct {
struct arg_int *start;
struct arg_int *stop;
struct arg_int *preempt_start;
struct arg_int *preempt_stop;
struct arg_end *end;
} cmd_indicator_args;

typedef struct {
led_indicator_cmd_cb cmd_cb;
} cmd_led_indicator_cmd_t;

static const char *TAG = "cmd_led_indicator";
static cmd_led_indicator_cmd_t cmd_led_indicator_cmd = {0};

static int cmd_br_fdb_remove(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **) &cmd_indicator_args); \
if (nerrors != 0) {
arg_print_errors(stderr, cmd_indicator_args.end, argv[0]);
return 1;
}

if (cmd_indicator_args.start->count > 0) {
cmd_led_indicator_cmd.cmd_cb(START, cmd_indicator_args.start->ival[0]);
} else if (cmd_indicator_args.stop->count > 0) {
cmd_led_indicator_cmd.cmd_cb(STOP, cmd_indicator_args.stop->ival[0]);
} else if (cmd_indicator_args.preempt_start->count > 0) {
cmd_led_indicator_cmd.cmd_cb(PREEMPT_START, cmd_indicator_args.preempt_start->ival[0]);
} else if (cmd_indicator_args.preempt_stop->count > 0) {
cmd_led_indicator_cmd.cmd_cb(PREEMPT_STOP, cmd_indicator_args.preempt_stop->ival[0]);
} else {
ESP_LOGE(TAG, "no valid arguments");
return 1;
}

return 0;
}

esp_err_t cmd_led_indicator_init(cmd_led_indicator_t *cmd_led_indicator)
{
ESP_RETURN_ON_FALSE(cmd_led_indicator != NULL, ESP_ERR_INVALID_ARG, TAG, "cmd_led_indicator is NULL");
ESP_RETURN_ON_FALSE(cmd_led_indicator->cmd_cb != NULL, ESP_ERR_INVALID_ARG, TAG, "cmd_led_indicator->cmd_cb is NULL");

cmd_led_indicator_cmd.cmd_cb = cmd_led_indicator->cmd_cb;
uint32_t max_mode = cmd_led_indicator->mode_count - 1;

esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();

/* Register commands */
esp_console_register_help_command();

#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM)
esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
ESP_RETURN_ON_ERROR(esp_console_new_repl_uart(&hw_config, &repl_config, &repl), TAG, "Failed to initialize UART REPL");

#elif defined(CONFIG_ESP_CONSOLE_USB_CDC)
esp_console_dev_usb_cdc_config_t hw_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
ESP_RETURN_ON_ERROR(esp_console_new_repl_usb_cdc(&hw_config, &repl_config, &repl), TAG, "Failed to initialize USB CDC REPL");

#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
ESP_RETURN_ON_ERROR(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl), TAG, "Failed to initialize USB serial REPL");

#else
#error Unsupported console type
#endif

cmd_indicator_args.start = arg_intn("s", "start", "<start>", 0, max_mode, "Start blinking the mode with given index");
cmd_indicator_args.stop = arg_intn("e", "stop", "<stop>", 0, max_mode, "Stop blinking the mode with given index");
cmd_indicator_args.preempt_start = arg_intn("p", "preempt_start", "<preempt_start>", 0, max_mode, "Preemptively start blinking the mode with given index");
cmd_indicator_args.preempt_stop = arg_intn("x", "preempt_stop", "<preempt_stop>", 0, max_mode, "Preemptively stop blinking the mode with given index");
cmd_indicator_args.end = arg_end(4);

const esp_console_cmd_t cmd = {
.command = "led",
.help = "LED indicator commands",
.hint = NULL,
.func = &cmd_br_fdb_remove,
.argtable = &cmd_indicator_args
};

ESP_RETURN_ON_ERROR(esp_console_cmd_register(&cmd), TAG, "Failed to register command");
ESP_RETURN_ON_ERROR(esp_console_start_repl(repl), TAG, "Failed to start REPL");

return ESP_OK;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "esp_err.h"

typedef enum {
START = 0,
STOP,
PREEMPT_START,
PREEMPT_STOP,
} cmd_type_t;

typedef void (*led_indicator_cmd_cb)(cmd_type_t cmd_type, uint32_t mode_index);

typedef struct {
uint32_t mode_count;
led_indicator_cmd_cb cmd_cb;
} cmd_led_indicator_t;

/**
* @brief install led indicator cmd
*
* @param cmd_led_indicator led indicator cmd cfg
* @return
* ESP_OK success
* ESP_FAIL failed
*/
esp_err_t cmd_led_indicator_init(cmd_led_indicator_t *cmd_led_indicator);

#ifdef __cplusplus
}
#endif
6 changes: 6 additions & 0 deletions examples/lighting/indicator/gpio/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(gpio_led_indicator)
42 changes: 42 additions & 0 deletions examples/lighting/indicator/gpio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## LED Indicator WS2812

* Support ON/OFF

### Hardware Required

* LED

### Configure the project

```
idf.py menuconfig
```

* Set `EXAMPLE_GPIO_NUM` to set led gpio.
* Set `EXAMPLE_GPIO_ACTIVE_LEVEL` to set gpio level when led light

### How to USE

If the macro `EXAMPLE_ENABLE_CONSOLE_CONTROL` is enabled, please use the following method for control; otherwise, the indicator lights will flash sequentially in order.

* Help
```shell
help
```

* Immediate display mode, without considering priority.
```shell
led -p 0 # Start
led -p 2 # Start
led -x 2 # Stop
```

* Display mode based on priority.
```shell
led -s 0 # Start 0
led -s 2 # Start 2
led -e 2 # Stop 2
```

Note:
> Support replacing the LED with an active buzzer to achieve the functionality of a buzzer indicator.
2 changes: 2 additions & 0 deletions examples/lighting/indicator/gpio/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
19 changes: 19 additions & 0 deletions examples/lighting/indicator/gpio/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
menu "Example Configuration"

config EXAMPLE_GPIO_NUM
int "GPIO number"
default 1
help
GPIO number to use for example.

config EXAMPLE_GPIO_ACTIVE_LEVEL
bool "GPIO active level"
default y
help
GPIO active level.

config EXAMPLE_ENABLE_CONSOLE_CONTROL
bool "Enable console control"
default n

endmenu
9 changes: 9 additions & 0 deletions examples/lighting/indicator/gpio/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "0.0.1"
dependencies:
idf: ">=4.4"
cmd_led_indicator:
version: "*"
override_path: "../../components/cmd_led_indicator"
led_indicator:
version: "*"
override_path: "../../../../../components/led/led_indicator"
Loading

0 comments on commit 640d3d9

Please sign in to comment.