用ESP32+GC9A01圆形屏幕做一个小挂件

起因是因为水群的时候有个老哥问我可不可以把阿宅徽章做到屏幕上并且能更换,我就去找了找合适的屏幕,结果发现GC9A01这块1.28英寸240*240的圆形屏幕刚好适合,但是本人小白一个,于是就找了两天的教程,由于SD卡模块还在路上,所以先用自带的flash试了试,下一步就是把屏幕和ESP32集成到一小块PCB上,再打印一个外壳然后做成背包挂件,成本估计60不到的样子
PCB上我没画USB转TTL电路,所以Type-C接口只能供电,烧录文件的话我在PCB上预留了串口


现已开源
项目开源和bom表在这里:https://github.com/Myzhazha/ESP-32_GC9A01_JPG
PCB文件开源地址:https://oshwhub.com/Myzhazha/1-28tft-esp32
播放视频使用这个项目:https://github.com/Myzhazha/ESP-32_GC9A01_JPG/tree/main/Video_Demo
播放视频预览:https://www.bilibili.com/video/BV1DV411q7rG/
交流群:636426429


原链接:https://giltesa.com/en/2021/01/05/photographic-album-using-esp32-and-gc9a01-round-screen


成品预览:


1.jpg
2.jpg
3.jpg
加上外壳

PCB:


0.jpg

所需材料:

GC9A01圆形屏幕(¥40包邮)


GC9A01

ESP32模块,我这里用的是带有外围电路的开发板(¥19包邮)


ESP32模块

Micro SD卡模块(¥1.78 可以在买ESP32模块的店里购买)


Micro SD卡模块

一张小于2G的内存卡,需要格式化成FAT32格式(Micro SD卡模块官方说只支持小于等于2G的内存卡,但是我用8G的测试也可以)

母对母杜邦线13根


所需软件:

Arduino IDE 下载链接https://www.arduino.cc(下载后安装)

Arduino_GFX库 链接https://github.com/moononournation/Arduino_GFX/releases/tag/v1.0.5
(下载后解压至C:\Users\用户名\Documents\Arduino\libraries\目录)

JPEGDEC库https://github.com/bitbank2/JPEGDEC
下载后解压至C:\Users\用户名\Documents\Arduino\libraries\目录)


打开Arduino IDE选择文件>首选项>附加开发板管理器网址 右侧的小图标

填入https://dl.espressif.com/dl/package_esp32_index.json

截图1

然后选择工具>开发板>开发板管理器


截图2

等它下载完索引之后在搜索框输入ESP32然后安装


截图3

安装完之后重启一下ArduinoIDE


打开ArduinoIDE新建一个项目,把以下代码复制进去然后保存为ESP32_GC9A01.ino

#include <Arduino_GFX_Library.h>
#include "JpegClass.h"
#include <FS.h>
#include <SD.h>
#include <SPI.h>


#define MISO     2
#define SCLK    14  //SCL
#define MOSI    15  //SDA
#define SD_CS   13
#define TFT_CS   5
#define TFT_BLK 22
#define TFT_DC  27
#define TFT_RST 33


Arduino_DataBus *bus = new Arduino_HWSPI(TFT_DC, TFT_CS, SCLK, MOSI, MISO, true);
Arduino_GC9A01  *gfx = new Arduino_GC9A01(bus, TFT_RST, 0, true);
static JpegClass jpegClass;


void setup()
{
    Serial.begin(115200);


   //Init MicroSD
    SPI.begin(SCLK, MISO, MOSI, SD_CS);
    if( !SD.begin(SD_CS) )
    {
        Serial.println("Card Mount Failed");
        gfx->println(F("ERROR: Card Mount Failed!"));
        return;
    }

    uint8_t cardType = SD.cardType();
    if( cardType == CARD_NONE )
    {
        Serial.println("No SD card attached");
        gfx->println(F("ERROR: No SD card attached"));
        return;
    }

    Serial.print("SD Card Type: ");
    switch( cardType )
    {
        case CARD_MMC:  Serial.println("MMC");  break;
        case CARD_SD:   Serial.println("SDSC"); break;
        case CARD_SDHC: Serial.println("SDHC"); break;
        default:        Serial.println("UNKNOWN");
    }


    //Init Display
    gfx->begin();
    gfx->fillScreen(BLACK);

    #ifdef TFT_BLK
      pinMode(TFT_BLK, OUTPUT);
      digitalWrite(TFT_BLK, HIGH);
    #endif
}



void loop()
{
    unsigned long start = millis();

    File root = SD.open("/img");
    printDirectory(root, 0);

    Serial.printf("Time used: %lu\n", millis() - start);
}



