Feature: 支持 LVGL 作为嵌入式显示屏的底层。 #7

Merged
Ivan merged 5 commits from feature/lvgl into master 2023-05-03 21:04:25 +08:00
15 changed files with 937 additions and 188 deletions

View File

@ -10,6 +10,12 @@ dependencies:
source: source:
type: idf type: idf
version: 5.0.1 version: 5.0.1
manifest_hash: d23f3b15e8b95dfe5da6cf83768d24158a3a0222f95694b1fa09c3ca8602f79f lvgl/lvgl:
component_hash: 0f2006e7b800eee17b73ed4f92ffbaa76d61c02ba4779ec9efbcd5f453bb0102
source:
service_url: https://api.components.espressif.com/
type: service
version: 8.3.6~1
manifest_hash: 9a88337b9db92c26041847f5fd4efc58df1dcf0e9c6b8758da96aaac2e63c2a2
target: esp32c3 target: esp32c3
version: 1.0.0 version: 1.0.0

View File

@ -1,2 +1,24 @@
idf_component_register(SRCS "udp_server.c" "service_discovery.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" idf_component_register(
INCLUDE_DIRS ".") SRCS
"udp_server.c"
"service_discovery.c"
"app_nvs.c"
"ch1116.c"
# "apds_9960.c"
"pca9555.c"
"i2c.c"
"asr_pro.c"
"ci_03t.c"
"ui_input.c"
# "ambient_light.c"
# "temperature.c"
# "mqtt.c"
"main.c"
"wifi.c"
"light.c"
"led_strip_encoder/led_strip_encoder.c"
"gui.c"
"lvgl_demo_ui.c"
"app_icon_8.c"
INCLUDE_DIRS "."
)

View File

@ -1,10 +1,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "ch1116.c"
#include "common.h" #include "common.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "embedded_display.c"
#include "esp_log.h" #include "esp_log.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"

157
main/app_icon_8.c Normal file
View File

