Lire une video avec une carte uno et un ecran TFT

Bonjour tout le monde

Je suis un petit nouveau dans la communauté :relaxed: , j'ai reussi tant bien que mal à lire des fichiers en .bmp d 'une carte SD de mon ecran TFT 3.5 pouces, mais cela a été avec les bonnes bibliothèques.

Là je veux m'attaquer à un plus projet, je veux donc pouvoir lire en boucle une video qui sera sur le support SD de l'ecran TFT. Il y a bien un sujet sur internet avec une boite de chocolats et un ecran lcd avec une vidéo qui tourne , mais je n'arrive pas à reproduire la même chose, surement parce que les librairies sont differentes.

Autre petite question, une fois le code televersé , il est renseigné dans la memoire de l'arduino oui il est inscrit sur la carte SD de l'ecran ?, juste pour savoir car pour un gain de place j'aurai souhaité avoir que l'ecran.

Ce n'est pas evident de comprendre, enfin moi je me suis compris si vous avez besoin de precisions demandez moi, merci de votre aide :wink:

1 Like

lavache599:
Il y a bien un sujet sur internet avec une boite de chocolats et un écran LCD avec une vidéo qui tourne, mais je n'arrive pas à reproduire la même chose, surement parce que les librairies sont différentes.

Pas facile d'aider si tu ne donnes pas le lien ni ton code qui affiche des images. Pour l'instant, on ne sait que 'UNO' et 'LCD 3.5 pouces' : quelles bibliothèques utilises-tu, est-ce un écran SPI, quelle définition (nombre de pixels), combien d'images par seconde ...?

Je n'ai pas d'expérience sur la vidéo sur Arduino, mais j'ai peur que ça ne soit pas facile. Peut-être plus à la portée d'un ESP8266 ou un ESP32.

Quand tu téléverses un code sur un Arduino, il se loge dans la mémoire flash pas sur la SD. Sinon, que ferait-on si on n'a pas de carte SD... ? :sunglasses: Certains écrans n'ont pas de lecteur SD.

Merci de votre réponse rapide, alors l'ecran est le suivant 3.5inch Arduino Display-UNO - LCD wiki c'est d'ailleurs ici que le constructeur m'a demandé de telecharger les bibliotheques.

Tout ce que je sais de l'ecran

Details techniques
Type d'ecran: 3.5 inch TFT LCD Module
IC: driver ILI9486 (default in ramdon)
Interface: 8 bits parallele
Resolution: 480 x 320
Dimension of the LCD: 85mm x 55mm x 1mm
Dimension du PCB: 85.4955.63(mm)
Dimension de la surface active: 73.44
48.96(mm)
Plage de temperature en fonctionnement : -20℃~70℃
Plage de temperature pour le stockage : -40℃~70℃

Pour le code que j'ai utilisé pour l'affichage des images bmp , je le mettrai ce soir sur ce post car je ne suis pas chez moi en ce moment.

Ah d'accord, je pensais qu'il y avait une petite memoire integrée à la carte d'ecran. Oui certains ecrans n'ont pas de lecteur de carte sd

