• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Jak podłącza się ekran dotykowy typu tft o rozmiarze 2.8 cala?
#1
Dzień dobry,
Jestem bardzo nowy w arduino więc nie zam się na wszystkim,i potrzebuje pomocy,czy wie ktoś jak podłączyć i ustawić taki ekran by wyświetlał zdięcie z karty SD?
Z widocznych oznaczeń jest,2.8" TFT 240xRGBx320,piny to vcc,gnd,CS,reset,dc,sdi(mosi),sck,led,sdo(miso)t_ck,t_ck,t_din,t_do,t_irq
Z góry dziękuję.


Załączone pliki Miniatury
       
 
Odpowiedź
#2
(27-07-2024, 13:32)Filipunio napisał(a): Dzień dobry,
Jestem bardzo nowy w arduino więc nie zam się na wszystkim,i potrzebuje pomocy,czy wie ktoś jak podłączyć i ustawić taki ekran by wyświetlał zdięcie z karty SD?
Z widocznych oznaczeń jest,2.8" TFT 240xRGBx320,piny to vcc,gnd,CS,reset,dc,sdi(mosi),sck,led,sdo(miso)t_ck,t_ck,t_din,t_do,t_irq
Z góry dziękuję.

Ten wyświetlacz to jakie 3 w 1 - trzy praktycznie niezależne obwody na jednej płytce.
1 - sam wyświetlacz 320x240x16 (HiColor) osbługiwamy interfejsem SPI (z dodatkowym bitem dc rozróżniającym rozkazy od danych, sck, mosi, miso, cs to standard SPI)
2 - czujnik dotykowy na wyświetlaczu (piny t_*)
3 - karta SD (gniazdko) - te 4 piny przy drugiej krawędzi płytki - to w sumie też jest SPI.
Trochę szkoda, że nie ma wyprowadzonych pinów od czujnika włożenia karty.

Wyświetlaczem się bawiłem, resztą nie, ale np. karta SD to standard.
Do wyświetlania zdjęć ten interfejs jest trochę wolny - będzie trzeba rysować cały wyświetlacz, a to jest 320*240*2 => ponad 150kB do wyświetlenia całego obrazu, a to trochę trwa. Układ umożliwia niezależne rysowanie dowolnego 'okienka' co ułatwia rysowanie różnych GUI, ale całoekranowe zdjęcia będą wolne. No ale jak nie będą zmieniane zbyt często..
Druga sprawa to obróbka zdjęć - one zwykle mają dużo większe rozmiary, trzeba będzie przeliczyć, no i jak jeszcze mają być w JPG lub czyms podobnym... Jak chcesz dać 8-bitowy procek (atmega) to raczej tylko gdy na karcie będą od razu odpowiednbio zapisane obrazki (przeskalowane w 16bitach bez kompresji np. odpowiedni BMP). Jak mają ty być bezpośrednio fotki z aparatu (megapixele, true color, jpg) to 32-bitowy procek (arm - np. STM32).
 
Odpowiedź
#3
(27-07-2024, 14:07)oscarX napisał(a):
(27-07-2024, 13:32)Filipunio napisał(a): Dzień dobry,
Jestem bardzo nowy w arduino więc nie zam się na wszystkim,i potrzebuje pomocy,czy wie ktoś jak podłączyć i ustawić taki ekran by wyświetlał zdięcie z karty SD?
Z widocznych oznaczeń jest,2.8" TFT 240xRGBx320,piny to vcc,gnd,CS,reset,dc,sdi(mosi),sck,led,sdo(miso)t_ck,t_ck,t_din,t_do,t_irq
Z góry dziękuję.

Ten wyświetlacz to jakie 3 w 1 - trzy praktycznie niezależne obwody na jednej płytce.
1 - sam wyświetlacz 320x240x16 (HiColor) osbługiwamy interfejsem SPI (z dodatkowym bitem dc rozróżniającym rozkazy od danych, sck, mosi, miso, cs to standard SPI)
2 - czujnik dotykowy na wyświetlaczu (piny t_*)
3 - karta SD (gniazdko) - te 4 piny przy drugiej krawędzi płytki - to w sumie też jest SPI.
Trochę szkoda, że nie ma wyprowadzonych pinów od czujnika włożenia karty.

