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

[ESP32]Add ColorControl for ESP32C3-DevKitM #8201

Merged
Merged
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
11 changes: 5 additions & 6 deletions examples/all-clusters-app/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ set(EXTRA_COMPONENT_DIRS
"${CMAKE_CURRENT_LIST_DIR}/../../common/QRCode"
)
if(${IDF_TARGET} STREQUAL "esp32")
set(EXTRA_COMPONENT_DIRS
${EXTRA_COMPONENT_DIRS}
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/../../common/screen-framework"
)
list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/../../common/screen-framework")
elseif(${IDF_TARGET} STREQUAL "esp32c3")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/peripherals/rmt/led_strip/components")
endif()

project(chip-all-clusters-app)
Expand Down
25 changes: 19 additions & 6 deletions examples/all-clusters-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,23 @@ commissioning and cluster control.

### Cluster control

- After successful commissioning, use the OnOff cluster command to control the
OnOff attribute. This allows you to toggle a parameter implemented by the
device to be On or Off.
- After successful commissioning, use the OnOff cluster commands to control
the OnOff attribute. This allows you to toggle a parameter implemented by
the device to be On or Off.

`chip-device-ctrl > zcl OnOff Off 135246 1 0`
`chip-device-ctrl > zcl OnOff Off 135246 1 1`

- Use the LevelControl cluster commands to control the CurrentLevel attribute.
This allows you to control the brightness of the led.

`chip-device-ctrl > zcl LevelControl MoveToLevel 135246 1 1 level=10 transitionTime=0 optionMask=0 optionOverride=0`

- For ESP32C3-DevKitM, use the ColorContorl cluster commands to control the
CurrentHue and CurrentSaturation attribute. This allows you to control the
color of on-board LED.

`zcl ColorControl MoveToHue 135246 1 1 hue=100 direction=0 transitionTime=0 optionsMask=0 optionsOverride=0`
`zcl ColorControl MoveToSaturation 135245 1 1 saturation=200 transitionTime=0 optionsMask=0 optionsOverride=0`

### Flashing app using script

Expand Down Expand Up @@ -243,5 +255,6 @@ through the on/off/toggle commands from the `python-controller`. For `M5Stack`,
a virtual Green LED on the display is used for the same.

If you wish to see the actual effect of the commands on `ESP32-DevKitC`,
`ESP32-WROVER-KIT_V4.1` and `ESP32C3-DevKitM`, you will have to connect an
external LED to GPIO `STATUS_LED_GPIO_NUM`.
`ESP32-WROVER-KIT_V4.1`, you will have to connect an external LED to GPIO
`STATUS_LED_GPIO_NUM`. For `ESP32C3-DevKitM`, the on-board LED will show the
actual effect of the commands.
8 changes: 6 additions & 2 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,17 @@ set(SRC_DIRS_LIST
)

if(("${CONFIG_DEVICE_TYPE_ESP32_DEVKITC}" STREQUAL "y") OR ("${CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM}" STREQUAL "y"))
set(PRIV_INCLUDE_DIRS_LIST ${PRIV_INCLUDE_DIRS_LIST}
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/screen-framework/include")
list(APPEND PRIV_INCLUDE_DIRS_LIST
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/screen-framework/include")
set(PRIV_REQUIRES_LIST chip QRCode bt)
elseif(("${CONFIG_DEVICE_TYPE_M5STACK}" STREQUAL "y") OR ("${CONFIG_DEVICE_TYPE_ESP32_WROVER_KIT}" STREQUAL "y"))
set(PRIV_REQUIRES_LIST chip QRCode bt tft spidrier screen-framework)
endif()

if("${CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM}" STREQUAL "y")
list(APPEND PRIV_REQUIRES_LIST led_strip)
endif()

idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST}
SRC_DIRS ${SRC_DIRS_LIST}
PRIV_REQUIRES ${PRIV_REQUIRES_LIST})
Expand Down
36 changes: 35 additions & 1 deletion examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, Cluster
case ZCL_LEVEL_CONTROL_CLUSTER_ID:
OnLevelControlAttributeChangeCallback(endpointId, attributeId, value);
break;

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
case ZCL_COLOR_CONTROL_CLUSTER_ID:
OnColorControlAttributeChangeCallback(endpointId, attributeId, value);
break;
#endif
default:
ESP_LOGI(TAG, "Unhandled cluster ID: %d", clusterId);
break;
Expand Down Expand Up @@ -164,6 +168,36 @@ void DeviceCallbacks::OnLevelControlAttributeChangeCallback(EndpointId endpointI
return;
}

// Currently we only support ColorControl cluster for ESP32C3_DEVKITM which has an on-board RGB-LED
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void DeviceCallbacks::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
VerifyOrExit(attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID ||
attributeId == ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
ESP_LOGI(TAG, "Unhandled AttributeId ID: '0x%04x", attributeId));
VerifyOrExit(endpointId == 1 || endpointId == 2, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId));
if (endpointId == 1)
{
uint8_t hue, saturation;
if (attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID)
{
hue = *value;
emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
&saturation, sizeof(uint8_t));
}
else
{
saturation = *value;
emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, &hue,
sizeof(uint8_t));
}
statusLED1.SetColor(hue, saturation);
}
exit:
return;
}
#endif

void IdentifyTimerHandler(Layer * systemLayer, void * appState, CHIP_ERROR error)
{
statusLED1.Animate();
Expand Down
3 changes: 2 additions & 1 deletion examples/all-clusters-app/esp32/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ menu "Demo"

choice
prompt "Device Type"
default DEVICE_TYPE_ESP32_DEVKITC
default DEVICE_TYPE_ESP32_DEVKITC if IDF_TARGET_ESP32
default DEVICE_TYPE_ESP32_C3_DEVKITM if IDF_TARGET_ESP32C3
help
Specifies the type of ESP32 device.

Expand Down
105 changes: 102 additions & 3 deletions examples/all-clusters-app/esp32/main/LEDWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@

#include "ScreenManager.h"

#include "driver/ledc.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_timer.h"
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
#include "driver/rmt.h"
#include "led_strip.h"
#define RMT_TX_DEFAULT_GPIO GPIO_NUM_8
#define RMT_TX_DEFAULT_CHANNEL RMT_CHANNEL_0
static led_strip_t * strip = NULL;
#else
#include "driver/ledc.h"
#include "hal/ledc_types.h"

#endif
void LEDWidget::Init(gpio_num_t gpioNum)
{
mLastChangeTimeUS = 0;
Expand All @@ -44,7 +51,20 @@ void LEDWidget::Init(gpio_num_t gpioNum)
mState = false;
mError = false;
errorTimer = NULL;

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (gpioNum == RMT_TX_DEFAULT_GPIO)
{
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_DEFAULT_GPIO, RMT_TX_DEFAULT_CHANNEL);
config.clk_div = 2;
rmt_config(&config);
rmt_driver_install(config.channel, 0, 0);
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t) config.channel);
strip = led_strip_new_rmt_ws2812(&strip_config);
mDefaultOnBrightness = UINT8_MAX;
mHue = 0;
mSaturation = 0;
}
#else
if (gpioNum < GPIO_NUM_MAX)
{
ledc_timer_config_t ledc_timer = {
Expand All @@ -67,6 +87,7 @@ void LEDWidget::Init(gpio_num_t gpioNum)
ledc_channel_config(&ledc_channel);
mDefaultOnBrightness = UINT8_MAX;
}
#endif
}

void LEDWidget::Set(bool state)
Expand All @@ -77,11 +98,21 @@ void LEDWidget::Set(bool state)

void LEDWidget::SetBrightness(uint8_t brightness)
{
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (strip)
{
uint8_t red, green, blue;
HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}
#else
if (mGPIONum < GPIO_NUM_MAX)
{
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, brightness);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
#endif
if (brightness > 0)
{
mDefaultOnBrightness = brightness;
Expand Down Expand Up @@ -155,11 +186,22 @@ void LEDWidget::DoSet(bool state)
{
bool stateChange = (mState != state);
mState = state;
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (strip)
{
uint8_t red, green, blue;
uint8_t brightness = state ? mDefaultOnBrightness : 0;
HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}
#else
if (mGPIONum < GPIO_NUM_MAX)
{
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, state ? mDefaultOnBrightness : 0);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
#endif
if (stateChange)
{
#if CONFIG_HAVE_DISPLAY
Expand All @@ -186,3 +228,60 @@ void LEDWidget::SetVLED(int id1, int id2)
}
}
#endif

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void LEDWidget::SetColor(uint8_t Hue, uint8_t Saturation)
{
uint8_t red, green, blue;
uint8_t brightness = mState ? mDefaultOnBrightness : 0;
mHue = static_cast<uint16_t>(Hue) * 360 / 254; // mHue [0, 360]
mSaturation = static_cast<uint16_t>(Saturation) * 100 / 254; // mSaturation [0 , 100]

HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}

void LEDWidget::HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue)
{
uint16_t i = Hue / 60;
uint16_t rgb_max = brightness;
uint16_t rgb_min = rgb_max * (100 - Saturation) / 100;
uint16_t diff = Hue % 60;
uint16_t rgb_adj = (rgb_max - rgb_min) * diff / 60;

switch (i)
{
case 0:
red = rgb_max;
green = rgb_min + rgb_adj;
blue = rgb_min;
break;
case 1:
red = rgb_max - rgb_adj;
green = rgb_max;
blue = rgb_min;
break;
case 2:
red = rgb_min;
green = rgb_max;
blue = rgb_min + rgb_adj;
break;
case 3:
red = rgb_min;
green = rgb_max - rgb_adj;
blue = rgb_max;
break;
case 4:
red = rgb_min + rgb_adj;
green = rgb_min;
blue = rgb_max;
break;
default:
red = rgb_max;
green = rgb_min;
blue = rgb_max - rgb_adj;
break;
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks
void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event);
void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void OnColorControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
#endif
void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);

bool mEndpointOnOffState[2];
Expand Down
8 changes: 8 additions & 0 deletions examples/all-clusters-app/esp32/main/include/LEDWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ class LEDWidget
void BlinkOnError();

void Animate();
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void SetColor(uint8_t Hue, uint8_t Saturation);

void HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue);
#endif
#if CONFIG_HAVE_DISPLAY
void SetVLED(int id1, int id2);
#endif
Expand All @@ -55,6 +59,10 @@ class LEDWidget
uint32_t mBlinkOnTimeMS;
uint32_t mBlinkOffTimeMS;
uint8_t mDefaultOnBrightness;
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
uint16_t mHue; // mHue [0, 360]
uint8_t mSaturation; // mSaturation [0, 100]
#endif
gpio_num_t mGPIONum;
int mVLED1;
int mVLED2;
Expand Down
2 changes: 1 addition & 1 deletion examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ using namespace ::chip::DeviceLayer;

#elif CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM

#define STATUS_LED_GPIO_NUM GPIO_NUM_2
#define STATUS_LED_GPIO_NUM GPIO_NUM_8

#else // !CONFIG_DEVICE_TYPE_ESP32_DEVKITC

Expand Down