Prototype på ESP32-skjerm som tastatur
ESP32 Cheap Yellow Display Board (ESP32-2432S028R)

ESP32-2432S028R, bedre kjent som Cheap Yellow Display (CYD), er en liten berøringsskjerm med ESP32-brikke. Jeg har laget meg en liten prototype til bruk for snarveier i Microsoft Teams.
Kort forklart så har jeg laget 3 knapper på skjermen. Ved trykk så mimiker den tastetrykk på et tastatur. De 3 knappene utfører med andre ord hver sin hurtigtast for å sku av/på mikrofon, av/på kamera eller avslutte samtalen.
Ikke en veldig nyttig, men artig å prøve seg frem for å se om jeg fikk det til (det gjorde jeg).
Det er bare å google så ser man at det er mange som har laget langt mer avanserte og fancy ting enn hva jeg har gjort. Men så er det jo slik da at jeg har noen ganger har et driv til å utfordre meg selv og se om jeg klarer å lage noe jeg har i tankene.
Litt om CYD
Den har en ESP32-mikrokontroller og en 2,8-tommers TFT-berøringsskjerm. Den er populær for å bygge grafiske brukergrensesnitt for IoT-prosjekter.
- Basert på ESP32-D0WDQ6-brikken, og tilbyr en tokjerners CPU med en klokkefrekvens på opptil 240 MHz.
- Oppløsning på 240 x 320 piksler med en resistiv berøringsskjerm.
- Støtter forskjellige grensesnitt som UART, SPI, I2C, PWM, ADC og DAC.
- Inkluderer et TF-kortgrensesnitt (microSD) for ekstern lagring.
- Kan programmeres ved hjelp av Arduino IDE, MicroPython eller ESP-IDF (Espressif IoT Development Framework).
- Integrerte Wi-Fi- og Bluetooth-muligheter for tilkobling til nettverk og andre enheter.
- Inkluderer en bakgrunnsbelysningskontrollkrets, et temperatur- og fuktighetssensorgrensesnitt og en RGB-LED.
Så med andre ord, et allsidig lite kort for oss som liker å fikle med elektronikk og sensorer.
Bilder



Ulempen
Det finnes noen ulike varianter av kortet. Mitt kort er av den eldre typen og noe jeg fant igjen innerst i skuffen. Dvs. den har en eldre versjon av ESP32 som ikke har USB OTG (USB-host/device) maskinvare. Med andre ord jeg kan ikke programmere den som en USB-enhet slik at den blir gjenkjent som f.eks. et tastatur når den kobles til en datamaskin. Men den har bluetooth, og kan derfor programeres til å bli gjenkjent som et bluetoothtastatur.
Hus
På MakerWorld (og sikker andre steder) finner man mange ulike skisser for å 3D-printe hus til skjermen. Jeg valgte meg dette som er litt skråstilt og kan stå på skrivebordet.