@ -0,0 +1,157 @@
/*******************************************************************************
* Size: 8 px
* Bpp: 1
* Opts:
******************************************************************************/
#pragma once
#include "lvgl.h"
#ifndef APP_ICON_8
#define APP_ICON_8 1
#endif
#if APP_ICON_8
/*-----------------
* BITMAPS
*----------------*/
/*Store the image of the glyphs*/
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
/* U+E1CB "" */
0x38, 0x31, 0x88, 0xfa, 0x49, 0x54, 0x44, 0x10, 0xf8,
/* U+E1CC "" */
0x80, 0x1f, 0xa, 0x22, 0x6b, 0xd4, 0x44, 0xd0, 0xc8, 0x1,
/* U+E29E "" */
0xe, 0x4, 0xa8, 0x32, 0x18, 0xe, 0xd, 0x8c, 0x7c,
/* U+F1EB "" */
0x1e, 0x18, 0x68, 0x4, 0x78, 0x21, 0x0, 0x0, 0xc0, 0x0,
/* U+F6AA "" */
0xc0,
/* U+F6AB "" */
0x79, 0x8, 0x1, 0x80};
/*---------------------
* GLYPH DESCRIPTION
*--------------------*/
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 0,
.adv_w = 0,
.box_w = 0,
.box_h = 0,
.ofs_x = 0,
.ofs_y = 0} /* id = 0 reserved */,
{.bitmap_index = 0,
.adv_w = 160,
.box_w = 10,
.box_h = 7,
.ofs_x = 0,
.ofs_y = 0},
{.bitmap_index = 9,
.adv_w = 160,
.box_w = 10,
.box_h = 8,
.ofs_x = 0,
.ofs_y = -1},
{.bitmap_index = 19,
.adv_w = 128,
.box_w = 9,
.box_h = 8,
.ofs_x = 0,
.ofs_y = -1},
{.bitmap_index = 28,
.adv_w = 160,
.box_w = 10,
.box_h = 8,
.ofs_x = 0,
.ofs_y = -1},
{.bitmap_index = 38,
.adv_w = 32,
.box_w = 2,
.box_h = 2,
.ofs_x = 4,
.ofs_y = -1},
{.bitmap_index = 39,
.adv_w = 112,
.box_w = 7,
.box_h = 4,
.ofs_x = 2,
.ofs_y = 0}};
/*---------------------
* CHARACTER MAPPING
*--------------------*/
static const uint16_t unicode_list_0[] = {0x0, 0x1, 0xd3,
0x1020, 0x14df, 0x14e0};
/*Collect the unicode lists and glyph_id offsets*/
static const lv_font_fmt_txt_cmap_t cmaps[] = {
{.range_start = 57803,
.range_length = 5345,
.glyph_id_start = 1,
.unicode_list = unicode_list_0,
.glyph_id_ofs_list = NULL,
.list_length = 6,
.type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}};
/*--------------------
* ALL CUSTOM DATA
*--------------------*/
#if LV_VERSION_CHECK(8, 0, 0)
/*Store all the custom data of the font*/
static lv_font_fmt_txt_glyph_cache_t cache;
static const lv_font_fmt_txt_dsc_t font_dsc = {
#else
static lv_font_fmt_txt_dsc_t font_dsc = {
#endif
.glyph_bitmap = glyph_bitmap,
.glyph_dsc = glyph_dsc,
.cmaps = cmaps,
.kern_dsc = NULL,
.kern_scale = 0,
.cmap_num = 1,
.bpp = 1,
.kern_classes = 0,
.bitmap_format = 0,
#if LV_VERSION_CHECK(8, 0, 0)
.cache = &cache
#endif
};
/*-----------------
* PUBLIC FONT
*----------------*/
/*Initialize a public general font descriptor*/
#if LV_VERSION_CHECK(8, 0, 0)
const lv_font_t app_icon_8 = {
#else
lv_font_t app_icon_8 = {
#endif
.get_glyph_dsc =
lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/
.get_glyph_bitmap =
lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/
.line_height = 8, /*The maximum line height required by the font*/
.base_line = 1, /*Baseline measured from the bottom of the line*/
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
.subpx = LV_FONT_SUBPX_NONE,
#endif
#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
.underline_position = -1,
.underline_thickness = 0,
#endif
.dsc = &font_dsc /*The custom font data. Will be accessed by
`get_glyph_bitmap/dsc` */
};
#endif /*#if APP_ICON_8*/

269
main/ch1116.c Normal file
View File

@ -0,0 +1,269 @@
#pragma once
#include <string.h>
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/task.h"
#include "sdkconfig.h" // generated by "make menuconfig"
#define CH1116_TAG "CH1116"
#define SDA_PIN GPIO_NUM_4
#define SCL_PIN GPIO_NUM_5
#define CH1116_WIDTH 128
#define CH1116_HEIGHT 64
#define CH1116_ADDRESS 0x3C // 011110+SA0 - 0x3C or 0x3D
// CH1116 Control
#define CH1116_CONTROL_BYTE_COMMAND_SINGLE 0x80
#define CH1116_CONTROL_BYTE_COMMAND_STREAM 0x00
#define CH1116_CONTROL_BYTE_DATA_SINGLE 0xC0
#define CH1116_CONTROL_BYTE_DATA_STREAM 0x40
// CH1116 Config Commands
#define CH1116_DISPLAY_OFF 0xAE // #13
#define CH1116_LOWER_COLUMN_ADDRESS 0x02 // #1 0x02-0x0F
#define CH1116_HIGHER_COLUMN_ADDRESS 0x10 // #2 0x10-0x1F
#define CH1116_DISPLAY_START_LINE 0x40 // #3
#define CH1116_PAGE_ADDRESS 0xB0 // #18 0xB0-0xB7
#define CH1116_CONTRACT_CONTROL 0x81 // #10
#define CH1116_CONTRACT_CONTROL_128 0xCF // #10
#define CH1116_SEGMENT_REMAP 0xA1 // #12 ADC=1 (right)
#define CH1116_NORMAL_DISPLAY 0xA6 // #14
#define CH1116_MULTIPLEX_RATIO 0xA8 // #15
#define CH1116_MULTIPLEX_RATIO_1_64 0x3F
// VCC Generated by Internal DC/DC Circuit
#define CH1116_CHARGE_PUMP_ENABLE 0xAD // #16
#define CH1116_CHARGE_PUMP_ENABLE_INTERNAL_VCC 0x8B // #16
#define CH1116_CHARGE_PUMP_VOLTAGE_9V 0x33 // #8
#define CH1116_COM_SCAN_DIRECTION 0xC8 // #19
#define CH1116_DISPLAY_OFFSET 0xD3 // #20
#define CH1116_DISPLAY_OFFSET_0 0x00 // #20
#define CH1116_SET_OSC_DIVISION 0xD5 // #21
#define CH1116_SET_OSC_DIVISION_1 0x80 // #21
#define CH1116_SET_PRE_CHARGE_PERIOD 0xD9 // #22
#define CH1116_SET_PRE_CHARGE_PERIOD_1 0x1F // #22
#define CH1116_SET_COM_PINS 0xDA // #23
#define CH1116_SET_COM_PINS_1 0x12 // #23
#define CH1116_SET_VCOMH 0xDB // #24
#define CH1116_SET_VCOMH_1 0x40 // #24
#define CH1116_DISPLAY_ON 0xAF // #13
void ch1116_init() {
esp_err_t err;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true);
i2c_master_write_byte(cmd, CH1116_DISPLAY_OFF, true);
i2c_master_write_byte(cmd, CH1116_LOWER_COLUMN_ADDRESS, true);
i2c_master_write_byte(cmd, CH1116_HIGHER_COLUMN_ADDRESS, true);
i2c_master_write_byte(cmd, CH1116_DISPLAY_START_LINE, true);
i2c_master_write_byte(cmd, CH1116_PAGE_ADDRESS, true);
i2c_master_write_byte(cmd, CH1116_CONTRACT_CONTROL, true);
i2c_master_write_byte(cmd, CH1116_CONTRACT_CONTROL_128, true);
i2c_master_write_byte(cmd, CH1116_SEGMENT_REMAP, true);
i2c_master_write_byte(cmd, CH1116_NORMAL_DISPLAY, true);
i2c_master_write_byte(cmd, CH1116_MULTIPLEX_RATIO, true);
i2c_master_write_byte(cmd, CH1116_MULTIPLEX_RATIO_1_64, true);
i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_ENABLE, true);
i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_ENABLE_INTERNAL_VCC, true);
i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_VOLTAGE_9V, true);
i2c_master_write_byte(cmd, CH1116_COM_SCAN_DIRECTION, true);
i2c_master_write_byte(cmd, CH1116_DISPLAY_OFFSET, true);
i2c_master_write_byte(cmd, CH1116_DISPLAY_OFFSET_0, true);
i2c_master_write_byte(cmd, CH1116_SET_OSC_DIVISION, true);
i2c_master_write_byte(cmd, CH1116_SET_OSC_DIVISION_1, true);
i2c_master_write_byte(cmd, CH1116_SET_PRE_CHARGE_PERIOD, true);
i2c_master_write_byte(cmd, CH1116_SET_PRE_CHARGE_PERIOD_1, true);
i2c_master_write_byte(cmd, CH1116_SET_COM_PINS, true);
i2c_master_write_byte(cmd, CH1116_SET_COM_PINS_1, true);
i2c_master_write_byte(cmd, CH1116_SET_VCOMH, true);
i2c_master_write_byte(cmd, CH1116_SET_VCOMH_1, true);
i2c_master_write_byte(cmd, CH1116_DISPLAY_ON, true);
i2c_master_stop(cmd);
err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (err == ESP_OK) {
ESP_LOGI(CH1116_TAG, "OLED configured successfully");
} else {
ESP_LOGE(CH1116_TAG, "OLED configuration failed. code: %s",
esp_err_to_name(err));
}
i2c_cmd_link_delete(cmd);
}
void task_ch1116_display_pattern(void *ignore) {
i2c_cmd_handle_t cmd;
for (uint8_t i = 0; i < 8; i++) {
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_SINGLE, true);
i2c_master_write_byte(cmd, 0xB0 | i, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true);
for (uint8_t j = 0; j < 132; j++) {
i2c_master_write_byte(cmd, 0xFF >> (j % 8), true);
}
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
}
void task_ch1116_display_clear(void *ignore) {
i2c_cmd_handle_t cmd;
uint8_t zero[132];
memset(zero, 0, 132);
for (uint8_t i = 0; i < 8; i++) {
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_SINGLE, true);
i2c_master_write_byte(cmd, 0xB0 | i, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true);
i2c_master_write(cmd, zero, 132, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true);
i2c_master_write_byte(cmd, 0x00, true); // reset column
i2c_master_write_byte(cmd, 0x10, true);
i2c_master_write_byte(cmd, 0xB0, true); // reset page
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
static esp_err_t ch1116_draw_bitmap(int x_start, int y_start, int x_end,
int y_end, const void *color_data) {
assert((x_start < x_end) && (y_start < y_end) &&
"start position must be smaller than end position");
// one page contains 8 rows (COMs)
uint8_t page_start = y_start / 8;
uint8_t page_end = y_end / 8;
// define an area of frame memory where MCU can access
esp_err_t err;
i2c_cmd_handle_t cmd;
uint8_t *color_data_ptr = (uint8_t *)color_data;
uint16_t page_data_size = (x_end - x_start + 1);
// ESP_LOGI(CH1116_TAG, "y_start: %d, y_end: %d, page_start: %d, page_end:
// %d",
// y_start, y_end, page_start, page_end);
// ESP_LOGI(CH1116_TAG, "x_start: %d, x_end: %d, page_data_size: %d", x_start,
// x_end, page_data_size);
for (int page = page_start; page <= page_end; page++) {
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true);
// set cursor position
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true);
i2c_master_write_byte(cmd, CH1116_LOWER_COLUMN_ADDRESS | (x_start & 0x0f),
true);
i2c_master_write_byte(cmd, CH1116_HIGHER_COLUMN_ADDRESS | (x_start >> 4),
true);
i2c_master_write_byte(cmd, CH1116_PAGE_ADDRESS | (page & 0x0f), true);
i2c_master_stop(cmd);
err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (err != ESP_OK) {
i2c_cmd_link_delete(cmd);
return err;
}
i2c_cmd_link_delete(cmd);
// write page data
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true);
i2c_master_write(cmd, color_data_ptr, page_data_size, true);
i2c_master_stop(cmd);
err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
// ESP_LOG_BUFFER_HEXDUMP(CH1116_TAG, color_data_ptr, page_data_size,
// ESP_LOG_INFO);
color_data_ptr += page_data_size;
if (err != ESP_OK) {
i2c_cmd_link_delete(cmd);
return err;
}
i2c_cmd_link_delete(cmd);
}
return ESP_OK;
}
void ch1116_main(void) {
ch1116_init();
task_ch1116_display_pattern(NULL);
// vTaskDelay(1000 / portTICK_PERIOD_MS);
// task_ch1116_display_clear(NULL);
}

