So Jupp, da bin ich wieder.
Dein Display ist heute angekommen und ich konnte alles aufbauen.
Zunächst einmal habe ich den Treiber in menuconfig auf den PCD8544 abgeändert und weil dieser nach Datenblatt nicht der schnellste ist, die SPI-Busgeschwindigkeit auf "niedliche" 1 MHz runtergesetzt.
1.jpg (Größe: 20,13 KB / Downloads: 179)
Die Verkabelung ist jetzt beispielhaft, kann abweichen, sofern keine Ressourcenkonflikte mit anderen Bauteilen und/oder Daemonen (gpiod, ...) bestehen.
2.jpg (Größe: 12,07 KB / Downloads: 180)
Im displayd_code noch die Auflösung gesetzt
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 84;
disp_drv.ver_res = 48;
disp_drv.flush_cb = disp_driver_flush;
kompiliert, geflashed und .... bam. Genau das gleiche Bild wie bei Dir!
Ich bin dann nochmal die Verkabelung durchgegangen, sollte man immer 2x / 3x prüfen - war aber alles in Ordnung.
Dann bin ich nochmal in den Initialisierungscode gegangen und dann kam mir etwas seltsam vor:
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
/* Actual size in pixels, not bytes. */
size_in_px *= 8;
#endif
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 84;
disp_drv.ver_res = 48;
disp_drv.flush_cb = disp_driver_flush;
Hier fehlt doch was -> nämlich dein PCD8544 Treiber, der doch genau auch diesen Codeteil benötigt. Das haben die in der LVGL-Beispielschablone für die Initialisierung, die man für eigenen Anwendungen kopieren soll wohl vergessen. Nun gut, füge ich es manuell hinzu:
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
/* Actual size in pixels, not bytes. */
size_in_px *= 8;
#endif
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 84;
disp_drv.ver_res = 48;
Kompilieren, flashen und bitte:
3.jpg (Größe: 17,9 KB / Downloads: 180)
Gut dieser displayd_code zeigt schon eine "zurechtgerückte" Ausgabe der Elemente, weil dein Display dann doch nochmal viel geringer auflöst, als das SSD1306 welches ich gestern als Beispiel gezeigt habe:
Den gesamten displayd_lvgl.c hast Du hier:
Code:
#include "displayd_lvgl.h"
#include "globals.h"
#include "messages.h"
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
static const char *TAG = "DISPLAYD_LVGL";
int old_ch = -1;
void lvgl_tick(void *pvParameters) {
while(1)
{
lv_task_handler();
lv_tick_inc(LV_TICK_PERIOD_MS);
vTaskDelay(LV_TICK_PERIOD_MS/portTICK_PERIOD_MS );
}
}
void displayd_lvgl(void *pvParameters) {
// Messagequeues
struct ADisplaydMessage *rxMsg; // -> vom Playerprozess
struct AMessage *txMsg; // -> zum Playerprozess
static uint32_t size_in_px = DISP_BUF_SIZE;
/////////////////////////////////// lib & driver init //////////////////////////////////////////
lv_init();
lvgl_driver_init();
lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);
/* Use double buffered when not working with monochrome displays */
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf2 != NULL);
#else
static lv_color_t *buf2 = NULL;
#endif
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
/* Actual size in pixels, not bytes. */
size_in_px *= 8;
#endif
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 84;
disp_drv.ver_res = 48;
disp_drv.flush_cb = disp_driver_flush;
/* When using a monochrome display we need to register the callbacks:
* - rounder_cb
* - set_px_cb */
#ifdef CONFIG_LV_TFT_DISPLAY_MONOCHROME
disp_drv.rounder_cb = disp_driver_rounder;
disp_drv.set_px_cb = disp_driver_set_px;
#endif
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);
/* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touch_driver_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif
/////////////////////////////////// END: lib & driver init //////////////////////////////////////////
/* Get the current screen */
lv_obj_t * scr = lv_disp_get_scr_act(NULL);
/*Create a widgets on the currently active screen*/
lv_obj_t * label_prog = lv_label_create(scr);
lv_obj_align(label_prog, LV_ALIGN_CENTER, -5, -10);
lv_label_set_text(label_prog,"P");
lv_obj_t * label_prog_num = lv_label_create(scr);
lv_obj_align(label_prog_num, LV_ALIGN_CENTER, 5, -10);
lv_obj_t * label_url = lv_label_create(scr);
lv_label_set_long_mode(label_url, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_width(label_url,250);
lv_obj_align(label_url, LV_ALIGN_LEFT_MID, 0, 5);
char buffer[10];
TaskHandle_t xlvglTickHandle = NULL;
xTaskCreate( lvgl_tick, "lvgl_tick", 4096, NULL , tskIDLE_PRIORITY, &xlvglTickHandle );
configASSERT(xlvglTickHandle);
// Daemonbetrieb
while(1)
{
xMessage.ucMessage = GET_CHANNEL_INFO;
txMsg = &xMessage;
xQueueSend( xPlayerQueue, ( void * ) &txMsg, ( TickType_t ) 0 );
if( xQueueReceive( xDisplaydQueue, &( rxMsg ), ( TickType_t ) 10 ) )
{
if (rxMsg->ucMessage==GET_CHANNEL_INFO) {
ESP_LOGI(TAG, "actual channel num: %i",rxMsg->iChannelNum);
if (old_ch!=rxMsg->iChannelNum) {
itoa(rxMsg->iChannelNum,buffer,10);
lv_label_set_text(label_prog_num, buffer);
lv_label_set_text(label_url, rxMsg->ucURI);
} // if (old_ch!=rxMsg->iChannelNum) {
old_ch = rxMsg->iChannelNum;
}
}
ESP_LOGI(TAG, "Heartbeat");
vTaskDelay(1000/portTICK_PERIOD_MS );
}
if (xlvglTickHandle)
vTaskDelete(xlvglTickHandle);
vTaskDelete(NULL);
}
Das kannst Du dann noch so hinrücken wie Du es haben willst. Du kannst auch zusätzliche Grafikprimitiven (Linien, Kästen, ...) zeichnen. Die Widgets findest Du hier in der Doku:
https://docs.lvgl.io/master/widgets/core/index.html
Wenn Du andere Schriften/Schriftgrößen nutzen willst, denke daran, diese erst in menuconfig zu aktivieren!
Gruß
Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung.
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")