Recibí algunos módulos desde AliExpress y lo primero que tuve que hacer con ellos fue entender cómo hacerlos funcionar. Así que hice un ejemplo el cual carga todas las imágenes desde la memoria MicroSD y las muestra por pantalla.
Es un ejemplo sencillo pero necesite bastantes horas para hacerlo funcionar ya que tuve problemas para que ambas cosas funcionaran al mismo tiempo debido a que ambos módulos usan el protocolo SPI. Sabia el funcionamiento con Arduino pero por alguna razón me empeñe en el ESP32 en usar dos puertos SPI y no compartir ningún pin, eso causaba que solo el primer modulo que iniciara pudiera usar la conexión y el otro daba error. Finalmente compartiendo solamente los pines SCK y MOSI conseguí hacerlo funcionar.
La placa de desarrollo es la TTGO T8 V1.8 ESP32-WROVER-B, la pantalla es una que incluye el driver GC9A01.
No es la placa de desarrollo que mas me gusta, pero la elegí por contar con lector de MicroSD integrado, el ESP32 WROVER, y la funcionalidad de auto reset. Necesitaba esas características debido a que la placa que estoy diseñando va a contar con todo eso, así que era la mejor forma de hacer las pruebas sobre la protoboard.
Este es el código del video:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
#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(1500); } } } static int jpegDrawCallback(JPEGDRAW *pDraw) { gfx->draw16bitBeRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight); } |
El código original de la librería utiliza la clase JpegClass. La he tenido que modificar un poco ya que originalmente el método que pinta recibía el nombre del fichero y yo he preferido pesarle directamente el fichero.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/******************************************************************************* * 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_ |