Compare commits
10 Commits
c27418aaf1
...
build/esp-
Author | SHA1 | Date | |
---|---|---|---|
f0a1dae657 | |||
58d1039c78 | |||
e947dc3ac1 | |||
c8eb0817e8 | |||
ac33f67d77 | |||
a54c554342 | |||
eaedd765ed | |||
895aa3058d | |||
33e08edeed | |||
e426829aa6 |
@ -4,7 +4,5 @@
|
|||||||
# CMakeLists in this exact order for cmake to work correctly
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/led_strip)
|
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(display-ambient-light-board)
|
project(display-ambient-light-board)
|
@ -1,2 +1,2 @@
|
|||||||
idf_component_register(SRCS "app_nvs.c" "apds_9960.c" "pca9555.c" "i2c.c" "asr_pro.c" "ci_03t.c" "ui_input.c" "ambient_light.c" "temperature.c" "embedded_display.c" "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c"
|
idf_component_register(SRCS "hw-ms03.c" "app_nvs.c" "apds_9960.c" "pca9555.c" "i2c.c" "asr_pro.c" "ci_03t.c" "ui_input.c" "ambient_light.c" "temperature.c" "embedded_display.c" "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c" "led_strip_encoder/led_strip_encoder.c"
|
||||||
INCLUDE_DIRS ".")
|
INCLUDE_DIRS ".")
|
@ -146,3 +146,12 @@ menu "UART Configuration"
|
|||||||
help
|
help
|
||||||
UART NUM
|
UART NUM
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
menu "ADPS 9960"
|
||||||
|
config APDS_9960_INT_GPIO
|
||||||
|
int "APDS 996O INT GPIO"
|
||||||
|
range 0 32
|
||||||
|
default 2
|
||||||
|
help
|
||||||
|
APDS 996O INT GPIO
|
||||||
|
endmenu
|
@ -120,9 +120,9 @@ void ambient_light_fetch(void* arg) {
|
|||||||
uint16_t als_ch0_raw;
|
uint16_t als_ch0_raw;
|
||||||
uint16_t als_ch1_raw;
|
uint16_t als_ch1_raw;
|
||||||
uint16_t proximity_raw;
|
uint16_t proximity_raw;
|
||||||
char als_ch0_str[10];
|
char als_ch0_str[20];
|
||||||
char als_ch1_str[10];
|
char als_ch1_str[20];
|
||||||
char proximity_str[10];
|
char proximity_str[20];
|
||||||
uint8_t als_ch0_buffer[] = {0, 0};
|
uint8_t als_ch0_buffer[] = {0, 0};
|
||||||
uint8_t als_ch1_buffer[] = {0, 0};
|
uint8_t als_ch1_buffer[] = {0, 0};
|
||||||
uint8_t proximity_buffer[] = {0, 0};
|
uint8_t proximity_buffer[] = {0, 0};
|
||||||
|
343
main/apds_9960.c
343
main/apds_9960.c
@ -1,14 +1,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
#include "embedded_display.c"
|
#include "embedded_display.c"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "i2c.c"
|
#include "i2c.c"
|
||||||
|
|
||||||
// #define APDS_9930_CMD_REPEATED 0x80 // 命令重复地址
|
#define APDS_9960_INT_GPIO CONFIG_APDS_9960_INT_GPIO
|
||||||
// #define APDS_9930_CMD_AUTO_INCREMENT 0x90 // 命令自动递增地址
|
|
||||||
|
|
||||||
|
// ===============================================
|
||||||
|
// Register addresses
|
||||||
|
// ===============================================
|
||||||
// 0x80 ENABLE R/W Enable states and interrupts 0x00
|
// 0x80 ENABLE R/W Enable states and interrupts 0x00
|
||||||
// 0x81 ATIME R/W ADC integration time 0xFF
|
// 0x81 ATIME R/W ADC integration time 0xFF
|
||||||
// 0x83 WTIME R/W Wait time (non-gesture) 0xFF
|
// 0x83 WTIME R/W Wait time (non-gesture) 0xFF
|
||||||
@ -109,13 +115,40 @@
|
|||||||
#define APDS_9960_REG_GFIFO_L 0xFE // 手势 FIFO 数据左 0x00
|
#define APDS_9960_REG_GFIFO_L 0xFE // 手势 FIFO 数据左 0x00
|
||||||
#define APDS_9960_REG_GFIFO_R 0xFF // 手势 FIFO 数据右 0x00
|
#define APDS_9960_REG_GFIFO_R 0xFF // 手势 FIFO 数据右 0x00
|
||||||
|
|
||||||
#define APDS_9960_CONTROL_VALUE \
|
#define APDS_9960_GVALID 0b00000001 // GVALID
|
||||||
0b00001010 // 50 mA LED, Reserved, 2x PGAIN, 4x ALS/Cain GAIN
|
#define APDS_9960_GFOV 0b00000010 // GFOV
|
||||||
#define APDS_9960_ENABLE_VALUE 0b00000111
|
#define APDS_9960_PINT 0x20 // PINT
|
||||||
#define APDS_9930_OFFSET_VALUE 0x8f
|
#define APDS_9960_AINT 0x10 // AINT
|
||||||
|
#define APDS_9960_GINT 0x04 // GINT
|
||||||
|
|
||||||
|
// 50 mA LED, Reserved, 2x PGAIN, 4x ALS/Cain GAIN
|
||||||
|
#define APDS_9960_CONTROL_VALUE 0b00001010
|
||||||
|
// Enable Gesture, Proximity, ALS, Power
|
||||||
|
// X, GEN, PIEN, AIEN, WEN, PEN, AEN, PON
|
||||||
|
#define APDS_9960_ENABLE_VALUE 0b01100111
|
||||||
|
|
||||||
#define APDS_9960_TAG "APDS-9960"
|
#define APDS_9960_TAG "APDS-9960"
|
||||||
|
|
||||||
|
static QueueHandle_t apds_9960_int_evt_queue = NULL;
|
||||||
|
|
||||||
|
static int64_t last_apds_9960_int_time = 0;
|
||||||
|
|
||||||
|
esp_err_t apds_9960_write_empty(uint8_t command) {
|
||||||
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, APDS_9960_ADDRESS << 1 | I2C_MASTER_WRITE,
|
||||||
|
ACK_CHECK_EN);
|
||||||
|
i2c_master_write_byte(cmd, command, ACK_CHECK_DIS);
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
esp_err_t error =
|
||||||
|
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "write failed. %d", error);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t apds_9960_write(uint8_t command, uint8_t data) {
|
esp_err_t apds_9960_write(uint8_t command, uint8_t data) {
|
||||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
@ -125,7 +158,7 @@ esp_err_t apds_9960_write(uint8_t command, uint8_t data) {
|
|||||||
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
|
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
esp_err_t error =
|
esp_err_t error =
|
||||||
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
|
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "write failed. %d", error);
|
ESP_LOGW(APDS_9960_TAG, "write failed. %d", error);
|
||||||
@ -145,10 +178,10 @@ esp_err_t apds_9960_read_byte(uint8_t command, uint8_t* data) {
|
|||||||
i2c_master_read_byte(cmd, data, NACK_VAL);
|
i2c_master_read_byte(cmd, data, NACK_VAL);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
esp_err_t error =
|
esp_err_t error =
|
||||||
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
|
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "write failed. %d", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -167,42 +200,87 @@ esp_err_t apds_9960_read_word(uint8_t command, uint16_t* data) {
|
|||||||
i2c_master_read_byte(cmd, (uint8_t*)data + 1, NACK_VAL);
|
i2c_master_read_byte(cmd, (uint8_t*)data + 1, NACK_VAL);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
esp_err_t error =
|
esp_err_t error =
|
||||||
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
|
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "write failed. %d", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apes_9960_fetch(void* arg) {
|
// read bytes by length
|
||||||
ESP_LOGI(APDS_9960_TAG, "apes_9960_fetch");
|
esp_err_t apds_9960_read_bytes_len(uint8_t command, uint8_t* data,
|
||||||
|
uint8_t len) {
|
||||||
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, APDS_9960_ADDRESS << 1 | I2C_MASTER_WRITE,
|
||||||
|
ACK_CHECK_EN);
|
||||||
|
i2c_master_write_byte(cmd, command, ACK_CHECK_EN);
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, APDS_9960_ADDRESS << 1 | I2C_MASTER_READ,
|
||||||
|
ACK_CHECK_EN);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (i == len - 1) {
|
||||||
|
i2c_master_read_byte(cmd, (uint8_t*)data + i, NACK_VAL);
|
||||||
|
} else {
|
||||||
|
i2c_master_read_byte(cmd, (uint8_t*)data + i, ACK_VAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
esp_err_t error =
|
||||||
|
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100 / portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_clear_all_int(void) {
|
||||||
|
ESP_LOGI(APDS_9960_TAG, "apds_9960_clear_all_int");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(apds_9960_write_empty(APDS_9960_REG_AICLEAR));
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(apds_9960_write(APDS_9960_REG_GCONF4, 0x06));
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_fetch(void* arg) {
|
||||||
|
ESP_LOGI(APDS_9960_TAG, "apds_9960_fetch");
|
||||||
esp_err_t error;
|
esp_err_t error;
|
||||||
uint16_t red_raw;
|
uint16_t red_raw;
|
||||||
uint16_t green_raw;
|
uint16_t green_raw;
|
||||||
uint16_t blue_raw;
|
uint16_t blue_raw;
|
||||||
uint16_t clear_raw;
|
uint16_t clear_raw;
|
||||||
uint8_t proximity_raw;
|
uint8_t byte_buffer;
|
||||||
char red_str[10];
|
uint8_t gesture_status_raw;
|
||||||
char green_str[10];
|
uint8_t status_raw;
|
||||||
char blue_str[10];
|
char red_str[20];
|
||||||
char clear_str[10];
|
char green_str[20];
|
||||||
char proximity_str[10];
|
char blue_str[20];
|
||||||
|
char clear_str[20];
|
||||||
|
char status_str[20];
|
||||||
|
uint8_t interrupt = 0;
|
||||||
display_fill_rect(0, 2, 128, 8, 0x00);
|
display_fill_rect(0, 2, 128, 8, 0x00);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Proximity
|
if (last_apds_9960_int_time + 1000000 < esp_timer_get_time()) {
|
||||||
error = apds_9960_read_byte(APDS_9960_REG_PDATA, &proximity_raw);
|
interrupt = gpio_get_level(APDS_9960_INT_GPIO);
|
||||||
|
if (interrupt == 1 ||
|
||||||
|
last_apds_9960_int_time + 10000000 < esp_timer_get_time()) {
|
||||||
|
apds_9960_clear_all_int();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear
|
||||||
|
error = apds_9960_read_word(APDS_9960_REG_CDATAL, &clear_raw);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "read proximity failed. %x", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
} else {
|
} else {
|
||||||
sprintf(proximity_str, "Prox: % 5d ", proximity_raw);
|
sprintf(clear_str, "C:% 5d", clear_raw);
|
||||||
display_print8_str(8, 2, proximity_str);
|
display_print8_str(64, 6, clear_str);
|
||||||
ESP_LOGD(APDS_9960_TAG, "Prox: %d %x", proximity_raw);
|
ESP_LOGD(APDS_9960_TAG, "Clear: %d", clear_raw);
|
||||||
}
|
}
|
||||||
// red
|
// red
|
||||||
error = apds_9960_read_word(APDS_9960_REG_RDATAL, &red_raw);
|
error = apds_9960_read_word(APDS_9960_REG_RDATAL, &red_raw);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "read failed. %x", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
} else {
|
} else {
|
||||||
sprintf(red_str, "R:% 5d", red_raw);
|
sprintf(red_str, "R:% 5d", red_raw);
|
||||||
display_print8_str(0, 4, red_str);
|
display_print8_str(0, 4, red_str);
|
||||||
@ -211,7 +289,7 @@ void apes_9960_fetch(void* arg) {
|
|||||||
// green
|
// green
|
||||||
error = apds_9960_read_word(APDS_9960_REG_GDATAL, &green_raw);
|
error = apds_9960_read_word(APDS_9960_REG_GDATAL, &green_raw);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "read failed. %x", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
} else {
|
} else {
|
||||||
sprintf(green_str, "G:% 5d", green_raw);
|
sprintf(green_str, "G:% 5d", green_raw);
|
||||||
display_print8_str(64, 4, green_str);
|
display_print8_str(64, 4, green_str);
|
||||||
@ -220,43 +298,228 @@ void apes_9960_fetch(void* arg) {
|
|||||||
// blue
|
// blue
|
||||||
error = apds_9960_read_word(APDS_9960_REG_BDATAL, &blue_raw);
|
error = apds_9960_read_word(APDS_9960_REG_BDATAL, &blue_raw);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
ESP_LOGW(APDS_9960_TAG, "read failed. %x", error);
|
ESP_LOGW(APDS_9960_TAG, "read failed. %d", error);
|
||||||
} else {
|
} else {
|
||||||
sprintf(blue_str, "B:% 5d", blue_raw);
|
sprintf(blue_str, "B:% 5d", blue_raw);
|
||||||
display_print8_str(0, 6, blue_str);
|
display_print8_str(0, 6, blue_str);
|
||||||
ESP_LOGD(APDS_9960_TAG, "Blue: %d", blue_raw);
|
ESP_LOGD(APDS_9960_TAG, "Blue: %d", blue_raw);
|
||||||
}
|
}
|
||||||
// clear
|
|
||||||
error = apds_9960_read_word(APDS_9960_REG_CDATAL, &clear_raw);
|
|
||||||
if (error != ESP_OK) {
|
|
||||||
ESP_LOGW(APDS_9960_TAG, "read failed. %x", error);
|
|
||||||
} else {
|
|
||||||
sprintf(clear_str, "C:% 4d", clear_raw);
|
|
||||||
display_print8_str(64, 6, clear_str);
|
|
||||||
ESP_LOGD(APDS_9960_TAG, "Clear: %d", clear_raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
}
|
}
|
||||||
display_fill_rect(0, 2, 128, 8, 0x00);
|
display_fill_rect(0, 2, 128, 8, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
void apes_9960_auto_fetch() {
|
void apds_9960_auto_fetch() {
|
||||||
if (is_apds_9960_online == 0) {
|
if (is_apds_9960_online == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xTaskCreate(apes_9960_fetch, "APDS-9960-fetch", 2048, NULL, 10, NULL);
|
xTaskCreate(apds_9960_fetch, "APDS-9960-fetch", 2048, NULL, 10, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void apes_9960_init() {
|
void apds_9960_read_gesture() {
|
||||||
|
ESP_LOGI(APDS_9960_TAG, "apes_9960_gesture_fetch");
|
||||||
|
uint8_t byte_buffer;
|
||||||
|
esp_err_t error;
|
||||||
|
uint32_t gesture_values_raw_arr[32];
|
||||||
|
char gesture_values_str_arr[20];
|
||||||
|
|
||||||
|
error = apds_9960_read_byte(APDS_9960_REG_GSTATUS, &byte_buffer);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "read APDS_9960_REG_GSTATUS failed. %d", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGD(APDS_9960_TAG, "APDS-9960 interrupt. status: %x", byte_buffer);
|
||||||
|
if (!(byte_buffer & APDS_9960_GVALID)) {
|
||||||
|
ESP_LOGI(APDS_9960_TAG, "Gesture no valid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(APDS_9960_TAG, "Gesture interrupt");
|
||||||
|
error = apds_9960_read_byte(APDS_9960_REG_GFLVL, &byte_buffer);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "read APDS_9960_REG_GFLVL failed. %d", error);
|
||||||
|
apds_9960_write(APDS_9960_REG_GCONF4, 0x06);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byte_buffer < 4) {
|
||||||
|
ESP_LOGD(APDS_9960_TAG, "Gesture FIFO level too low: %d", byte_buffer);
|
||||||
|
apds_9960_write(APDS_9960_REG_GCONF4, 0x06);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGD(APDS_9960_TAG, "Gesture FIFO Level: %d", byte_buffer);
|
||||||
|
|
||||||
|
error = apds_9960_read_bytes_len(
|
||||||
|
APDS_9960_REG_GFIFO_U, (uint8_t*)gesture_values_raw_arr, byte_buffer * 4);
|
||||||
|
apds_9960_write(APDS_9960_REG_GCONF4, 0x06);
|
||||||
|
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "read APDS_9960_REG_GFIFO(len: %d) failed. % d",
|
||||||
|
byte_buffer * 4, error);
|
||||||
|
} else {
|
||||||
|
int16_t before_ud = 0, before_lr = 0, after_ud = 0, after_lr = 0;
|
||||||
|
int16_t u = 0, d = 0, l = 0, r = 0;
|
||||||
|
|
||||||
|
uint8_t last_2_index = byte_buffer - 2;
|
||||||
|
|
||||||
|
// head 2
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
u = gesture_values_raw_arr[i] & 0xff;
|
||||||
|
d = gesture_values_raw_arr[i] >> 8 & 0xff;
|
||||||
|
l = gesture_values_raw_arr[i] >> 16 & 0xff;
|
||||||
|
r = gesture_values_raw_arr[i] >> 24 & 0xff;
|
||||||
|
before_ud += (u - d) * 100 / u + d;
|
||||||
|
before_lr += (l - r) * 100 / l + r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// last 2
|
||||||
|
for (int i = last_2_index; i < byte_buffer; i++) {
|
||||||
|
u = gesture_values_raw_arr[i] & 0xff;
|
||||||
|
d = gesture_values_raw_arr[i] >> 8 & 0xff;
|
||||||
|
l = gesture_values_raw_arr[i] >> 16 & 0xff;
|
||||||
|
r = gesture_values_raw_arr[i] >> 24 & 0xff;
|
||||||
|
after_ud += (u - d) * 100 / u + d;
|
||||||
|
after_lr += (l - r) * 100 / l + r;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < byte_buffer; i++) {
|
||||||
|
if (i < 2) {
|
||||||
|
u = gesture_values_raw_arr[i] & 0xff;
|
||||||
|
d = gesture_values_raw_arr[i] >> 8 & 0xff;
|
||||||
|
l = gesture_values_raw_arr[i] >> 16 & 0xff;
|
||||||
|
r = gesture_values_raw_arr[i] >> 24 & 0xff;
|
||||||
|
before_ud += (u - d) * 100 / u + d;
|
||||||
|
before_lr += (l - r) * 100 / l + r;
|
||||||
|
} else if (i >= last_2_index) {
|
||||||
|
u = gesture_values_raw_arr[i] & 0xff;
|
||||||
|
d = gesture_values_raw_arr[i] >> 8 & 0xff;
|
||||||
|
l = gesture_values_raw_arr[i] >> 16 & 0xff;
|
||||||
|
r = gesture_values_raw_arr[i] >> 24 & 0xff;
|
||||||
|
after_ud += (u - d) * 100 / u + d;
|
||||||
|
after_lr += (l - r) * 100 / l + r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Δud: %d, Δlr: %d \n", after_ud - before_ud, after_lr - before_lr);
|
||||||
|
display_fill_rect(0, 0, 128, 2, 0x00);
|
||||||
|
|
||||||
|
if (abs(after_ud - before_ud) * 2 > abs(after_lr - before_lr)) {
|
||||||
|
if (after_ud - before_ud < -80) {
|
||||||
|
display_print8_str(0, 0, "Gesture: up");
|
||||||
|
} else if (after_ud - before_ud > 80) {
|
||||||
|
display_print8_str(0, 0, "Gesture: down");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (after_lr - before_lr < -120) {
|
||||||
|
display_print8_str(0, 0, "Gesture: left");
|
||||||
|
} else if (after_lr - before_lr > 120) {
|
||||||
|
display_print8_str(0, 0, "Gesture: right");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// display_print8_str(0, 0, gesture_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_read_proximity() {
|
||||||
|
uint8_t proximity_raw;
|
||||||
|
char proximity_str[20];
|
||||||
|
esp_err_t error;
|
||||||
|
|
||||||
|
// Proximity
|
||||||
|
error = apds_9960_read_byte(APDS_9960_REG_PDATA, &proximity_raw);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(APDS_9960_TAG, "read proximity failed. %x", error);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(APDS_9960_TAG, "Prox: % 5d ", proximity_raw);
|
||||||
|
sprintf(proximity_str, "Prox: % 5d ", proximity_raw);
|
||||||
|
display_print8_str(8, 2, proximity_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_int_handler(void* arg) {
|
||||||
|
xQueueSendFromISR(apds_9960_int_evt_queue, &arg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_int_evt_handler() {
|
||||||
|
if (is_apds_9960_online == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apds_9960_clear_all_int();
|
||||||
|
esp_err_t error;
|
||||||
|
uint8_t status_raw;
|
||||||
|
while (xQueueReceive(apds_9960_int_evt_queue, NULL, portMAX_DELAY)) {
|
||||||
|
last_apds_9960_int_time = esp_timer_get_time();
|
||||||
|
ESP_ERROR_RETRY(apds_9960_read_byte(APDS_9960_REG_STATUS, &status_raw), 10);
|
||||||
|
ESP_ERROR_RETRY(apds_9960_write_empty(APDS_9960_REG_AICLEAR), 10);
|
||||||
|
|
||||||
|
ESP_LOGD(
|
||||||
|
APDS_9960_TAG, "[apds_9960_int_evt_handler] status %d%d%d%d %d%d%d%d",
|
||||||
|
(status_raw >> 7) & 1, (status_raw >> 6) & 1, (status_raw >> 5) & 1,
|
||||||
|
(status_raw >> 4) & 1, (status_raw >> 3) & 1, (status_raw >> 2) & 1,
|
||||||
|
(status_raw >> 1) & 1, status_raw & 1);
|
||||||
|
if (status_raw & APDS_9960_PINT) {
|
||||||
|
apds_9960_read_proximity();
|
||||||
|
}
|
||||||
|
if (status_raw & APDS_9960_GINT) {
|
||||||
|
apds_9960_read_gesture();
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apds_9960_init() {
|
||||||
if (is_apds_9960_online == 0) {
|
if (is_apds_9960_online == 0) {
|
||||||
ESP_LOGI(APDS_9960_TAG, "APDS-9960 is offline");
|
ESP_LOGI(APDS_9960_TAG, "APDS-9960 is offline");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGI(APDS_9960_TAG, "Initializing APDS-9960");
|
ESP_LOGI(APDS_9960_TAG, "Initializing APDS-9960");
|
||||||
|
// esp_log_level_set(APDS_9960_TAG, ESP_LOG_DEBUG);
|
||||||
|
|
||||||
|
gpio_config_t io_conf = {};
|
||||||
|
|
||||||
|
io_conf.mode = GPIO_MODE_INPUT;
|
||||||
|
io_conf.pull_up_en = 0;
|
||||||
|
io_conf.pull_down_en = 0;
|
||||||
|
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||||
|
io_conf.pin_bit_mask = 1ULL << APDS_9960_INT_GPIO;
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
|
||||||
|
gpio_isr_handler_add(APDS_9960_INT_GPIO, apds_9960_int_handler, NULL);
|
||||||
|
|
||||||
|
// 环境光 ADC 积分时间
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_ATIME, 246)); // 27.8ms
|
||||||
|
// 增益
|
||||||
ESP_ERROR_CHECK(
|
ESP_ERROR_CHECK(
|
||||||
apds_9960_write(APDS_9960_REG_CONTROL, APDS_9960_CONTROL_VALUE));
|
apds_9960_write(APDS_9960_REG_CONTROL, APDS_9960_CONTROL_VALUE));
|
||||||
|
|
||||||
|
// enable gesture interrupt
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_GCONF4, 0x06));
|
||||||
|
// 累积的手势数据达到 4 组时触发中断
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_GCONF1, 0x40));
|
||||||
|
// Gesture Enter Threshold
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_GPENTH, 3));
|
||||||
|
// Gesture Exit Threshold
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_GEXTH, 3));
|
||||||
|
// Gesture Drive Strength
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_GCONF2, 0b0110000));
|
||||||
|
|
||||||
|
// // set wait time
|
||||||
|
// ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_WTIME, 171));
|
||||||
|
|
||||||
|
// set interrupt persistence
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_PERS, 0x44));
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_PILT, 0x80));
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_PIHT, 0x40));
|
||||||
|
ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_CONFIG2, 0x80));
|
||||||
|
|
||||||
|
// // enable sleep after interrupt
|
||||||
|
// ESP_ERROR_CHECK(apds_9960_write(APDS_9960_REG_CONFIG3, 0x10));
|
||||||
|
|
||||||
ESP_ERROR_CHECK(
|
ESP_ERROR_CHECK(
|
||||||
apds_9960_write(APDS_9960_REG_ENABLE, APDS_9960_ENABLE_VALUE));
|
apds_9960_write(APDS_9960_REG_ENABLE, APDS_9960_ENABLE_VALUE));
|
||||||
|
|
||||||
|
apds_9960_int_evt_queue = xQueueCreate(10, NULL);
|
||||||
|
xTaskCreate(apds_9960_int_evt_handler, "apds_9960_gesture_fetch", 2048, NULL,
|
||||||
|
10, NULL);
|
||||||
}
|
}
|
||||||
|
20
main/common.h
Normal file
20
main/common.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define ESP_ERROR_RETRY(action, max_retries) \
|
||||||
|
{ \
|
||||||
|
uint8_t retry_count = 0; \
|
||||||
|
esp_err_t error; \
|
||||||
|
while (retry_count < max_retries) { \
|
||||||
|
error = action; \
|
||||||
|
if (error == ESP_OK) break; \
|
||||||
|
retry_count++; \
|
||||||
|
ESP_LOGI("RETRY", "Retrying... (%d/%d)\n", retry_count + 1, \
|
||||||
|
max_retries); \
|
||||||
|
} \
|
||||||
|
if (error != ESP_OK) { \
|
||||||
|
ESP_LOGE("RETRY", "retry failed. %d", error); \
|
||||||
|
ESP_ERROR_CHECK(error); \
|
||||||
|
} \
|
||||||
|
}
|
27
main/hw-ms03.c
Normal file
27
main/hw-ms03.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "freeRTOS/FreeRTOS.h"
|
||||||
|
|
||||||
|
#define HW_MS03_INT_GPIO 6
|
||||||
|
#define BEEP_GPIO 7
|
||||||
|
|
||||||
|
void hw_ms03_int_handler(void *arg) {
|
||||||
|
gpio_set_level(BEEP_GPIO, gpio_get_level(HW_MS03_INT_GPIO));
|
||||||
|
}
|
||||||
|
|
||||||
|
void hw_ms03_init() {
|
||||||
|
gpio_config_t io_conf = {};
|
||||||
|
|
||||||
|
io_conf.mode = GPIO_MODE_INPUT;
|
||||||
|
io_conf.pull_up_en = 0;
|
||||||
|
io_conf.pull_down_en = 1;
|
||||||
|
io_conf.intr_type = GPIO_INTR_ANYEDGE;
|
||||||
|
io_conf.pin_bit_mask = 1ULL << HW_MS03_INT_GPIO;
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.pin_bit_mask = 1ULL << BEEP_GPIO;
|
||||||
|
io_conf.pull_down_en = 0;
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
|
||||||
|
gpio_isr_handler_add(HW_MS03_INT_GPIO, hw_ms03_int_handler, NULL);
|
||||||
|
}
|
@ -54,7 +54,7 @@ uint8_t i2c_check_slave_exists(uint8_t address) {
|
|||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 50 / portTICK_RATE_MS);
|
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 50 / portTICK_PERIOD_MS);
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
|
|
||||||
if (ret == ESP_OK) {
|
if (ret == ESP_OK) {
|
||||||
|
141
main/led_strip_encoder/led_strip_encoder.c
Normal file
141
main/led_strip_encoder/led_strip_encoder.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "led_strip_encoder.h"
|
||||||
|
|
||||||
|
#include "esp_check.h"
|
||||||
|
|
||||||
|
static const char *TAG = "led_encoder";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rmt_encoder_t base;
|
||||||
|
rmt_encoder_t *bytes_encoder;
|
||||||
|
rmt_encoder_t *copy_encoder;
|
||||||
|
int state;
|
||||||
|
rmt_symbol_word_t reset_code;
|
||||||
|
} rmt_led_strip_encoder_t;
|
||||||
|
|
||||||
|
static size_t rmt_encode_led_strip(rmt_encoder_t *encoder,
|
||||||
|
rmt_channel_handle_t channel,
|
||||||
|
const void *primary_data, size_t data_size,
|
||||||
|
rmt_encode_state_t *ret_state) {
|
||||||
|
rmt_led_strip_encoder_t *led_encoder =
|
||||||
|
__containerof(encoder, rmt_led_strip_encoder_t, base);
|
||||||
|
rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder;
|
||||||
|
rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder;
|
||||||
|
rmt_encode_state_t session_state = 0;
|
||||||
|
rmt_encode_state_t state = 0;
|
||||||
|
size_t encoded_symbols = 0;
|
||||||
|
switch (led_encoder->state) {
|
||||||
|
case 0: // send RGB data
|
||||||
|
encoded_symbols += bytes_encoder->encode(
|
||||||
|
bytes_encoder, channel, primary_data, data_size, &session_state);
|
||||||
|
if (session_state & RMT_ENCODING_COMPLETE) {
|
||||||
|
led_encoder->state =
|
||||||
|
1; // switch to next state when current encoding session finished
|
||||||
|
}
|
||||||
|
if (session_state & RMT_ENCODING_MEM_FULL) {
|
||||||
|
state |= RMT_ENCODING_MEM_FULL;
|
||||||
|
goto out; // yield if there's no free space for encoding artifacts
|
||||||
|
}
|
||||||
|
// fall-through
|
||||||
|
case 1: // send reset code
|
||||||
|
encoded_symbols +=
|
||||||
|
copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code,
|
||||||
|
sizeof(led_encoder->reset_code), &session_state);
|
||||||
|
if (session_state & RMT_ENCODING_COMPLETE) {
|
||||||
|
led_encoder->state = 0; // back to the initial encoding session
|
||||||
|
state |= RMT_ENCODING_COMPLETE;
|
||||||
|
}
|
||||||
|
if (session_state & RMT_ENCODING_MEM_FULL) {
|
||||||
|
state |= RMT_ENCODING_MEM_FULL;
|
||||||
|
goto out; // yield if there's no free space for encoding artifacts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*ret_state = state;
|
||||||
|
return encoded_symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) {
|
||||||
|
rmt_led_strip_encoder_t *led_encoder =
|
||||||
|
__containerof(encoder, rmt_led_strip_encoder_t, base);
|
||||||
|
rmt_del_encoder(led_encoder->bytes_encoder);
|
||||||
|
rmt_del_encoder(led_encoder->copy_encoder);
|
||||||
|
free(led_encoder);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) {
|
||||||
|
rmt_led_strip_encoder_t *led_encoder =
|
||||||
|
__containerof(encoder, rmt_led_strip_encoder_t, base);
|
||||||
|
rmt_encoder_reset(led_encoder->bytes_encoder);
|
||||||
|
rmt_encoder_reset(led_encoder->copy_encoder);
|
||||||
|
led_encoder->state = 0;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config,
|
||||||
|
rmt_encoder_handle_t *ret_encoder) {
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
rmt_led_strip_encoder_t *led_encoder = NULL;
|
||||||
|
ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG,
|
||||||
|
"invalid argument");
|
||||||
|
led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t));
|
||||||
|
ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG,
|
||||||
|
"no mem for led strip encoder");
|
||||||
|
led_encoder->base.encode = rmt_encode_led_strip;
|
||||||
|
led_encoder->base.del = rmt_del_led_strip_encoder;
|
||||||
|
led_encoder->base.reset = rmt_led_strip_encoder_reset;
|
||||||
|
// different led strip might have its own timing requirements, following
|
||||||
|
// parameter is for WS2812
|
||||||
|
rmt_bytes_encoder_config_t bytes_encoder_config = {
|
||||||
|
.bit0 =
|
||||||
|
{
|
||||||
|
.level0 = 1,
|
||||||
|
.duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us
|
||||||
|
.level1 = 0,
|
||||||
|
.duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us
|
||||||
|
},
|
||||||
|
.bit1 =
|
||||||
|
{
|
||||||
|
.level0 = 1,
|
||||||
|
.duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us
|
||||||
|
.level1 = 0,
|
||||||
|
.duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us
|
||||||
|
},
|
||||||
|
.flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0
|
||||||
|
};
|
||||||
|
ESP_GOTO_ON_ERROR(
|
||||||
|
rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder),
|
||||||
|
err, TAG, "create bytes encoder failed");
|
||||||
|
rmt_copy_encoder_config_t copy_encoder_config = {};
|
||||||
|
ESP_GOTO_ON_ERROR(
|
||||||
|
rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder),
|
||||||
|
err, TAG, "create copy encoder failed");
|
||||||
|
|
||||||
|
uint32_t reset_ticks = config->resolution / 1000000 * 50 /
|
||||||
|
2; // reset code duration defaults to 50us
|
||||||
|
led_encoder->reset_code = (rmt_symbol_word_t){
|
||||||
|
.level0 = 0,
|
||||||
|
.duration0 = reset_ticks,
|
||||||
|
.level1 = 0,
|
||||||
|
.duration1 = reset_ticks,
|
||||||
|
};
|
||||||
|
*ret_encoder = &led_encoder->base;
|
||||||
|
return ESP_OK;
|
||||||
|
err:
|
||||||
|
if (led_encoder) {
|
||||||
|
if (led_encoder->bytes_encoder) {
|
||||||
|
rmt_del_encoder(led_encoder->bytes_encoder);
|
||||||
|
}
|
||||||
|
if (led_encoder->copy_encoder) {
|
||||||
|
rmt_del_encoder(led_encoder->copy_encoder);
|
||||||
|
}
|
||||||
|
free(led_encoder);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
38
main/led_strip_encoder/led_strip_encoder.h
Normal file
38
main/led_strip_encoder/led_strip_encoder.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "driver/rmt_encoder.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of led strip encoder configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t resolution; /*!< Encoder resolution, in Hz */
|
||||||
|
} led_strip_encoder_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create RMT encoder for encoding LED strip pixels into RMT symbols
|
||||||
|
*
|
||||||
|
* @param[in] config Encoder configuration
|
||||||
|
* @param[out] ret_encoder Returned encoder handle
|
||||||
|
* @return
|
||||||
|
* - ESP_ERR_INVALID_ARG for any invalid arguments
|
||||||
|
* - ESP_ERR_NO_MEM out of memory when creating led strip encoder
|
||||||
|
* - ESP_OK if creating encoder successfully
|
||||||
|
*/
|
||||||
|
esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config,
|
||||||
|
rmt_encoder_handle_t *ret_encoder);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
279
main/light.c
279
main/light.c
@ -1,28 +1,22 @@
|
|||||||
/* RMT example -- RGB LED Strip
|
|
||||||
|
|
||||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, this
|
|
||||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
*/
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "driver/rmt.h"
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "driver/rmt_tx.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "led_strip.h"
|
#include "led_strip_encoder/led_strip_encoder.h"
|
||||||
#include "nvs.h"
|
#include "nvs.h"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
static const char *LIGHT_TAG = "DisplayAmbientLight_Light";
|
static const char *LIGHT_TAG = "DisplayAmbientLight_Light";
|
||||||
|
|
||||||
#define RMT_TX_CHANNEL RMT_CHANNEL_0
|
|
||||||
#define RMT_TX_GPIO 1
|
#define RMT_TX_GPIO 1
|
||||||
#define STRIP_LED_NUMBER CONFIG_NUMBER_OF_LEDS
|
#define STRIP_LED_NUMBER CONFIG_NUMBER_OF_LEDS
|
||||||
#define EXAMPLE_CHASE_SPEED_MS (10)
|
#define EXAMPLE_CHASE_SPEED_MS (10)
|
||||||
|
#define RMT_LED_STRIP_RESOLUTION_HZ 10000000
|
||||||
|
|
||||||
typedef enum light_mode_e {
|
typedef enum light_mode_e {
|
||||||
light_mode_init = 0,
|
light_mode_init = 0,
|
||||||
@ -34,7 +28,13 @@ typedef enum light_mode_e {
|
|||||||
light_mode_off = 6,
|
light_mode_off = 6,
|
||||||
} light_mode_t;
|
} light_mode_t;
|
||||||
|
|
||||||
led_strip_t *light_led_strip;
|
rmt_channel_handle_t led_chan = NULL;
|
||||||
|
static uint8_t led_strip_pixels[STRIP_LED_NUMBER * 3];
|
||||||
|
rmt_encoder_handle_t led_encoder = NULL;
|
||||||
|
rmt_transmit_config_t tx_config = {
|
||||||
|
.loop_count = 0, // no transfer loop
|
||||||
|
};
|
||||||
|
|
||||||
light_mode_t light_mode;
|
light_mode_t light_mode;
|
||||||
float display_ambient_light_brightness = 1;
|
float display_ambient_light_brightness = 1;
|
||||||
uint8_t display_ambient_lighting_level = 255;
|
uint8_t display_ambient_lighting_level = 255;
|
||||||
@ -62,6 +62,22 @@ void led_strip_set_brightness(uint8_t level) {
|
|||||||
|
|
||||||
xTaskCreate(led_strip_fade_in_light_level, "LED_STRIP_FADE_IN_LIGHT_LEVEL",
|
xTaskCreate(led_strip_fade_in_light_level, "LED_STRIP_FADE_IN_LIGHT_LEVEL",
|
||||||
4096, NULL, 1, NULL);
|
4096, NULL, 1, NULL);
|
||||||
|
|
||||||
|
nvs_handle_t nvs_handle;
|
||||||
|
esp_err_t err = nvs_open("storage", NVS_READWRITE, &nvs_handle);
|
||||||
|
err = nvs_set_u8(nvs_handle, "brightness", level);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(LIGHT_TAG, "Error (%s) saving light level!\n",
|
||||||
|
esp_err_to_name(err));
|
||||||
|
nvs_close(nvs_handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = nvs_commit(nvs_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(LIGHT_TAG, "Error (%s) saving light level!\n",
|
||||||
|
esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
nvs_close(nvs_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_strip_set_color_calibration(float red, float green, float blue) {
|
void led_strip_set_color_calibration(float red, float green, float blue) {
|
||||||
@ -163,68 +179,53 @@ void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_desktop_connection_state() {
|
// void update_desktop_connection_state() {
|
||||||
static uint8_t tick = 0;
|
// static uint8_t tick = 0;
|
||||||
|
|
||||||
bool beat = tick / 10 % 2 ? 1 : 0;
|
// bool beat = tick / 10 % 2 ? 1 : 0;
|
||||||
|
|
||||||
switch (light_mode) {
|
// switch (light_mode) {
|
||||||
case light_mode_desktop_online:
|
// case light_mode_desktop_online:
|
||||||
if (beat) {
|
// if (beat) {
|
||||||
ESP_ERROR_CHECK(
|
// led_strip_pixels[0] = 0;
|
||||||
light_led_strip->set_pixel(light_led_strip, 0, 10, 10, 10));
|
// led_strip_pixels[1] = 0;
|
||||||
}
|
// led_strip_pixels[2] = 0;
|
||||||
ESP_ERROR_CHECK(
|
// }
|
||||||
light_led_strip->set_pixel(light_led_strip, 1, 10, 10, 10));
|
// led_strip_pixels[3] = 10
|
||||||
ESP_ERROR_CHECK(
|
// break;
|
||||||
light_led_strip->set_pixel(light_led_strip, 2, 10, 10, 10));
|
// case light_mode_mqtt_connected:
|
||||||
break;
|
// if (beat) {
|
||||||
case light_mode_mqtt_connected:
|
// ESP_ERROR_CHECK(
|
||||||
if (beat) {
|
// light_led_strip->set_pixel(light_led_strip, 0, 10, 10, 10));
|
||||||
ESP_ERROR_CHECK(
|
// ESP_ERROR_CHECK(
|
||||||
light_led_strip->set_pixel(light_led_strip, 0, 10, 10, 10));
|
// light_led_strip->set_pixel(light_led_strip, 1, 10, 10, 10));
|
||||||
ESP_ERROR_CHECK(
|
// }
|
||||||
light_led_strip->set_pixel(light_led_strip, 1, 10, 10, 10));
|
// ESP_ERROR_CHECK(
|
||||||
}
|
// light_led_strip->set_pixel(light_led_strip, 2, 22, 22, 22));
|
||||||
ESP_ERROR_CHECK(
|
// break;
|
||||||
light_led_strip->set_pixel(light_led_strip, 2, 22, 22, 22));
|
// case light_mode_idle:
|
||||||
break;
|
// if (beat) {
|
||||||
case light_mode_idle:
|
// ESP_ERROR_CHECK(
|
||||||
if (beat) {
|
// light_led_strip->set_pixel(light_led_strip, 0, 77, 77, 77));
|
||||||
ESP_ERROR_CHECK(
|
// ESP_ERROR_CHECK(
|
||||||
light_led_strip->set_pixel(light_led_strip, 0, 77, 77, 77));
|
// light_led_strip->set_pixel(light_led_strip, 1, 77, 77, 77));
|
||||||
ESP_ERROR_CHECK(
|
// ESP_ERROR_CHECK(
|
||||||
light_led_strip->set_pixel(light_led_strip, 1, 77, 77, 77));
|
// light_led_strip->set_pixel(light_led_strip, 2, 77, 77, 77));
|
||||||
ESP_ERROR_CHECK(
|
// }
|
||||||
light_led_strip->set_pixel(light_led_strip, 2, 77, 77, 77));
|
// break;
|
||||||
}
|
// default:
|
||||||
break;
|
// break;
|
||||||
default:
|
// }
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tick++;
|
// tick++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void light_for_init() {
|
void light_for_init() {
|
||||||
ESP_LOGI(LIGHT_TAG, "light_for_init");
|
ESP_LOGI(LIGHT_TAG, "light_for_init");
|
||||||
ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100));
|
|
||||||
|
|
||||||
uint32_t red = 0, green = 0, blue = 0;
|
memset(led_strip_pixels, 0, sizeof(led_strip_pixels));
|
||||||
int8_t i = 0;
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
do {
|
|
||||||
for (; i < 50; i++) {
|
|
||||||
for (int j = 0; j < STRIP_LED_NUMBER; j++) {
|
|
||||||
led_strip_hsv2rgb(0, 0, i, &red, &green, &blue);
|
|
||||||
ESP_ERROR_CHECK(
|
|
||||||
light_led_strip->set_pixel(light_led_strip, j, red, green, blue));
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(20));
|
|
||||||
}
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
|
||||||
} while (light_mode == light_mode_init);
|
|
||||||
|
|
||||||
nvs_handle local_nvs_handle;
|
nvs_handle local_nvs_handle;
|
||||||
esp_err_t err = nvs_open("storage", NVS_READWRITE, &local_nvs_handle);
|
esp_err_t err = nvs_open("storage", NVS_READWRITE, &local_nvs_handle);
|
||||||
@ -233,6 +234,7 @@ void light_for_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t r = 255, g = 255, b = 255;
|
uint8_t r = 255, g = 255, b = 255;
|
||||||
|
uint8_t brightness = 200;
|
||||||
err = nvs_get_u8(local_nvs_handle, "calibration_r", &r);
|
err = nvs_get_u8(local_nvs_handle, "calibration_r", &r);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGW(LIGHT_TAG, "Error (%s) reading calibration_r!",
|
ESP_LOGW(LIGHT_TAG, "Error (%s) reading calibration_r!",
|
||||||
@ -248,9 +250,42 @@ void light_for_init() {
|
|||||||
ESP_LOGW(LIGHT_TAG, "Error (%s) reading calibration_b!",
|
ESP_LOGW(LIGHT_TAG, "Error (%s) reading calibration_b!",
|
||||||
esp_err_to_name(err));
|
esp_err_to_name(err));
|
||||||
}
|
}
|
||||||
|
err = nvs_get_u8(local_nvs_handle, "brightness", &brightness);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(LIGHT_TAG, "Error (%s) reading brightness!", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
nvs_close(local_nvs_handle);
|
nvs_close(local_nvs_handle);
|
||||||
|
|
||||||
|
// set brightness
|
||||||
|
led_strip_set_brightness(brightness);
|
||||||
|
|
||||||
|
// play init light
|
||||||
|
float r_f = (float)r / 255.0;
|
||||||
|
float g_f = (float)g / 255.0;
|
||||||
|
float b_f = (float)b / 255.0;
|
||||||
|
|
||||||
|
uint8_t init_r, init_g, init_b;
|
||||||
|
|
||||||
|
do {
|
||||||
|
for (uint8_t i = 0; i < 50; i++) {
|
||||||
|
init_r = (uint8_t)(r_f * (float)i);
|
||||||
|
init_g = (uint8_t)(g_f * (float)i);
|
||||||
|
init_b = (uint8_t)(b_f * (float)i);
|
||||||
|
|
||||||
|
for (int j = 0; j < STRIP_LED_NUMBER; j++) {
|
||||||
|
led_strip_pixels[j * 3 + 0] = init_g;
|
||||||
|
led_strip_pixels[j * 3 + 1] = init_r;
|
||||||
|
led_strip_pixels[j * 3 + 2] = init_b;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
} while (light_mode == light_mode_init);
|
||||||
|
|
||||||
led_strip_set_color_calibration((float)r / 255.0, (float)g / 255.0,
|
led_strip_set_color_calibration((float)r / 255.0, (float)g / 255.0,
|
||||||
(float)b / 255.0);
|
(float)b / 255.0);
|
||||||
}
|
}
|
||||||
@ -261,19 +296,34 @@ void light_for_connecting_wifi() {
|
|||||||
int8_t tick_tock = 0;
|
int8_t tick_tock = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ESP_ERROR_CHECK(
|
if (tick_tock) {
|
||||||
light_led_strip->set_pixel(light_led_strip, tick_tock, 150, 150, 0));
|
led_strip_pixels[0] = 150;
|
||||||
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip,
|
led_strip_pixels[1] = 150;
|
||||||
(tick_tock + 1) % 2, 0, 200, 0));
|
led_strip_pixels[2] = 0;
|
||||||
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
|
led_strip_pixels[3] = 200;
|
||||||
|
led_strip_pixels[4] = 0;
|
||||||
|
led_strip_pixels[5] = 0;
|
||||||
|
} else {
|
||||||
|
led_strip_pixels[0] = 200;
|
||||||
|
led_strip_pixels[1] = 0;
|
||||||
|
led_strip_pixels[2] = 0;
|
||||||
|
led_strip_pixels[3] = 150;
|
||||||
|
led_strip_pixels[4] = 150;
|
||||||
|
led_strip_pixels[5] = 0;
|
||||||
|
}
|
||||||
tick_tock = !tick_tock;
|
tick_tock = !tick_tock;
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
vTaskDelay(pdMS_TO_TICKS(200));
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
} while (light_mode == light_mode_connection_wifi);
|
} while (light_mode == light_mode_connection_wifi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void light_for_idle() {
|
void light_for_idle() {
|
||||||
ESP_LOGI(LIGHT_TAG, "light_for_idle");
|
ESP_LOGI(LIGHT_TAG, "light_for_idle");
|
||||||
ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100));
|
|
||||||
|
memset(led_strip_pixels, 0, sizeof(led_strip_pixels));
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
|
|
||||||
uint32_t red = 0, green = 0, blue = 0;
|
uint32_t red = 0, green = 0, blue = 0;
|
||||||
uint16_t step_length = 360 / STRIP_LED_NUMBER;
|
uint16_t step_length = 360 / STRIP_LED_NUMBER;
|
||||||
@ -287,22 +337,23 @@ void light_for_idle() {
|
|||||||
// Build RGB values
|
// Build RGB values
|
||||||
led_strip_hsv2rgb(hue, 50, 30, &red, &green, &blue);
|
led_strip_hsv2rgb(hue, 50, 30, &red, &green, &blue);
|
||||||
|
|
||||||
red = red * display_ambient_light_brightness;
|
led_strip_pixels[j * 3 + 0] = green * display_ambient_light_brightness *
|
||||||
green = green * display_ambient_light_brightness;
|
led_strip_green_calibration;
|
||||||
blue = blue * display_ambient_light_brightness;
|
led_strip_pixels[j * 3 + 1] =
|
||||||
// Write RGB values to strip driver
|
red * display_ambient_light_brightness * led_strip_red_calibration;
|
||||||
ESP_ERROR_CHECK(
|
led_strip_pixels[j * 3 + 2] =
|
||||||
light_led_strip->set_pixel(light_led_strip, j, red, green, blue));
|
blue * display_ambient_light_brightness * led_strip_blue_calibration;
|
||||||
}
|
}
|
||||||
update_desktop_connection_state();
|
// update_desktop_connection_state();
|
||||||
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void light_strip_running_task(void *pv_parameters) {
|
void light_strip_running_task(void *pv_parameters) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!light_led_strip) {
|
if (!led_chan) {
|
||||||
ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed 2");
|
ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed 2");
|
||||||
}
|
}
|
||||||
switch (light_mode) {
|
switch (light_mode) {
|
||||||
@ -326,24 +377,28 @@ void light_strip_running_task(void *pv_parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void light_init_strip() {
|
void light_init_strip() {
|
||||||
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_GPIO, RMT_TX_CHANNEL);
|
rmt_tx_channel_config_t tx_chan_config = {
|
||||||
// set counter clock to 40MHz
|
.clk_src = RMT_CLK_SRC_DEFAULT, // select source clock
|
||||||
config.clk_div = 2;
|
.gpio_num = RMT_TX_GPIO,
|
||||||
|
.mem_block_symbols =
|
||||||
|
64, // increase the block size can make the LED less flickering
|
||||||
|
.resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ,
|
||||||
|
.trans_queue_depth = 4, // set the number of transactions that can be
|
||||||
|
// pending in the background
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));
|
||||||
|
|
||||||
ESP_ERROR_CHECK(rmt_config(&config));
|
ESP_LOGI(LIGHT_TAG, "Install led strip encoder");
|
||||||
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
|
|
||||||
|
|
||||||
// install ws2812 driver
|
led_strip_encoder_config_t encoder_config = {
|
||||||
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(
|
.resolution = RMT_LED_STRIP_RESOLUTION_HZ,
|
||||||
STRIP_LED_NUMBER, (led_strip_dev_t)config.channel);
|
};
|
||||||
light_led_strip = led_strip_new_rmt_ws2812(&strip_config);
|
ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_encoder));
|
||||||
if (!light_led_strip) {
|
|
||||||
ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed");
|
ESP_LOGI(LIGHT_TAG, "Enable RMT TX channel");
|
||||||
}
|
ESP_ERROR_CHECK(rmt_enable(led_chan));
|
||||||
// Clear LED strip (turn off all LEDs)
|
|
||||||
ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100));
|
ESP_LOGI(LIGHT_TAG, "Start LED rainbow chase");
|
||||||
// Show simple rainbow chasing pattern
|
|
||||||
ESP_LOGI(LIGHT_TAG, "LED Rainbow Chase Start");
|
|
||||||
|
|
||||||
light_mode = light_mode_init;
|
light_mode = light_mode_init;
|
||||||
|
|
||||||
@ -354,6 +409,8 @@ void light_init_strip() {
|
|||||||
void light_play_colors(uint16_t len, uint8_t *buffer) {
|
void light_play_colors(uint16_t len, uint8_t *buffer) {
|
||||||
light_mode = light_mode_desktop_sending_colors;
|
light_mode = light_mode_desktop_sending_colors;
|
||||||
|
|
||||||
|
uint16_t black_count = 0; // count of black pixels. r/g/b <= 10
|
||||||
|
|
||||||
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) {
|
||||||
@ -366,10 +423,30 @@ void light_play_colors(uint16_t len, uint8_t *buffer) {
|
|||||||
b = (uint8_t)((float)buffer[buffer_cursor + 2] *
|
b = (uint8_t)((float)buffer[buffer_cursor + 2] *
|
||||||
display_ambient_light_brightness *
|
display_ambient_light_brightness *
|
||||||
led_strip_blue_calibration);
|
led_strip_blue_calibration);
|
||||||
ESP_ERROR_CHECK(
|
if (r <= 7 && g <= 7 && b <= 7) {
|
||||||
light_led_strip->set_pixel(light_led_strip, led_index, r, g, b));
|
black_count++;
|
||||||
|
}
|
||||||
|
led_strip_pixels[led_index * 3 + 0] = g;
|
||||||
|
led_strip_pixels[led_index * 3 + 1] = r;
|
||||||
|
led_strip_pixels[led_index * 3 + 2] = b;
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
|
|
||||||
|
if (black_count > STRIP_LED_NUMBER / 5 * 4) {
|
||||||
|
uint8_t r = (uint8_t)((float)50 * display_ambient_light_brightness *
|
||||||
|
led_strip_red_calibration),
|
||||||
|
g = (uint8_t)((float)40 * display_ambient_light_brightness *
|
||||||
|
led_strip_green_calibration),
|
||||||
|
b = (uint8_t)((float)20 * display_ambient_light_brightness *
|
||||||
|
led_strip_blue_calibration);
|
||||||
|
for (uint16_t led_index = 0; led_index < STRIP_LED_NUMBER; led_index++) {
|
||||||
|
led_strip_pixels[led_index * 3 + 0] = g;
|
||||||
|
led_strip_pixels[led_index * 3 + 1] = r;
|
||||||
|
led_strip_pixels[led_index * 3 + 2] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels,
|
||||||
|
sizeof(led_strip_pixels), &tx_config));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "hw-ms03.c"
|
||||||
#include "i2c.c"
|
#include "i2c.c"
|
||||||
#include "light.c"
|
#include "light.c"
|
||||||
#include "mqtt.c"
|
#include "mqtt.c"
|
||||||
@ -19,13 +20,17 @@ static const char *TAG = "DisplayAmbientLight";
|
|||||||
void app_main(void) {
|
void app_main(void) {
|
||||||
app_nvs_init();
|
app_nvs_init();
|
||||||
light_init_strip();
|
light_init_strip();
|
||||||
|
|
||||||
|
gpio_install_isr_service(0);
|
||||||
init_i2c();
|
init_i2c();
|
||||||
i2c_check_slaves();
|
i2c_check_slaves();
|
||||||
|
|
||||||
init_display();
|
init_display();
|
||||||
display_print8_str(0, 0, "Ambient Light");
|
display_print8_str(0, 0, "Ambient Light");
|
||||||
|
// hw_ms03_init();
|
||||||
ci_03t_init();
|
ci_03t_init();
|
||||||
apes_9960_init();
|
apds_9960_init();
|
||||||
apes_9960_auto_fetch();
|
apds_9960_auto_fetch();
|
||||||
auto_fetch_temperature();
|
auto_fetch_temperature();
|
||||||
pca9555_init();
|
pca9555_init();
|
||||||
ui_input_init();
|
ui_input_init();
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
static const char *MQTT_TAG = "DisplayAmbientLight_MQTT";
|
static const char *MQTT_TAG = "DisplayAmbientLight_MQTT";
|
||||||
|
|
||||||
static EventGroupHandle_t s_mqtt_event_group;
|
static EventGroupHandle_t s_mqtt_event_group;
|
||||||
static xQueueHandle mqtt_cmd_event = NULL;
|
static QueueHandle_t mqtt_cmd_event = NULL;
|
||||||
static esp_mqtt_client_handle_t client = NULL;
|
static esp_mqtt_client_handle_t client = NULL;
|
||||||
|
|
||||||
typedef struct colors {
|
typedef struct colors {
|
||||||
@ -69,8 +69,8 @@ static void log_error_if_nonzero(const char *message, int error_code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
|
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
|
||||||
int32_t event_id, void *event_data) {
|
long event_id, void *event_data) {
|
||||||
ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%d",
|
ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%ld",
|
||||||
base, event_id);
|
base, event_id);
|
||||||
esp_mqtt_event_handle_t event = event_data;
|
esp_mqtt_event_handle_t event = event_data;
|
||||||
client = event->client;
|
client = event->client;
|
||||||
@ -195,7 +195,7 @@ static void mqtt_app_start() {
|
|||||||
xTaskCreate(mqtt_cmd_event_handler, "mqtt_cmd_event", 2048, NULL, 10, NULL);
|
xTaskCreate(mqtt_cmd_event_handler, "mqtt_cmd_event", 2048, NULL, 10, NULL);
|
||||||
|
|
||||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||||
.uri = MQTT_BROKER_URL,
|
.broker.address.uri = MQTT_BROKER_URL,
|
||||||
};
|
};
|
||||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler,
|
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler,
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
void fetch_temperature(void* arg) {
|
void fetch_temperature(void* arg) {
|
||||||
esp_err_t error;
|
esp_err_t error;
|
||||||
float temperature = DEFAULT_TEMPERATURE;
|
float temperature = DEFAULT_TEMPERATURE;
|
||||||
char temperature_str[10];
|
char temperature_str[20];
|
||||||
uint8_t temperature_buffer[] = {0, 0};
|
uint8_t temperature_buffer[] = {0, 0};
|
||||||
display_fill_rect(0, 0, 128, 2, 0x00);
|
display_fill_rect(0, 0, 128, 2, 0x00);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
|
|
||||||
static const char *UI_INPUT_TAG = "UiInput";
|
static const char *UI_INPUT_TAG = "UiInput";
|
||||||
|
|
||||||
static xQueueHandle ui_input_event = NULL;
|
static QueueHandle_t ui_input_event = NULL;
|
||||||
static xQueueHandle ui_input_raw_event = NULL;
|
static QueueHandle_t ui_input_raw_event = NULL;
|
||||||
|
|
||||||
typedef struct encoder_state {
|
typedef struct encoder_state {
|
||||||
e_ui_input_raw_key_t key;
|
e_ui_input_raw_key_t key;
|
||||||
@ -51,7 +51,6 @@ static encoder_state_t encoder_1_state = {.key = ui_input_raw_key_encoder_1,
|
|||||||
|
|
||||||
uint8_t level_byte;
|
uint8_t level_byte;
|
||||||
int8_t delta = 0;
|
int8_t delta = 0;
|
||||||
char changing_str[12] = "NC";
|
|
||||||
|
|
||||||
static void IRAM_ATTR gpio_isr_handler(void *arg) {
|
static void IRAM_ATTR gpio_isr_handler(void *arg) {
|
||||||
xQueueSendFromISR(ui_input_raw_event, NULL, NULL);
|
xQueueSendFromISR(ui_input_raw_event, NULL, NULL);
|
||||||
@ -59,7 +58,7 @@ static void IRAM_ATTR gpio_isr_handler(void *arg) {
|
|||||||
|
|
||||||
static void ui_input_update_embedded_display(void *arg) {
|
static void ui_input_update_embedded_display(void *arg) {
|
||||||
s_ui_input_t input;
|
s_ui_input_t input;
|
||||||
char changing_str[12] = "NC";
|
char changing_str[20] = "NC";
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (xQueueReceive(ui_input_event, &input, portMAX_DELAY)) {
|
if (xQueueReceive(ui_input_event, &input, portMAX_DELAY)) {
|
||||||
switch (input.key) {
|
switch (input.key) {
|
||||||
@ -196,8 +195,6 @@ void ui_input_init(void) {
|
|||||||
ui_input_event = xQueueCreate(10, sizeof(s_ui_input_t));
|
ui_input_event = xQueueCreate(10, sizeof(s_ui_input_t));
|
||||||
ui_input_raw_event = xQueueCreate(10, 0);
|
ui_input_raw_event = xQueueCreate(10, 0);
|
||||||
|
|
||||||
// install gpio isr service
|
|
||||||
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
|
|
||||||
// hook isr handler for specific gpio pin
|
// hook isr handler for specific gpio pin
|
||||||
gpio_isr_handler_add(ENCODER_INT_GPIO, gpio_isr_handler, NULL);
|
gpio_isr_handler_add(ENCODER_INT_GPIO, gpio_isr_handler, NULL);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user