View File

@ -1,145 +0,0 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "codetab.h"
#include "config_key.h"
#include "driver/i2c.h"
#include "esp_log.h"
#include "i2c.c"
#define Brightness 0xCF
#define X_WIDTH 128
#define Y_WIDTH 64
void i2cWriteByte(uint8_t reg, uint8_t data) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SSD1306_ADDRESS << 1 | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
i2c_master_write_byte(cmd, data, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
void i2cWriteCommand(uint8_t data) { i2cWriteByte(0x00, data); }
void i2cWriteData(uint8_t data) { i2cWriteByte(0x40, data); }
void display_fill(uint8_t bmpData) {
for (int y = 0; y < 8; y++) {
i2cWriteCommand(0xB0 + y);
i2cWriteCommand(0x01);
i2cWriteCommand(0x10);
for (int x = 0; x < X_WIDTH; x++) {
i2cWriteData(bmpData);
}
}
}
void display_fill_rect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
uint8_t bmpData) {
for (int y = y0; y < y1; y++) {
i2cWriteCommand(0xB0 + y);
i2cWriteCommand(0x01);
i2cWriteCommand(0x10);
for (int x = x0; x < x1; x++) {
i2cWriteData(bmpData);
}
}
}
void display_set_pos(uint8_t x, uint8_t y) {
i2cWriteCommand(0xB0 + y);
i2cWriteCommand(((x & 0xF0) >> 4) | 0x10);
i2cWriteCommand((x & 0x0F) | 0x01);
}
void display_print8_str(uint8_t x, uint8_t y, char str[]) {
if (!is_embedded_display_online) {
return;
}
uint8_t c;
for (uint8_t ch, ci = 0; ch = str[ci], ch != '\0'; ci++, x += 8) {
c = ch - 0x20;
display_set_pos(x, y);
for (uint8_t cx = 0; cx < 8; cx++) {
i2cWriteData(F8X16[c * 16 + cx]);
}
display_set_pos(x, y + 1);
for (uint8_t cx = 0; cx < 8; cx++) {
i2cWriteData(F8X16[c * 16 + cx + 8]);
};
}
}
void init_display() {
if (is_embedded_display_online == 0) {
ESP_LOGE("display", "display is offline");
return;
}
i2cWriteCommand(0xAE); // display off
i2cWriteCommand(0x00); // set lower column address
i2cWriteCommand(0x10); // set higher column address
i2cWriteCommand(0x40); // set start line address
i2cWriteCommand(0x81); // set contrast control register
i2cWriteCommand(0xCF); // set contrast
i2cWriteCommand(0xA1); // set segment re-map
i2cWriteCommand(0xC8); // set COM output scan direction
i2cWriteCommand(0xA6); // set normal display
i2cWriteCommand(0xA8); // set multiplex ratio(1 to 64)
i2cWriteCommand(0x3F); // 1/64 duty
i2cWriteCommand(0xD3); // set display offset
i2cWriteCommand(0x00); // not offset
i2cWriteCommand(0xD5); // set display clock divide ratio/oscillator frequency
i2cWriteCommand(0x80); // set divide ratio
i2cWriteCommand(0xD9); // set pre-charge period
i2cWriteCommand(0xF1); // set pre-charge voltage
i2cWriteCommand(0xDA); // set com pins hardware configuration
i2cWriteCommand(0x12);
i2cWriteCommand(0xDB); // set vcomh
i2cWriteCommand(0x40); // 0.77*vcc
i2cWriteCommand(0x20); // set memory addressing mode
i2cWriteCommand(0x02); // set page addressing mode
i2cWriteCommand(0x8D); // set charge pump enable/disable
i2cWriteCommand(0x14); // set(0x10) disable
i2cWriteCommand(0xAF); // display on
display_fill(0x00);
display_set_pos(0, 0);
}
void gui_update_config_uint8(uint8_t key, uint8_t value) {
char changing_str[12] = "NC";
switch (key) {
case ui_input_key_display_0_brightness:
sprintf(changing_str, "Dis0: % 3d", value);
break;
case ui_input_key_display_1_brightness:
sprintf(changing_str, "Dis1: % 3d", value);
break;
case ui_input_key_computer_volume:
sprintf(changing_str, "CVol: % 3d", value);
break;
case ui_input_key_display_ambient_lighting_level:
sprintf(changing_str, "ALLv: % 3d", value);
break;
case ui_input_key_display_ambient_lighting_mode:
sprintf(changing_str, "ALMd: % 3d", value);
break;
case ui_input_key_display_0_mode:
sprintf(changing_str, "Dis0M: % 2d", value);
break;
case ui_input_key_display_1_mode:
sprintf(changing_str, "Dis1M: % 2d", value);
break;
default:
strcpy(changing_str, "NC");
break;
}
display_fill_rect(0, 6, 128, 8, 0);
display_print8_str(8, 6, changing_str);
}