Vous avez 480*320 pixels (si vous avez de la couleur, chaque pixel vaut 16 bits (5,6,5) , soit 2 octets.
Une image bmp tiendra donc dans 310 kiloctets . Mettons qu'une video nécessite, pour être agréable à lire, 25 images par secondes, il vous faudra transmettre ca 8 megaoctets par seconde, i.e faire sortir 8M du SPI et les faire rentre dans le TFT .
Quel est le débit maximum du SPI -sur la carte SD- de l'arduino?
Quel est le débit maximum d'entrée du TFT?

C'est une interface 8 bits parallèle, pas du SPI. Ça devrait aller plus vite.
Si on transmet un octet à chaque période d'horloge, il faudrait tourner à 8 MHz pour les 8 Mo/s, ce qui me parait trop rapide pour un Uno.

"C'est une interface 8 bits parallèle, pas du SPI. Ça devrait aller plus vite.
"
Le TFT qui reçoit est une interface 8 bits parallélle, je suis d'accord.
Je doute que la carte SD (qui emet : les goulets d'étranglement ont lieu aussi bien en émission qu'en reception) soit une interface 8 bits parallèlle : les cartes d'adaptation que je connais ont moins de 7 fils de liaison, alim incluse..... ou alors c'est spécifique à certains écrans, qui ont leur propre emplacement pour carte SD...
Même un mega2560 ne peut pas stocker plus d'une image BMP à pleine résolution ... D'où l'existence de deux (la TFT et la carte SD) goulets d'étranglement (il suffit que l'un des soit trop lent pour résoudre le problème, en le déclarant infaisable)
au mieux, on pourrait faire une animation avec des portions d'image ou des aplats rectangulaires....

Merci de vos réponses, j espère juste arriver à le faire, je posterai demain le script utilisé pour l affichage des 4 images bmp, ce script permet d afficher doucement une image entière, puis passe à la suivante etc... Et en lisant vos commentaires, je me demande si justement ce n est pas fait exprès que ça charge doucement l image style ligne par ligne, peut être dû àu temps de transfert de donner de la sd vers le tft :frowning:

Je ne sais pas si on peut le faire sur le forum mais je mettrai le lien qui montre comment la personne a fait pour mettre une vidéo sur une carte sd. De mémoire c 20 images par seconde., après le format de la vidéo doit être en. rgb peut être un format plus simple à lire ?

Bon ce matin j ai voulu poster le code mais impossible gros problème internet, j essaie de poster cela ce soir.

Me revoilà, alors voici le code fonctionnel pour l'affichage des 4 .BMP avec les bonnes bibliotheques, merci de votre aide

/***********************************************************************************
*This program is a demo of how to display a bmp picture from SD card
*This demo was made for LCD modules with 8bit or 16bit data port.
*This program requires the the LCDKIWI library.

* File                : show_bmp_picture.ino
* Hardware Environment: Arduino UNO
* Build Environment   : Arduino

*Set the pins to the correct ones for your development shield or breakout board.
*This demo use the BREAKOUT BOARD only and use these 8bit data lines to the LCD,
*pin usage as follow:
*                  LCD_CS  LCD_CD  LCD_WR  LCD_RD  LCD_RST  SD_SS  SD_DI  SD_DO  SD_SCK 
*     Arduino Uno    A3      A2      A1      A0      A4      10     11     12      13                                                     

*                  LCD_D0  LCD_D1  LCD_D2  LCD_D3  LCD_D4  LCD_D5  LCD_D6  LCD_D7  
*     Arduino Uno    8       9       2       3       4       5       6       7

*Remember to set the pins to suit your display module!
*
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, QD electronic SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
**********************************************************************************/

#include <SD.h>
#include <SPI.h>
#include <LCDWIKI_GUI.h> //Core graphics library
#include <LCDWIKI_KBV.h> //Hardware-specific library

//if the IC model is known or the modules is unreadable,you can use this constructed function
LCDWIKI_KBV my_lcd(ILI9486,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//if the IC model is not known and the modules is readable,you can use this constructed function
//LCDWIKI_KBV my_lcd(320,480,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset

#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define PIXEL_NUMBER  (my_lcd.Get_Display_Width()/4)
#define FILE_NUMBER 4
#define FILE_NAME_SIZE_MAX 20

uint32_t bmp_offset = 0;
uint16_t s_width = my_lcd.Get_Display_Width();  
uint16_t s_heigh = my_lcd.Get_Display_Height();
//int16_t PIXEL_NUMBER;

char file_name[FILE_NUMBER][FILE_NAME_SIZE_MAX];

uint16_t read_16(File fp)
{
    uint8_t low;
    uint16_t high;
    low = fp.read();
    high = fp.read();
    return (high<<8)|low;
}

uint32_t read_32(File fp)
{
    uint16_t low;
    uint32_t high;
    low = read_16(fp);
    high = read_16(fp);
    return (high<<8)|low;   
 }
 
bool analysis_bpm_header(File fp)
{
    if(read_16(fp) != 0x4D42)
    {
      return false;  
    }
    //get bpm size
    read_32(fp);
    //get creator information
    read_32(fp);
    //get offset information
    bmp_offset = read_32(fp);
    //get DIB infomation
    read_32(fp);
    //get width and heigh information
    uint32_t bpm_width = read_32(fp);
    uint32_t bpm_heigh = read_32(fp);
    if((bpm_width != s_width) || (bpm_heigh != s_heigh))
    {
      return false; 
    }
    if(read_16(fp) != 1)
    {
        return false;
    }
    read_16(fp);
    if(read_32(fp) != 0)
    {
      return false; 
     }
     return true;
}

void draw_bmp_picture(File fp)
{
  uint16_t i,j,k,l,m=0;
  uint8_t bpm_data[PIXEL_NUMBER*3] = {0};
  uint16_t bpm_color[PIXEL_NUMBER];
  fp.seek(bmp_offset);
  for(i = 0;i < s_heigh;i++)
  {
    for(j = 0;j<s_width/PIXEL_NUMBER;j++)
    {
      m = 0;
      fp.read(bpm_data,PIXEL_NUMBER*3);
      for(k = 0;k<PIXEL_NUMBER;k++)
      {
        bpm_color[k]= my_lcd.Color_To_565(bpm_data[m+2], bpm_data[m+1], bpm_data[m+0]); //change to 565
        m +=3;
      }
      for(l = 0;l<PIXEL_NUMBER;l++)
      {
        my_lcd.Set_Draw_color(bpm_color[l]);
        my_lcd.Draw_Pixel(j*PIXEL_NUMBER+l,i);
      }    
     }
   }    
}

void setup() 
{
    Serial.begin(9600);
   my_lcd.Init_LCD();
   Serial.println(my_lcd.Read_ID(), HEX);
   my_lcd.Fill_Screen(BLUE);
   //s_width = my_lcd.Get_Display_Width();  
   //s_heigh = my_lcd.Get_Display_Height();
   //PIXEL_NUMBER = my_lcd.Get_Display_Width()/4;
   if(PIXEL_NUMBER == 60) //240*320
   {
       strcpy(file_name[0],"tulip.bmp");
       strcpy(file_name[1],"game.bmp");
       strcpy(file_name[2],"tree.bmp");
       strcpy(file_name[3],"flower.bmp");
   }
   else //320*480
   {
       strcpy(file_name[0],"01.bmp");
       strcpy(file_name[1],"02.bmp");
       strcpy(file_name[2],"03.bmp");
       strcpy(file_name[3],"04.bmp");
   }
  //Init SD_Card
   pinMode(10, OUTPUT);
   
    if (!SD.begin(10)) 
    {
      my_lcd.Set_Text_Back_colour(BLUE);
      my_lcd.Set_Text_colour(WHITE);    
      my_lcd.Set_Text_Size(1);
      my_lcd.Print_String("SD Card Init fail!",0,0);
    }
}

void loop() 
{
    int i = 0;
    File bmp_file;
    for(i = 0;i<FILE_NUMBER;i++)
    {
       bmp_file = SD.open(file_name[i]);
       if(!bmp_file)
       {
            my_lcd.Set_Text_Back_colour(BLUE);
            my_lcd.Set_Text_colour(WHITE);    
            my_lcd.Set_Text_Size(1);
            my_lcd.Print_String("didnt find BMPimage!",0,10);
            while(1);
        }
        if(!analysis_bpm_header(bmp_file))
        {  
            my_lcd.Set_Text_Back_colour(BLUE);
            my_lcd.Set_Text_colour(WHITE);    
            my_lcd.Set_Text_Size(1);
            my_lcd.Print_String("bad bmp picture!",0,0);
            return;
        }
          draw_bmp_picture(bmp_file);
         bmp_file.close(); 
         delay(2000);
     }
}

Désolé du multi post mais j'obtiens un message car le texte est trop long

Le projet video que la personne avait reussi à faire est sur le lien suivant :

et son code est ici, en fait il faudrait adapter mes bibliotheques à ce code ci mais je suis vraiment pas trop doué :\

/*
 * Arduino TFT_shield_SD2TFT example
 * 
 * Author: Kamil Lee (2018)
 * 
 * Comments:
 * This sketch shows jpeg pictures and rgb video on TFT screen
 */

#include <YATFT.h>   // Hardware-specific library
#include <util/yasdc.h>

YATFT tft(0);
SDC   sdc;

/*************************************************************************************************/
void  setup(void)
{
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 
    pinMode(13, INPUT); pinMode(12, INPUT); pinMode(11, INPUT); // set pins to input
#endif

    Serial.begin(115200);  // initialize the serial port
    Serial.println(F("TFT_shield_SD2TFT example!"));

    tft.begin();           // initialize the display
    tft.SetColor(BLACK);
    tft.ClearDevice();     // Clear screen

    Serial.print(F("FS Init... "));
    uint8_t state = sdc.FSInit();
    if (state == 0)  Serial.println(F("unsuccess."));
    else             Serial.println(F("success."));
    sdc.currentFileType = DEMO_FILE_TYPE_RGB;
}

void  loop(void)
{
    if(-1 != sdc.FindFirst("*.*", ATTR_ARCHIVE, &sdc.nextFile))
    {
        do
        {
            if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_JPEG)
            {
                if (sdc.currentFileType != DEMO_FILE_TYPE_JPEG)
                {
                    // Set YUV mode to display JPEG
                    tft.SetColor(0x007F); // Black in YUV
                    tft.ClearDevice();
                    tft.SetYUV();         // Switching shows a little green flicker
                    sdc.currentFileType = DEMO_FILE_TYPE_JPEG;
                }
                Serial.print(F("View JPEG image: "));
                Serial.println(sdc.nextFile.filename);

                FSFILE * jpeg_file;
                JPEG_DECODE  jpeg_decode;
                jpeg_file = sdc.FSfopen(sdc.nextFile.filename, "r");
                if (!jpeg_file) { Serial.println(F("Open failed!")); return (FALSE);}
                jpeg_decode.stream = (void *)jpeg_file;
                sdc.JPEGReadFromSD(&jpeg_decode, 0, 0, GetMaxX()+1, GetMaxY()+1);
                uint8_t err = sdc.FSfclose(jpeg_file);
                if (err) { Serial.println(F("Close failed!")); return err;}

                delay(1000);
            }
            else if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_RGB)
            {
                if (sdc.currentFileType != DEMO_FILE_TYPE_RGB)
                {
                    // Set RGB mode to display RGB
                    tft.SetColor(BLACK);  // Black in RGB is dark green in YUV
                    tft.ClearDevice();
                    tft.SetRGB();         // Switching shows a little green flicker
                    sdc.currentFileType = DEMO_FILE_TYPE_RGB;
                }
                Serial.print(F("Play RGB video: "));
                Serial.println(sdc.nextFile.filename);

                FSFILE * pFile = sdc.FSfopen(sdc.nextFile.filename, "rb");
                if (!pFile) { Serial.println(F("Open failed!")); return (FALSE);}
                tft.SetColor(BLACK); tft.ClearDevice();
                sdc.RGBReadFromSD(pFile, NULL);
                tft.SetColor(BLACK); tft.ClearDevice();
                sdc.FSfclose(pFile);
                delay(1000);
            }
        } while(-1 != sdc.FindNext(&sdc.nextFile));
    }
}

Ya vraiment personne pour m'aider svp ? :frowning:

Ben, on te dit que l'affichage d'une vidéo n'est pas à la portée d'un arduino.
De plus en parcourant le code, je vois bien des instructions de lecture de fichier jpeg sur carte SD mais pas celles d'affichage.
Et les bibliothèques ne sont pas celles dont on a l'habitude.

Donc ça demande un investissement lourd pour comprendre voire corriger un code pour un résultat auquel on ne croit pas

Conclusion : pas trop envie de se lancer dedans, désolé...

:frowning: Je comprend mais si la personne y est arrivée c'est que cela doit etre possible :confused: , je vais continuer à me debrouiller par moi même mais ce n'est pas une mince affaire surtout que le code n'est pas à ma portée.

Cela m'aurait été fort utile dans le projet que je pensais faire ... enfin tant pis

Que cette déception ne t'empêche pas de venir sur le forum pour des problèmes plus accessibles... :wink:

Bonsoir

et son code est ici, en fait il faudrait adapter mes bibliotheques à ce code ci mais je suis vraiment pas trop doué :

Si tu as confiance dans la réalité de la reussite de l'exemple pourquoi ne pas commencer avec SA librairie et le code qui va avec ? GitHub - YATFT/YATFT: Yet Another TFT

As tu au moins fait l'essai de cet ensemble librairie + code avant d'ambitionner une adaptation de tes librairies au code ?
Le travail se résumera peut être à une éventuelle adaptation de la librairie YATFT à ton écran.

@lesept, oui bien sur d'ailleurs 'ai acheter un petit kit complet avec plein d'experiences à faire avec ma fille, ce qui me permettra en mçme temps d'apprendre et de comprendre le fonctionnement.

@al1fch, oui oui j'ai essayé avec sa librairie qui me sort une erreur, je me suis dit peut etre que ce n'est pas adapter avec mon ecran, donc j'ai essayé de faire avec mes librairies en plus et modifier un peu le code malheureusement je tombe toujours sur une erreur. Avant de poster j'ai bien tenté de comprendre le fonctionnement. J'y pense même si çça ne fonctionne pas sans mon ecran, logiquement le programme ne devrait pas me retourner de code erreur si ?., au pire si le code est verifié et qu'il est bon mais que je ne vois rien sur mon ecran c'est qu'il faut que j'adapte juste à ma librairie?, en tous cas là ca me sort un code erreur

Arduino : 1.8.8 (Windows 7), Carte : "Arduino/Genuino Uno"

In file included from C:\Users\MAISONµ\Documents\Arduino\libraries\YATFT-master\example\TFT_shield_SD2TFT\TFT_shield_SD2TFT.ino:10:0:

C:\Users\MAISONµ\Documents\Arduino\libraries\YATFT-master\src/YATFT.h:23:40: fatal error: TimeLib.h: No such file or directory

compilation terminated.

exit status 1
Erreur de compilation pour la carte Arduino/Genuino Uno

C:\Users\MAISONµ\Documents\Arduino\libraries\YATFT-master\src/YATFT.h:23:40: fatal error: TimeLib.h: No such file or director

Comme toujours il faut analyser le message d'erreur et faire le nécessaire
Ici le message d'erreur annonce clairement une absence de la librairie TimeLib ou Time

Effectivement un coup d'oeuil à la librairie YATFT (fichier Yattft2.h ligne 23) montre que cette librairie a besoin de la librairie TimeLib.

Oui et la librairie TimeLib ne se trouve aps dans le package, alors en cherchant sur le net j'en ai bien trouvé des Timelib mais je suppose que c'est propre à chaque bibliothèque :frowning: , ca serait trop faicle de recuperer juste un TimeLib.h est que ça passe

Il te faut trouver et installer la tolalité de la librairie que l'auteur de YATFT a utilisé, pas seulement son fichier TimeLib.h

Peut être cette librairie Time souvent utilisée avec Arduino

Ici d'autre info sur le projet:
https://create.arduino.cc/projecthub/alf81010/photos-and-rgb-video-on-tft-spi-display-482914?f=1

C'est bien celle ci. La bibliothèque YATFT utilise la fonction y2kYearToTm qui vient de la bibliothèque Time de Paul Stoffregen.

C'est bizarre car la bibliothèque YATFT qui devrait gérer un écran, définit aussi des fonctions liées à une RTC DS1307... Et je ne comprends pas pourquoi...