#include #include #include #include #include #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 #define FONT_SIZE 2 #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8)) uint32_t draw_buf[DRAW_BUF_SIZE / 4]; const int ONBOARD_LED_PIN = 2; const int ANALOG_INPUT_PIN = 34; const int ANALOG_OUTPUT_PIN = 25; const int ENTER_BUTTON_PIN = 14; const int ENCODER_A_PIN = 12; const int ENCODER_B_PIN = 13; void handleToneGeneration(void *pvParameters); void handleInputControls(void *pvParameters); void handle_lvgl_logs(lv_log_level_t level, const char *buf); void handle_pad_inputs(void *pvParameters); void handle_update_display(void *pvParameters); void handle_update_values(lv_timer_t *timer); bool toneOn = false; int frequency = 220; // A4 String label_text; Versatile_RotaryEncoder *encoder; void handlePress(); void handleRelease(); void handleRotate(int8_t rotation); uint32_t get_time(); lv_obj_t *label; lv_timer_t *update_values_timer; void setup() { Serial.begin(115200); pinMode(ONBOARD_LED_PIN, OUTPUT); pinMode(ANALOG_INPUT_PIN, INPUT); pinMode(ANALOG_OUTPUT_PIN, OUTPUT); pinMode(ENTER_BUTTON_PIN, INPUT); pinMode(ENCODER_A_PIN, INPUT); pinMode(ENCODER_B_PIN, INPUT); encoder = new Versatile_RotaryEncoder(ENCODER_A_PIN, ENCODER_B_PIN, ENTER_BUTTON_PIN); encoder->setHandlePress(handlePress); encoder->setHandlePressRelease(handleRelease); encoder->setHandleRotate(handleRotate); xTaskCreate(handleToneGeneration, "handleToneGeneration", 2048, NULL, 1, NULL); xTaskCreate(handleInputControls, "handleInputContols", 2048, NULL, 1, NULL); xTaskCreate(handle_pad_inputs, "handle_pad_inputs", 2048, NULL, 1, NULL); lv_init(); lv_log_register_print_cb(handle_lvgl_logs); lv_tick_set_cb(get_time); update_values_timer = lv_timer_create(handle_update_values, 5, NULL); lv_timer_ready(update_values_timer); lv_display_t *display; display = lv_tft_espi_create(SCREEN_HEIGHT, SCREEN_WIDTH, draw_buf, sizeof(draw_buf)); lv_display_set_rotation(display, LV_DISPLAY_ROTATION_90); label = lv_label_create(lv_screen_active()); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); Serial.println("setup complete"); label_text = "Boot complete."; } void handle_lvgl_logs(lv_log_level_t level, const char *buf) { Serial.printf("LVGL: %s\r\n", buf); } uint32_t get_time() { return esp_timer_get_time() / 1000; } void loop() { lv_timer_handler(); delay(5); } void handle_pad_inputs(void *pvParameters) { while (true) { int max = 0; for (int i = 0; i < 100; i++) { int value = analogRead(ANALOG_INPUT_PIN); if (!toneOn && value > 0) { toneOn = true; } if (value > max) { max = value; } delay(1); } } } void handleToneGeneration(void *pvParameters) { int toneDuration = 100; while (true) { if (toneOn) { // tone(ANALOG_OUTPUT_PIN, frequency, toneDuration); delay(toneDuration); toneOn = false; } delay(10); } } void handleInputControls(void *pvParameters) { while (true) { encoder->ReadEncoder(); delay(1); } } void handlePress() { Serial.println("Encoder pressed"); digitalWrite(ONBOARD_LED_PIN, HIGH); label_text = "Button pressed."; } void handleRelease() { Serial.println("Encoder released"); digitalWrite(ONBOARD_LED_PIN, LOW); } void handleRotate(int8_t rotation) { Serial.print("Encoder rotated by "); Serial.println(rotation); if (rotation > 0) { frequency += 10; } else if (rotation < 0) { frequency -= 10; } Serial.print("Frequency: "); Serial.println(frequency); label_text = "Frequency: " + String(frequency) + "Hz"; } void handle_update_display(void *pvParameters) { while (true) { if (lv_label_get_text(label) != label_text.c_str()) { lv_label_set_text(label, label_text.c_str()); } delay(100); } } void handle_update_values(lv_timer_t *timer) { if (label != NULL && lv_label_get_text(label) != label_text.c_str()) { lv_label_set_text(label, label_text.c_str()); } }