Add HW-069 v1.1 4-digit TM1637 test with SoftSPI touch and LVGL.
CLK on GPIO22, DIO on GPIO27; value/brightness/colon controls and flashable firmware/cyd package. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
178
src/digit.cpp
Normal file
178
src/digit.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "digit.h"
|
||||
#include "pins.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// HW-069 v1.1:TM1637 两线协议(非 I2C)
|
||||
static constexpr uint8_t CMD_DATA_AUTO = 0x40;
|
||||
static constexpr uint8_t CMD_ADDR_BASE = 0xC0;
|
||||
static constexpr uint8_t CMD_DISP_OFF = 0x80;
|
||||
static constexpr uint8_t CMD_DISP_ON = 0x88; // | brightness 0..7
|
||||
|
||||
static const uint8_t SEG_DIGIT[10] = {
|
||||
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,
|
||||
};
|
||||
|
||||
static bool g_on = true;
|
||||
static bool g_colon = false;
|
||||
static uint8_t g_pct = 60;
|
||||
static int g_value = 1234;
|
||||
static uint8_t g_raw[4] = {0, 0, 0, 0};
|
||||
|
||||
static void bit_delay() { delayMicroseconds(50); }
|
||||
|
||||
static void start() {
|
||||
digitalWrite(HW069_DIO_PIN, HIGH);
|
||||
digitalWrite(HW069_CLK_PIN, HIGH);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_DIO_PIN, LOW);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_CLK_PIN, LOW);
|
||||
bit_delay();
|
||||
}
|
||||
|
||||
static void stop() {
|
||||
digitalWrite(HW069_CLK_PIN, LOW);
|
||||
digitalWrite(HW069_DIO_PIN, LOW);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_CLK_PIN, HIGH);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_DIO_PIN, HIGH);
|
||||
bit_delay();
|
||||
}
|
||||
|
||||
static void write_byte(uint8_t b) {
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
digitalWrite(HW069_CLK_PIN, LOW);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_DIO_PIN, (b & 0x01) ? HIGH : LOW);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_CLK_PIN, HIGH);
|
||||
bit_delay();
|
||||
b >>= 1;
|
||||
}
|
||||
// ACK
|
||||
digitalWrite(HW069_CLK_PIN, LOW);
|
||||
pinMode(HW069_DIO_PIN, INPUT_PULLUP);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_CLK_PIN, HIGH);
|
||||
bit_delay();
|
||||
digitalWrite(HW069_CLK_PIN, LOW);
|
||||
pinMode(HW069_DIO_PIN, OUTPUT);
|
||||
bit_delay();
|
||||
}
|
||||
|
||||
static uint8_t level_from_pct(uint8_t pct) {
|
||||
if (pct > 100) {
|
||||
pct = 100;
|
||||
}
|
||||
// 0% -> 0, 100% -> 7
|
||||
return (uint8_t)((pct * 7U) / 100U);
|
||||
}
|
||||
|
||||
static void encode_value() {
|
||||
int v = g_value;
|
||||
if (v < 0) {
|
||||
v = 0;
|
||||
}
|
||||
if (v > 9999) {
|
||||
v = 9999;
|
||||
}
|
||||
g_raw[0] = SEG_DIGIT[(v / 1000) % 10];
|
||||
g_raw[1] = SEG_DIGIT[(v / 100) % 10];
|
||||
g_raw[2] = SEG_DIGIT[(v / 10) % 10];
|
||||
g_raw[3] = SEG_DIGIT[v % 10];
|
||||
// 时钟型模块:中间冒号挂在第 2 位的 bit7
|
||||
if (g_colon) {
|
||||
g_raw[1] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
static void apply() {
|
||||
start();
|
||||
write_byte(CMD_DATA_AUTO);
|
||||
stop();
|
||||
|
||||
start();
|
||||
write_byte(CMD_ADDR_BASE);
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
write_byte(g_on ? g_raw[i] : 0x00);
|
||||
}
|
||||
stop();
|
||||
|
||||
start();
|
||||
if (g_on) {
|
||||
write_byte((uint8_t)(CMD_DISP_ON | level_from_pct(g_pct)));
|
||||
} else {
|
||||
write_byte(CMD_DISP_OFF);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void digit_init() {
|
||||
pinMode(HW069_CLK_PIN, OUTPUT);
|
||||
pinMode(HW069_DIO_PIN, OUTPUT);
|
||||
digitalWrite(HW069_CLK_PIN, HIGH);
|
||||
digitalWrite(HW069_DIO_PIN, HIGH);
|
||||
|
||||
g_on = true;
|
||||
g_colon = false;
|
||||
g_pct = 60;
|
||||
g_value = 1234;
|
||||
encode_value();
|
||||
apply();
|
||||
Serial.printf("HW-069 TM1637 CLK=GPIO%d DIO=GPIO%d value=%d bright=%u%%\n",
|
||||
HW069_CLK_PIN, HW069_DIO_PIN, g_value, (unsigned)g_pct);
|
||||
}
|
||||
|
||||
void digit_set_on(bool on) {
|
||||
g_on = on;
|
||||
apply();
|
||||
Serial.printf("Digit %s\n", g_on ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
bool digit_is_on() { return g_on; }
|
||||
|
||||
void digit_set_value(int value) {
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
if (value > 9999) {
|
||||
value = 9999;
|
||||
}
|
||||
g_value = value;
|
||||
encode_value();
|
||||
apply();
|
||||
Serial.printf("Digit value %d\n", g_value);
|
||||
}
|
||||
|
||||
int digit_get_value() { return g_value; }
|
||||
|
||||
void digit_set_brightness(uint8_t percent) {
|
||||
if (percent > 100) {
|
||||
percent = 100;
|
||||
}
|
||||
g_pct = percent;
|
||||
apply();
|
||||
Serial.printf("Digit bright %u%% (lvl %u)\n", (unsigned)g_pct,
|
||||
(unsigned)level_from_pct(g_pct));
|
||||
}
|
||||
|
||||
uint8_t digit_brightness() { return g_pct; }
|
||||
|
||||
void digit_set_colon(bool on) {
|
||||
g_colon = on;
|
||||
encode_value();
|
||||
apply();
|
||||
Serial.printf("Digit colon %s\n", g_colon ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
bool digit_colon() { return g_colon; }
|
||||
|
||||
void digit_clear() {
|
||||
g_value = 0;
|
||||
g_colon = false;
|
||||
encode_value();
|
||||
apply();
|
||||
Serial.println("Digit clear");
|
||||
}
|
||||
45
src/main.cpp
Normal file
45
src/main.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <Arduino.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
#include "digit.h"
|
||||
#include "pins.h"
|
||||
#include "touch.h"
|
||||
#include "ui.h"
|
||||
|
||||
static constexpr uint32_t DRAW_BUF_SIZE =
|
||||
(SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8));
|
||||
static uint32_t draw_buf[DRAW_BUF_SIZE / 4];
|
||||
|
||||
void setup() {
|
||||
Serial.begin(460800);
|
||||
delay(200);
|
||||
Serial.println();
|
||||
Serial.printf("LVGL %d.%d.%d | HW-069 Digit Display v1.1\n", lv_version_major(),
|
||||
lv_version_minor(), lv_version_patch());
|
||||
Serial.println("BOOT_OK");
|
||||
|
||||
pinMode(TFT_BL_PIN, OUTPUT);
|
||||
digitalWrite(TFT_BL_PIN, HIGH);
|
||||
|
||||
touch_init();
|
||||
digit_init();
|
||||
|
||||
lv_init();
|
||||
|
||||
lv_display_t *disp =
|
||||
lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
|
||||
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
|
||||
|
||||
lv_indev_t *indev = lv_indev_create();
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_read_cb(indev, touch_read_cb);
|
||||
lv_indev_set_display(indev, disp);
|
||||
|
||||
ui_create();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
lv_timer_handler();
|
||||
lv_tick_inc(5);
|
||||
delay(5);
|
||||
}
|
||||
125
src/touch.cpp
Normal file
125
src/touch.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "touch.h"
|
||||
#include "pins.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/**
|
||||
* SoftSPI XPT2046
|
||||
* BL↔TR 是矩形主对角线镜像(XY 对调),不是 180°(180° 会搞成 TL↔BR)。
|
||||
* 先按 rot2 得到旧 UI,再做对角修正,反变换喂给 LVGL 270。
|
||||
*/
|
||||
|
||||
int16_t g_dbg_phys_x = -1;
|
||||
int16_t g_dbg_phys_y = -1;
|
||||
int16_t g_dbg_logic_x = -1;
|
||||
int16_t g_dbg_logic_y = -1;
|
||||
bool g_dbg_touch_down = false;
|
||||
|
||||
static void soft_write(uint8_t data) {
|
||||
for (int i = 7; i >= 0; --i) {
|
||||
digitalWrite(CYD_TOUCH_MOSI, (data >> i) & 1);
|
||||
digitalWrite(CYD_TOUCH_CLK, HIGH);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
delayMicroseconds(2);
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t soft_read12() {
|
||||
uint16_t v = 0;
|
||||
digitalWrite(CYD_TOUCH_CLK, HIGH);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
delayMicroseconds(2);
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
digitalWrite(CYD_TOUCH_CLK, HIGH);
|
||||
delayMicroseconds(2);
|
||||
v = (uint16_t)((v << 1) | (digitalRead(CYD_TOUCH_MISO) ? 1u : 0u));
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
delayMicroseconds(2);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint16_t xpt_read(uint8_t cmd) {
|
||||
digitalWrite(CYD_TOUCH_CS, LOW);
|
||||
soft_write(cmd);
|
||||
uint16_t v = soft_read12();
|
||||
digitalWrite(CYD_TOUCH_CS, HIGH);
|
||||
return v;
|
||||
}
|
||||
|
||||
static int16_t clampi(int32_t v, int32_t lo, int32_t hi) {
|
||||
if (v < lo) {
|
||||
return (int16_t)lo;
|
||||
}
|
||||
if (v > hi) {
|
||||
return (int16_t)hi;
|
||||
}
|
||||
return (int16_t)v;
|
||||
}
|
||||
|
||||
void touch_init() {
|
||||
pinMode(CYD_TOUCH_CS, OUTPUT);
|
||||
pinMode(CYD_TOUCH_CLK, OUTPUT);
|
||||
pinMode(CYD_TOUCH_MOSI, OUTPUT);
|
||||
pinMode(CYD_TOUCH_MISO, INPUT);
|
||||
pinMode(CYD_TOUCH_IRQ, INPUT);
|
||||
digitalWrite(CYD_TOUCH_CS, HIGH);
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
Serial.println("Touch: SoftSPI + diagonal fix (BL/TR)");
|
||||
}
|
||||
|
||||
void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
uint16_t adc_x = xpt_read(0x90);
|
||||
uint16_t adc_y = xpt_read(0xD0);
|
||||
adc_x = (uint16_t)((adc_x + xpt_read(0x90)) / 2);
|
||||
adc_y = (uint16_t)((adc_y + xpt_read(0xD0)) / 2);
|
||||
|
||||
const bool irq = (digitalRead(CYD_TOUCH_IRQ) == LOW);
|
||||
const bool in_range =
|
||||
(adc_x > 80 && adc_x < 4000 && adc_y > 80 && adc_y < 4000);
|
||||
|
||||
if (!in_range || (!irq && (adc_x < 200 || adc_y < 200))) {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
g_dbg_touch_down = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const int16_t p_x = (int16_t)adc_x;
|
||||
const int16_t p_y = (int16_t)(4095 - adc_y);
|
||||
|
||||
int16_t x = map(p_x, 200, 3700, 1, SCREEN_WIDTH);
|
||||
int16_t y = map(p_y, 240, 3800, 1, SCREEN_HEIGHT);
|
||||
x = clampi(x, 0, SCREEN_WIDTH - 1);
|
||||
y = clampi(y, 0, SCREEN_HEIGHT - 1);
|
||||
|
||||
// 旧 UI(LVGL270):(y, 239-x) — 该空间里 BL↔TR,做主对角线镜像
|
||||
// (ux,uy) -> (uy*(319/239), ux*(239/319))
|
||||
const int32_t old_ux = y;
|
||||
const int32_t old_uy = (SCREEN_WIDTH - 1) - x;
|
||||
int16_t ui_x = clampi((old_uy * (UI_HOR_RES - 1)) / (UI_VER_RES - 1), 0,
|
||||
UI_HOR_RES - 1);
|
||||
int16_t ui_y = clampi((old_ux * (UI_VER_RES - 1)) / (UI_HOR_RES - 1), 0,
|
||||
UI_VER_RES - 1);
|
||||
|
||||
// 反变换喂 LVGL,使最终落在 (ui_x, ui_y)
|
||||
const int16_t feed_x = (int16_t)((SCREEN_WIDTH - 1) - ui_y);
|
||||
const int16_t feed_y = ui_x;
|
||||
|
||||
g_dbg_phys_x = x;
|
||||
g_dbg_phys_y = y;
|
||||
g_dbg_logic_x = ui_x;
|
||||
g_dbg_logic_y = ui_y;
|
||||
g_dbg_touch_down = true;
|
||||
|
||||
static uint32_t last_log = 0;
|
||||
if (millis() - last_log > 80) {
|
||||
last_log = millis();
|
||||
Serial.printf("Touch UI(%d,%d)\n", ui_x, ui_y);
|
||||
}
|
||||
|
||||
data->point.x = feed_x;
|
||||
data->point.y = feed_y;
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
}
|
||||
224
src/ui.cpp
Normal file
224
src/ui.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "ui.h"
|
||||
#include "digit.h"
|
||||
#include "pins.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <lvgl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static constexpr uint32_t COL_BG = 0x0A1016;
|
||||
static constexpr uint32_t COL_INK = 0xEAF0F6;
|
||||
static constexpr uint32_t COL_MUTED = 0x7A8B9C;
|
||||
static constexpr uint32_t COL_BTN = 0x243140;
|
||||
static constexpr uint32_t COL_ON = 0x1B5E4A;
|
||||
static constexpr uint32_t COL_ACCENT = 0xFFB74D;
|
||||
static constexpr uint32_t COL_DIM = 0x3A4656;
|
||||
|
||||
static lv_obj_t *lbl_title;
|
||||
static lv_obj_t *lbl_pin;
|
||||
static lv_obj_t *lbl_value;
|
||||
static lv_obj_t *lbl_bright;
|
||||
static lv_obj_t *slider;
|
||||
static lv_obj_t *btn_power;
|
||||
static lv_obj_t *lbl_power;
|
||||
static lv_obj_t *btn_colon;
|
||||
static lv_obj_t *lbl_colon;
|
||||
static lv_obj_t *btn_m100;
|
||||
static lv_obj_t *btn_m1;
|
||||
static lv_obj_t *btn_p1;
|
||||
static lv_obj_t *btn_p100;
|
||||
|
||||
static void style_btn(lv_obj_t *btn, uint32_t bg) {
|
||||
lv_obj_set_style_radius(btn, 10, 0);
|
||||
lv_obj_set_style_bg_color(btn, lv_color_hex(bg), 0);
|
||||
lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_shadow_width(btn, 0, 0);
|
||||
lv_obj_set_style_border_width(btn, 0, 0);
|
||||
lv_obj_set_style_pad_all(btn, 0, 0);
|
||||
}
|
||||
|
||||
static lv_obj_t *make_step_btn(lv_obj_t *parent, const char *txt, int16_t x,
|
||||
int16_t y, int16_t w, int16_t h,
|
||||
lv_event_cb_t cb, void *user) {
|
||||
lv_obj_t *btn = lv_button_create(parent);
|
||||
lv_obj_set_size(btn, w, h);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x, y);
|
||||
style_btn(btn, COL_BTN);
|
||||
lv_obj_add_event_cb(btn, cb, LV_EVENT_CLICKED, user);
|
||||
lv_obj_t *lbl = lv_label_create(btn);
|
||||
lv_label_set_text(lbl, txt);
|
||||
lv_obj_set_style_text_color(lbl, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lbl, &lv_font_montserrat_18, 0);
|
||||
lv_obj_center(lbl);
|
||||
return btn;
|
||||
}
|
||||
|
||||
void ui_refresh_digit() {
|
||||
const bool on = digit_is_on();
|
||||
const bool colon = digit_colon();
|
||||
const int value = digit_get_value();
|
||||
const uint8_t pct = digit_brightness();
|
||||
|
||||
if (lbl_value) {
|
||||
if (colon) {
|
||||
lv_label_set_text_fmt(lbl_value, "%02d:%02d", value / 100, value % 100);
|
||||
} else {
|
||||
lv_label_set_text_fmt(lbl_value, "%04d", value);
|
||||
}
|
||||
lv_obj_set_style_text_color(lbl_value,
|
||||
lv_color_hex(on ? COL_ACCENT : COL_MUTED), 0);
|
||||
}
|
||||
if (lbl_bright) {
|
||||
lv_label_set_text_fmt(lbl_bright, "Brightness %u%%", (unsigned)pct);
|
||||
}
|
||||
if (slider) {
|
||||
lv_slider_set_value(slider, pct, LV_ANIM_OFF);
|
||||
lv_obj_set_style_bg_opa(slider, on ? LV_OPA_COVER : LV_OPA_50, LV_PART_MAIN);
|
||||
}
|
||||
if (lbl_power) {
|
||||
lv_label_set_text(lbl_power, on ? "Display OFF" : "Display ON");
|
||||
}
|
||||
if (btn_power) {
|
||||
style_btn(btn_power, on ? COL_ON : COL_BTN);
|
||||
}
|
||||
if (lbl_colon) {
|
||||
lv_label_set_text(lbl_colon, colon ? "Colon ON" : "Colon OFF");
|
||||
}
|
||||
if (btn_colon) {
|
||||
style_btn(btn_colon, colon ? COL_ON : COL_DIM);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_power(lv_event_t *e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
|
||||
return;
|
||||
}
|
||||
digit_set_on(!digit_is_on());
|
||||
ui_refresh_digit();
|
||||
}
|
||||
|
||||
static void on_colon(lv_event_t *e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
|
||||
return;
|
||||
}
|
||||
digit_set_colon(!digit_colon());
|
||||
ui_refresh_digit();
|
||||
}
|
||||
|
||||
static void on_step(lv_event_t *e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
|
||||
return;
|
||||
}
|
||||
const intptr_t delta = (intptr_t)lv_event_get_user_data(e);
|
||||
int v = digit_get_value() + (int)delta;
|
||||
if (v < 0) {
|
||||
v = 0;
|
||||
}
|
||||
if (v > 9999) {
|
||||
v = 9999;
|
||||
}
|
||||
digit_set_value(v);
|
||||
if (!digit_is_on()) {
|
||||
digit_set_on(true);
|
||||
}
|
||||
ui_refresh_digit();
|
||||
}
|
||||
|
||||
static void on_slider(lv_event_t *e) {
|
||||
const lv_event_code_t code = lv_event_get_code(e);
|
||||
if (code != LV_EVENT_VALUE_CHANGED && code != LV_EVENT_RELEASED) {
|
||||
return;
|
||||
}
|
||||
lv_obj_t *obj = (lv_obj_t *)lv_event_get_target(e);
|
||||
const int32_t v = lv_slider_get_value(obj);
|
||||
digit_set_brightness((uint8_t)v);
|
||||
if (!digit_is_on() && v > 0) {
|
||||
digit_set_on(true);
|
||||
}
|
||||
ui_refresh_digit();
|
||||
}
|
||||
|
||||
void ui_create() {
|
||||
lv_obj_t *scr = lv_screen_active();
|
||||
lv_obj_set_style_bg_color(scr, lv_color_hex(COL_BG), 0);
|
||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||
|
||||
lbl_title = lv_label_create(scr);
|
||||
lv_label_set_text(lbl_title, "HW-069");
|
||||
lv_obj_set_style_text_color(lbl_title, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lbl_title, &lv_font_montserrat_28, 0);
|
||||
lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 4);
|
||||
|
||||
lbl_pin = lv_label_create(scr);
|
||||
lv_label_set_text_fmt(lbl_pin, "v1.1 CLK%d DIO%d TM1637", HW069_CLK_PIN,
|
||||
HW069_DIO_PIN);
|
||||
lv_obj_set_style_text_color(lbl_pin, lv_color_hex(COL_MUTED), 0);
|
||||
lv_obj_set_style_text_font(lbl_pin, &lv_font_montserrat_14, 0);
|
||||
lv_obj_align(lbl_pin, LV_ALIGN_TOP_MID, 0, 36);
|
||||
|
||||
lbl_value = lv_label_create(scr);
|
||||
lv_label_set_text(lbl_value, "1234");
|
||||
lv_obj_set_style_text_color(lbl_value, lv_color_hex(COL_ACCENT), 0);
|
||||
lv_obj_set_style_text_font(lbl_value, &lv_font_montserrat_28, 0);
|
||||
lv_obj_align(lbl_value, LV_ALIGN_TOP_MID, 0, 56);
|
||||
|
||||
const int16_t row_y = 92;
|
||||
const int16_t gap = 8;
|
||||
const int16_t bw = (UI_HOR_RES - 48 - 3 * gap) / 4;
|
||||
const int16_t bx0 = 24;
|
||||
btn_m100 = make_step_btn(scr, "-100", bx0, row_y, bw, 40, on_step,
|
||||
(void *)(intptr_t)-100);
|
||||
btn_m1 = make_step_btn(scr, "-1", bx0 + (bw + gap), row_y, bw, 40, on_step,
|
||||
(void *)(intptr_t)-1);
|
||||
btn_p1 = make_step_btn(scr, "+1", bx0 + 2 * (bw + gap), row_y, bw, 40, on_step,
|
||||
(void *)(intptr_t)1);
|
||||
btn_p100 = make_step_btn(scr, "+100", bx0 + 3 * (bw + gap), row_y, bw, 40,
|
||||
on_step, (void *)(intptr_t)100);
|
||||
(void)btn_m100;
|
||||
(void)btn_m1;
|
||||
(void)btn_p1;
|
||||
(void)btn_p100;
|
||||
|
||||
lbl_bright = lv_label_create(scr);
|
||||
lv_label_set_text(lbl_bright, "Brightness 60%");
|
||||
lv_obj_set_style_text_color(lbl_bright, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lbl_bright, &lv_font_montserrat_14, 0);
|
||||
lv_obj_align(lbl_bright, LV_ALIGN_TOP_MID, 0, 140);
|
||||
|
||||
slider = lv_slider_create(scr);
|
||||
lv_obj_set_size(slider, UI_HOR_RES - 48, 24);
|
||||
lv_slider_set_range(slider, 0, 100);
|
||||
lv_slider_set_value(slider, 60, LV_ANIM_OFF);
|
||||
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 162);
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(COL_BTN), LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(COL_ACCENT), LV_PART_INDICATOR);
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(COL_INK), LV_PART_KNOB);
|
||||
lv_obj_set_ext_click_area(slider, 12);
|
||||
lv_obj_add_event_cb(slider, on_slider, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
lv_obj_add_event_cb(slider, on_slider, LV_EVENT_RELEASED, nullptr);
|
||||
|
||||
const int16_t btn_w = (UI_HOR_RES - 48 - gap) / 2;
|
||||
btn_colon = lv_button_create(scr);
|
||||
lv_obj_set_size(btn_colon, btn_w, 40);
|
||||
lv_obj_align(btn_colon, LV_ALIGN_TOP_LEFT, 24, 196);
|
||||
style_btn(btn_colon, COL_DIM);
|
||||
lv_obj_add_event_cb(btn_colon, on_colon, LV_EVENT_CLICKED, nullptr);
|
||||
lbl_colon = lv_label_create(btn_colon);
|
||||
lv_label_set_text(lbl_colon, "Colon OFF");
|
||||
lv_obj_set_style_text_color(lbl_colon, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lbl_colon, &lv_font_montserrat_16, 0);
|
||||
lv_obj_center(lbl_colon);
|
||||
|
||||
btn_power = lv_button_create(scr);
|
||||
lv_obj_set_size(btn_power, btn_w, 40);
|
||||
lv_obj_align(btn_power, LV_ALIGN_TOP_LEFT, 24 + btn_w + gap, 196);
|
||||
style_btn(btn_power, COL_ON);
|
||||
lv_obj_add_event_cb(btn_power, on_power, LV_EVENT_CLICKED, nullptr);
|
||||
lbl_power = lv_label_create(btn_power);
|
||||
lv_label_set_text(lbl_power, "Display OFF");
|
||||
lv_obj_set_style_text_color(lbl_power, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lbl_power, &lv_font_montserrat_16, 0);
|
||||
lv_obj_center(lbl_power);
|
||||
|
||||
ui_refresh_digit();
|
||||
}
|
||||
Reference in New Issue
Block a user