lovyan03 / lovyangfx Goto Github PK
View Code? Open in Web Editor NEWSPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
License: Other
SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
License: Other
Hi,
I've just started with ESP32 and using M5StickC to make some games.
I'm using your library, which seems great although I have a hard time finding out how to use it (eg. no idea how to generate bitmap/jpg/png hex arrays to be read by sprite.generateFromBitmap or similar, as that's not shown in the examples).
So I've made my custom pixel loader, with input generated in java and including a palette array and an array of indices, and I'd like to know how to set a color to act as a no draw pixel (to act as alpha, showing the pixel below the sprite).
Anyway, how can I achieve this simple alpha color feature... whether using existing bitmap loading (doc?) or compatible with my custom pixel loading?
I use sprite.drawPixel(x, y, lcd.color888(r,g,b)), where I set r, g, b from my custom image loader... maybe there's something like drawPixel(x, y, lcd.ALPHA)?
I understand maybe this is not possible, if data is sent in bulk to the display (really no idea how all this gfx stuff works internally, but saw some DMA reference that hints at that).
In that case, I guess my only option is to draw all relevant pixels directly to the lcd (ie. without sprites), skipping the alpha ones, which is going to be rather slow.
any other link to documentation, api reference would be great :)
Cheers
I found that drawJpgFile can't display image if I set datum except top_left.
lcd.drawJpgFile(SD, "/hoge.jpg", 0, 0,0, 0, 0, 0, 1.0, 1.0,top_left); //Work
lcd.drawJpgFile(SD, "/hoge.jpg", 0, 0,0, 0, 0, 0, 1.0, 1.0,top_center); //Can't display
Unitil the commit 48bee0d, both works well but from the next(a6bfce4), it doesn't.
It also doesn't work on M5GFX.
Thank you in advance for your help.
I flashed the LovyanGFX_Clock firmware on an M5Stack Core2 with M2Burner. Now the Core2 is not switching on again. Tried the reset and power buttons.
Any idea what happened? Did I corrupt the boot flash? How can I recover the device?
Any idea welcome.
Thanks, Ondrej
Hi there...
I'd like to help creating a truly english version of the documentation, and possibly create spiffy documentation on Read The Docs by creating a documentation source directory. Is there interest for that?
Hello, I've been trying to setup a dual display setup, sadly it still doesn't work,
you can find the full code here: https://pastebin.com/vXLQESUd
my issue is that when I use this code, I can see both screen trigger during setup but the loop doesn't move forward, it just stay stuck and doesn't start the loop, could you tell me what I'm doing wrong.
Thanks
I've define both panels like this:
struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_miso = -1;
static constexpr int spi_dlen = 8;
};
//static LGFX lcd;
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::LGFX_SPI<LGFX_Config> lcdB;
static lgfx::Panel_ST7789 panel;
static lgfx::Panel_ST7789 panelB;
static TCPReceiver recv;
static TCPReceiver recvB;`
then in setup I did this:
`//SETTING LEFT PANEL
panel.freq_write = 40000000;
panel.freq_fill = 40000000;
panel.freq_read = 6000000;
panel.spi_mode = 3;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = false;
panel.spi_cs = 5;
panel.spi_dc = 2;
panel.gpio_rst = 4;
panel.gpio_bl = 32;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = true;
//SETTING RIGHT PANEL
panelB.freq_write = 40000000;
panelB.freq_fill = 40000000;
panelB.freq_read = 6000000;
panelB.spi_mode = 3;
panelB.spi_mode_read = 0;
panelB.len_dummy_read_pixel = 8;
panelB.spi_read = true;
panelB.spi_3wire = false;
panelB.spi_cs = 17;
panelB.spi_dc = 2;
panelB.gpio_rst = 4;
panelB.gpio_bl = 32;
panelB.pwm_ch_bl = 7;
panelB.backlight_level = true;
panelB.invert = true;
// panel.rgb_order = false;
lcd.setPanel(&panel);
lcdB.setPanel(&panelB); //STARTING RIGHT PANEL
素晴らしいライブラリを使わせて頂き、ありがとうございます。
M5Paperで以下のコードの#define ERROR_DISPLAY
を有効すると
2行表示していた文字と図が1行目の領域に潰れて表示されます。
この問題は、これらを最後にまとめて実行する事で回避できます。
改善できそうでしょうか?
#include <M5EPD.h>
#define LGFX_M5PAPER
#include <LovyanGFX.hpp>
static LGFX gfx;
// --------------------------------
// これを有効にすると不具合が再現します
// --------------------------------
//#define ERROR_DISPLAY
void setup() {
int x = 10;
int y = 50;
int y_offset = 120;
M5.begin(true, true, true, true);
gfx.init();
gfx.setFont(&fonts::lgfxJapanGothic_32);
#ifdef ERROR_DISPLAY
//ここだと表示が潰れる
gfx.drawFastVLine(70, 0, gfx.height());
#endif
gfx.setCursor(x, y);
gfx.println("0.1");
gfx.fillArc( 270, y + 8, 54, 32, 270 + 20, 270 - 20, TFT_BLACK);
#ifdef ERROR_DISPLAY
//ここだと表示が潰れる
gfx.drawFastHLine( 0, 124, gfx.width() );
#endif
y = y + y_offset;
gfx.setCursor(x, y);
gfx.println("0.2");
gfx.fillArc( 270, y + 22, 42, 28, 90 + 20, 90 - 20, TFT_BLACK);
#ifndef ERROR_DISPLAY
//ここだと正常に表示できる
gfx.drawFastVLine(70, 0, gfx.height());
gfx.drawFastHLine( 0, 124, gfx.width() );
#endif
}
void loop() {}
I created Core2ez, a widget-based toolkit for the Core2. It's still very fresh, and it'll need more work. Given that M5Stack is going for your display driver, it might be good if I tell you something about what I have done. I think some of the things that I have implemented would be possibly be cleaner and useful for more people if they migrated to your driver. Also I'd just like to hear what you think...
I have a class called ezDisplayZone
, which inherits from ezZone
, which just defines a rectangle and you can ask it whether a given ezPoint
is inside of it, etc etc. ezDisplayZone
then lets you create a hierarchy of zones that are either directly on the screen, or inside a parent ezDisplayZone
. ezDisplayZone
then implements the methods of the display, so drawRoundRect
is implemented. If you do not set it to buffer in a sprite, all it does is send it to its parent, after subtracting its own position within that parent from the coordinates.
When you set it to buffer, it will draw whatever comes 'from below' and will similarly 'pass up' when pushed, until it meets another sprite-buffered ezDisplayZone
or the display itself. I implemented this as a shim, but it works remarkable well: an entire widget toolkit runs on it.
Could I maybe interest you to have this as part of the display driver instead. A sort of sprite that is pass-through when not active, that stores and corrects for its position in the parent sprite or screen?
I'd be happy to discuss further...
参考までにLGFX_Config_AutoDetectESP32.hpp:558の行末コメントを解除することで認識しました
Hi lovyan03,
First of all, I would like to thank you for your high quality work and the services offered by your LovyanGFX library.
Thank you so much for making it available to all of us.
However, since your last update v0.2.3, I can no longer compile my project when I specify a transparency color with the pushImage
function :
// it doesn't compile anymore when :
// - TRANS_COLOR is defined as a single variable
// - TRANS_COLOR is defined as a global constant
// - TRANS_COLOR is defined as a static constant within a class
sprite.pushImage(x, y, w, h, data, TRANS_COLOR);
While it compiled perfectly with version 0.2.2.
Here's the error I get :
.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp: In instantiation of 'void lgfx::LGFXBase::pushImage(int32_t, int32_t, int32_t, int32_t, const T*, const U&) [with T = lgfx::rgb565_t; U = short unsigned int; int32_t = int]':
.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp:265:9: required from 'void lgfx::LGFXBase::pushImage(int32_t, int32_t, int32_t, int32_t, const uint16_t*, const U&) [with U = short unsigned int; int32_t = int; uint16_t = short unsigned int]'
src/Player.cpp:14:91: required from here
.pio/libdeps/m5/LovyanGFX/src/lgfx/LGFXBase.hpp:246:90: error: invalid use of non-static member function
pixelcopy_t p(data, _write_conv.depth, get_depth<T>::value, hasPalette, nullptr, tr);
Am I misusing the new version of pushImage()
?
Request for TFT SPI 5.0inch (RA8875) SPI4pin too.
https://www.buydisplay.com/5-inch-tft-lcd-display-capacitive-touchscreen-ra8875-controller-800x480
Thank you very much.
Hi,
thanks for this wonderful library!
I am using an M5Stack module with a fairly low backlight setting of 8. I am using deep_sleep and some ULP code to keep the backlight on during sleep.. Whenever the device comes out of deepsleep, I use init_without_reset() which is great to avoid the screen from going blank. However, the screen is initialized with a backlight setting higher than mine which causes the screen to flicker for a split second.
I think I have traced down and avoided the problem. However, my C is not very good. Maybe you can use the code below to trace down the issue and develop a proper fix.
There seem to be two problems:
lcd.setBacklight()
can only be called after initPanelCommon.init()
calls initPWM()
without the optional duty parameter and therefore duty=128I "fixed" 1) with repeating the init code in my own class and setting the panel backlight value after autodetect()
:
void WeatherDisplay::init_without_reset(std::uint8_t brightness) {
int retry = 3;
while (!mylcd.autodetect(false) && --retry);
mylcd.getPanel()->brightness = brightness;
//taken from private function mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::init_impl(false);
mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initBus();
mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initPanel(false);
mylcd.lgfx::LGFX_SPI<lgfx::LGFX_Config>::initTouch();
// mylcd.init_without_reset();
}
I "fixed" 2) by adding the parameter in PanelCommon.hpp
:
virtual void init(bool use_reset)
{
...
initPWM(gpio_bl, pwm_ch_bl, pwm_freq, backlight_level ? brightness : (255 - brightness));
...
}
Following compilation errors occur when using the latest framework-arduinoespressif32 (idf-release/v4.2 branch) and PlatformIO.
I'll create a PR to fix this issue.
Error 1
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp: In function 'void lgfx::spi::init(int, int, int, int, int)':
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: error: 'DPORT_SPI_DMA_CHAN_SEL_REG' was not declared in this scope
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: note: suggested alternative: 'SOC_SPI_DMA_CHAN_NUM'
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~~~~
SOC_SPI_DMA_CHAN_NUM
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: error: 'DPORT_SET_PERI_REG_BITS' was not declared in this scope
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: note: suggested alternative: 'SET_PERI_REG_BITS'
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~
SET_PERI_REG_BITS
Error2
In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/LovyanGFX.hpp:65,
from src\main.cpp:2:
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp: In function 'void lgfx::spi_dma_transfer_active(int)':
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: error: 'spicommon_dmaworkaround_transfer_active' was not declared in this scope
spicommon_dmaworkaround_transfer_active(dmachan);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: note: suggested alternative: 'spi_dma_transfer_active'
spicommon_dmaworkaround_transfer_active(dmachan);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
spi_dma_transfer_active
*** [.pio\build\m5paper-test\src\main.cpp.o] Error 1
platformio.ini
[platformio]
packages_dir = .pio/packages
[env:m5paper-test]
platform = espressif32
board = m5stack-fire
framework = arduino
platform_packages =
toolchain-xtensa32 @ https://bintray.com/platformio/tool-packages/download_file?file_path=53bcf98-toolchain-xtensa32-windows-2.80400.2020.tar.gz
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#idf-release/v4.2
build_flags =
-DESP32=1
-DARDUINO_ARCH_ESP32=1
lib_deps =
lovyan03/LovyanGFX
src/main.cpp
#define LGFX_AUTODETECT
#include <LovyanGFX.hpp>
void setup(void)
{
}
void loop(void)
{
}
pio run
PS C:\Users\estshorter\src\esp> pio run
Processing m5paper-test (platform: espressif32; board: m5stack-fire; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/m5stack-fire.html
PLATFORM: Espressif 32 (2.1.0) > M5Stack FIRE
HARDWARE: ESP32 240MHz, 6.25MB RAM, 16MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 0.0.0+sha.7d3f499
- tool-esptoolpy 1.30000.201119 (3.0.0)
- toolchain-xtensa32 2.80400.2020 (8.4.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 31 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <LovyanGFX> 0.3.5
| |-- <SPI> 1.0
| |-- <Wire> 1.0.1
Building in release mode
Compiling .pio\build\m5paper-test\lib64e\LovyanGFX\lgfx\platforms\esp32_common.cpp.o
Compiling .pio\build\m5paper-test\src\main.cpp.o
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp: In function 'void lgfx::spi::init(int, int, int, int, int)':
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: error: 'DPORT_SPI_DMA_CHAN_SEL_REG' was not declared in this scope
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:33: note: suggested alternative: 'SOC_SPI_DMA_CHAN_NUM'
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~~~~
SOC_SPI_DMA_CHAN_NUM
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: error: 'DPORT_SET_PERI_REG_BITS' was not declared in this scope
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\m5paper-test\LovyanGFX\src\lgfx\platforms\esp32_common.cpp:199:9: note: suggested alternative: 'SET_PERI_REG_BITS'
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_channel, (spi_host * 2));
^~~~~~~~~~~~~~~~~~~~~~~
SET_PERI_REG_BITS
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-matrix.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-misc.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-psram.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-rmt.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-sigmadelta.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-spi.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-time.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-timer.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-tinyusb.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-touch.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\esp32-hal-uart.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\libb64\cdecode.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\libb64\cencode.c.o
Compiling .pio\build\m5paper-test\FrameworkArduino\main.cpp.o
*** [.pio\build\m5paper-test\lib64e\LovyanGFX\lgfx\platforms\esp32_common.cpp.o] Error 1
In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/LovyanGFX.hpp:65,
from src\main.cpp:2:
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp: In function 'void lgfx::spi_dma_transfer_active(int)':
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: error: 'spicommon_dmaworkaround_transfer_active' was not declared in this scope
spicommon_dmaworkaround_transfer_active(dmachan);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.pio/libdeps/m5paper-test/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp:65:5: note: suggested alternative: 'spi_dma_transfer_active'
spicommon_dmaworkaround_transfer_active(dmachan);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
spi_dma_transfer_active
*** [.pio\build\m5paper-test\src\main.cpp.o] Error 1
=============================================================================================================== [FAILED] Took 5.28 seconds ===============================================================================================================
I am using Wemos D32 Pro + TFT3.5inch (ILI9488) . and connect line like the following image
When I test by 「 ClockSample」example, it 's fine for me by the following config.
struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_miso = 19;
static constexpr int spi_dlen = 8;
};
static lgfx::LGFX_SPI<LGFX_Config> lcd;
// Panelクラスのインスタンスを作成します。使用するパネルにあった記述をコメントアウトしてください。
//static lgfx::Panel_HX8357B panel;
//static lgfx::Panel_HX8357D panel;
//static lgfx::Panel_ILI9163 panel;
//static lgfx::Panel_ILI9341 panel;
//static lgfx::Panel_ILI9342 panel;
//static lgfx::Panel_ILI9486 panel;
static lgfx::Panel_ILI9488 panel;
//static lgfx::Panel_SSD1351 panel;
//static lgfx::Panel_ST7789 panel;
//static lgfx::Panel_ST7735S panel;
void panel_config(){
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 0;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = false;
panel.spi_cs = 14;
panel.spi_dc = 27;
panel.gpio_rst = 33;
panel.gpio_bl = 32;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = false;
panel.rgb_order = false;
panel.memory_width = 320;//320;
panel.memory_height = 480;//240;
panel.panel_width = 320;//320;
panel.panel_height = 480;//240;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 3;
panel.offset_rotation = 0;
}
// ....
void setup(){
Serial.begin(115200);
#if defined(ARDUINO_M5Stick_C)
axp.begin();
#endif
panel_config();
lcd.setPanel(&panel);
lcd.init();
//. ....
}
void loop(){
//.....
}
However when I use this config for 「 MovingIcons」or 「 MovingCircles」 example ,
it occurs some strange display like the following clip.
How to solve this example ?
Thank you very much.
とりあえず立てました
#define LGFX_USE_V1
was added to ESP32-Chimera-Core as instructed.
Tests scope:
Test Sketches: esp32-doomfire, USB Soft Host, esp32-sidview
'Font_Blah' was not declared in this scope
// ESP32-Chimera-Core/src/M5Display.h
static auto Font_Blah = fonts::Font_Blah;
static auto Font_Blah1 = fonts::Font_Blah1;
// ESP32-Chimera-Core/src/M5Display.cpp
/*
if ( lgfx::LGFX_Config::spi_host == HSPI_HOST ) {
Lcd.setSPIShared(false);
}
*/
Panel id 3ff0897c
(ST7735) is ignored when LGFX_LOLIN_D32_PRO
is used.
[W][LGFX_AutoDetect_ESP32.hpp:284] init_impl(): [Autodetect] load from NVS : board:0
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff7f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:09 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 3ff0897c <<<< detect ignored
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = ffffffff
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:70 = ffffff3f
[W][LGFX_AutoDetect_ESP32.hpp:252] _read_panel_id(): [Autodetect] read cmd:04 = 00000000
[W][LGFX_AutoDetect_ESP32.hpp:361] init_impl(): [Autodetect] save to NVS : board:0
[W][LGFX_Config_AutoDetectESP32.hpp:288] autodetect(): [Autodetect] load from NVS : board:0
[W][LGFX_Config_AutoDetectESP32.hpp:306] autodetect(): [Autodetect] panel id:ffffff7f
[W][LGFX_Config_AutoDetectESP32.hpp:363] autodetect(): [Autodetect] panel id:ffffff7f
[W][LGFX_Config_AutoDetectESP32.hpp:424] autodetect(): [Autodetect] panel id:ffffffff
[W][LGFX_Config_AutoDetectESP32.hpp:466] autodetect(): [Autodetect] panel id:3ff0897c <<<< detect success
[W][LGFX_Config_AutoDetectESP32.hpp:476] autodetect(): [Autodetect] LoLinD32Pro ST7735
[W][LGFX_Config_AutoDetectESP32.hpp:1216] autodetect(): [Autodetect] save to NVS : board:12
Extend gitTagVersion.h
as follows:
#define LGFX_VERSION_MAJOR 7
#define LGFX_VERSION_MINOR 8
#define LGFX_VERSION_PATCH 9
#define LOVYANGFX_VERSION F( LGFX_VERSION_MAJOR "." LGFX_VERSION_MINOR "." LGFX_VERSION_PATCH )
// #define LOVYANGFX_VERSION F("7.8.9")
So any library/sketch can extend compatibility from v0 to v1 by doing this:
#if defined( LGFX_VERSION_MAJOR ) && LGFX_VERSION_MAJOR >= 1
// newer driver version, assume `LGFX_USE_V1` is enabled
#else
// older driver version, use `lgfx::v0` syntax
#endif
I would like to try TFT parallel i2s mode.
Is there any ESP32 I2S + TFT wire-mapping
for trying LovyanGFX with parellel I2S mode ?
Thank you very much.
Hello
I recently bought this screen from Aliexpress: https://www.aliexpress.com/item/3-5-inch-8P-SPI-TFT-LCD-Color-Screen-Module-ILI9486-Drive-IC-320-480-RGB/32828284227.html
After wired it to my ESP32 board and changed some settings in the example sketch "2_spi_setting", the display does not work at all.
By studying the datasheet, I realized that the ILI9486L controller only support RGB111 and RGB666 mode when using SPI mode(Chapter 7.5.3, Page 45). So I changed the configuration "write_depth" from "rgb565_2Byte" to "rgb666_3Byte" in the "PanelCommon.hpp"(Line 39), and then, I upload the code, the display seems worked flawlessly.
But when I moved to the project "ScreenShotReceiver" with same configurations, the WiFi information displayed normally, but the image seems got twisted.
Here is my configuration codes, and did I miss anything important?
`struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_miso = 19;
static constexpr int spi_dlen = 8;
};
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ILI9486 panel;
void pannel_cfg()
{
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 3;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = false;
panel.spi_3wire = true;
panel.spi_cs = -1;
panel.spi_dc = 5;
panel.gpio_rst = 4;
panel.gpio_bl = 15;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = false;
panel.rgb_order = false;
panel.memory_width = 320;
panel.memory_height = 480;
panel.panel_width = 320;
panel.panel_height = 480;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 0;
panel.offset_rotation = 0;
lcd.setPanel(&panel);
}`
LovyanGFX 0.3.0/0.3.2 Arduino M5Stack Grey.
#include<M5Stack.h> を #include<LovyanGFX.h> の前に入れるか入れないかでの経路が 0.3.2 から変わったようです。
0.3.0 までは同経路の解釈をしていると思われます。
LGFX_Sprite.hpp の 150行目付近の createFromBmp付近の分岐に #pragma messageを仕込んだ結果は以下の通りです。
0.3.2以降は必ず #include<M5Stack.h> すべきでしょうか?
scratch.ino
#include <M5Stack.h>
#include <LovyanGFX.h>
test.cpp
#include <LovyanGFX.h>
Ver 0.3.0 .ino/.cpp 同経路
In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
from /Users/gob/tmp/sketch/test.cpp:1:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:35: note: #pragma message: FS_H/SEEED_FS
#pragma message("FS_H/SEEED_FS")
^
In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
from /Users/gob/projects/M5Stack/scratch/scratch.ino:7:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:32: note: #pragma message: FS_H/SEEED_FS
#pragma message("FS_H/SEEED_FS")
Ver 0.3.2 .ino/.cpp 違経路
In file included from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.hpp:43:0,
from /Users/gob/projects/M5Stack/libraries/LovyanGFX/src/LovyanGFX.h:5,
from /Users/gob/projects/M5Stack/scratch/scratch.ino:7:
/Users/gob/projects/M5Stack/libraries/LovyanGFX/src/lgfx/LGFX_Sprite.hpp:151:32: note: #pragma message: FS_H/SEEED_FS
#pragma message("FS_H/SEEED_FS")
I'm getting this warning when setting the compiler debug level to "All":
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:156:14: warning: 'ty' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (y) *y = ty;
^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:153:24: note: 'ty' was declared here
std::int32_t tx, ty;
^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:155:14: warning: 'tx' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (x) *x = tx;
^
~/Arduino/libraries/LovyanGFX/src/lgfx/platforms/../LGFX_Device.hpp:153:20: note: 'tx' was declared here
std::int32_t tx, ty;
^
Initializing with std::int32_t tx=0, ty=0
makes the warning go away, but there may be side effects.
Maybe std::int32_t tx=-1, ty=-1
would be better ?
template <typename T>
std::uint_fast8_t getTouch(T *x, T *y, std::uint_fast8_t number = 0)
{
// std::int32_t tx, ty; // warning: 'ty' and 'tx' may be used uninitialized in this function [-Wmaybe-uninitialized]
std::int32_t tx=0, ty=0; // no more warning
auto res = getTouch(&tx, &ty, number);
if (x) *x = tx;
if (y) *y = ty;
return res;
}
Hardware: LoLin D32Pro (with psram) + TFT-2.4 @320x240
sprite::createSprite()
crashes when used in combination with psram.
createSprite should return NULL when allocation failed
// width = 240, height = 320 (portrait mode)
TFT_eSprite *sprite = new TFT_eSprite( &tft );
// this triggers a guru mediation error
sprite->setPsram(true);
void * sptr = sprite->createSprite( tft.width(), tft.height() );
// this triggers a guru mediation error
sprite->setPsram(false);
void * sptr = sprite->createSprite( tft.width(), tft.height() );
// this triggers a guru mediation error
sprite->setPsram(true);
sprite->setColorDepth(8);
void * sptr = sprite->createSprite( tft.width(), tft.height() );
// this succeeds
sprite->setPsram(false);
sprite->setColorDepth(8);
void * sptr = sprite->createSprite( tft.width(), tft.height() );
Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x4008bf06 PS : 0x00060533 A0 : 0x8008ddf6 A1 : 0x3ffb1e50
A2 : 0xb3ff0706 A3 : 0x0000abab A4 : 0xb33fffff A5 : 0x00000001
A6 : 0x00060520 A7 : 0x0000cdcd A8 : 0x0000abab A9 : 0x3ffb1e20
A10 : 0x00004000 A11 : 0x00000000 A12 : 0x3ff65000 A13 : 0x3ff650c0
A14 : 0xd941d941 A15 : 0xd941d941 SAR : 0x00000012 EXCCAUSE: 0x0000001d
EXCVADDR: 0xb3ff0706 LBEG : 0x40088a24 LEND : 0x40088a40 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x4008bf06:0x3ffb1e50 0x4008ddf3:0x3ffb1e80 0x4008e42d:0x3ffb1ea0 0x40081e11:0x3ffb1ec0 0x400dac8f:0x3ffb1ee0 0x400d376a:0x3ffb1f00 0x400d3a4d:0x3ffb1f30 0x400e59a2:0x3ffb1fb0 0x4008b162:0x3ffb1fd0
Decoding 12 results
0x4008bf06: uxPortCompareSet at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
: (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h line 86
: (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.h line 98
: (inlined by) vTaskEnterCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4201
0x40088a24: memcpy at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/memcpy.S line 175
0x40088a40: memcpy at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/memcpy.S line 197
0x4008bf06: uxPortCompareSet at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
: (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h line 86
: (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.h line 98
: (inlined by) vTaskEnterCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4201
0x4008ddf3: multi_heap_internal_lock at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 380
0x4008e42d: multi_heap_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c line 321
0x40081e11: heap_caps_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 232
0x400dac8f: lgfx::v1::Panel_Sprite::createSprite(int, int, lgfx::v1::color_conv_t*, bool) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/misc/colortype.hpp line 84
: (inlined by) lgfx::v1::SpriteBuffer::reset(unsigned int, lgfx::v1::AllocationSource) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/misc/SpriteBuffer.hpp line 162
: (inlined by) lgfx::v1::Panel_Sprite::createSprite(int, int, lgfx::v1::color_conv_t*, bool) at /home/tobozo/Arduino/libraries/LovyanGFX/src/lgfx/v1/LGFX_Sprite.cpp line 98
0x400d376a: lgfx::v1::LGFX_Sprite::createSprite(int, int) at /home/tobozo/Arduino/libraries/ESP32-USB-Soft-Host/src/ESP32-USBSoftHost.hpp line 192
: (inlined by) setupUI() at /home/tobozo/Arduino/libraries/SID6581/examples/SidUSBSoftHost/C64_UI.h line 137
0x400d3a4d: setup() at /home/tobozo/Arduino/libraries/ESP32-USB-Soft-Host/src/ESP32-USBSoftHost.hpp line 192
0x400e59a2: loopTask(void*) at /home/tobozo/.arduino15/packages/esp32/hardware/esp32/1.0.6/cores/esp32/main.cpp line 18
0x4008b162: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 355 (discriminator 1)
Does it make sense to add something like this ?
https://github.com/tobozo/M5Stack-SD-Updater/blob/master/src/gitTagVersion.h
Hello @lovyan03,
Thanks for your last update... but since I switched to version 0.3.9, I have compilation problems with the <M5Stack.h>
and <M5StickCPlus.h>
libraries:
In file included from .pio/libdeps/stick/M5StickCPlus/src/M5Display.h:7:0,
from .pio/libdeps/stick/M5StickCPlus/src/M5StickCPlus.h:69,
from src/stick.cpp:2:
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:494:18: error: expected unqualified-id before numeric constant
#define TL_DATUM 0 // Top left (default)
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:168:34: note: in expansion of macro 'TL_DATUM'
static constexpr textdatum_t TL_DATUM = textdatum_t::top_left;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:495:18: error: expected unqualified-id before numeric constant
#define TC_DATUM 1 // Top centre
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:169:34: note: in expansion of macro 'TC_DATUM'
static constexpr textdatum_t TC_DATUM = textdatum_t::top_center;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:496:18: error: expected unqualified-id before numeric constant
#define TR_DATUM 2 // Top right
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:170:34: note: in expansion of macro 'TR_DATUM'
static constexpr textdatum_t TR_DATUM = textdatum_t::top_right;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:497:18: error: expected unqualified-id before numeric constant
#define ML_DATUM 3 // Middle left
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:171:34: note: in expansion of macro 'ML_DATUM'
static constexpr textdatum_t ML_DATUM = textdatum_t::middle_left;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:498:18: error: expected unqualified-id before numeric constant
#define CL_DATUM 3 // Centre left, same as above
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:172:34: note: in expansion of macro 'CL_DATUM'
static constexpr textdatum_t CL_DATUM = textdatum_t::middle_left;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:499:18: error: expected unqualified-id before numeric constant
#define MC_DATUM 4 // Middle centre
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:173:34: note: in expansion of macro 'MC_DATUM'
static constexpr textdatum_t MC_DATUM = textdatum_t::middle_center;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:500:18: error: expected unqualified-id before numeric constant
#define CC_DATUM 4 // Centre centre, same as above
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:174:34: note: in expansion of macro 'CC_DATUM'
static constexpr textdatum_t CC_DATUM = textdatum_t::middle_center;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:501:18: error: expected unqualified-id before numeric constant
#define MR_DATUM 5 // Middle right
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:175:34: note: in expansion of macro 'MR_DATUM'
static constexpr textdatum_t MR_DATUM = textdatum_t::middle_right;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:502:18: error: expected unqualified-id before numeric constant
#define CR_DATUM 5 // Centre right, same as above
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:176:34: note: in expansion of macro 'CR_DATUM'
static constexpr textdatum_t CR_DATUM = textdatum_t::middle_right;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:503:18: error: expected unqualified-id before numeric constant
#define BL_DATUM 6 // Bottom left
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:177:34: note: in expansion of macro 'BL_DATUM'
static constexpr textdatum_t BL_DATUM = textdatum_t::bottom_left;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:504:18: error: expected unqualified-id before numeric constant
#define BC_DATUM 7 // Bottom centre
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:178:34: note: in expansion of macro 'BC_DATUM'
static constexpr textdatum_t BC_DATUM = textdatum_t::bottom_center;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:505:18: error: expected unqualified-id before numeric constant
#define BR_DATUM 8 // Bottom right
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:179:34: note: in expansion of macro 'BR_DATUM'
static constexpr textdatum_t BR_DATUM = textdatum_t::bottom_right;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:506:21: error: expected unqualified-id before numeric constant
#define L_BASELINE 9 // Left character baseline (Line the 'A' character would sit on)
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:180:34: note: in expansion of macro 'L_BASELINE'
static constexpr textdatum_t L_BASELINE = textdatum_t::baseline_left;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:507:20: error: expected unqualified-id before numeric constant
#define C_BASELINE 10 // Centre character baseline
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:181:34: note: in expansion of macro 'C_BASELINE'
static constexpr textdatum_t C_BASELINE = textdatum_t::baseline_center;
^
.pio/libdeps/stick/M5StickCPlus/src/utility/In_eSPI.h:508:20: error: expected unqualified-id before numeric constant
#define R_BASELINE 11 // Right character baseline
^
.pio/libdeps/stick/LovyanGFX/src/lgfx/v0/lgfx_common.hpp:182:34: note: in expansion of macro 'R_BASELINE'
static constexpr textdatum_t R_BASELINE = textdatum_t::baseline_right;
^
Archiving .pio/build/stick/libFrameworkArduinoVariant.a
Indexing .pio/build/stick/libFrameworkArduinoVariant.a
Compiling .pio/build/stick/FrameworkArduino/Esp.cpp.o
*** [.pio/build/stick/src/stick.cpp.o] Error 1
Do you know why?
I don't have these problems with the previous version.
Thank you in advance,
Steph
I used Lolin D32 Pro + TFT3.5 Touch , it can calibrate well,
However when I changed the ESP32 board to DOIT Devkit V1.0 (30pins) + TFT3.5 Touch.
It can't calibrate. The result is the following clip.
https://streamable.com/iaebdt
[Code] ( Adapted from example 2_spi_setting
)
#include <LovyanGFX.hpp>
struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_miso = 19;
static constexpr int spi_dlen = 8;
};
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ILI9488 panel;
static lgfx::Touch_XPT2046 touch;
void panel_d32pro_config(){
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 0;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = false;
panel.spi_cs = 14;
panel.spi_dc = 27;
panel.gpio_rst = 33;
panel.gpio_bl = 32;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = false;
panel.rgb_order = false;
panel.memory_width = 320;//320;
panel.memory_height = 480;//240;
panel.panel_width = 320;//320;
panel.panel_height = 480;//240;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 3;
panel.offset_rotation = 0;
}
void panel_devkit_config(){
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 0;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = false;
panel.spi_cs = 15;
panel.gpio_rst = 2;
panel.spi_dc = 4;
panel.gpio_bl = 5;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.invert = false;
panel.rgb_order = false;
panel.memory_width = 320;//320;
panel.memory_height = 480;//240;
panel.panel_width = 320;//320;
panel.panel_height = 480;//240;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 3;
panel.offset_rotation = 0;
}
void touch_config(){
touch.spi_host = VSPI_HOST; // VSPI_HOST or HSPI_HOST
touch.spi_sclk = 18;
touch.spi_mosi = 23;
touch.spi_miso = 19;
touch.spi_cs = 27;
touch.freq = 1000000;
touch.bus_shared = true; // If the LCD and touch share SPI, set to true.
touch.x_min = 470; //0;
touch.x_max = 3740; //319;
touch.y_min = 3850;//0;
touch.y_max = 447; //319;
}
void setup(void)
{
Serial.begin(115200);
// panel_d32pro_config(); // D32Pro + TFT3.5 Touch
panel_devkit_config(); // DOIT Devkit V1.0 + TFT3.5 Touch
lcd.setPanel(&panel);
touch_config();
lcd.setTouch(&touch);
lcd.init();
if (lcd.width() > 240 || lcd.height() > 240) lcd.setTextSize(2);
if (lcd.touch())
{
if (lcd.width() < lcd.height()) lcd.setRotation(3 & (lcd.getRotation() + 1));
lcd.drawString("touch the arrow marker.", 0, lcd.height()>>1);
lcd.calibrateTouch(nullptr, 0xFFFFFFU, 0x000000U, 30);
lcd.clear();
}
}
uint32_t count = ~0;
void loop(void)
{
delay(10);
lcd.startWrite();
lcd.setRotation(++count & 7);
lcd.setColorDepth((count & 8) ? 16 : 24);
lcd.setTextColor(random(65536));
lcd.drawNumber(lcd.getRotation(), 16, 0);
lcd.setTextColor(0xFF0000U);
lcd.drawString("R", 30, 16);
lcd.setTextColor(0x00FF00U);
lcd.drawString("G", 40, 16);
lcd.setTextColor(0x0000FFU);
lcd.drawString("B", 50, 16);
lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));
lcd.endWrite();
int32_t x, y;
if (lcd.getTouch(&x, &y)) {
Serial.printf("x,y = %d, %d\n", x,y);
lcd.fillRect(x-2, y-2, 5, 5, random(65536));
}
}
How to fix the issue?
Thank you very much.
Hi @lovyan03,
Sorry to bother you, but I can't figure out what's going on?
I'm trying to run simple code on an M5StickC Plus, but the ESP32 reacts strangely.
If it helps, I work with Visual Studio Code and PlatformIO on macOS 10.14.6:
Here is the configuration file of my project :
; platformio.ini
[env:stick+]
platform = espressif32
board = m5stick-c
framework = arduino
lib_deps =
m5stack/M5StickCPlus @ ^0.0.1
lovyan03/LovyanGFX @ ^0.3.4
Here is the tree structure of my dummy
project:
dummy
├── platformio.ini
└── src
└── main.cpp
And here is my initial code:
// main.cpp
#include <M5StickCPlus.h>
#include <LovyanGFX.h>
LGFX lcd;
LGFX_Sprite fb(&lcd);
void setup() {
M5.begin(false, true, false);
lcd.init();
lcd.setColorDepth(16);
fb.createSprite(135, 240);
}
void loop() {
M5.update();
fb.clear(0xfe40);
fb.pushSprite(0, 0);
}
Well... so far so good, I'm getting an orange screen on my stick.
Now I want to deport the content of my loop()
in a GraphicsEngine
class :
dummy
├── lib
│ └── GraphicsEngine
│ └── GraphicsEngine.h
├── platformio.ini
└── src
└── main.cpp
So here is the new version of the code :
// main.cpp
#include <M5StickCPlus.h>
#include <LovyanGFX.h>
#include "GraphicsEngine.h"
LGFX lcd;
LGFX_Sprite fb(&lcd);
GraphicsEngine ge;
void setup() {
M5.begin(false, true, false);
lcd.init();
lcd.setColorDepth(16);
fb.createSprite(135, 240);
}
void loop() {
M5.update();
ge.draw(fb);
}
// lib/GraphicsEngine/GraphicsEngine.h
#pragma once
#include <LovyanGFX.h>
class GraphicsEngine {
public:
void draw(LGFX_Sprite &fb) {
fb.clear(0xfe40);
fb.pushSprite(0, 0);
}
};
Everything functions normally, as before.
Now I want to separate the declarative part from the implementation of the class:
dummy
├── lib
│ └── GraphicsEngine
│ ├── GraphicsEngine.cpp
│ └── GraphicsEngine.h
├── platformio.ini
└── src
└── main.cpp
And here's the new code (main.cpp
does not change):
// lib/GraphicsEngine/GraphicsEngine.h
#pragma once
#include <LovyanGFX.h>
class GraphicsEngine {
public:
void draw(LGFX_Sprite &fb);
};
// lib/GraphicsEngine/GraphicsEngine.cpp
#include "GraphicsEngine.h"
void GraphicsEngine::draw(LGFX_Sprite &fb) {
fb.clear(0xfe40);
fb.pushSprite(0, 0);
}
And that's when it all goes to hell!
Black screen... and the stick restarts continuously.
Here are the crash logs if it can help you:
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d7f6c PS : 0x00060330 A0 : 0x800d3db6 A1 : 0x3ffb1f00
A2 : 0x400d268c A3 : 0x3ffc01b8 A4 : 0x000d268c A5 : 0x0000268c
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb1ee0
A10 : 0x3ffc01b8 A11 : 0x00010000 A12 : 0x00000000 A13 : 0x0000ffff
A14 : 0x000000f0 A15 : 0x00000012 SAR : 0x00000007 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000078 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Backtrace: 0x400d7f6c:0x3ffb1f00 0x400d3db3:0x3ffb1f90 0x400dab8d:0x3ffb1fb0 0x40088c99:0x3ffb1fd0
Rebooting...
There's probably something I'm missing, but I don't see what!
I seem to remember that I didn't encounter this kind of problem some time ago, when I was using version 0.2.4 of LovyanGFX...
Has something happened in the meantime that makes this way of structuring my code not work anymore?
Hello, is there a way to easily flip the display, something like a mirror mode?
Thank you
Hello, I have created a "MultiSprite" concept, based on the examples of the library.
Basically, it manage the case where you don't have memory enough to store a sprite, and you have to split in "bands".
class MultiSprite
{
public:
MultiSprite()
{
}
void Init(LGFX* lcd, std::int_fast8_t div = 1)
{
_lcd = lcd;
lcd_width = _lcd->width();
lcd_height = _lcd->height();
for (;;) {
sprite_height = (lcd_height + div - 1) / div;
bool fail = false;
for (std::uint32_t i = 0; !fail && i < 2; ++i)
{
sprite[i].setColorDepth(lcd->getColorDepth());
fail = !sprite[i].createSprite(lcd_width, sprite_height);
}
if (!fail) break;
for (std::uint32_t i = 0; i < 2; ++i)
{
sprite[i].deleteSprite();
}
div *= 2;
}
_div = div;
}
LGFX* _lcd;
uint32_t _div;
uint16_t currentStrip = 0;
std::int_fast16_t lcd_width;
std::int_fast16_t lcd_height;
MultiSpriteStrip sprite[2];
int_fast16_t sprite_height;
void startWrite() {_lcd->startWrite();};
void endWrite() {_lcd->endWrite();};
void display() {_lcd->display();};
void Render(void (*render)(MultiSpriteStrip&, uint8_t))
{
currentStrip = 0;
for (std::int32_t y = 0; y < lcd_height; y += sprite_height)
{
auto index = currentStrip % 2;
sprite[index].lowerY = y;
sprite[index].upperY = y + sprite_height;
render(sprite[index], currentStrip);
std::uint32_t len = sprite_height * lcd_width;
if (y + sprite_height > lcd_height) {
len = (lcd_height - y) * lcd_width;
}
_lcd->pushPixelsDMA(sprite[index].getBuffer(), len);
currentStrip++;
}
}
};
No conversion between global (full screen) and local (sprite band) is required
This way, for example, the "moving circle" demo is as easy as
void draw(MultiSpriteStrip& sprite, uint8_t spriteNum)
{
sprite.clear();
for (std::uint32_t i = 0; i < obj_count; i++)
{
sprite.drawCircle(circles[i].x, circles[i].y, circles[i].r, circles[i].color);
}
if (spriteNum >= 3) drawFps(sprite);
}
void loop(void)
{
fpsCounter.Update(millis());
for (std::uint32_t i = 0; i != obj_count; i++)
{
circles[i].move();
}
multiSprite.Render(draw);
}
Please, let me know if you find it interesting, and if there is anything more that i can do for helping (share the code, fork, PR,...)
Thank you for you great work
Request for TFT SPI 4.0inch (ST7796) too
https://www.aliexpress.com/item/4000572980706.html
Thank you very much.
How about introducing CI using GitHub Actions to ensure successful build when new PRs are submitted? (though this doesn't help to detect runtime error...
Web pages below would be good examples.
PlatformIO document:
https://docs.platformio.org/en/latest/integration/ci/github-actions.html
Files in FastLED:
https://github.com/FastLED/FastLED/blob/master/ci/ci-compile
https://github.com/FastLED/FastLED/blob/master/.github/workflows/build.yml
I wish to use TTGO T-Display 1.3inch (ST7789 240x135) on LovyaGFX library.
If TTGO T-Display config by TFT-eSPI, it's configed by the following.
#define ST7789_DRIVER
#define TFT_WIDTH 135
#define TFT_HEIGHT 240
#define CGRAM_OFFSET // Library will add offsets required
//#define TFT_MISO -1
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 16
#define TFT_RST 23
#define TFT_BL 4 // Display backlight control pin
#define TFT_BACKLIGHT_ON HIGH // HIGH or LOW are options
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
//#define SPI_FREQUENCY 27000000
#define SPI_FREQUENCY 40000000 // Maximum for ILI9341
#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V
When I config on LovyanGFX by the following code , it occurs some error , how to fix it ?
Thank you.
#include <LovyanGFX.hpp>
struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_miso = 19;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = -1;
static constexpr int spi_dlen = 8;
};
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ST7789 panel;
void setup(void)
{
// panel.freq_write = 20000000;
panel.freq_fill = 40000000; //27000000;
panel.freq_read = 6000000;//16000000;
panel.spi_mode = 0;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = false;
panel.spi_cs = 5;
panel.spi_dc = 16;
panel.gpio_rst = 23;//-1;//33;
panel.gpio_bl = 4;//32;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.reverse_invert = false;
panel.rgb_order = false;
panel.memory_width = 240; //320;
panel.memory_height = 135; //240;
panel.panel_width = 240; //320;
panel.panel_height = 135; //240;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 0;
panel.offset_rotation = 0;
lcd.setPanel(&panel);
lcd.init();
}
uint32_t count = ~0;
void loop(void)
{
delay(10);
lcd.startWrite();
lcd.setRotation(++count & 7);
lcd.setColorDepth((count & 8) ? 16 : 24);
lcd.setTextColor(random(65536));
lcd.drawNumber(lcd.getRotation(), 16, 0);
lcd.setTextColor(0xFF0000U);
lcd.drawString("R", 30, 16);
lcd.setTextColor(0x00FF00U);
lcd.drawString("G", 40, 16);
lcd.setTextColor(0x0000FFU);
lcd.drawString("B", 50, 16);
lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));
lcd.endWrite();
int32_t x, y;
if (lcd.getTouch(&x, &y)) {
lcd.fillRect(x-2, y-2, 5, 5, random(65536));
}
}
Some error on serial monitor...
rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Hi So i just want to confirm how to do the pin config for the lib. I do have a ST7789 lcd and i see in you config : Lgfx-config-esp-Wrover-kit.hpp this :
static lgfx::Panel_ST7789 panel;
panel.spi_3wire = false;
panel.spi_cs = 22;
panel.spi_dc = 21;
panel.gpio_rst = 18;
panel.gpio_bl = 5;
panel.pwm_ch_bl = 7;
So is this the pin connected from the esp32 to the lcd ? As GPIO 22/21/18/5 .. but for 7 : is it Gpio 26 ? Fow the wrover esp32 normal 30pin version, not the 36pin.
And i think loading the tft-graphictest.ino will load the LovyanGFX.hpp and this call to the Lgfx-config...
And is there a way to force to lcd st7789 or it goes only with an autodetect ?
Thank again
I would like to change the brightness of an image before pushing it to the LCD.
What would be the best way of accomplishing this? It would be nice if the library would support a lambda style processing.
here my pseudo code:
auto brightness_up = [](uint8_t r, uint8_t g, uint8_t b) -> return {min(255, r + 10), min(255, g + 10), min(255, b + 10)}
sprite.pushSprite(lcd, brightness_up);
For now: What is the easiest way to implement such processing?
Hello Lovyan03,
I have two questions for you:
1: What is the display type you have found to be the fastest with your library?
2: I have gotten this Open Smart Watch to work with tft_eSpi and would love to make it run on yours. The display type is GC9A01 (pdf datasheet), do you think it will work?
Thanks, have a nice day
Hi,
I have tried to config for TFT1.3inch ST7789
by the following code
#include <LovyanGFX.hpp>
struct LGFX_Config
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_miso = -1; //19;
static constexpr int spi_sclk = 18;
static constexpr int spi_mosi = 23;
static constexpr int spi_dlen = 8;
};
static lgfx::LGFX_SPI<LGFX_Config> lcd;
static lgfx::Panel_ST7789 panel;
void setup(void)
{
panel.freq_write = 20000000;
panel.freq_fill = 27000000;
panel.freq_read = 16000000;
panel.spi_mode = 0;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = true;
panel.spi_3wire = true; //false;
panel.spi_cs = -1;
panel.spi_dc = 4;
panel.gpio_rst = 2;
panel.gpio_bl = 5;
panel.pwm_ch_bl = 7;
panel.backlight_level = true;
panel.reverse_invert = false;
panel.rgb_order = false;
panel.memory_width = 240;
panel.memory_height = 240;
panel.panel_width = 240;
panel.panel_height = 240;
panel.offset_x = 0;
panel.offset_y = 0;
panel.rotation = 0;
panel.offset_rotation = 0;
lcd.setPanel(&panel);
lcd.init();
}
uint32_t count = ~0;
void loop(void)
{
delay(10);
lcd.startWrite();
lcd.setRotation(++count & 7);
lcd.setColorDepth((count & 8) ? 16 : 24);
lcd.setTextColor(random(65536));
lcd.drawNumber(lcd.getRotation(), 16, 0);
lcd.setTextColor(0xFF0000U);
lcd.drawString("R", 30, 16);
lcd.setTextColor(0x00FF00U);
lcd.drawString("G", 40, 16);
lcd.setTextColor(0x0000FFU);
lcd.drawString("B", 50, 16);
lcd.drawRect(30,30,lcd.width()-60,lcd.height()-60,random(65536));
lcd.endWrite();
}
But by the code , it can't display anything.
When I tried on TFT_eSPI as the same pins-config.
#define ST7789_DRIVER
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define TFT_MISO -1 //19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS -1
#define TFT_DC 4
#define TFT_RST 2
#define TFT_BL 5
TFT can display.
How to solve the issue?
Thank you.
Those characters are not aligned correctly.
canvas.setTextFont( &fonts::FreeMonoBold18pt7b );
canvas.setTextDatum( textdatum_t::top_left );
canvas.drawChar( '0', 50, 2 );
canvas.setTextFont( &fonts::Font4 );
canvas.drawChar( '0', 70, 2 );
If I use the library on a TWatch 2020 I get no picture or other reaction from the screen.
It does work with the TTGO drivers, so the HW works.
I get this response on boot:
[W][LGFX_Config_AutoDetectESP32.hpp:288] autodetect(): [Autodetect] load from NVS : board:7
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400DA2A4 arg=3FFBDD74
[W][LGFX_Config_AutoDetectESP32.hpp:306] autodetect(): [Autodetect] panel id:00528585
[W][LGFX_Config_AutoDetectESP32.hpp:308] autodetect(): [Autodetect] TWatch
[E][esp32-hal-cpu.c:115] removeApbChangeCallback(): not found func=400DA2A4 arg=3FFBDD74
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400DA2A4 arg=3FFBDD74
Anybody else got this issue or am I the only one?
I am using two displays (part of the cheApR project) and i have chosen to save some GPIO pins for other use by wiring the displays in series, but with different CS pins. I tested the wiring by running a simple sketch using tft_eSPI and the displays work independently, with each display updating properly when its CS pin is pulled LOW.
When I use Lovyan, however, only the display with CS pin of 5 works, the display with CS pin of 25 does not. If I switch the CS pins (left uses 5 and right uses 25, then switch so left uses 25 and right uses 5) the display with CS pin of 5 always works.
This is the file that sets up the displays:
// LovyanGFX by Lovyan03
// https://github.com/lovyan03/LovyanGFX
// https://github.com/lovyan03/ESP32_ScreenShotReceiver Better version than my cheApR_UI, give it a try
#include <LovyanGFX.hpp>
#include "src/TCPReceiverdual.h"
/////////////////////////////////////////////////////////////////
//DISPLAY SETUP
struct LGFX_DisplayA
{
static constexpr spi_host_device_t spi_host = HSPI_HOST;
static constexpr int dma_channel = 1;
static constexpr int spi_sclk = 18; //SCL_PIN
static constexpr int spi_mosi = 23; //SDA_PIN
static constexpr int spi_miso = -1; //NOT NEEDED
static constexpr int spi_dlen = 8;
};
struct LGFX_DisplayB
{
static constexpr spi_host_device_t spi_host = VSPI_HOST;
static constexpr int dma_channel = 2;
static constexpr int spi_sclk = 18; //SCL_PIN
static constexpr int spi_mosi = 23; //SDA_PIN
static constexpr int spi_miso = -1; //NOT NEEDED
static constexpr int spi_dlen = 8;
};
//
//
static LGFX_Sprite sprite[10];
static std::uint32_t count = 0;
static float zoom = 0;
static lgfx::LGFX_SPI<LGFX_DisplayA> lcd; //display LEFT = LCD
static lgfx::LGFX_SPI<LGFX_DisplayB> lcdB; //display LEFT = LCD
static lgfx::Panel_ST7789 panel;
static lgfx::Panel_ST7789 panelB;
static TCPReceiver recv;
static TCPReceiver recvB;
/////////////////////////////////////////////////////////////////
void displaySetup() {
//SETTING RIGHT PANEL
panel.freq_write = 40000000;
panel.freq_fill = 40000000;
panel.freq_read = 6000000;
panel.spi_mode = 3;
panel.spi_mode_read = 0;
panel.len_dummy_read_pixel = 8;
panel.spi_read = false;
panel.spi_3wire = false;
panel.spi_cs = 5; //CS PIN
panel.spi_dc = 17; //DC PIN
panel.gpio_rst = 4; //RST PIN
panel.gpio_bl = 27; //BL PIN
panel.pwm_ch_bl = 7;
panel.backlight_level = false;
panel.invert = true;
panel.rgb_order = false;
// panel.memory_width = 240;
// panel.memory_height = 240;
// panel.panel_width = 240;
panel.panel_height = 240; //SET THIS WITH YOUR DISPLAY HEIGHT
lcd.setPanel(&panel);//STARTING RIGHT PANEL
//SETTING LEFT PANEL
panelB.freq_write = 40000000;
panelB.freq_fill = 40000000;
panelB.freq_read = 6000000;
panelB.spi_mode = 3;
panelB.spi_mode_read = 0;
panelB.len_dummy_read_pixel = 8;
panelB.spi_read = false;
panelB.spi_3wire = false;
panelB.spi_cs = 25; //CS PIN
panelB.spi_dc = 17; //DC_PIN
panelB.gpio_rst = 4; //RST_PIN
panelB.gpio_bl = 27; //BL_PIN
panelB.pwm_ch_bl = 7;
panelB.backlight_level = false;
panelB.invert = true;
panelB.rgb_order = false;
// panelB.memory_width = 240;
// panelB.memory_height = 240;
// panelB.panel_width = 240;
panelB.panel_height = 240; //SET THIS WITH YOUR DISPLAY HEIGHT
lcdB.setPanel(&panelB); //STARTING RIGHT PANEL
lcd.init();
lcdB.init();
//SET ROTATION OF DISPLAYS
lcd.setRotation(1);
lcdB.setRotation(3);
// MIRROR MODE
// lcd.setRotation(5);
// lcdB.setRotation(7);
lcd.setTextColor(0x000000U, 0xFFFFFFU);
lcdB.setTextColor(0x000000U, 0xFFFFFFU);
// DISPLAY QUICK TEST LOOP
// while (1) {
// displayBatt();
// displayUptime();
// loopImg();
// }
for ( int i = 0; i < 240; i++) {
lcd.drawRect(0, i, lcd.width(), lcd.height(), 0xFF0000U);
lcdB.drawRect(0, i, lcdB.width(), lcdB.height(), 0xFF0000U);
delay(2);
}
for ( int i = 0; i < 240; i++) {
lcd.drawRect(i, 0, lcd.width(), lcd.height(), 0xFFFFFFU);
lcdB.drawRect(i, 0, lcdB.width(), lcdB.height(), 0xFFFFFFU);
delay(2);
}
lcd.setFont(&fonts::Font2); lcdB.setFont(&fonts::Font2);
lcd.setCursor(40, 110); lcd.print("CONNECTING TO WIFI");
lcdB.setCursor(40, 110); lcdB.print("WAITING FOR IP");
}
The following warning occurs when compiling with ESP-IDF 4.x.
In file included from .pio/libdeps/m5paper-test/LovyanGFX/src/utility/miniz.c:959:
.pio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32/include/esp_spiram.h:1:2: warning: #warning esp_spiram.h has been replaced by esp32/spiram.h, please include esp32/spiram.h instead [-Wcpp]
#warning esp_spiram.h has been replaced by esp32/spiram.h, please include esp32/spiram.h instead
This is because #include "esp_spiram.h"
was deprecated in ESP-IDF 4.0.
I'll create a PR to fix this issue.
M5Stack gray, Arduino, LovyanGFX 0.2.7
pushRotateZoom()
想定範囲を超えて描画が行われているように見えますが、仕様でしょうか?
または私の使い方に誤りがありますか?
It appears to be out of the expected range.
Is it a specification,my mistake or bug?
大きさは問題なく描画位置が zoom/2 pixelずれている気がしますが...。
#include <M5Stack.h>
#include <LovyanGFX.hpp>
static LGFX lcd;
static LGFX_Sprite sprite(&lcd);
#define SW (18)
#define SH (18)
void setup()
{
M5.begin(false /* LCD*/, true /* SD*/ , true /*Serial*/);
lcd.init();
lcd.setRotation(1);
lcd.setBrightness(32);
sprite.createSprite(SW,SH);
float z = 1.0f;
sprite.fillScreen(TFT_DARKGREEN);
sprite.setPivot(0,0);
for(int i=0; i<4; i++, z+=1.0f)
{
sprite.pushRotateZoom(i * sprite.width(), 32, 0, 1.0f, z);
sprite.pushRotateZoom(180, 32 + i * sprite.height(), 0, z, 1.0f);
}
lcd.drawLine(0,32,SW*5,32,TFT_RED);
lcd.drawLine(180,32, 180, 32+SH*5, TFT_BLUE);
z = 1.0f;
sprite.fillScreen(TFT_YELLOW);
sprite.setPivot(SW/2,SH/2); // center
for(int i=0; i<4; i++, z+=1.0f)
{
sprite.pushRotateZoom(i * sprite.width() + SW/2, 180, 0 ,1.0f, z);
sprite.pushRotateZoom(216, 144 + i * sprite.height() + SH/2, 0, z, 1.0f);
}
for(int i = 0; i < 5; ++i)
{
lcd.drawLine(0,180 - i*SH/2, 100, 180 - i*SH/2, TFT_RED);
lcd.drawLine(0,180 + i*SH/2, 100, 180 + i*SH/2, TFT_RED);
lcd.drawLine(216 - i*SW/2 ,144,216 - i*SW/2, 240, TFT_BLUE);
lcd.drawLine(216 + i*SW/2 ,144,216 + i*SW/2, 240, TFT_BLUE);
}
lcd.drawLine(0,180,100,180, TFT_RED);
lcd.drawLine(216,144,216,240, TFT_BLUE);
}
void loop()
{
delay(1);
}
On my Core2, with the master branches of LovyanGFX and m5core2, if I try this:
#include <M5Core2.h>
#define LGFX_M5STACK_CORE2
#include <LovyanGFX.hpp>
static LGFX scr;
void setup() {
M5.begin(false);
scr.fillCircle(160, 120, 100, TFT_RED);
}
void loop() {
}
I get a boot loop with this:
PC: 0x400d3bf8: lgfx::LGFX_SPI ::begin_transaction() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 233
EXCVADDR: 0x00000008
Decoding stack results
0x400d3bf8: lgfx::LGFX_SPI ::begin_transaction() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 233
0x400d3cf5: lgfx::LGFX_SPI ::beginTransaction_impl() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/platforms/LGFX_SPI_ESP32.hpp line 225
0x400db473: lgfx::LGFXBase::fillCircle(int, int, int) at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/LGFXBase.hpp line 167
0x400d2ff1: setup() at /Users/rop/code/Arduino/libraries/LovyanGFX/src/lgfx/LGFXBase.hpp line 95
0x400df00b: loopTask(void*) at /Users/rop/Library/Arduino15/packages/m5stack/hardware/esp32/1.0.5/cores/esp32/main.cpp line 14
0x4008b619: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
#include <M5Core2.h>
void setup() {
M5.begin();
M5.Lcd.fillCircle(160, 120, 100, TFT_RED);
}
void loop() {
}
works as expected
Hi Lovyan, first of all, thank you for your great work on making this library. Was using the TFT_eSPI from Bodmer, thanks to him as well of course, but yours seems a bit faster and I love your analog gauge. Today I received my ILI9481 IPS displays and wonder if you could add that driver to your library. The display is a 3.5" 480x320 pixel with the FT6236 capacitive touchscreen controller, which you library supports as well, and has the ILI9481 driver chip as opposed to the ILI9488 which my Makerfabs display uses. Btw, Bodmer's library does support the ILI9481 and I tried to add it to your library but the configuration files are quite different. I am of course happy to test and give feedback. The reason why I did go with the ILI9481 is that the display is IPS and fully sunlight readable which I need for my project. Thank you very much in advance and if there is anything I can do to help. please let me know.
Happy New Year.
basically the ability to achieve things like this:
// setup font style in a sprite
sprite.setFont( &myFont );
sprite.setTextSize(1);
sprite.setTextColor( fgcolor, bgcolor );
sprite.setTextDatum( MC_DATUM );
// then later
display1.getFontStyle( sprite.getFontStyle() );
using some wrapper where font + textstyle are available
struct FontStyle
{
TextStyle _style;
IFont _font;
};
Hello @lovyan03,
I have ESP32 3.5" TFT touch(capacitive) board and I want to push the image from the camera with CAMERA_PIXEL_FORMAT -> PIXFORMAT_GRAYSCALE however, I got the result below.
if (img == nullptr || img == 0)
{
Serial.printf("snap fail\n");
return;
}
tft.pushImage(0, 0, 96, 96, (lgfx::swap565_t*)img->buf);
}
How do I display a grayscale image on the TFT screen?
For more details check the repo - Link
static LGFX_Sprite sprite = LGFX_Sprite( &tft );
these work:
sprite.setColorDepth( 8 );
sprite.setPsram( true );
sprite.setColorDepth( 24 );
sprite.setPsram( true );
however these do not seem to produce a valid result
sprite.setColorDepth( tft.getColorDepth() );
sprite.setPsram( true );
sprite.setColorDepth( 16 );
sprite.setPsram( true );
Is that a limitation of the display ?
None of my jpeg would work, only this error was thrown jpeg prepare error:3
which means Insufficient memory pool for the image
.
This is the function:
void draw_jpg(DataWrapper* data, int16_t x, int16_t y, int16_t maxWidth, int16_t maxHeight, int16_t offX, int16_t offY, jpeg_div_t scale)
{
draw_jpg_info_t jpeg;
pixelcopy_t pc(nullptr, this->getColorDepth(), bgr888_t::depth, this->hasPalette());
jpeg.pc = &pc;
jpeg.tft = this;
jpeg.data = data;
jpeg.x = x - offX;
jpeg.y = y - offY;
jpeg.scale = scale;
TJpgD jpegdec;
const uint16_t sz_pool = 2500;
uint8_t pool[sz_pool];
// ( ... )
}
I found two problems with this part of the code:
const uint16_t sz_pool = 2500;
uint8_t pool[sz_pool];
pool
allocation fails when performed from inside the functionsz_pool
value isn't high enoughMoving the two declarations outside the function and raising the value fixed it for me.
#define sz_pool 4096
uint8_t pool[sz_pool];
void draw_jpg(DataWrapper* data, int16_t x, int16_t y, int16_t maxWidth, int16_t maxHeight, int16_t offX, int16_t offY, jpeg_div_t scale)
{
// (...)
}
This quick workaround may not be the best solution though, it wastes 4Kb of ram for nothing when this jpeg function isn't used.
I haven't tested images bigger than 32x32 yet, the value 4096 may need to be higher with bigger images.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.