Electro BOY
Published © GPL3+

ESP32C3 can run a mini TV?

Smallest single core @240Mhz max Microcontroller is able to display the pictures with slide show on a capacitive touch 3.5inch SPI display.

IntermediateFull instructions provided2 hours548
ESP32C3 can run a mini TV?

Things used in this project

Hardware components

ESP32c3
×1

Software apps and online services

Arduino IDE
Arduino IDE
EasyEDA
JLCPCB EasyEDA

Story

Read more

Schematics

Schematics

Code

Firmware updated

Arduino
updated with 5 photos, need H files also. So download the full code from embedded links in post
//
#define LGFX_USE_V1

#include <LovyanGFX.hpp>
#include <vector>
#include <SPI.h>
#include <SD.h>
#include <FS.h>

#include "FT6236.h"
const int i2c_touch_addr = TOUCH_I2C_ADD;
#define get_pos ft6236_pos

#define LCD_MOSI 6
#define LCD_MISO 7
#define LCD_SCK 5
#define LCD_CS 4
#define LCD_RST -1
#define LCD_DC 10
#define LCD_BL 8

#define I2C_SDA 2
#define I2C_SCL 3

#define SD_CS 1

class LGFX : public lgfx::LGFX_Device
{
    // lgfx::Panel_ILI9341 _panel_instance;
    lgfx::Panel_ILI9488 _panel_instance;
    lgfx::Bus_SPI _bus_instance;

public:
    // 
    // 
    LGFX(void)
    {
        {                                      // 
            auto cfg = _bus_instance.config(); // 

            // SPI
            cfg.spi_host = SPI2_HOST;  // SPI  (VSPI_HOST or HSPI_HOST)
            cfg.spi_mode = 0;          // SPI (0 ~ 3)
            cfg.freq_write = 40000000; // SPI (80MHz, 80MHz)
            cfg.freq_read = 16000000;  // SPI
            cfg.spi_3wire = true;      // MOSItrue
            cfg.use_lock = true;       // true
            cfg.dma_channel = 1;       // Set the DMA channel (1 or 2. 0=disable)   DMA (0=DMA)
            cfg.pin_sclk = LCD_SCK;    // SPISCLK
            cfg.pin_mosi = LCD_MOSI;   // SPIMOSI
            cfg.pin_miso = LCD_MISO;   // SPIMISO (-1 = disable)
            cfg.pin_dc = LCD_DC;       // SPID/C  (-1 = disable)
                                       // SDSPIMISO

            _bus_instance.config(cfg);              // 
            _panel_instance.setBus(&_bus_instance); // 
        }

        {                                        // 
            auto cfg = _panel_instance.config(); // 

            cfg.pin_cs = LCD_CS;   // CS   (-1 = disable)
            cfg.pin_rst = LCD_RST; // RST  (-1 = disable)
            cfg.pin_busy = -1;     // BUSY (-1 = disable)

            //  

            cfg.memory_width = 320;   // IC
            cfg.memory_height = 480;  // IC
            cfg.panel_width = 320;    // 
            cfg.panel_height = 480;   // 
            cfg.offset_x = 0;         // X
            cfg.offset_y = 0;         // Y
            cfg.offset_rotation = 0;  //  0~7 (4~7)
            cfg.dummy_read_pixel = 8; // 
            cfg.dummy_read_bits = 1;  // 
            cfg.readable = true;      //  true
            cfg.invert = false;       //  true
            cfg.rgb_order = false;    //  true
            cfg.dlen_16bit = false;   // 16bit true
            cfg.bus_shared = true;    // SD true(drawJpgFile)

            _panel_instance.config(cfg);
        }

        setPanel(&_panel_instance); // 
    }
};

LGFX lcd;

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

    lcd.init();
    lcd.fillScreen(TFT_WHITE);

    lcd.setTextSize(3);

    sd_init();
    touch_init();

    lcd.fillRect(80, 160, 160, 160, TFT_BLACK);
    lcd.setCursor(90, 180);
    lcd.println(" TOUCH");
    lcd.setCursor(90, 210);
    lcd.println("  TO");
    lcd.setCursor(90, 240);
    lcd.println("CONTINUE");

    int pos[2] = {0, 0};

    while (1)
    {
        get_pos(pos);

        if (pos[0] > 80 && pos[0] < 240 && pos[1] > 160 && pos[1] < 320)
            break;
        delay(100);
    }
}

static int colors[] = {TFT_RED, TFT_GREEN, TFT_BLUE };

int i = 0;

void loop(void)
{
    lcd.fillScreen(colors[i++]);
    delay(100);

    if (i > 2)
    {
        i = 0;
        lcd.setRotation(3);
        print_img(SD, "/logo.bmp", 480, 320);
        delay(1000);
        print_img(SD, "/logo1.bmp", 480, 320);
        delay(1000);
        print_img(SD, "/logo2.bmp", 480, 320);
        delay(1000);
        print_img(SD, "/logo3.bmp", 480, 320);
        delay(1000);
        print_img(SD, "/logo4.bmp", 480, 320);
        delay(1000);
        
    }
}

void touch_init()
{
    // I2C init
    Wire.begin(I2C_SDA, I2C_SCL);
    byte error, address;

    Wire.beginTransmission(i2c_touch_addr);
    error = Wire.endTransmission();

    if (error == 0)
    {
        Serial.print("I2C device found at address 0x");
        Serial.print(i2c_touch_addr, HEX);
        Serial.println("  !");
    }
    else if (error == 4)
    {
        Serial.print("Unknown error at address 0x");
        Serial.println(i2c_touch_addr, HEX);
        lcd.setCursor(10, 40);
        lcd.println("Touch Failed");
    }
}

void sd_init()
{
    // SD_SPI.begin(SD_SCK, SD_MISO, SD_MOSI);
    if (!SD.begin(SD_CS, SPI, 40000000))
    {
        Serial.println("Card Mount Failed");
        lcd.setCursor(10, 10);
        lcd.println("SD Card Failed");
        while (1)
            delay(1000);
    }
    else
    {
        Serial.println("Card Mount Successed");
    }

    Serial.println("SD init over.");
}

// Display image from file
int print_img(fs::FS &fs, String filename, int x, int y)
{

    File f = fs.open(filename, "r");
    if (!f)
    {
        Serial.println("Failed to open file for reading");
        f.close();
        return 0;
    }

    f.seek(54);
    int X = x;
    int Y = y;
    uint8_t RGB[3 * X];
    for (int row = 0; row < Y; row++)
    {
        f.seek(54 + 3 * X * row);
        f.read(RGB, 3 * X);

        lcd.pushImage(0, row, X, 1, (lgfx::rgb888_t *)RGB);
    }

    f.close();
    return 0;
}

Credits

Electro BOY

Electro BOY

57 projects • 53 followers
Electronics is my passion. I am not professional, Always learning something new. I am good at soldering, designing pcb, Arduino programing.

Comments