Copy /*******************************************************************************
* Example 5: GPIO Dashboard
*
* Combined widgets: LED, Switch, Button, Container
* Official Refs:
* - LED: https://docs.lvgl.io/9.2/widgets/led.html
* - Switch: https://docs.lvgl.io/9.2/widgets/switch.html
* - Container: https://docs.lvgl.io/9.2/widgets/obj.html
******************************************************************************/
#define NUM_GPIOS 4
/* Data structure for each GPIO channel */
typedef struct {
lv_obj_t *led;
lv_obj_t *sw;
lv_obj_t *label;
const char *name;
bool state;
} gpio_item_t;
/* Global array of GPIO items */
static gpio_item_t gpios[NUM_GPIOS];
/* Individual switch callback */
static void switch_cb(lv_event_t * e)
{
gpio_item_t * gpio = (gpio_item_t *)lv_event_get_user_data(e);
lv_obj_t * sw = lv_event_get_target(e);
gpio->state = lv_obj_has_state(sw, LV_STATE_CHECKED);
if(gpio->state) {
lv_led_on(gpio->led);
printf("%s: ON\r\n", gpio->name);
} else {
lv_led_off(gpio->led);
printf("%s: OFF\r\n", gpio->name);
}
}
/* All ON button callback */
static void all_on_cb(lv_event_t * e)
{
(void)e;
for(int i = 0; i < NUM_GPIOS; i++) {
gpios[i].state = true;
lv_led_on(gpios[i].led);
lv_obj_add_state(gpios[i].sw, LV_STATE_CHECKED);
lv_obj_invalidate(gpios[i].sw); /* Force redraw */
lv_obj_invalidate(gpios[i].led); /* Force redraw */
}
printf("All LEDs: ON\r\n");
}
/* All OFF button callback */
static void all_off_cb(lv_event_t * e)
{
(void)e;
for(int i = 0; i < NUM_GPIOS; i++) {
gpios[i].state = false;
lv_led_off(gpios[i].led);
lv_obj_clear_state(gpios[i].sw, LV_STATE_CHECKED);
lv_obj_invalidate(gpios[i].sw); /* Force redraw */
lv_obj_invalidate(gpios[i].led); /* Force redraw */
}
printf("All LEDs: OFF\r\n");
}
void week3_ex5_gpio_dashboard(void)
{
const char *gpio_names[] = {"LED1", "LED2", "LED3", "LED4"};
lv_color_t gpio_colors[] = {
lv_palette_main(LV_PALETTE_RED),
lv_palette_main(LV_PALETTE_GREEN),
lv_palette_main(LV_PALETTE_BLUE),
lv_palette_main(LV_PALETTE_YELLOW)
};
/* Background */
lv_obj_set_style_bg_color(lv_screen_active(),
lv_color_hex(0x1a1a2e),
LV_PART_MAIN);
/* Title */
lv_obj_t * title = lv_label_create(lv_screen_active());
lv_label_set_text(title, "Week 3 - Example 5: GPIO Dashboard");
lv_obj_set_style_text_color(title, lv_color_hex(0xFFFFFF), 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
/* Create container */
lv_obj_t * cont = lv_obj_create(lv_screen_active());
lv_obj_set_size(cont, 420, 200);
lv_obj_align(cont, LV_ALIGN_CENTER, 0, 10);
lv_obj_set_style_bg_color(cont, lv_color_hex(0x0f0f23), 0);
lv_obj_set_style_border_width(cont, 2, 0);
lv_obj_set_style_border_color(cont, lv_color_hex(0x444444), 0);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
/* Create GPIO items in 2x2 grid */
for(int i = 0; i < NUM_GPIOS; i++) {
gpios[i].name = gpio_names[i];
gpios[i].state = false;
/* Calculate grid position */
int x_pos = (i % 2) * 200 + 20;
int y_pos = (i / 2) * 80 + 20;
/* LED */
gpios[i].led = lv_led_create(cont);
lv_obj_set_size(gpios[i].led, 40, 40);
lv_obj_set_pos(gpios[i].led, x_pos, y_pos);
lv_led_set_color(gpios[i].led, gpio_colors[i]);
lv_led_off(gpios[i].led);
/* Name Label */
gpios[i].label = lv_label_create(cont);
lv_label_set_text(gpios[i].label, gpio_names[i]);
lv_obj_set_style_text_color(gpios[i].label, lv_color_hex(0xFFFFFF), 0);
lv_obj_align_to(gpios[i].label, gpios[i].led,
LV_ALIGN_OUT_RIGHT_MID, 10, 0);
/* Switch */
gpios[i].sw = lv_switch_create(cont);
lv_obj_set_size(gpios[i].sw, 60, 30);
lv_obj_align_to(gpios[i].sw, gpios[i].label,
LV_ALIGN_OUT_RIGHT_MID, 15, 0);
lv_obj_add_event_cb(gpios[i].sw, switch_cb,
LV_EVENT_VALUE_CHANGED, &gpios[i]);
}
/* All ON button */
lv_obj_t * btn_all_on = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn_all_on, all_on_cb, LV_EVENT_CLICKED, NULL);
lv_obj_align(btn_all_on, LV_ALIGN_BOTTOM_LEFT, 40, -50);
lv_obj_set_style_bg_color(btn_all_on, lv_palette_main(LV_PALETTE_GREEN), 0);
lv_obj_set_style_pad_hor(btn_all_on, 30, 0);
lv_obj_set_style_pad_ver(btn_all_on, 15, 0);
lv_obj_t * label_on = lv_label_create(btn_all_on);
lv_label_set_text(label_on, "All ON");
lv_obj_center(label_on);
/* All OFF button */
lv_obj_t * btn_all_off = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn_all_off, all_off_cb, LV_EVENT_CLICKED, NULL);
lv_obj_align(btn_all_off, LV_ALIGN_BOTTOM_RIGHT, -40, -50);
lv_obj_set_style_bg_color(btn_all_off, lv_palette_main(LV_PALETTE_RED), 0);
lv_obj_set_style_pad_hor(btn_all_off, 30, 0);
lv_obj_set_style_pad_ver(btn_all_off, 15, 0);
lv_obj_t * label_off = lv_label_create(btn_all_off);
lv_label_set_text(label_off, "All OFF");
lv_obj_center(label_off);
}