feat: 完善显示器、氛围灯亮度调整。#2.

This commit is contained in:
Ivan Li 2023-02-18 15:19:26 +08:00
parent fbbf31e4e3
commit 0b1e0ef67c
11 changed files with 416 additions and 186 deletions

View File

@ -7,7 +7,7 @@
"idf.openOcdConfigs": [ "idf.openOcdConfigs": [
"board/esp32c3-builtin.cfg" "board/esp32c3-builtin.cfg"
], ],
"idf.port": "/dev/cu.usbmodem149201", "idf.port": "/dev/cu.usbmodem14A01",
"idf.pythonBinPath": "/Users/ivan/.espressif/python_env/idf4.4_py3.8_env/bin/python", "idf.pythonBinPath": "/Users/ivan/.espressif/python_env/idf4.4_py3.8_env/bin/python",
"idf.toolsPath": "/Users/ivan/.espressif", "idf.toolsPath": "/Users/ivan/.espressif",
"idf.gitPath": "/usr/bin/git", "idf.gitPath": "/usr/bin/git",
@ -46,6 +46,7 @@
"esp_event.h": "c", "esp_event.h": "c",
"string.h": "c", "string.h": "c",
"i2c.h": "c", "i2c.h": "c",
"esp_log.h": "c" "esp_log.h": "c",
"queue.h": "c"
} }
} }

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "ambient_light.c" "temperature.c" "embedded_display.c" "ui.c" "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c" idf_component_register(SRCS "ui_input.c" "asr_pro.c" "ambient_light.c" "temperature.c" "embedded_display.c" "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

View File

@ -164,20 +164,20 @@ void ambient_light_fetch(void* arg) {
als_ch0_raw); als_ch0_raw);
} }
// als ch1 // als ch1
error = apds_9930_read_word( // error = apds_9930_read_word(
APDS_9930_CMD_AUTO_INCREMENT | APDS_9930_REG_Ch1DATAL, // APDS_9930_CMD_AUTO_INCREMENT | APDS_9930_REG_Ch1DATAL,
&(als_ch1_buffer[1]), &(als_ch1_buffer[0])); // &(als_ch1_buffer[1]), &(als_ch1_buffer[0]));
if (error != ESP_OK) { // if (error != ESP_OK) {
ESP_LOGW(AMBIENT_LIGHT_TAG, "read failed. %x", error); // ESP_LOGW(AMBIENT_LIGHT_TAG, "read failed. %x", error);
} else { // } else {
als_ch1_raw = als_ch1_buffer[0] << 8 | als_ch1_buffer[1]; // als_ch1_raw = als_ch1_buffer[0] << 8 | als_ch1_buffer[1];
sprintf(als_ch1_str, "Ch1: % 5d ", als_ch1_raw); // sprintf(als_ch1_str, "Ch1: % 5d ", als_ch1_raw);
display_print8_str(8, 6, als_ch1_str); // display_print8_str(8, 6, als_ch1_str);
ESP_LOGD(AMBIENT_LIGHT_TAG, "ALS Ch1: %d, %x", als_ch1_raw, // ESP_LOGD(AMBIENT_LIGHT_TAG, "ALS Ch1: %d, %x", als_ch1_raw,
als_ch1_raw); // als_ch1_raw);
} // }
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(1000));
} }
display_fill_rect(0, 2, 128, 8, 0x00); display_fill_rect(0, 2, 128, 8, 0x00);
} }
@ -187,7 +187,7 @@ void ambient_light_auto_fetch() {
} }
void ambient_light_init() { void ambient_light_init() {
// esp_log_level_set(AMBIENT_LIGHT_TAG, ESP_LOG_DEBUG); esp_log_level_set(AMBIENT_LIGHT_TAG, ESP_LOG_ERROR);
ESP_ERROR_CHECK(apds_9930_write(APDS_9930_CMD_REPEATED | APDS_9930_REG_ATIME, ESP_ERROR_CHECK(apds_9930_write(APDS_9930_CMD_REPEATED | APDS_9930_REG_ATIME,
APDS_9930_ATIME_VALUE)); APDS_9930_ATIME_VALUE));
ESP_ERROR_CHECK(apds_9930_write(APDS_9930_CMD_REPEATED | APDS_9930_REG_PTIME, ESP_ERROR_CHECK(apds_9930_write(APDS_9930_CMD_REPEATED | APDS_9930_REG_PTIME,

87
main/asr_pro.c Normal file
View File

@ -0,0 +1,87 @@
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "light.c"
#include "string.h"
static const int RX_BUF_SIZE = 1024;
#define TXD_PIN (GPIO_NUM_12)
#define RXD_PIN (GPIO_NUM_13)
int sendData(const char *logName, const char *data) {
const int len = strlen(data);
const int txBytes = uart_write_bytes(UART_NUM_1, data, len);
ESP_LOGI(logName, "Wrote %d bytes", txBytes);
return txBytes;
}
static void tx_task(void *arg) {
static const char *TX_TASK_TAG = "TX_TASK";
esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);
while (1) {
sendData(TX_TASK_TAG, "Hello world");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
static void rx_task(void *arg) {
static const char *RX_TASK_TAG = "RX_TASK";
esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
uint8_t *data = (uint8_t *)malloc(RX_BUF_SIZE + 1);
uint8_t tx_buff[4] = {0};
while (1) {
const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE,
100 / portTICK_PERIOD_MS);
if (rxBytes > 0) {
data[rxBytes] = 0;
ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
if (data[0] == 0x11 && rxBytes >= 2) {
if (data[1] <= 6) {
light_mode = data[1];
}
tx_buff[0] = data[0];
tx_buff[1] = light_mode;
uart_write_bytes(UART_NUM_1, tx_buff, 2);
} else if (data[0] == 0x12 && rxBytes >= 2) {
tx_buff[0] = 0x12;
tx_buff[1] = data[1];
led_strip_set_brightness(data[1]);
uart_write_bytes(UART_NUM_1, tx_buff, 2);
} else if (data[0] == 0x13 && rxBytes >= 2) {
tx_buff[0] = 0x12;
tx_buff[1] = display_ambient_lighting_level + (int8_t)data[1];
led_strip_set_brightness(tx_buff[1]);
uart_write_bytes(UART_NUM_1, tx_buff, 2);
}
}
}
free(data);
}
void asr_pro_init() {
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
// We won't use a buffer for sending data.
uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE,
UART_PIN_NO_CHANGE);
xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES,
NULL);
// xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES -
// 1,
// NULL);
}

View File

@ -101,4 +101,4 @@ void init_display() {
display_fill(0x00); display_fill(0x00);
display_set_pos(0, 0); display_set_pos(0, 0);
} }

View File

@ -6,6 +6,7 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once
#include "driver/rmt.h" #include "driver/rmt.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
@ -27,10 +28,18 @@ typedef enum light_mode_e {
light_mode_mqtt_connected = 3, light_mode_mqtt_connected = 3,
light_mode_desktop_online = 4, light_mode_desktop_online = 4,
light_mode_desktop_sending_colors = 5, light_mode_desktop_sending_colors = 5,
light_mode_off = 6,
} light_mode_t; } light_mode_t;
led_strip_t *light_led_strip; led_strip_t *light_led_strip;
light_mode_t light_mode; light_mode_t light_mode;
float display_ambient_light_brightness = 1;
uint8_t display_ambient_lighting_level = 255;
void led_strip_set_brightness(uint8_t level) {
display_ambient_lighting_level = level;
display_ambient_light_brightness = (float)level / 255.0;
}
/** /**
* @brief Simple helper function, converting HSV color space to RGB color * @brief Simple helper function, converting HSV color space to RGB color
@ -178,7 +187,11 @@ void light_for_idle() {
for (uint16_t j = 0, hue = offset; j < STRIP_LED_NUMBER; for (uint16_t j = 0, hue = offset; j < STRIP_LED_NUMBER;
j++, hue += step_length) { j++, hue += step_length) {
// Build RGB values // Build RGB values
led_strip_hsv2rgb(hue, 100, 50, &red, &green, &blue); led_strip_hsv2rgb(hue, 50, 100, &red, &green, &blue);
red = red * display_ambient_light_brightness;
green = green * display_ambient_light_brightness;
blue = blue * display_ambient_light_brightness;
// Write RGB values to strip driver // Write RGB values to strip driver
ESP_ERROR_CHECK( ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, j, red, green, blue)); light_led_strip->set_pixel(light_led_strip, j, red, green, blue));
@ -246,8 +259,12 @@ void light_play_colors(uint16_t len, uint8_t *buffer) {
for (uint16_t led_index = 0, buffer_cursor = 0; for (uint16_t led_index = 0, buffer_cursor = 0;
led_index < STRIP_LED_NUMBER && buffer_cursor < len; led_index < STRIP_LED_NUMBER && buffer_cursor < len;
led_index++, buffer_cursor += 3) { led_index++, buffer_cursor += 3) {
uint8_t r = buffer[buffer_cursor], g = buffer[buffer_cursor + 1], uint8_t r = (uint8_t)((float)buffer[buffer_cursor] *
b = buffer[buffer_cursor + 2]; display_ambient_light_brightness),
g = (uint8_t)((float)buffer[buffer_cursor + 1] *
display_ambient_light_brightness),
b = (uint8_t)((float)buffer[buffer_cursor + 2] *
display_ambient_light_brightness);
ESP_ERROR_CHECK( ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, led_index, r, g, b)); light_led_strip->set_pixel(light_led_strip, led_index, r, g, b));
} }

View File

@ -1,4 +1,5 @@
#include "ambient_light.c" #include "ambient_light.c"
#include "asr_pro.c"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
@ -6,6 +7,7 @@
#include "light.c" #include "light.c"
#include "mqtt.c" #include "mqtt.c"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "ui_input.c"
#include "wifi.c" #include "wifi.c"
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
@ -49,9 +51,10 @@ void app_main(void) {
ambient_light_init(); ambient_light_init();
ambient_light_auto_fetch(); ambient_light_auto_fetch();
auto_fetch_temperature(); auto_fetch_temperature();
init_ui(); ui_input_init();
xTaskCreate(publish_ui_input, "ui_input_event", 2048, NULL, 10, NULL); xTaskCreate(mqtt_publish_ui_input, "ui_input_event", 2048, NULL, 10, NULL);
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
asr_pro_init();
light_play(light_mode_connection_wifi); light_play(light_mode_connection_wifi);
if (connect_wifi()) { if (connect_wifi()) {
light_play(light_mode_idle); light_play(light_mode_idle);

View File

@ -13,7 +13,7 @@
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "mqtt_client.h" #include "mqtt_client.h"
#include "ui.c" #include "ui_input.c"
#define MQTT_BROKER_URL CONFIG_MQTT_BROKER_URL #define MQTT_BROKER_URL CONFIG_MQTT_BROKER_URL
#define NUMBER_OF_LEDS CONFIG_NUMBER_OF_LEDS #define NUMBER_OF_LEDS CONFIG_NUMBER_OF_LEDS
@ -193,21 +193,21 @@ static bool waiting_and_get_colors() {
} }
} }
static void publish_ui_input(void *arg) { static void mqtt_publish_ui_input(void *arg) {
s_ui_input_t input; s_ui_input_t input;
for (;;) { for (;;) {
if (xQueueReceive(ui_input_event, &input, portMAX_DELAY)) { if (xQueueReceive(ui_input_event, &input, portMAX_DELAY)) {
switch (input.key) { switch (input.key) {
case UI_INPUT_DISPLAY_0_BRIGHTNESS: case ui_input_key_display_0_brightness:
case UI_INPUT_DISPLAY_1_BRIGHTNESS: { case ui_input_key_display_1_brightness: {
cJSON *publish_json_root, *brightness; cJSON *publish_json_root, *brightness;
publish_json_root = cJSON_CreateObject(); publish_json_root = cJSON_CreateObject();
cJSON_AddNumberToObject( cJSON_AddNumberToObject(
publish_json_root, "display_index", publish_json_root, "display_index",
UI_INPUT_DISPLAY_0_BRIGHTNESS == input.key ? 0 : 1); ui_input_key_display_0_brightness == input.key ? 0 : 1);
cJSON_AddItemToObject(publish_json_root, "brightness", cJSON_AddItemToObject(publish_json_root, "brightness",
brightness = cJSON_CreateObject()); brightness = cJSON_CreateObject());
cJSON_AddNumberToObject(brightness, "Absolute", input.value); cJSON_AddNumberToObject(brightness, "Relative", input.value);
char *publish_str = cJSON_Print(publish_json_root); char *publish_str = cJSON_Print(publish_json_root);
cJSON_Delete(publish_json_root); cJSON_Delete(publish_json_root);
esp_mqtt_client_publish(client, MQTT_KEY_DISPLAY_BRIGHTNESS_INPUT, esp_mqtt_client_publish(client, MQTT_KEY_DISPLAY_BRIGHTNESS_INPUT,

View File

@ -64,7 +64,7 @@ void fetch_temperature(void* arg) {
} }
display_print8_str(8, 0, temperature_str); display_print8_str(8, 0, temperature_str);
} }
vTaskDelay(pdMS_TO_TICKS(500)); vTaskDelay(pdMS_TO_TICKS(2000));
} }
display_fill_rect(0, 0, 128, 2, 0x00); display_fill_rect(0, 0, 128, 2, 0x00);
} }

156
main/ui.c
View File

@ -1,156 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#define GPIO_OUTPUT_IO_0 5
#define GPIO_OUTPUT_IO_1 6
#define GPIO_OUTPUT_PIN_SEL \
((1ULL << GPIO_OUTPUT_IO_0) | (1ULL << GPIO_OUTPUT_IO_1))
#define ENCODER_0_CLK_PIN CONFIG_ENCODER_0_CLK_PIN
#define ENCODER_0_DT_PIN CONFIG_ENCODER_0_DT_PIN
#define ENCODER_0_CLK_PIN_MASK 1ULL << ENCODER_0_CLK_PIN
#define ENCODER_0_DT_PIN_MASK 1ULL << ENCODER_0_DT_PIN
#define ENCODER_1_CLK_PIN CONFIG_ENCODER_1_CLK_PIN
#define ENCODER_1_DT_PIN CONFIG_ENCODER_1_DT_PIN
#define ENCODER_1_CLK_PIN_MASK 1ULL << ENCODER_1_CLK_PIN
#define ENCODER_1_DT_PIN_MASK 1ULL << ENCODER_1_DT_PIN
#define ESP_INTR_FLAG_DEFAULT 0
#define NOT_ROTATING -1
#define CLOCKWISE 1
#define COUNTER_CLOCKWISE 0
#define UI_INPUT_DISPLAY_0_BRIGHTNESS 1
#define UI_INPUT_DISPLAY_1_BRIGHTNESS 2
typedef struct s_ui_input {
uint8_t key;
uint16_t value;
} s_ui_input_t;
static xQueueHandle ui_input_event = NULL;
static int8_t rising_edge_rotation_direction = NOT_ROTATING;
static int8_t falling_edge_rotation_direction = NOT_ROTATING;
static uint8_t display_0_brightness = 20;
static uint8_t display_1_brightness = 20;
static s_ui_input_t current_ui_input = {};
uint8_t input_key;
uint8_t clk_pin = ENCODER_0_CLK_PIN;
uint8_t dt_level;
uint8_t dt_pin = ENCODER_0_DT_PIN;
uint8_t* value = &display_0_brightness;
static void IRAM_ATTR gpio_isr_handler(void* arg) {
uint8_t input_key = (uint8_t)arg;
switch (input_key) {
case UI_INPUT_DISPLAY_0_BRIGHTNESS:
clk_pin = ENCODER_0_CLK_PIN;
dt_pin = ENCODER_0_DT_PIN;
value = &display_0_brightness;
break;
case UI_INPUT_DISPLAY_1_BRIGHTNESS:
clk_pin = ENCODER_1_CLK_PIN;
dt_pin = ENCODER_1_DT_PIN;
value = &display_1_brightness;
break;
default:
break;
}
dt_level = gpio_get_level(dt_pin);
if (gpio_get_level(clk_pin)) {
rising_edge_rotation_direction = dt_level == 0;
if (falling_edge_rotation_direction == rising_edge_rotation_direction) {
if (rising_edge_rotation_direction) {
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
gpio_set_level(GPIO_OUTPUT_IO_1, 0);
*value += 1;
} else {
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
gpio_set_level(GPIO_OUTPUT_IO_1, 1);
*value -= 1;
}
falling_edge_rotation_direction = NOT_ROTATING;
current_ui_input.key = input_key;
current_ui_input.value = *value;
xQueueSendFromISR(ui_input_event, &current_ui_input, NULL);
} else {
if (falling_edge_rotation_direction != NOT_ROTATING) {
rising_edge_rotation_direction = NOT_ROTATING;
}
}
} else {
falling_edge_rotation_direction = dt_level;
// printf("F %d\t", falling_edge_rotation_direction);
if (rising_edge_rotation_direction == falling_edge_rotation_direction) {
if (falling_edge_rotation_direction) {
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
gpio_set_level(GPIO_OUTPUT_IO_1, 0);
*value += 1;
} else {
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
gpio_set_level(GPIO_OUTPUT_IO_1, 1);
*value -= 1;
}
rising_edge_rotation_direction = NOT_ROTATING;
current_ui_input.key = input_key;
current_ui_input.value = *value;
xQueueSendFromISR(ui_input_event, &current_ui_input, NULL);
} else {
if (rising_edge_rotation_direction != NOT_ROTATING) {
falling_edge_rotation_direction = NOT_ROTATING;
}
}
}
}
void init_ui(void) {
// zero-initialize the config structure.
gpio_config_t io_conf = {};
// disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
// set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
// bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
// disable pull-down mode
io_conf.pull_down_en = 0;
// disable pull-up mode
io_conf.pull_up_en = 0;
// configure GPIO with the given settings
gpio_config(&io_conf);
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
io_conf.pull_down_en = 0;
// interrupt of rising edge
io_conf.intr_type = GPIO_INTR_ANYEDGE;
io_conf.pin_bit_mask = ENCODER_0_CLK_PIN_MASK | ENCODER_1_CLK_PIN_MASK;
gpio_config(&io_conf);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pin_bit_mask = ENCODER_0_DT_PIN_MASK | ENCODER_1_DT_PIN_MASK;
gpio_config(&io_conf);
// start encoder task
ui_input_event = xQueueCreate(10, sizeof(s_ui_input_t));
// install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// hook isr handler for specific gpio pin
gpio_isr_handler_add(ENCODER_0_CLK_PIN, gpio_isr_handler,
(void*)UI_INPUT_DISPLAY_0_BRIGHTNESS);
// hook isr handler for specific gpio pin
gpio_isr_handler_add(ENCODER_1_CLK_PIN, gpio_isr_handler,
(void*)UI_INPUT_DISPLAY_1_BRIGHTNESS);
}

278
main/ui_input.c Normal file
View File

@ -0,0 +1,278 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "driver/gpio.h"
#include "embedded_display.c"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "light.c"
#define GPIO_OUTPUT_IO_0 5
#define GPIO_OUTPUT_IO_1 6
#define GPIO_OUTPUT_PIN_SEL \
((1ULL << GPIO_OUTPUT_IO_0) | (1ULL << GPIO_OUTPUT_IO_1))
#define ENCODER_0_CLK_PIN CONFIG_ENCODER_0_CLK_PIN
#define ENCODER_0_DT_PIN CONFIG_ENCODER_0_DT_PIN
#define ENCODER_0_SW_PIN CONFIG_ENCODER_0_SW_PIN
#define ENCODER_0_CLK_PIN_MASK 1ULL << ENCODER_0_CLK_PIN
#define ENCODER_0_DT_PIN_MASK 1ULL << ENCODER_0_DT_PIN
#define ENCODER_0_SW_PIN_MASK 1ULL << ENCODER_0_SW_PIN
#define ENCODER_1_CLK_PIN CONFIG_ENCODER_1_CLK_PIN
#define ENCODER_1_DT_PIN CONFIG_ENCODER_1_DT_PIN
#define ENCODER_1_SW_PIN CONFIG_ENCODER_1_SW_PIN
#define ENCODER_1_CLK_PIN_MASK 1ULL << ENCODER_1_CLK_PIN
#define ENCODER_1_DT_PIN_MASK 1ULL << ENCODER_1_DT_PIN
#define ENCODER_1_SW_PIN_MASK 1ULL << ENCODER_1_SW_PIN
#define ESP_INTR_FLAG_DEFAULT 0
#define NOT_ROTATING -1
#define CLOCKWISE 1
#define COUNTER_CLOCKWISE 0
static const char *UI_INPUT_TAG = "UiInput";
typedef enum e_ui_input_key {
ui_input_key_display_0_brightness = 0,
ui_input_key_display_1_brightness = 1,
ui_input_key_computer_volume = 2,
ui_input_key_display_ambient_lighting_level = 3,
ui_input_key_display_ambient_lighting_mode = 4,
ui_input_key_display_0_mode = 5,
ui_input_key_display_1_mode = 6,
} e_ui_input_key_t;
typedef struct s_ui_input {
e_ui_input_key_t key;
int16_t value;
} s_ui_input_t;
typedef enum e_ui_input_raw_key {
ui_input_raw_key_encoder_0 = 0,
ui_input_raw_key_encoder_1 = 1,
} e_ui_input_raw_key_t;
typedef struct s_ui_input_raw {
e_ui_input_raw_key_t key;
uint8_t value;
} s_ui_input_raw_t;
static xQueueHandle ui_input_event = NULL;
static xQueueHandle ui_input_raw_event = NULL;
static int8_t rising_edge_rotation_direction = NOT_ROTATING;
static int8_t falling_edge_rotation_direction = NOT_ROTATING;
static uint8_t display_0_brightness = 20;
static uint8_t display_1_brightness = 20;
static uint8_t computer_volume = 30;
static s_ui_input_t current_ui_input = {};
uint8_t input_key;
static void IRAM_ATTR gpio_isr_handler(void *arg) {
input_key = (e_ui_input_raw_key_t)arg;
switch (input_key) {
case ui_input_raw_key_encoder_0: {
s_ui_input_raw_t event = {
.key = input_key,
.value = (gpio_get_level(ENCODER_0_SW_PIN) << 2) |
(gpio_get_level(ENCODER_0_CLK_PIN) << 1) |
(gpio_get_level(ENCODER_0_DT_PIN)),
};
xQueueSendFromISR(ui_input_raw_event, &event, NULL);
break;
}
case ui_input_raw_key_encoder_1: {
s_ui_input_raw_t event = {
.key = input_key,
.value = (gpio_get_level(ENCODER_1_SW_PIN) << 2) |
(gpio_get_level(ENCODER_1_CLK_PIN) << 1) |
(gpio_get_level(ENCODER_1_DT_PIN)),
};
xQueueSendFromISR(ui_input_raw_event, &event, NULL);
break;
}
default:
return;
}
}
static void ui_input_update_embedded_display(void *arg) {
s_ui_input_t input;
char changing_str[12] = "NC";
for (;;) {
if (xQueueReceive(ui_input_event, &input, portMAX_DELAY)) {
switch (input.key) {
case ui_input_key_display_0_brightness:
sprintf(changing_str, "Dis0: % 3d", input.value);
break;
case ui_input_key_display_1_brightness:
sprintf(changing_str, "Dis1: % 3d", input.value);
break;
case ui_input_key_computer_volume:
sprintf(changing_str, "CVol: % 3d", input.value);
break;
case ui_input_key_display_ambient_lighting_level:
sprintf(changing_str, "ALLv: % 3d", display_ambient_lighting_level);
break;
case ui_input_key_display_ambient_lighting_mode:
sprintf(changing_str, "ALMd: % 3d", input.value);
break;
case ui_input_key_display_0_mode:
sprintf(changing_str, "Dis0M: % 2d", input.value);
break;
case ui_input_key_display_1_mode:
sprintf(changing_str, "Dis1M: % 2d", input.value);
break;
default:
strcpy(changing_str, "NC");
break;
}
display_fill_rect(0, 6, 128, 8, 0);
display_print8_str(8, 6, changing_str);
}
}
}
static void ui_input_raw_handler(void *arg) {
s_ui_input_raw_t input;
uint8_t clk_level;
uint8_t dt_level;
uint8_t sw_level;
int8_t delta = 0;
char changing_str[12] = "NC";
for (;;) {
if (xQueueReceive(ui_input_raw_event, &input, portMAX_DELAY)) {
sw_level = input.value >> 2 & 1;
clk_level = input.value >> 1 & 1;
dt_level = input.value & 1;
if (clk_level) {
rising_edge_rotation_direction = dt_level == 0;
if (falling_edge_rotation_direction == rising_edge_rotation_direction) {
if (rising_edge_rotation_direction) {
delta = 1;
} else {
delta = -1;
}
falling_edge_rotation_direction = NOT_ROTATING;
} else {
delta = 0;
if (falling_edge_rotation_direction != NOT_ROTATING) {
rising_edge_rotation_direction = NOT_ROTATING;
}
}
} else {
falling_edge_rotation_direction = dt_level;
if (rising_edge_rotation_direction == falling_edge_rotation_direction) {
if (falling_edge_rotation_direction) {
delta = 1;
} else {
delta = -1;
}
rising_edge_rotation_direction = NOT_ROTATING;
} else {
delta = 0;
if (rising_edge_rotation_direction != NOT_ROTATING) {
falling_edge_rotation_direction = NOT_ROTATING;
}
}
}
if (delta == 0) {
continue;
}
// display_fill_rect(0, 6, 128, 8, 0);
// switch (input.key) {
// case ui_input_raw_key_encoder_0:
// sprintf(changing_str, "E0 %d: %u%u%u%u%u", delta,
// (input.value >> 4) & 1, (input.value >> 3) & 1,
// (input.value >> 2) & 1, (input.value >> 1) & 1,
// (input.value) & 1);
// break;
// case ui_input_raw_key_encoder_1:
// sprintf(changing_str, "E1 %d: %u%u%u%u%u", delta,
// (input.value >> 4) & 1, (input.value >> 3) & 1,
// (input.value >> 2) & 1, (input.value >> 1) & 1,
// (input.value) & 1);
// break;
// default:
// strcpy(changing_str, "NC");
// break;
// }
// display_print8_str(8, 6, changing_str);
s_ui_input_t event = {.value = delta};
if (input.key == ui_input_raw_key_encoder_0) {
if (sw_level) {
event.key = ui_input_key_computer_volume;
} else {
event.key = ui_input_key_display_0_brightness;
}
} else if (input.key == ui_input_raw_key_encoder_1) {
if (sw_level) {
event.key = ui_input_key_display_ambient_lighting_level;
led_strip_set_brightness(display_ambient_lighting_level + delta);
} else {
event.key = ui_input_key_display_1_brightness;
}
}
xQueueSendFromISR(ui_input_event, &event, NULL);
}
}
}
void ui_input_init(void) {
// zero-initialize the config structure.
gpio_config_t io_conf = {};
// disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
// set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
// bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
// disable pull-down mode
io_conf.pull_down_en = 0;
// disable pull-up mode
io_conf.pull_up_en = 0;
// configure GPIO with the given settings
gpio_config(&io_conf);
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
// interrupt of rising edge
io_conf.intr_type = GPIO_INTR_ANYEDGE;
io_conf.pin_bit_mask = ENCODER_0_CLK_PIN_MASK | ENCODER_1_CLK_PIN_MASK;
gpio_config(&io_conf);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pin_bit_mask = ENCODER_0_DT_PIN_MASK | ENCODER_1_DT_PIN_MASK;
gpio_config(&io_conf);
io_conf.pull_up_en = 1;
io_conf.pull_down_en = 0;
io_conf.pin_bit_mask = ENCODER_0_SW_PIN_MASK | ENCODER_1_SW_PIN_MASK;
gpio_config(&io_conf);
// start encoder task
ui_input_event = xQueueCreate(10, sizeof(s_ui_input_t));
ui_input_raw_event = xQueueCreate(10, sizeof(s_ui_input_raw_t));
// install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// hook isr handler for specific gpio pin
gpio_isr_handler_add(ENCODER_0_CLK_PIN, gpio_isr_handler,
(void *)ui_input_raw_key_encoder_0);
// hook isr handler for specific gpio pin
gpio_isr_handler_add(ENCODER_1_CLK_PIN, gpio_isr_handler,
(void *)ui_input_raw_key_encoder_1);
xTaskCreate(ui_input_update_embedded_display, "ui_input_event", 2048, NULL,
10, NULL);
xTaskCreate(ui_input_raw_handler, "ui_input_event", 2048, NULL, 10, NULL);
}