Kode
Man trenger 3 ulike biblioteker.
#include <LVGL_CYD.h> // VIKTIG: Bruker hjelpebiblioteket!
#include <BleKeyboard.h>
// --- Konfigurasjon ---
#define SCREEN_ORIENTATION USB_RIGHT // Eller USB_LEFT, avhengig av hvordan du holder den
// BLE-tastatur innstillinger
const char* BLE_DEVICE_NAME = "Helges Teams Kontroller";
const char* BLE_MANUFACTURER = "Espressif";
const uint8_t BLE_BATTERY_LEVEL = 100;
BleKeyboard bleKeyboard(BLE_DEVICE_NAME, BLE_MANUFACTURER, BLE_BATTERY_LEVEL);
// Globale pekere til UI-elementer for å kunne manipulere dem
lv_obj_t * current_screen = nullptr; // Holder styr på den aktive skjermen
bool ble_connected_state = false; // For å holde styr på den nåværende BLE-tilkoblingsstatusen
// --- Applikasjonslogikk ---
void sendTeamsShortcut(char shortcutKey) {
if (bleKeyboard.isConnected()) {
Serial.printf("Sender snarvei: GUI+SHIFT+%c\n", shortcutKey);
bleKeyboard.press(KEY_LEFT_GUI);
bleKeyboard.press(KEY_LEFT_SHIFT);
bleKeyboard.press(shortcutKey);
delay(100);
bleKeyboard.releaseAll();
} else {
Serial.println("BLE ikke tilkoblet.");
}
}
// Event handler - denne funksjonen kalles når en knapp blir trykket
static void button_event_handler(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e);
char shortcutKey = (char)(intptr_t)lv_event_get_user_data(e);
if(code == LV_EVENT_CLICKED) {
LV_LOG_USER("Knapp trykket, sender: %c", shortcutKey);
sendTeamsShortcut(shortcutKey);
}
}
// Funksjon for å lage en knapp
void create_button(lv_obj_t *parent, const char *text, char shortcutKey, lv_style_t *style) {
lv_obj_t * btn = lv_btn_create(parent);
lv_obj_add_style(btn, style, 0);
lv_obj_set_size(btn, 130, 70);
lv_obj_add_event_cb(btn, button_event_handler, LV_EVENT_CLICKED, (void*)(intptr_t)shortcutKey);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, text);
lv_obj_center(label);
}
// --- UI-funksjoner for forskjellige stater ---
static lv_style_t style_btn_green, style_btn_red, style_btn_blue;
static bool styles_initialized = false;
void init_styles() {
if (!styles_initialized) {
lv_style_init(&style_btn_green);
lv_style_set_bg_color(&style_btn_green, lv_color_hex(0x477A1D));
lv_style_set_border_color(&style_btn_green, lv_color_hex(0xFFFFFF));
lv_style_set_border_width(&style_btn_green, 2);
lv_style_set_radius(&style_btn_green, 8);
lv_style_set_text_color(&style_btn_green, lv_color_hex(0xFFFFFF));
lv_style_init(&style_btn_red);
lv_style_set_bg_color(&style_btn_red, lv_color_hex(0xD13438));
lv_style_set_border_color(&style_btn_red, lv_color_hex(0xFFFFFF));
lv_style_set_border_width(&style_btn_red, 2);
lv_style_set_radius(&style_btn_red, 8);
lv_style_set_text_color(&style_btn_red, lv_color_hex(0xFFFFFF));
lv_style_init(&style_btn_blue);
lv_style_set_bg_color(&style_btn_blue, lv_color_hex(0x0072BC));
lv_style_set_border_color(&style_btn_blue, lv_color_hex(0xFFFFFF));
lv_style_set_border_width(&style_btn_blue, 2);
lv_style_set_radius(&style_btn_blue, 8);
lv_style_set_text_color(&style_btn_blue, lv_color_hex(0xFFFFFF));
styles_initialized = true;
}
}
void setup_waiting_screen() {
if (current_screen != nullptr) {
lv_obj_del(current_screen);
}
current_screen = lv_obj_create(NULL);
lv_screen_load(current_screen);
lv_obj_set_style_bg_color(current_screen, lv_color_hex(0x000000), LV_PART_MAIN);
lv_obj_set_style_bg_opa(current_screen, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_t * label = lv_label_create(current_screen);
lv_label_set_text(label, "Venter på Bluetooth-tilkobling...");
lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), 0);
lv_obj_set_style_text_font(label, &lv_font_montserrat_18, 0);
lv_obj_center(label);
Serial.println("Viser venteskjerm.");
}
void setup_connected_ui() {
init_styles();
if (current_screen != nullptr) {
lv_obj_del(current_screen);
}
current_screen = lv_obj_create(NULL);
lv_screen_load(current_screen);
lv_obj_set_style_bg_color(current_screen, lv_color_hex(0x000000), LV_PART_MAIN);
lv_obj_set_style_bg_opa(current_screen, LV_OPA_COVER, LV_PART_MAIN);
// --- Tittel ---
lv_obj_t * title_label = lv_label_create(current_screen);
lv_label_set_text(title_label, "Teams Snarveier");
lv_obj_set_style_text_color(title_label, lv_color_hex(0x477A1D), 0);
lv_obj_set_style_text_font(title_label, &lv_font_montserrat_18, 0);
lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 10);
// --- Knapp-kontainer med Flexbox Layout ---
lv_obj_t * btn_container = lv_obj_create(current_screen);
lv_obj_set_size(btn_container, LV_PCT(100), LV_PCT(100));
lv_obj_center(btn_container);
lv_obj_set_style_bg_opa(btn_container, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btn_container, 0, 0);
// Sett layout til Flexbox
lv_obj_set_layout(btn_container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(btn_container, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_flex_align(btn_container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_row(btn_container, 15, 0);
lv_obj_set_style_pad_column(btn_container, 15, 0);
// --- Lag knappene ---
create_button(btn_container, "Mikrofon", 'm', &style_btn_green);
create_button(btn_container, "Kamera", 'o', &style_btn_green);
create_button(btn_container, "Chat", 'c', &style_btn_blue);
create_button(btn_container, "Avslutt", 'h', &style_btn_red);
Serial.println("Viser tilkoblet UI.");
}
// --- SETUP OG LOOP ---
void setup() {
Serial.begin(115200);
LVGL_CYD::begin(SCREEN_ORIENTATION);
// Sett opp initial venteskjerm
setup_waiting_screen();
ble_connected_state = false; // Sørg for at initial state er "ikke tilkoblet"
bleKeyboard.begin();
Serial.println("BLE Keyboard startet. Venter på tilkobling...");
}
void loop() {
// Sjekk BLE-tilkoblingsstatus i loop()
bool current_ble_status = bleKeyboard.isConnected();
// Hvis statusen har endret seg, oppdater UI
if (current_ble_status != ble_connected_state) {
ble_connected_state = current_ble_status; // Oppdater lagret tilstand
if (ble_connected_state) {
Serial.println("Bluetooth TILKOBLET!");
setup_connected_ui(); // Vis knappene når tilkoblet
} else {
Serial.println("Bluetooth FRAKOBLET!");
setup_waiting_screen(); // Gå tilbake til venteskjermen når frakoblet
}
}
lv_task_handler();
}

Nyttige kilder
Tenker du at dette virker spennende eller utgangspunkt for et eget prisjekt så kan jeg anbefale noen kilder.
https://randomnerdtutorials.com/cheap-yellow-display-esp32-2432s028r/
https://docs.arduino.cc/language-reference/en/functions/usb/Keyboard/