Wyświetlaczem się bawiłem, resztą nie, ale np. karta SD to standard.
Do wyświetlania zdjęć ten interfejs jest trochę wolny - będzie trzeba rysować cały wyświetlacz, a to jest 320*240*2 => ponad 150kB do wyświetlenia całego obrazu, a to trochę trwa. Układ umożliwia niezależne rysowanie dowolnego 'okienka' co ułatwia rysowanie różnych GUI, ale całoekranowe zdjęcia będą wolne. No ale jak nie będą zmieniane zbyt często..
Druga sprawa to obróbka zdjęć - one zwykle mają dużo większe rozmiary, trzeba będzie przeliczyć, no i jak jeszcze mają być w JPG lub czyms podobnym... Jak chcesz dać 8-bitowy procek (atmega) to raczej tylko gdy na karcie będą od razu odpowiednbio zapisane obrazki (przeskalowane w 16bitach bez kompresji np. odpowiedni BMP). Jak mają ty być bezpośrednio fotki z aparatu (megapixele, true color, jpg) to 32-bitowy procek (arm - np. STM32).
Ok,masz może jakiś przykładowy kod i jak kable podpiąłeś,patrzyłem każdy tutorial i nie działa, naprawdę przydało by się,serio naprawdę nie rozumiem jak to ustrojstwo działa.
Z góry dzięki!
Edit:może być co kolwiek,ważne by było.
 
Odpowiedź
#4
(27-07-2024, 20:03)Filipunio napisał(a): Ok,masz może jakiś przykładowy kod i jak kable podpiąłeś,patrzyłem każdy tutorial i nie działa, naprawdę przydało by się,serio naprawdę nie rozumiem jak to ustrojstwo działa.
Z góry dzięki!
Edit:może być co kolwiek,ważne by było.

Tak dla rozjaśnienia, bo nie powiedziałem tego jasno wcześniej. Ta płytka sama nie wyświetli żadnego obrazu. Jak wspomniałem czytnik kart nie ma nic wspólnego z wyświetlaczem poza zasilaniem i tym, że są na jednej płytce. Odczyt zdjęć z karty i wyświetlanie na wyświetlaczu musi zrealizować podłączony komputerek z odpowiednim programem.
Nie wiem czy istnieje jakiś gotowiec do "ramki na zdjęcia".

Wyświetlacz jest na układzie ILI9341, jego manual wyjaśnia wszystko. Sam układ na kilka możliwych do użycia intersejsów, ale ta płytka ma wyprowadzony tylko SPI. Podłączasz pin w pin - można podłaczyć kilkia urządzeń SPI do jednego kontrolera, tylko piny CS trzeba podłączyć oddzielnie. Jest do tego układu jakaś gotowa biblioteka w zasobach Arduino. Ja się wzorowałem na takiej bibliotece, ale chciałem pewne specyficzne funkcje, więc musiałem napisać własny kod. Jest on przeznaczony do płytki Blackpill - chciałem spróbować zrobić "kieszonkowy" emulator ZXSpectrum, więc co najmniej 64KB RAMu było potrzebne.
W tej bibliotece były dość rozbudowana sekwencja inicjalizacji tego wyświetlacza. Najpierw funkcja wysyłająca komendę z parametrami:
Kod:
static void sendCommand(uint8_t cmd, const uint8_t * params, int paramsCnt)
{
    SPI.beginTransaction (SPISettings( 20000000, MSBFIRST , SPI_MODE0)) ;

    digitalWrite (LCD_D_Cm, 0);
    SPI.transfer(cmd);
    digitalWrite(LCD_D_Cm, 1);
    for (int i = 0; i<paramsCnt; i++)
    {
        SPI.transfer(params[i]);
    }

    SPI.endTransaction () ;
}

Jak widać w trakcie transferu zmieniany jest stan linii dc - więc musi to być wykonywane synchronicznie, nie w tle.
Procedura inicjalizacji:

Kod:
void ILI9341_begin(void)
{
    Select();
    sendCommand(ILI9341_SWRESET, NULL, 0); // Engage software reset
    delay(150);

    uint8_t cmd, x, numArgs;
    const uint8_t *addr = initcmd;
    while ((cmd = *addr++) != ILI9341_NOP)
    {
        x = *addr++;
        numArgs = x & 0x7F;
        sendCommand(cmd, addr, numArgs);
        addr += numArgs;
        if (x & 0x80)
            delay(150);
    }
    Deselect();
}

