#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "lvgl.h"
#include "lvgl_helpers.h"
#include "lv_init.h"
#include "lv_ili9341.h"
#include "lv_lcd_generic_mipi.h"
// External declarations for background and font
LV_IMG_DECLARE(ammoCount_bg);
LV_FONT_DECLARE(sf_transrobotics);
// Define GPIO for the KW11-3Z-A-1 switch
#define BUTTON_GPIO 0 // Replace with your actual GPIO pin
// Default display buffer size
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
// Counter state
static int counter_value = 0;
static lv_obj_t *counter_label;
// LVGL display refresh task
static void lv_tick_task(void *arg) {
(void) arg;
while (1) {
vTaskDelay(pdMS_TO_TICKS(10));
lv_tick_inc(10); // Tell LVGL that 10 milliseconds have passed
}
}
// Button ISR handler
static void IRAM_ATTR button_isr_handler(void* arg) {
// Increment counter value
counter_value++;
}
// Initialize the button
static void button_init(void) {
// Configure the button GPIO
gpio_config_t io_conf = {
.intr_type = GPIO_INTR_POSEDGE, // Interrupt on rising edge
.pin_bit_mask = (1ULL << BUTTON_GPIO),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
gpio_config(&io_conf);
// Install GPIO ISR service
gpio_install_isr_service(0);
// Hook ISR handler for button GPIO
gpio_isr_handler_add(BUTTON_GPIO, button_isr_handler, NULL);
}
// Update counter display
static void update_counter_display(void *pvParameter) {
int last_counter = -1;
while (1) {
// Only update the display if the counter value has changed
if (last_counter != counter_value) {
last_counter = counter_value;
// Format counter text
char buf[16];
snprintf(buf, sizeof(buf), "%d", counter_value);
// Update the label text in the LVGL task
lv_task_handler();
if (counter_label != NULL) {
lv_label_set_text(counter_label, buf);
}
}
vTaskDelay(pdMS_TO_TICKS(50)); // Check every 50ms
}
}
// Create the UI
static void create_ui(void) {
// Create a full screen background
lv_obj_t *bg_img = lv_img_create(lv_scr_act(), NULL);
lv_img_set_src(bg_img, &ammoCount_bg);
lv_obj_align(bg_img, NULL, LV_ALIGN_CENTER, 0, 0);
// Create a counter label
counter_label = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_style_local_text_font(counter_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &sf_transrobotics);
lv_obj_set_style_local_text_color(counter_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_label_set_text(counter_label, "0");
lv_obj_set_size(counter_label, 100, 40);
lv_obj_align(counter_label, NULL, LV_ALIGN_CENTER, 0, 0);
}
void app_main(void) {
// Initialize logging
esp_log_level_set("*", ESP_LOG_INFO);
ESP_LOGI("COUNTER", "Starting Counter Application");
// Initialize LVGL
lv_init();
// Initialize the display
lvgl_driver_init();
// Allocate display buffer
static lv_color_t buf1[DISP_BUF_SIZE];
static lv_color_t buf2[DISP_BUF_SIZE];
static lv_disp_buf_t disp_buf;
lv_disp_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE);
// Register display driver
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.buffer = &disp_buf;
disp_drv.flush_cb = disp_driver_flush;
lv_disp_drv_register(&disp_drv);
// Create LVGL tick task
xTaskCreate(lv_tick_task, "lv_tick_task", 2048, NULL, 5, NULL);
// Initialize button
button_init();
// Create UI
create_ui();
// Create counter update task
xTaskCreate(update_counter_display, "update_counter", 4096, NULL, 4, NULL);
// LVGL task handler in main loop
while (1) {
vTaskDelay(pdMS_TO_TICKS(10));
lv_task_handler();
}
}