399
main/gui.c Normal file
View File

@ -0,0 +1,399 @@
#pragma once
#include <stdio.h>
#include "app_icon_8.c"
#include "ch1116.c"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lvgl.h"
static const char *GUI_TAG = "LVGL_GUI";
#define I2C_HOST 0
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000)
#define EXAMPLE_LCD_H_RES CH1116_WIDTH
#define EXAMPLE_LCD_V_RES CH1116_HEIGHT
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2
// EF 9A AA
#define APP_WIFI_WEAK_SYMBOL "\xEF\x9A\xAA"
// EF 9A AB
#define APP_WIFI_FAIR_SYMBOL "\xEF\x9A\xAB"
// EF 87 AB
#define APP_WIFI_GOOD_SYMBOL "\xEF\x87\xAB"
// EE 87 8B
#define APP_CONNECTED_SYMBOL "\xEE\x87\x8B"
// EE 87 8C
#define APP_DISCONNECTED_SYMBOL "\xEE\x87\x8C"
// EE 8A 9E
#define APP_TIMER_SYMBOL "\xEE\x8A\x9E"
extern void example_lvgl_demo_ui(lv_disp_t *disp);
static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area,
lv_color_t *color_map) {
int offsetx1 = area->x1;
int offsetx2 = area->x2;
int offsety1 = area->y1;
int offsety2 = area->y2;
// copy a buffer's content to a specific area of the display
ch1116_draw_bitmap(offsetx1, offsety1, offsetx2, offsety2, color_map);
lv_disp_flush_ready(drv);
}
static void example_lvgl_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf,
lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa) {
uint16_t byte_index = x + ((y >> 3) * buf_w);
uint8_t bit_index = y & 0x7;
if ((color.full == 0) && (LV_OPA_TRANSP != opa)) {
buf[byte_index] |= (1 << bit_index);
} else {
buf[byte_index] &= ~(1 << bit_index);
}
}
static lv_obj_t *wifi_label;
static lv_anim_t wifi_animate;
static lv_obj_t *timer_label;
static lv_anim_t timer_animate;
static lv_obj_t *desktop_label;
static lv_anim_t desktop_animate;
static lv_obj_t *value_setting_panel;
static lv_obj_t *value_setting_bar;
static lv_obj_t *value_setting_label;
static lv_obj_t *value_setting_value_label;
static lv_obj_t *scr;
static void example_lvgl_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area) {
area->y1 = area->y1 & (~0x7);
area->y2 = area->y2 | 0x7;
}
static void example_increase_lvgl_tick(void *arg) {
/* Tell LVGL how many milliseconds has elapsed */
lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
}
static void set_value(void *bar, int32_t v) {
lv_bar_set_value(bar, v, LV_ANIM_OFF);
}
static void set_visible(void *obj, int32_t v) {
if (v) {
lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN);
} else {
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
}
}
static void set_obj_blink_animate(lv_obj_t *obj, lv_anim_t *a) {
lv_anim_init(a);
lv_anim_set_exec_cb(a, set_visible);
lv_anim_set_time(a, 100);
lv_anim_set_playback_time(a, 100);
lv_anim_set_playback_delay(a, 200);
lv_anim_set_repeat_delay(a, 200);
lv_anim_set_values(a, 0, 1);
lv_anim_set_var(a, obj);
lv_anim_set_repeat_count(a, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(a);
}
static void change_wifi_icon(void *obj, int32_t v) {
switch (v) {
case 0:
lv_label_set_text(obj, APP_WIFI_WEAK_SYMBOL);
break;
case 1:
lv_label_set_text(obj, APP_WIFI_FAIR_SYMBOL);
break;
case 2:
lv_label_set_text(obj, APP_WIFI_GOOD_SYMBOL);
break;
default:
ESP_LOGW(GUI_TAG, "Unknown wifi strength: %ld", v);
break;
}
}
static void gui_set_wifi_connecting() {
lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN);
lv_anim_init(&wifi_animate);
lv_anim_set_exec_cb(&wifi_animate, change_wifi_icon);
lv_anim_set_time(&wifi_animate, 300);
lv_anim_set_repeat_delay(&wifi_animate, 300);
lv_anim_set_values(&wifi_animate, 0, 2);
lv_anim_set_var(&wifi_animate, wifi_label);
lv_anim_set_repeat_count(&wifi_animate, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&wifi_animate);
}
static void gui_set_wifi_connected() {
lv_anim_del(wifi_label, NULL);
vTaskDelay(300 / portTICK_PERIOD_MS);
lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN);
lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL);
}
static void gui_set_wifi_disconnected() {
lv_anim_del(&wifi_label, NULL);
vTaskDelay(300 / portTICK_PERIOD_MS);
lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN);
lv_label_set_text(wifi_label, APP_WIFI_WEAK_SYMBOL);
}
static void gui_set_server_connecting() {
set_obj_blink_animate(desktop_label, &desktop_animate);
}
static void gui_set_server_connected() {
lv_anim_del(desktop_label, NULL);
vTaskDelay(300 / portTICK_PERIOD_MS);
lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN);
lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL);
}
static void gui_set_server_disconnected() {
lv_anim_del(desktop_label, NULL);
vTaskDelay(300 / portTICK_PERIOD_MS);
lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN);
lv_label_set_text(desktop_label, APP_DISCONNECTED_SYMBOL);
}
static void gui_bar_value_update_cb(lv_event_t *e) {
lv_obj_draw_part_dsc_t *dsc = lv_event_get_param(e);
if (dsc->part != LV_PART_INDICATOR) return;
lv_obj_t *obj = lv_event_get_target(e);
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
label_dsc.font = &lv_font_montserrat_10;
char buf[8];
lv_snprintf(buf, sizeof(buf), "%ld", lv_bar_get_value(obj));
lv_point_t txt_size;
lv_txt_get_size(&txt_size, buf, label_dsc.font, label_dsc.letter_space,
label_dsc.line_space, LV_COORD_MAX, label_dsc.flag);
lv_coord_t txt_x;
/*If the indicator is long enough put the text inside on the right*/
if (lv_area_get_width(dsc->draw_area) > txt_size.x + 20) {
txt_x = dsc->draw_area->x2 - 8 - txt_size.x + 1;
lv_obj_set_style_text_color(value_setting_value_label, lv_color_white(),
LV_PART_MAIN);
label_dsc.color = lv_color_white();
}
/*If the indicator is still short put the text out of it on the right*/
else {
txt_x = dsc->draw_area->x2 - 8 + txt_size.x - 1;
lv_obj_set_style_text_color(value_setting_value_label, lv_color_black(),
LV_PART_MAIN);
}
lv_obj_align(value_setting_value_label, LV_ALIGN_LEFT_MID, txt_x, 0);
lv_label_set_text(value_setting_value_label, buf);
lv_obj_set_width(value_setting_value_label, txt_size.x);
}
static void gui_create_value_setting_panel() {
if (value_setting_panel != NULL) {
return;
}
value_setting_panel = lv_obj_create(scr);
lv_obj_set_size(value_setting_panel, 128, 40);
lv_obj_align(value_setting_panel, LV_ALIGN_BOTTOM_MID, 0, 0);
lv_obj_set_style_border_width(value_setting_panel, 1, LV_PART_MAIN);
lv_obj_set_style_border_color(value_setting_panel, lv_color_black(),
LV_PART_MAIN);
lv_obj_set_style_radius(value_setting_panel, 5, LV_PART_MAIN);
lv_obj_set_style_pad_all(value_setting_panel, 2, LV_PART_MAIN);
value_setting_label = lv_label_create(value_setting_panel);
lv_obj_align(value_setting_label, LV_ALIGN_BOTTOM_LEFT, 0, 0);
value_setting_bar = lv_bar_create(value_setting_panel);
lv_obj_set_size(value_setting_bar, 120, 12);
lv_obj_align(value_setting_bar, LV_ALIGN_TOP_MID, 0, 0);
lv_bar_set_range(value_setting_bar, 0, 100);
lv_bar_set_value(value_setting_bar, 50, LV_ANIM_ON);
lv_obj_set_style_bg_color(value_setting_bar, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_border_color(value_setting_bar, lv_color_black(),
LV_PART_MAIN);
lv_obj_set_style_border_width(value_setting_bar, 1, LV_PART_MAIN);
lv_obj_set_style_radius(value_setting_bar, 5, LV_PART_MAIN);
lv_obj_set_style_pad_hor(value_setting_bar, 0, LV_PART_MAIN);
lv_obj_set_style_pad_ver(value_setting_bar, 2, LV_PART_MAIN);
lv_obj_set_style_bg_color(value_setting_bar, lv_color_black(),
LV_PART_INDICATOR);
lv_obj_add_event_cb(value_setting_bar, gui_bar_value_update_cb,
LV_EVENT_DRAW_PART_END, NULL);
value_setting_value_label = lv_label_create(value_setting_bar);
lv_obj_align(value_setting_value_label, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_text_font(value_setting_value_label, &lv_font_montserrat_10,
LV_PART_MAIN);
}
static void gui_change_strip_level(int32_t target_value) {
gui_create_value_setting_panel();
lv_label_set_text(value_setting_label, "Strip Level");
lv_bar_set_range(value_setting_bar, 0, 255);
lv_bar_set_value(value_setting_bar, target_value, LV_ANIM_ON);
}
void lv_example_bar_6(lv_obj_t *src) {
static lv_style_t style_bar;
lv_style_init(&style_bar);
lv_style_set_bg_color(&style_bar, lv_color_white());
lv_style_set_border_width(&style_bar, 1);
lv_style_set_border_color(&style_bar, lv_color_black());
lv_style_set_pad_hor(&style_bar, 4);
lv_style_set_pad_ver(&style_bar, 2);
static lv_style_t style_indic;
lv_style_init(&style_indic);
lv_style_set_bg_color(&style_indic, lv_color_black());
lv_obj_t *bar = lv_bar_create(src);
lv_obj_set_size(bar, 100, 10);
lv_obj_center(bar);
lv_obj_add_style(bar, &style_bar, LV_PART_MAIN);
lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);
lv_bar_set_range(bar, 0, 100);
lv_bar_set_value(bar, 0, LV_ANIM_ON);
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, set_value);
lv_anim_set_time(&a, 3000);
lv_anim_set_playback_time(&a, 3000);
lv_anim_set_var(&a, bar);
lv_anim_set_values(&a, 0, 50);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&a);
}
void gui_status_bar_create(lv_obj_t *scr) {
// wifi icon
wifi_label = lv_label_create(scr);
lv_label_set_long_mode(wifi_label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL);
lv_obj_set_width(wifi_label, 10);
lv_obj_align(wifi_label, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
lv_obj_set_style_text_color(wifi_label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(wifi_label, &app_icon_8, LV_PART_MAIN);
lv_obj_add_flag(wifi_label, LV_OBJ_FLAG_HIDDEN);
// timer icon
timer_label = lv_label_create(scr);
lv_label_set_long_mode(timer_label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_label_set_text(timer_label, APP_TIMER_SYMBOL);
lv_obj_set_width(timer_label, 10);
lv_obj_align(timer_label, LV_ALIGN_OUT_TOP_LEFT, 12, 0);
lv_obj_set_style_text_color(timer_label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(timer_label, &app_icon_8, LV_PART_MAIN);
lv_obj_add_flag(timer_label, LV_OBJ_FLAG_HIDDEN);
// desktop icon
desktop_label = lv_label_create(scr);
lv_label_set_long_mode(desktop_label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL);
lv_obj_set_width(desktop_label, 10);
lv_obj_align(desktop_label, LV_ALIGN_OUT_TOP_LEFT, 24, 0);
lv_obj_set_style_text_color(desktop_label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(desktop_label, &app_icon_8, LV_PART_MAIN);
lv_obj_add_flag(desktop_label, LV_OBJ_FLAG_HIDDEN);
}
void example_lvgl_demo_ui(lv_disp_t *disp) {
scr = lv_disp_get_scr_act(disp);
lv_obj_t *label = lv_label_create(scr);
lv_label_set_long_mode(label,
LV_LABEL_LONG_SCROLL_CIRCULAR); /* Circular scroll
*/
lv_label_set_text(label, "Hello Espressif, Hello LVGL.");
lv_obj_set_width(label, 120);
lv_obj_align(label, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
lv_example_bar_6(scr);
gui_status_bar_create(scr);
gui_create_value_setting_panel();
}
static void gui_tick(void *pvParameters) {
while (1) {
// raise the task priority of LVGL and/or reduce the handler period can
// improve the performance
vTaskDelay(pdMS_TO_TICKS(10));
// The task running lv_timer_handler should have lower priority than that
// running `lv_tick_inc`
lv_timer_handler();
}
}
void gui_main(void) {
static lv_disp_draw_buf_t
disp_buf; // contains internal graphic buffer(s) called draw buffer(s)
static lv_disp_drv_t disp_drv; // contains callback functions
ESP_LOGI(GUI_TAG, "Initialize LVGL library");
lv_init();
// alloc draw buffers used by LVGL
// it's recommended to choose the size of the draw buffer(s) to be at least
// 1/10 screen sized
lv_color_t *buf1 = malloc(EXAMPLE_LCD_H_RES * 20 * sizeof(lv_color_t));
assert(buf1);
lv_color_t *buf2 = malloc(EXAMPLE_LCD_H_RES * 20 * sizeof(lv_color_t));
assert(buf2);
// initialize LVGL draw buffers
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * 20);
ESP_LOGI(GUI_TAG, "Register display driver to LVGL");
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = EXAMPLE_LCD_H_RES;
disp_drv.ver_res = EXAMPLE_LCD_V_RES;
disp_drv.flush_cb = example_lvgl_flush_cb;
disp_drv.draw_buf = &disp_buf;
disp_drv.rounder_cb = example_lvgl_rounder;
disp_drv.set_px_cb = example_lvgl_set_px_cb;
lv_disp_t *disp = lv_disp_drv_register(&disp_drv);
ESP_LOGI(GUI_TAG, "Install LVGL tick timer");
// Tick interface for LVGL (using esp_timer to generate 2ms periodic event)
const esp_timer_create_args_t lvgl_tick_timer_args = {
.callback = &example_increase_lvgl_tick, .name = "lvgl_tick"};
esp_timer_handle_t lvgl_tick_timer = NULL;
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer,
EXAMPLE_LVGL_TICK_PERIOD_MS * 1000));
ESP_LOGI(GUI_TAG, "Display LVGL Scroll Text");
example_lvgl_demo_ui(disp);
xTaskCreate(gui_tick, "gui_tick", 4096, (void *)NULL, 5, NULL);
}

View File

@ -1,5 +1,6 @@
## IDF Component Manager Manifest File ## IDF Component Manager Manifest File
dependencies: dependencies:
lvgl/lvgl: "^8.3.6~1"
espressif/mdns: "^1.0.9" espressif/mdns: "^1.0.9"
## Required IDF version ## Required IDF version
idf: idf:

19
main/lvgl_demo_ui.c Executable file
View File

@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include "lvgl.h"
void example_lvgl_demo_ui(lv_disp_t *disp) {
lv_obj_t *scr = lv_disp_get_scr_act(disp);
lv_obj_t *label = lv_label_create(scr);
lv_label_set_long_mode(label,
LV_LABEL_LONG_SCROLL_CIRCULAR); /* Circular scroll
*/
lv_label_set_text(label, "Hello Espressif, Hello LVGL.");
lv_obj_set_width(label, 120);
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);
}

View File

@ -1,17 +1,18 @@
#include "apds_9960.c" // #include "apds_9960.c"
#include "app_nvs.c" #include "app_nvs.c"
#include "ch1116.c"
#include "ci_03t.c" #include "ci_03t.c"
#include "embedded_display.c"
#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 "gui.c"
#include "i2c.c" #include "i2c.c"
#include "light.c" #include "light.c"
#include "mqtt.c" // #include "mqtt.c"
#include "pca9555.c" // #include "pca9555.c"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "service_discovery.c" #include "service_discovery.c"
#include "temperature.c" // #include "temperature.c"
#include "udp_server.c" #include "udp_server.c"
#include "ui_input.c" #include "ui_input.c"
#include "wifi.c" #include "wifi.c"
@ -26,33 +27,41 @@ void app_main(void) {
init_i2c(); init_i2c();
i2c_check_slaves(); i2c_check_slaves();
init_display(); ch1116_main();
display_print8_str(0, 0, "Ambient Light"); gui_main();
ci_03t_init(); gui_set_wifi_connecting();
apds_9960_init(); gui_set_server_connecting();
apds_9960_auto_fetch();
auto_fetch_temperature(); // display_print8_str(0, 0, "Ambient Light");
// ci_03t_init();
// apds_9960_init();
// apds_9960_auto_fetch();
// auto_fetch_temperature();
pca9555_init(); pca9555_init();
ui_input_init(); ui_input_init();
xTaskCreate(mqtt_publish_ui_input, "mqtt_publish_ui_input", 2048, NULL, 10, // xTaskCreate(mqtt_publish_ui_input, "mqtt_publish_ui_input", 2048, NULL, 10,
NULL); // NULL);
vTaskDelay(pdMS_TO_TICKS(10)); // vTaskDelay(pdMS_TO_TICKS(10));
light_play(light_mode_connection_wifi); light_play(light_mode_connection_wifi);
if (connect_wifi()) { if (connect_wifi()) {
gui_set_wifi_connected();
light_play(light_mode_idle); light_play(light_mode_idle);
} else {
gui_set_wifi_disconnected();
} }
udp_server_init(); udp_server_init();
service_discovery_init(); service_discovery_init();
vTaskDelay(pdMS_TO_TICKS(1000)); // vTaskDelay(pdMS_TO_TICKS(1000));
mqtt_app_start(); // mqtt_app_start();
// if (waiting_for_mqtt_connected()) { // if (waiting_for_mqtt_connected()) {
// light_play(light_mode_mqtt_connected); // light_play(light_mode_mqtt_connected);
// } // }
// if (waiting_for_desktop_online()) { // if (waiting_for_desktop_online()) {
// light_play(light_mode_desktop_online); // light_play(light_mode_desktop_online);
// } // }
while (waiting_and_get_colors()) { // while (waiting_and_get_colors()) {
light_play_colors(NUMBER_OF_LEDS * 3, mqtt_colors_buffer); // light_play_colors(NUMBER_OF_LEDS * 3, mqtt_colors_buffer);
} // }
} }

View File

@ -4,7 +4,6 @@
#include "cJSON.h" #include "cJSON.h"
#include "ci_03t.c" #include "ci_03t.c"
#include "embedded_display.c"
#include "esp_bit_defs.h" #include "esp_bit_defs.h"
#include "esp_event.h" #include "esp_event.h"
#include "esp_log.h" #include "esp_log.h"

View File

@ -3,7 +3,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "driver/i2c.h" #include "driver/i2c.h"
#include "embedded_display.c"
#include "esp_log.h" #include "esp_log.h"
#include "i2c.c" #include "i2c.c"
@ -79,19 +78,15 @@ void pca9555_fetch(void* arg) {
esp_err_t error; esp_err_t error;
uint8_t buff; uint8_t buff;
char disp_str[17]; char disp_str[17];
display_fill_rect(0, 6, 128, 8, 0x00);
for (;;) { for (;;) {
error = pca9555_read_one_input(PCA95555_CMD_INPUT_PORT_1, &buff); error = pca9555_read_one_input(PCA95555_CMD_INPUT_PORT_1, &buff);
if (error != ESP_OK) { if (error != ESP_OK) {
ESP_LOGW(PCA_9555_TAG, "read failed. %x", error); ESP_LOGW(PCA_9555_TAG, "read failed. %x", error);
} else { } else {
sprintf(disp_str, "IO0: 0x%2x ", buff);
display_print8_str(8, 6, disp_str);
ESP_LOGD(PCA_9555_TAG, "IO0: 0x%2x", buff); ESP_LOGD(PCA_9555_TAG, "IO0: 0x%2x", buff);
} }
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
} }
display_fill_rect(0, 6, 128, 8, 0x00);
} }
void pca9555_auto_fetch() { void pca9555_auto_fetch() {

View File

@ -10,6 +10,7 @@
#include "esp_wifi.h" #include "esp_wifi.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "gui.c"
#include "light.c" #include "light.c"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
@ -20,6 +21,9 @@
static const char *UDP_SERVER_TAG = "UDP_SERVER"; static const char *UDP_SERVER_TAG = "UDP_SERVER";
static bool desktop_connected = false;
static uint64_t last_desktop_ping_at = 0;
static void udp_server_task(void *pvParameters) { static void udp_server_task(void *pvParameters) {
char rx_buffer[1024]; char rx_buffer[1024];
char addr_str[128]; char addr_str[128];
@ -84,6 +88,7 @@ static void udp_server_task(void *pvParameters) {
switch (rx_buffer[0]) { switch (rx_buffer[0]) {
case 1: case 1:
last_desktop_ping_at = esp_timer_get_time();
sendto(sock, rx_buffer, 1, 0, (struct sockaddr *)&source_addr, sendto(sock, rx_buffer, 1, 0, (struct sockaddr *)&source_addr,
sizeof(source_addr)); sizeof(source_addr));
break; break;
@ -127,8 +132,28 @@ static void udp_server_task(void *pvParameters) {
vTaskDelete(NULL); vTaskDelete(NULL);
} }
void udp_server_init(void) { static void change_desktop_connection_status(bool connected) {
ESP_ERROR_CHECK(nvs_flash_init()); desktop_connected = connected;
ESP_ERROR_CHECK(esp_netif_init()); if (connected) {
xTaskCreate(udp_server_task, "udp_server", 4096, (void *)AF_INET, 5, NULL); gui_set_server_connected();
} else {
gui_set_server_disconnected();
}
}
static void desktop_online_check_task(void *pvParameters) {
while (1) {
if (esp_timer_get_time() - last_desktop_ping_at > 5000000) { // 2 seconds
change_desktop_connection_status(false);
} else {
change_desktop_connection_status(true);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void udp_server_init(void) {
xTaskCreate(udp_server_task, "udp_server", 4096, (void *)AF_INET, 5, NULL);
xTaskCreate(desktop_online_check_task, "desktop_online_check", 4096, NULL, 10,
NULL);
} }

View File

@ -6,10 +6,10 @@
#include "config_key.h" #include "config_key.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "embedded_display.c"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "gui.c"
#include "light.c" #include "light.c"
#include "pca9555.c" #include "pca9555.c"
@ -72,7 +72,6 @@ static void ui_input_update_embedded_display(void *arg) {
sprintf(changing_str, "CVol: % 3d", input.value); sprintf(changing_str, "CVol: % 3d", input.value);
break; break;
case ui_input_key_display_ambient_lighting_level: case ui_input_key_display_ambient_lighting_level:
sprintf(changing_str, "ALLv: % 3d", display_ambient_lighting_level);
break; break;
case ui_input_key_display_ambient_lighting_mode: case ui_input_key_display_ambient_lighting_mode:
sprintf(changing_str, "ALMd: % 3d", input.value); sprintf(changing_str, "ALMd: % 3d", input.value);
@ -88,8 +87,6 @@ static void ui_input_update_embedded_display(void *arg) {
strcpy(changing_str, "NC"); strcpy(changing_str, "NC");
break; break;
} }
display_fill_rect(0, 6, 128, 8, 0);
display_print8_str(8, 6, changing_str);
} }
} }
} }
@ -148,6 +145,8 @@ static void encoder_value_change(encoder_state_t *state) {
return; return;
} }
ESP_LOGI(UI_INPUT_TAG, "key: %d, delta: %d", state->key, delta);
s_ui_input_t event = {.value = delta}; s_ui_input_t event = {.value = delta};
if (state->key == ui_input_raw_key_encoder_0) { if (state->key == ui_input_raw_key_encoder_0) {
if (state->value & 1) { if (state->value & 1) {
@ -159,6 +158,7 @@ static void encoder_value_change(encoder_state_t *state) {
if (state->value & 1) { if (state->value & 1) {
event.key = ui_input_key_display_ambient_lighting_level; event.key = ui_input_key_display_ambient_lighting_level;
led_strip_set_brightness(display_ambient_lighting_level + delta); led_strip_set_brightness(display_ambient_lighting_level + delta);
gui_change_strip_level(display_ambient_lighting_level);
} else { } else {
event.key = ui_input_key_display_1_brightness; event.key = ui_input_key_display_1_brightness;
} }

View File

@ -151,14 +151,7 @@ bool wifi_init_sta(void) {
} }
bool connect_wifi(void) { bool connect_wifi(void) {
// Initialize NVS //! Should init NVS before wifi init
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA");
return wifi_init_sta(); return wifi_init_sta();