Select() i Deselect() sterują linią CS.
Funkcja ta korzysta z sekwensji rozkazów zapisanych w tabelce initcmd. Tablica ta wygląda następująco:

Kod:
static const uint8_t initcmd[] = {
  0xEF, 3, 0x03, 0x80, 0x02,
  0xCF, 3, 0x00, 0xC1, 0x30,
  0xED, 4, 0x64, 0x03, 0x12, 0x81,
  0xE8, 3, 0x85, 0x00, 0x78,
  0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
  0xF7, 1, 0x20,
  0xEA, 2, 0x00, 0x00,
  ILI9341_PWCTR1  , 1, 0x23,             // Power control VRH[5:0]
  ILI9341_PWCTR2  , 1, 0x10,             // Power control SAP[2:0];BT[3:0]
  ILI9341_VMCTR1  , 2, 0x3e, 0x28,       // VCM control
  ILI9341_VMCTR2  , 1, 0x86,             // VCM control2
  ILI9341_MADCTL  , 1, 0x48,             // Memory Access Control
  ILI9341_VSCRSADD, 1, 0x00,             // Vertical scroll zero
  ILI9341_PIXFMT  , 1, 0x55,
  ILI9341_FRMCTR1 , 2, 0x00, 0x18,
  ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
  0xF2, 1, 0x00,                         // 3Gamma Function Disable
  ILI9341_GAMMASET , 1, 0x01,             // Gamma curve selected
  ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
    0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
  ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
    0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
  ILI9341_SLPOUT  , 0x80,                // Exit Sleep
  ILI9341_DISPON  , 0x80,                // Display on
  ILI9341_NOP                            // End of list
};


