PlatformIo+ESP32 使用Arduino_GFX 库点亮GC9A01并利用littlefs显示esp32 flash中的PNG图片

入手一块圆形屏幕GC9A01,刚开始用tft_espi点了一天也没点亮,不知道是什么原因,后来换了Arduino_GFX这个库成功点亮,库地址:https://github.com/moononournation/Arduino_GFX/wiki/Display-Class 示例程序hello world时钟啥的改个端口声明就完事了就可以跑起来了,但是显示图片就涉及到我这个屏幕小白的知识盲区了,示例里面的例子兼容性很强几乎每个都写了SD模块我没有这个,于是想看看能不能直接取模然后读这个取模的数组,因为是第一次点屏幕很遗憾我没有成功找到那个API(也可能是传参不对),如果有大佬知道请务必教我一下,最终在示例中找到了ImgViewerPng_PNGdec这个示例并加以修改得到了下面的成果请添加图片描述

点亮屏幕

首先在PlatformIo中搜索并安装Arduino GFX,这个不多讲了
然后打开helloworld或者clock示例,位置如下图所示,进入后全选复制粘贴到 mian.cpp文件中,记得清空mian.cpp后保留首行的#include <Arduino.h>
在这里插入图片描述

红框用下面的代码替换掉

//MOSI 是SDA 这里对应自己的接口就可以了
Arduino_DataBus *bus =new Arduino_ESP32SPI(5 /* DC */, 6 /* CS */, 14 /* SCK */, 15 /* MOSI */, -1 /* MISO */, HSPI /* spi_num */);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, 7 /* RST */, 0 /* rotation */, true /* IPS */);

编译后,clock示例可能会出现报错,‘xxx‘ was not declared in this scope ,需要手动改一下方法顺序,原因详见我的上一篇文章
https://blog.csdn.net/qq_40288383/article/details/113736395?spm=1001.2014.3001.5502 之后烧录成功就可以进行下一步了

PlatformIo中设置littlefs

在platformIo.ini中加入board_build.filesystem = littlefs

board_build.filesystem = littlefs

在这里插入图片描述

然后在src文件夹的同级建立data文件夹,把要显示的图片放在data文件夹下
在这里插入图片描述
然后点击PlatformIo图标进入PlatformIo页面依次点击执行下面三个命令(一个执行成功后再点下一个) 将data中的数据烧录到flash中
在这里插入图片描述

做完这些我们还要再装一个PNGdec库去读取png格式的文件
platformIo.ini的参考
lib_ldf_mode = deep+可加可不加
bodmer/TFT_eSPI@^2.5.43是因为我没跑起来没有删掉
在这里插入图片描述
至此图片的准备工作完成

代码烧录

我对ImgViewerPng_PNGdec.ino这个实例做了删减,删除了SD相关的代码改为直接读取 flash中的PNG图片,并做了翻译以便理解,大伙在做完上面的配置之后可以直接复制粘贴烧录

#include <Arduino.h>
/*******************************************************************************
 * PNG图像查看器
 * 这是一个简单的PNG图像查看器示例,适用于ESP32并使用LittleFS文件系统。
 * 图像来源:https://github.com/logos
 *
 * 依赖库:
 * PNGdec:https://github.com/bitbank2/PNGdec.git
 *
 * 设置步骤:
 * 1. 在Arduino_GFX设置中更改您的LCD参数。
 * 2. 使用ESP8266 LittleFS Data Upload工具(针对ESP32,参考:https://github.com/lorol/arduino-esp32fs-plugin)上传PNG文件到LittleFS文件系统。
 ******************************************************************************/
#define PNG_FILENAME "/image.png"
#define PNG_4BPP_FILENAME "/image.png"

/*******************************************************************************
 * Arduino_GFX设置开始
 *
 * Arduino_GFX会根据在Arduino IDE中所选的开发板尝试查找设置,
 * 这里我们针对非显示开发套件的默认引脚进行设置(以ESP32为例)。
 * ESP32开发板默认引脚列表:CS:5,DC:27,RST:33,BL:22,SCK:18,MOSI:23,MISO:无
 ******************************************************************************/
#include <Arduino_GFX_Library.h>

#define GFX_BL DF_GFX_BL // 默认背光灯引脚,您可以将DF_GFX_BL替换为实际的背光灯引脚

/* 更多开发设备声明:https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /*!defined(DISPLAY_DEV_KIT) */
//这里记得改成自己的引脚
Arduino_DataBus *bus =new Arduino_ESP32SPI(5 /* DC */, 6 /* CS */, 14 /* SCK */, 15 /* MOSI */, -1 /* MISO */, HSPI /* spi_num */);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, 7 /* RST */, 0 /* rotation */, true /* IPS */);

 
#endif /*!defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
 * Arduino_GFX设置结束
 ******************************************************************************/

#include <LittleFS.h>
#include <PNGdec.h>

PNG png;

int16_t w, h, xOffset, yOffset;

// 用于访问LittleFS文件系统上文件的函数
File pngFile;

// 打开文件的函数,从LittleFS文件系统中打开指定的PNG文件
void *myOpen(const char *filename, int32_t *size)
{
    pngFile = LittleFS.open(filename, "r");

    if (!pngFile || pngFile.isDirectory())
    {
        Serial.println(F("错误:打开 " PNG_FILENAME " 文件用于读取失败"));
        gfx->println(F("错误:打开 " PNG_FILENAME " 文件用于读取失败"));
    }
    else
    {
        *size = pngFile.size();
        Serial.printf("已打开 '%s',大小:%d\n", filename, *size);
    }

    return &pngFile;
}

// 关闭文件的函数
void myClose(void *handle)
{
    if (pngFile)
        pngFile.close();
}

// 从打开的文件中读取数据的函数
int32_t myRead(PNGFILE *handle, uint8_t *buffer, int32_t length)
{
    if (!pngFile)
        return 0;
    return pngFile.read(buffer, length);
}

// 在打开的文件中定位到指定位置的函数
int32_t mySeek(PNGFILE *handle, int32_t position)
{
    if (!pngFile)
        return 0;
    return pngFile.seek(position);
}

// 将像素绘制到显示器上的函数
void PNGDraw(PNGDRAW *pDraw)
{
    uint16_t usPixels[320];
    uint8_t usMask[320];

    png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0x00000000);
    png.getAlphaMask(pDraw, usMask, 1);
    gfx->draw16bitRGBBitmapWithMask(xOffset, yOffset + pDraw->y, usPixels, usMask, pDraw->iWidth, 1);
}

// 初始化设置函数
void setup()
{
    Serial.begin(9600);
    // Serial.setDebugOutput(true);
    // while(!Serial);
    Serial.println("Arduino_GFX PNG图像查看器示例(ESP32 - LittleFS)");

#ifdef GFX_EXTRA_PRE_INIT
    GFX_EXTRA_PRE_INIT();
#endif

    // 初始化显示器
    if (!gfx->begin())
    {
        Serial.println("gfx->begin()失败!");
    }
    gfx->fillScreen(BLACK);

    w = gfx->width(), h = gfx->height();
    gfx->fillScreen(BLACK);
    for (int16_t x = 0; x < w; x += 5)
    {
        gfx->drawFastVLine(x, 0, h, PALERED);
    }

#ifdef GFX_BL
    pinMode(GFX_BL, OUTPUT);
    digitalWrite(GFX_BL, HIGH);
#endif

    if (!LittleFS.begin())
    {
        Serial.println(F("错误:LittleFS文件系统挂载失败!"));
        gfx->println(F("错误:LittleFS文件系统挂载失败!"));
    }
    else
    {
        unsigned long start = millis();
        int rc;
        rc = png.open(PNG_FILENAME, myOpen, myClose, myRead, mySeek, PNGDraw);
        if (rc == PNG_SUCCESS)
        {
            int16_t pw = png.getWidth();
            int16_t ph = png.getHeight();

            xOffset = (w - pw) / 2;
            yOffset = (h - ph) / 2;

            rc = png.decode(NULL, 0);

            Serial.printf("绘制偏移量:(%d, %d),所用时间:%lu\n", xOffset, yOffset, millis() - start);
            Serial.printf("图像规格:(%d x %d),%d bpp,像素类型:%d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
            png.close();
        }
        else
        {
            Serial.println("png.open()失败!");
        }
    }

    delay(5000); // 5秒钟
}

// 循环执行的函数
void loop()
{
    unsigned long start = millis();
    int rc;
    rc = png.open(PNG_4BPP_FILENAME, myOpen, myClose, myRead, mySeek, PNGDraw);
    if (rc == PNG_SUCCESS)
    {
        // 随机绘制位置
        int16_t pw = png.getWidth();
        int16_t ph = png.getHeight();
        xOffset = random(w) - (pw / 2);
        yOffset = random(h) - (ph / 2);

        rc = png.decode(NULL, 0);

        Serial.printf("绘制偏移量:(%d, %d),所用时间:%lu\n", xOffset, yOffset, millis() - start);
        Serial.printf("图像规格:(%d x %d),%d bpp,像素类型:%d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
        png.close();
    }
    else
    {
        Serial.println("png.open()失败!");
    }

    delay(1000); // 1秒钟
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值