void printDirectory(File dir, int numTabs)
{
    while( true )
    {
        File entry =  dir.openNextFile();
        if( !entry )
        {
            //No more files. Return to the first file in the directory
            dir.rewindDirectory();
            break;
        }

        for( uint8_t i=0 ; i<numTabs ; i++ )
        {
            Serial.print('\t');
        }

        Serial.print(entry.name());

        if( entry.isDirectory() )
        {
            Serial.println("/");
            printDirectory(entry, numTabs+1);
        }
        else
        {
            //Files have sizes, directories do not
            Serial.print("\t\t");
            Serial.println(entry.size(), DEC);

            jpegClass.draw(entry, jpegDrawCallback, true, 0, 0, gfx->width(), gfx->height());
            delay(5000); //图片显示时长,单位ms
        }
    }
}




static int jpegDrawCallback(JPEGDRAW *pDraw)
{
    gfx->draw16bitBeRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight);
}

然后在ino工程同目录新建一个.h工程,把以下代码复制进去(也可以用记事本,保存后把.txt扩展名改成.h)

/*******************************************************************************
 * JPEGDEC Wrapper Class
 *
 * Dependent libraries:
 * JPEGDEC: https://github.com/bitbank2/JPEGDEC.git
 ******************************************************************************/
#ifndef _JPEGCLASS_H_
#define _JPEGCLASS_H_

#include <JPEGDEC.h>

class JpegClass
{
public:
    void draw( File f, JPEG_DRAW_CALLBACK *jpegDrawCallback, bool useBigEndian, int x, int y, int widthLimit, int heightLimit )
    {
        _jpeg.open(f, jpegDrawCallback);

        // scale to fit height
        int _scale;
        int iMaxMCUs;
        float ratio = (float)_jpeg.getHeight() / heightLimit;
        if (ratio <= 1)
        {
            _scale = 0;
            iMaxMCUs = widthLimit / 16;
        }
        else if (ratio <= 2)
        {
            _scale = JPEG_SCALE_HALF;
            iMaxMCUs = widthLimit / 8;
        }
        else if (ratio <= 4)
        {
            _scale = JPEG_SCALE_QUARTER;
            iMaxMCUs = widthLimit / 4;
        }
        else
        {
            _scale = JPEG_SCALE_EIGHTH;
            iMaxMCUs = widthLimit / 2;
        }
        _jpeg.setMaxOutputSize(iMaxMCUs);
        if (useBigEndian)
        {
            _jpeg.setPixelType(RGB565_BIG_ENDIAN);
        }
        _jpeg.decode(x, y, _scale);
        _jpeg.close();
    }

private:
    JPEGDEC _jpeg;
};

#endif // _JPEGCLASS_H_

然后保存为JpegClass.h文件


Arduino IDE打开保存的ESP32_GC9A01.ino文件
选择工具>开发板>ESP32 Arduino>ESP32 Dev Module
把你的ESP32用数据线连到电脑USB接口(请提前安装驱动)
在设备管理器里会看到有个COM口,记住COM后面的那个数字
在Arduino IDE>工具>端口选择你的开发板所在的端口
然后点击Arduino IDE>项目>上传
此时Arduino IDE会编译文件,等到下方窗口出现Connecting........的时候按下ESP32开发板上的BOOT按钮


截图4

此时代码开始写入
等到显示“上传成功”


截图5

拔掉开发板开始连接屏幕和SD卡模块

屏幕连接开发板引脚

屏幕GND对应开发板GND
屏幕VCC对应开发板3.3
屏幕SCL对应开发板D14
屏幕SDA对应开发板D15
屏幕RES对应开发板D33
屏幕DC对应开发板D27
屏幕CS对应开发板D5
屏幕BLK引脚留空不连


Micro SD卡模块连接开发板引脚(MOSI和SCK引脚是和屏幕共用的)

SD卡GND对应开发板GND
SD卡VCC对应开发板VIN
SD卡MISO对应开发板D2
SD卡MOSI对应开发板D15(和屏幕共用)
SD卡SCK对应开发板D14(和屏幕共用)
SD卡CS对应开发板D13


把SD卡用读卡器连接电脑,格式化成FAT32格式,在SD卡根目录创建img文件夹,把需要显示的图片用软件裁剪更改为240*240分辨率的jpg图片然后放到img文件夹里
拔出读卡器把SD卡插到SD卡模块上把ESP32通电就行了

图片更换的时长在ESP32_GC9A01.ino的delay()里更改,单位毫秒,默认显示时长为5000毫秒(5秒)

1.jpg

实际显示效果要好很多

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容