Jak widać, część rozkazów jest nazwana (#define wcześniej) a części nawet autorzy biblioteki nie znali.
 
Odpowiedź
#5
(27-07-2024, 21:10)oscarX napisał(a):
(27-07-2024, 20:03)Filipunio napisał(a): Ok,masz może jakiś przykładowy kod i jak kable podpiąłeś,patrzyłem każdy tutorial i nie działa, naprawdę przydało by się,serio naprawdę nie rozumiem jak to ustrojstwo działa.
Z góry dzięki!
Edit:może być co kolwiek,ważne by było.

Tak dla rozjaśnienia, bo nie powiedziałem tego jasno wcześniej. Ta płytka sama nie wyświetli żadnego obrazu. Jak wspomniałem czytnik kart nie ma nic wspólnego z wyświetlaczem poza zasilaniem i tym, że są na jednej płytce. Odczyt zdjęć z karty i wyświetlanie na wyświetlaczu musi zrealizować podłączony komputerek z odpowiednim programem.
Nie wiem czy istnieje jakiś gotowiec do "ramki na zdjęcia".

Wyświetlacz jest na układzie ILI9341, jego manual wyjaśnia wszystko. Sam układ na kilka możliwych do użycia intersejsów, ale ta płytka ma wyprowadzony tylko SPI. Podłączasz pin w pin - można podłaczyć kilkia urządzeń SPI do jednego kontrolera, tylko piny CS trzeba podłączyć oddzielnie. Jest do tego układu jakaś gotowa biblioteka w zasobach Arduino. Ja się wzorowałem na takiej bibliotece, ale chciałem pewne specyficzne funkcje, więc musiałem napisać własny kod. Jest on przeznaczony do płytki Blackpill - chciałem spróbować zrobić "kieszonkowy" emulator ZXSpectrum, więc co najmniej 64KB RAMu było potrzebne.
W tej bibliotece były dość rozbudowana sekwencja inicjalizacji tego wyświetlacza. Najpierw funkcja wysyłająca komendę z parametrami:
Kod:
static void sendCommand(uint8_t cmd, const uint8_t * params, int paramsCnt)
{
    SPI.beginTransaction (SPISettings( 20000000, MSBFIRST , SPI_MODE0)) ;

    digitalWrite (LCD_D_Cm, 0);
    SPI.transfer(cmd);
    digitalWrite(LCD_D_Cm, 1);
    for (int i = 0; i<paramsCnt; i++)
    {
        SPI.transfer(params[i]);
    }

    SPI.endTransaction () ;
}

Jak widać w trakcie transferu zmieniany jest stan linii dc - więc musi to być wykonywane synchronicznie, nie w tle.
Procedura inicjalizacji:

Kod:
void ILI9341_begin(void)
{
    Select();
    sendCommand(ILI9341_SWRESET, NULL, 0); // Engage software reset
    delay(150);

    uint8_t cmd, x, numArgs;
    const uint8_t *addr = initcmd;
    while ((cmd = *addr++) != ILI9341_NOP)
    {
        x = *addr++;
        numArgs = x & 0x7F;
        sendCommand(cmd, addr, numArgs);
        addr += numArgs;
        if (x & 0x80)
            delay(150);
    }
    Deselect();
}

Select() i Deselect() sterują linią CS.
Funkcja ta korzysta z sekwensji rozkazów zapisanych w tabelce initcmd. Tablica ta wygląda następująco:

Kod:
static const uint8_t initcmd[] = {
  0xEF, 3, 0x03, 0x80, 0x02,
  0xCF, 3, 0x00, 0xC1, 0x30,
  0xED, 4, 0x64, 0x03, 0x12, 0x81,
  0xE8, 3, 0x85, 0x00, 0x78,
  0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
  0xF7, 1, 0x20,
  0xEA, 2, 0x00, 0x00,
  ILI9341_PWCTR1  , 1, 0x23,             // Power control VRH[5:0]
  ILI9341_PWCTR2  , 1, 0x10,             // Power control SAP[2:0];BT[3:0]
  ILI9341_VMCTR1  , 2, 0x3e, 0x28,       // VCM control
  ILI9341_VMCTR2  , 1, 0x86,             // VCM control2
  ILI9341_MADCTL  , 1, 0x48,             // Memory Access Control
  ILI9341_VSCRSADD, 1, 0x00,             // Vertical scroll zero
  ILI9341_PIXFMT  , 1, 0x55,
  ILI9341_FRMCTR1 , 2, 0x00, 0x18,
  ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
  0xF2, 1, 0x00,                         // 3Gamma Function Disable
  ILI9341_GAMMASET , 1, 0x01,             // Gamma curve selected
  ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
    0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
  ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
    0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
  ILI9341_SLPOUT  , 0x80,                // Exit Sleep
  ILI9341_DISPON  , 0x80,                // Display on
  ILI9341_NOP                            // End of list
};


Jak widać, część rozkazów jest nazwana (#define wcześniej) a części nawet autorzy biblioteki nie znali.
 
Odpowiedź
#6
Jeśli weźmiemy bibliotekę TFT_eSPI  od Bodmera, to w przypadku rozdzielczości 240 x 320 czas narastania obrazu jest krótszy niż 1 sekunda. Ten Kod 
static const uint8_t initcmd[] = {

  0xEF, 3, 0x03, 0x80, 0x02,
  0xCF, 3, 0x00, 0xC1, 0x30,
  0xED, 4, 0x64, 0x03, 0x12, 0x81,
  0xE8, 3, 0x85, 0x00, 0x78,
  0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
  0xF7, 1, 0x20,
  0xEA, 2, 0x00, 0x00,
  ILI9341_PWCTR1  , 1, 0x23,             // Power control VRH[5:0]
  ILI9341_PWCTR2  , 1, 0x10,             // Power control SAP[2:0];BT[3:0]
  ILI9341_VMCTR1  , 2, 0x3e, 0x28,       // VCM control
  ILI9341_VMCTR2  , 1, 0x86,             // VCM control2
  ILI9341_MADCTL  , 1, 0x48,             // Memory Access Control
  ILI9341_VSCRSADD, 1, 0x00,             // Vertical scroll zero
  ILI9341_PIXFMT  , 1, 0x55,
  ILI9341_FRMCTR1 , 2, 0x00, 0x18,
  ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
  0xF2, 1, 0x00,                         // 3Gamma Function Disable
  ILI9341_GAMMASET , 1, 0x01,             // Gamma curve selected
  ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
    0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
  ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
    0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
  ILI9341_SLPOUT  , 0x80,                // Exit Sleep
  ILI9341_DISPON  , 0x80,                // Display on
  ILI9341_NOP                            // End of list
};

Kod pochodzi z biblioteki Adafruit i powinien działać ze wszystkimi wyświetlaczami dostępnymi na rynku, w tym z ILI9341 V2.

Warto zapoznać się trochę z materiałem i nie krytykować go od razu

To o czym kolega zapomniał napisać to fakt, że większość wyświetlaczy SPI jest na układy 3,3V

nie dla UNO R3, Mega, i innych co pracują na poziomie 5V.
Owszem będzie działać ale jak długo?
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości