light driver thread implemented
This commit is contained in:
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
||||
st7290
|
||||
@@ -7,7 +7,6 @@ Generalnie co ma dzialac to juz dziala, thank fuck. Ja pierdole ale api do zigbe
|
||||
### TODO
|
||||
- hardware
|
||||
- weird start up behavior
|
||||
- wylaczanie lamp nie dziala po gammie
|
||||
- identyfikacja, niby opcjonalna ale fajny bajer
|
||||
- factory reset zigbee zeby bylo legitnie, dzwonisz po `esp_zb_factory_reset();`
|
||||
- status LED zeby bylo legitnie (pokazuje factory reset i OTA kiedys)
|
||||
|
||||
@@ -6,7 +6,8 @@ dependencies:
|
||||
type: local
|
||||
version: 1.6.8
|
||||
espressif/cmake_utilities:
|
||||
component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
component_hash:
|
||||
351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
@@ -16,7 +17,8 @@ dependencies:
|
||||
type: service
|
||||
version: 0.5.3
|
||||
espressif/esp-zboss-lib:
|
||||
component_hash: 321883d142421f65009972408287441794250057668a11abbdfd8bec77c3309a
|
||||
component_hash:
|
||||
321883d142421f65009972408287441794250057668a11abbdfd8bec77c3309a
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "esp_err.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
esp_err_t light_driver_init(bool default_state);
|
||||
esp_err_t light_driver_set_level(uint8_t level, uint16_t transition_ms);
|
||||
esp_err_t light_driver_set_power(bool power, uint16_t transition_ms);
|
||||
void light_driver_task(void *pvParameter);
|
||||
void light_driver_set_level(uint8_t level);
|
||||
void light_driver_set_power(bool power);
|
||||
|
||||
#endif //LIGHT_DRIVER_H
|
||||
@@ -7,11 +7,12 @@
|
||||
#include "esp_err.h"
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
static const char* TAG = "light_driver";
|
||||
|
||||
/* tweakable stuff */
|
||||
static const uint8_t light_gpio = 2;
|
||||
static const uint8_t light_gpio = 15;
|
||||
static const uint16_t light_pwm_freq = 65000;
|
||||
static const ledc_timer_bit_t light_pwm_resolution = LEDC_TIMER_10_BIT;
|
||||
static const double light_lowest_duty_pct = 0.05; // lowest duty percentage where the LEDs still light up nice
|
||||
@@ -20,32 +21,27 @@ static const double light_lowest_duty_pct = 0.05; // lowest duty percentage wher
|
||||
static const ledc_channel_t light_ledc_channel = LEDC_CHANNEL_0;
|
||||
static const ledc_mode_t light_ledc_speed_mode = LEDC_LOW_SPEED_MODE;
|
||||
static const uint32_t light_brightness_steps = (1 << light_pwm_resolution) - 1;
|
||||
SemaphoreHandle_t light_sem = NULL;
|
||||
|
||||
/* global vars */
|
||||
static bool light_init_done = false;
|
||||
static uint8_t light_current_level = 0;
|
||||
static uint8_t light_target_level = 0;
|
||||
static uint16_t gamma_lut[ZIGBEE_LIGHT_LEVELS + 1];
|
||||
|
||||
esp_err_t light_driver_set_level(const uint8_t level, const uint16_t transition_ms) {
|
||||
if (!light_init_done) {
|
||||
ESP_LOGW(TAG, "light driver not ready!");
|
||||
return ESP_FAIL;
|
||||
|
||||
void light_driver_set_level(const uint8_t level) {
|
||||
xSemaphoreTake(light_sem, portMAX_DELAY);
|
||||
light_target_level = level;
|
||||
xSemaphoreGive(light_sem);
|
||||
}
|
||||
|
||||
light_current_level = level;
|
||||
const uint16_t duty = gamma_lut[light_current_level];
|
||||
ESP_ERROR_CHECK(ledc_fade_stop(light_ledc_speed_mode, light_ledc_channel));
|
||||
ESP_ERROR_CHECK(ledc_set_fade_with_time(light_ledc_speed_mode, light_ledc_channel, duty, transition_ms));
|
||||
ESP_ERROR_CHECK(ledc_fade_start(light_ledc_speed_mode, light_ledc_channel, LEDC_FADE_NO_WAIT));
|
||||
// ESP_LOGI(TAG, "led set to %d, max is %d", duty, light_brightness_steps);
|
||||
return ESP_OK;
|
||||
uint16_t get_level(void) {
|
||||
xSemaphoreTake(light_sem, portMAX_DELAY);
|
||||
const uint16_t lvl = light_target_level;
|
||||
xSemaphoreGive(light_sem);
|
||||
return MIN(254, lvl);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_power(const bool power, const uint16_t transition_ms) {
|
||||
return light_driver_set_level(power ? light_current_level : 0, transition_ms);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_init(const bool default_state) {
|
||||
void light_driver_task(void *pvParameter) {
|
||||
const ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = light_ledc_speed_mode,
|
||||
.duty_resolution = light_pwm_resolution,
|
||||
@@ -60,9 +56,14 @@ esp_err_t light_driver_init(const bool default_state) {
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = light_gpio,
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
.hpoint = (int)light_brightness_steps
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
static uint8_t prev_level = 0;
|
||||
|
||||
// pre-compute gamma table
|
||||
for (uint8_t i = 0; i <= ZIGBEE_LIGHT_LEVELS; i++) {
|
||||
const double brightness_pct = (double)i / (double)ZIGBEE_LIGHT_LEVELS;
|
||||
const double gamma_corrected = pow(brightness_pct, 2.2);
|
||||
@@ -73,11 +74,32 @@ esp_err_t light_driver_init(const bool default_state) {
|
||||
if (gamma_lut[ZIGBEE_LIGHT_LEVELS] > light_brightness_steps) gamma_lut[ZIGBEE_LIGHT_LEVELS] = light_brightness_steps;
|
||||
ESP_LOGI(TAG, "pre-computed brightness lookup table");
|
||||
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
ESP_ERROR_CHECK(ledc_fade_func_install(0));
|
||||
// semaphore init
|
||||
light_sem = xSemaphoreCreateMutex();
|
||||
xSemaphoreGive(light_sem);
|
||||
|
||||
ESP_LOGI(TAG, "ledc driver initialized, f=%d Hz, %d step resolution", light_pwm_freq, light_brightness_steps);
|
||||
light_init_done = true;
|
||||
light_driver_set_power(default_state, 100);
|
||||
return ESP_OK;
|
||||
light_driver_set_level(0);
|
||||
|
||||
while (true) {
|
||||
const uint16_t tgt = get_level();
|
||||
if (tgt != prev_level) {
|
||||
const int diff = tgt - prev_level;
|
||||
const int abs_diff = abs(diff);
|
||||
const int step = MIN(abs_diff / 8 + 1, 20);
|
||||
|
||||
if (diff > 0)
|
||||
prev_level += step;
|
||||
else
|
||||
prev_level -= step;
|
||||
|
||||
ESP_LOGI(TAG, "setting light level to %d, tgt is %d, step of %d", prev_level, tgt, step);
|
||||
ledc_set_duty_and_update(light_ledc_speed_mode, light_ledc_channel, gamma_lut[prev_level], light_brightness_steps);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
}
|
||||
|
||||
void light_driver_set_power(const bool power) {
|
||||
light_driver_set_level(power ? get_level() : 0);
|
||||
}
|
||||
@@ -12,13 +12,10 @@ static char manufacturer[] = "\x05""Drath";
|
||||
static char model[] = "\x15""Dimmable Zigbee Light";
|
||||
static const uint8_t endpoint_no = 1;
|
||||
|
||||
static const uint16_t transition_on_off_ms = 500;
|
||||
static const uint16_t transition_level_ms = 100; // looks like it gets lvl updates from HA every 100ms
|
||||
|
||||
static esp_err_t deferred_driver_init(void) {
|
||||
static bool is_inited = false;
|
||||
if (!is_inited) {
|
||||
light_driver_init(LIGHT_DEFAULT_OFF);
|
||||
xTaskCreate(light_driver_task, "light task", 4096, NULL, 6, NULL);
|
||||
is_inited = true;
|
||||
}
|
||||
return is_inited ? ESP_OK : ESP_FAIL;
|
||||
@@ -60,7 +57,7 @@ static esp_err_t zigbee_attribute_handler(const esp_zb_zcl_set_attr_value_messag
|
||||
bool light_state = false;
|
||||
light_state = message->attribute.data.value ? *(bool*)message->attribute.data.value : light_state;
|
||||
ESP_LOGI(TAG, "Light sets to %s", light_state ? "On" : "Off");
|
||||
light_driver_set_power(light_state, transition_on_off_ms);
|
||||
light_driver_set_power(light_state);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -68,7 +65,7 @@ static esp_err_t zigbee_attribute_handler(const esp_zb_zcl_set_attr_value_messag
|
||||
if (message->attribute.id == ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) {
|
||||
uint8_t light_level = 0;
|
||||
light_level = message->attribute.data.value ? *(uint8_t*)message->attribute.data.value : light_level;
|
||||
light_driver_set_level(light_level, transition_level_ms);
|
||||
light_driver_set_level(light_level);
|
||||
ESP_LOGI(TAG, "Light level changes to %d", light_level);
|
||||
}
|
||||
break;
|
||||
@@ -166,9 +163,9 @@ void zigbee_endpoint_init(esp_zb_ep_list_t *ep_list, esp_zb_cluster_list_t *clus
|
||||
}
|
||||
|
||||
/* appearently you cant rename this? */
|
||||
void esp_zb_app_signal_handler(esp_zb_app_signal_t* signal_struct) {
|
||||
uint32_t* p_sg_p = signal_struct->p_app_signal;
|
||||
const esp_err_t err_status = signal_struct->esp_err_status;
|
||||
void esp_zb_app_signal_handler(const esp_zb_app_signal_t* signal_s) {
|
||||
uint32_t* p_sg_p = signal_s->p_app_signal;
|
||||
const esp_err_t err_status = signal_s->esp_err_status;
|
||||
const esp_zb_app_signal_type_t sig_type = *p_sg_p;
|
||||
|
||||
switch (sig_type) {
|
||||
|
||||
Reference in New Issue
Block a user