Uno + ecran graphique

Bonjour a tous,

Je suis nouveau ici, et c' est mon premier message, je me presente rapidement, je me prenomme Christian, 46 ans environ,

de bonnes connaissances en electronique, mais nul en C, je decouvre.... soyez indulgents...

Mon soucis:

j'ai un uno, et un module afficheur graphique (2.8" nuelectronics) , sur lequel je souhaiterais juste afficher une photo qui est stockee

sur une SD, presente egalement sur le module afficheur

j' ai le morceau de code ci dessous, qui me fait un diaporama de tout ce qu'il y a sur la SD, ce que je souhaite c' est juste afficher

une photo en la chargeant par son nom !!! la je suis pas tres clair ???

et cela fait un moment que j' essaye de comprendre ce code mais cela ne m'inspire pas vraiment !

si l'un d' entre vous pouvais m' aider, me mettre sur la voix

Le code:

#include <string.h>
#include <TFT_ILI9325.h>
#include <TFT_PFF.h>


TFT_PFF pff;

uint8_t bitmap_show(char* pFile);
void buf_display(uint8_t *buf_ptr, uint16_t count);
void setup()
{
	uint8_t res;
	
	LCD::init(LCD_HORIZONTAL);
	LCD::resetArea();
	LCD::fill(LCD::GetWidth()-1, LCD::GetHeight()-1, BLACK);
	
	
  res = disk_initialize();
  if (!res)
    res = pf_mount(&pff.fs);
  
}


void loop()
{
  uint8_t res;
  DIR dir;      
  FILINFO file_info;  
	
  res = pf_opendir(&dir, "/");
  	
  if (!res )
  {
 
    while(1)
    {
      res = pf_readdir(&dir, &file_info);
      if(res) break; 
       
      if (!file_info.fname[0])
        break;
      if (!(file_info.fattrib & AM_DIR))
      {
        if (strstr(file_info.fname, ".BMP") != 0)
        {
					if(bitmap_show(file_info.fname)==0)          
	      		delay(3000);
        }
      }
		}
	}
	
}

#define BUF_SIZE 512

typedef struct BMIH { //declares BitMap Info Header structure
  unsigned long biSize;            //Length of bitmap information header (40 bytes for Windows V3 bitmaps)
  unsigned long biWidth;           //Width (pixels)
  unsigned long biHeight;          //Height (pixels)
  unsigned short biPlanes;         //Color planes, always 1
  unsigned short biBitCount;       //Color bits per pixel (1, 4, 8, 16, 24 and 32)
  unsigned long biCompression;     //Compression method, we only read uncompressed (type 0)
  unsigned long biSizeImage;       //Image data length
  unsigned long biXPelsPerMeter;   //Horizontal resolution (pixels per meter)
  unsigned long biYPelsPerMeter;   //Vertical resolution (pixel per meter)
  unsigned long biClrUsed;         //Number of colors, ignored.
  unsigned long biClrImportant;    //Number of important colors, ignored.                                  
}BMP_INFO;

typedef struct BMFH { //declares BitMap File Header structure
  unsigned short bfType;           //Always 0x42 0x4D (hex for BM <-- indicating a bitmap)
  unsigned long  bfSize;           //File size (bytes)
  unsigned short bfReserved1;      //Reserved, ignored
  unsigned short bfReserved2;      //Reserved, ignored
  unsigned long  bfOffBits;        //Location in file of the first bitmap data               
}BMP_HEADER;

uint16_t bitmap_width;
uint16_t bitmap_height;
uint8_t buf[BUF_SIZE];

uint8_t rgb_cnt=0;		
uint8_t pad_len=0;		
uint8_t pad_cnt=0;
uint16_t pixel_cnt = 0;
uint8_t RGB[3];	

void buf_display(uint8_t *buf_ptr, uint16_t count)
{
	uint16_t i;
	
	for(i=0; i<count; i++)
	{
		if(!pad_cnt){  // skip padding bytes
			RGB[rgb_cnt++]= *(buf_ptr+i);
			if(rgb_cnt==3){
				// output data
				LCD_SET_DATH((RGB[2]&0xF8)|(RGB[1]>>5));
      	LCD_SET_DATL ( ((RGB[1]&0xFC)<<3) |(RGB[0]>>3) );
      	WR0;
      	WR1;
      	rgb_cnt = 0;
				// check if there is padding data
				if(pad_len){
      		pixel_cnt++;
      		if(pixel_cnt>= bitmap_width)
      		{
      			pad_cnt = 1;
						pixel_cnt = 0;  
      		}
      	}
      }
   	}
   	else {  // pad bytes
   		if(pad_cnt++>= pad_len) pad_cnt = 0;
   	}
  }
}
      	 



uint8_t bitmap_show(char* pFile)
{
  BMP_HEADER *ptr_header;
  BMP_INFO *ptr_info;

  uint8_t res;
  unsigned short br;			// File Read count

  res = pf_open(pFile);
  if (res)
    return res;

  res = pf_read(&buf, BUF_SIZE, &br);	// read bmp header
  if (res)
    return res;
	
	// set LCD area position
  LCD::resetArea();
 	LCD::fill(LCD::GetWidth()-1, LCD::GetHeight()-1, SILVER);
 	
	ptr_header= (BMP_HEADER *)buf;
	ptr_info = (BMP_INFO *)(buf+sizeof(BMP_HEADER));
	
  if (ptr_header->bfType != 0x4d42 )		// type is 'BM'
    return 0xff;
  

 	if (ptr_info->biWidth       >  240) return 0xff; 
 	if (ptr_info->biHeight      > 320) return 0xff; 
  if (ptr_info->biCompression !=   0) return 0xff; 

	// reset count values
	rgb_cnt=0;		
	pad_cnt=0;
	pixel_cnt = 0;

  // set data
  bitmap_width  = ptr_info->biWidth;
  bitmap_height  = ptr_info->biHeight;
  
  pad_len = (4 - ((bitmap_width*3)%4))%4;
  //pad_len = 1;
  LCD::setArea(  (LCD::GetWidth()-bitmap_height)>>1, (LCD::GetHeight()-bitmap_width)>>1, 
  							 ((LCD::GetWidth()+bitmap_height)>>1)-1, ((LCD::GetHeight()+bitmap_width)>>1)-1);
  //LCD::setArea(0,0,319,239);
  
  // first display buffer - need to skip headers
  CS0;
  buf_display( buf+sizeof(BMP_HEADER)+sizeof(BMP_INFO), br-(sizeof(BMP_HEADER)+sizeof(BMP_INFO)) );
  
  if(br!= BUF_SIZE) return 0;  // very small bitmap?
  
  
  do{
  	res = pf_read((void*)buf, BUF_SIZE, &br);		// read data
    buf_display( buf,br);
  } while (!res && (br == BUF_SIZE));  				// error or eof 
  
  CS1;
 
	return 0;
  
}

Merci et a bientot

si tu remplaces file_info.fname par le nom de l'image (en extension BMP, et sans l'extension), normallement, je vois pas pourquoi ça marcherait pas.

En gros, si tu veux afficher l'image 'toto.bmp', il faut que file_info.fname='toto'

Me revoila,

une petite precision, je souhaiterais utiliser ce bout de code modifié, comme une fonction,

pour pouvoir depuis mon prog principal l' appeller quand j'aurais besoin d'afficher une image

evidement a l' appel de celui ci lui passer le nom de l' image a chager

j' espere m' etre fait comrendre.....si vous avez besoin de precisions....

A priori, pour afficher une image il suffit d'appeler la fonction bitmap_show(char* pFile) en lui passant en argument le nom du fichier à visualiser.

C' est ce que je tente, mais l' ecran reste vide..

je suppose que ma declaration de nom n' est pas bonne, mon fichier se nomme : Gplan.bmp

j' ai essayé avec et sans l' extension.... Help !

void loop()
{
  uint8_t res;
  DIR dir;      
  FILINFO file_info;  

  res = pf_opendir(&dir, "/");
  	
 // if (!res )
  {
 
   char pFile[] = ("Gplan") ;
    uint8_t bitmap_show(char* pFile);
    
    
    
	}
	
}
        if (strstr(file_info.fname, ".BMP") != 0)
        {
					if(bitmap_show(file_info.fname)==0)

D'après le code en exemple, il faut bien mettre l'extension.

regarde si bitmap_show retourne une valeur différente de 0. C'est le code d'erreur retourné par la fonction qui ouvre le fichier ou qui essaye d'y accéder.

ce matin j' ai fait de nombreux essais, sans resultat,

avec ou sans extension, le fichier est valide, quand je lance le prog exemple, pas de soucis, mon fichier s' affiche

je pense que c' est mon code qui n' est pas bon.

void loop()
{
  uint8_t res;
  DIR dir;      
  FILINFO file_info;  
	
  res = pf_opendir(&dir, "/");
  	
  if (!res )
  {
 
    while(1)
    {
      res = pf_readdir(&dir, &file_info);
      if(res) break; 
       
      if (!file_info.fname[0])
        break;
      if (!(file_info.fattrib & AM_DIR))
      {
        if (strstr(file_info.fname, ".BMP") != 0)
        {
					if(bitmap_show(file_info.fname)==0)          
	      		delay(3000);
        }
      }
		}
	}
	
}

Voila la partie du code de demo qui me semble etre la boucle principale,

mais je ne la comprends pas, j' ai l' impression qu'il n' y a que des test, je ne vois pas d' appel de fonction,

si quelqu'un pouvais m' expliquer !

Le code commenté avec l'ajout de quelques Serial.print pour voir ce qui ce passe.
Ne pas oublier de mettre un Serial.begin dans le setup

void loop()
{
  uint8_t res;
  DIR dir;      
  FILINFO file_info;  
	
  res = pf_opendir(&dir, "/");       // ouvre le fichier racine de la carte SD
  	
  if (!res )                                 // si on a ouvert le fichier racine avec succès
  {
    Serial.println("fichier racine ouvert");
    while(1)
    {
      res = pf_readdir(&dir, &file_info);         // Lecture de l'arborescence de la carte
      if(res) break;                                     // si on échoue on quitte
      Serial.println("Lecture arborescence");
       
      if (!file_info.fname[0])                         // s'il n'y a pas de fichier on quitte
        break;
      if (!(file_info.fattrib & AM_DIR))           // Si le fichier n'est pas un répertoire
      {
        Serial.println("fichier trouvé");
        if (strstr(file_info.fname, ".BMP") != 0)    // on ajoute .BMP à la fin du nom de fichier
        {
           Serial.print("ouverture de ");
           Serial.println(file_info.fname);
					if(bitmap_show(file_info.fname)==0)          // affichage du fichier
	      		delay(3000);
        }
      }
    }
}
	
}

Merci pour les commentaires,

un petit soucis suplementaire, la sortie serie fonctionne, mais cela me bloque l' afficheur, j' ai bien les donnees sur le terminal

mais l' afficheur reste muet ! peut une pin comune ou une interuption ????? dommage,

pour finir, je n' ai garde qu'une ligne de code dans ma boucle, et la pas de soucis j' affiche bien l' image de mon choix

void loop()
{
 	
     if(bitmap_show("uno.bmp")==0)          // affichage du fichier

	       		delay(3000);
     if(bitmap_show("gplan.bmp")==0)          // affichage du fichier

	       		delay(3000);  	
 }

Jamais je n' aurais pensé que l' on puisse appeller une routine avec une ligne de code commencant par if !!!

vraiment le C, a encore plein de secrets pour moi !

encore Merci, et a bientot avec d'autres questions, j' en aurai d' ici la fin du projet !!!

a bientot

Cette version devrait normalement avoir le même comportement

void loop()
{
 	
     bitmap_show("uno.bmp");          // affichage du fichier

	       		delay(3000);
     bitmap_show("gplan.bmp");          // affichage du fichier

	       		delay(3000);  	
 }

Le seul intérêt de l'autre version est de sauter la temporisation de 3 secondes si le fichier image est absent.

Jamais je n' aurais pensé que l' on puisse appeller une routine avec une ligne de code commençant par if !!!

en fait on peut mettre n'importe quoi entre les parenthèses du if pour autant que le n'importe quoi en question retourne une valeur. Si le résultat est différent de 0 on exécute le if s'il est égal à 0 on passe.

Persiste et signe....

J' ai epluché la doc de l' afficheur, nul part on ne trouve trace de la liaison serie,

des que je met la ligne serial begin, mon programme tourne, et m' envoie bien les info dans le terminal,

mais me bloque l' affichage.......

j' aimerais bien comprendre, je precise que j' utilise l'environnement 1.0, et a premiere vue il y a des soucis......

Help ! Help !

Le rétro-éclairage de l'afficheur est bien allumé?

Slt,

Oui le retro est allumé, il n'y a pas de commande pour celui-ci, des la mise sous tension, il s' allume,

et je precise bien que le programme tourne normalement, car j' ai bien tous les serial print qui s' affichent sur le terminal,

Donc , soit c' est une ligne d'e/s , utilisée par les deux, ou une interupt, ou un timer,

ou encore un probleme lié a l' utilisation de l' ide 1.0 !!!

Comment s' y retrouver dans cette jungle ?

Ok je viens de regarder la doc de l'afficheur. Toutes les broches logiques sont utilisées par l'afficheur donc on ne peut pas utiliser Serial.print et l'afficheur en même temps. Les lignes RX/TX sont utilisées comme bits de données.

ou encore un probleme lié a l' utilisation de l' ide 1.0 !!!

Dans ce cas là le plus simple c'est d'installer la version 0.23 et de re-tester.

Re,

Je doit avoir de la crotte devant les yeux, tu a trouvé cela ou dans la doc ???

il y a bien le schema, mais la j' ai pas tout compris,

Je comptais utiliser 2 sorties Pwm, j' espere qu' elles ne sont pas deja prises !

Bon je retourne regarder la doc

Bon, apres Re-lecture du Schema,

effectivement sur la gauche de celui ci, on voit bien que toutes les broches sont utilisée,

Donc, j' ai l' impression, que je ne vais rien pouvoir faire d' autre avec le Uno et ce Shield !

Si le fait d' utiliser cet afficheur empeche de faire autre chose avec l' arduino, alors j' aurais mieux fait d' acheter 10Kg de moutarde !

effectivement sur la gauche de celui ci, on voit bien que toutes les broches sont utilisée,

Oui en fait il ne reste que 3 broches de disponibles sur la carte arduino lorsque l'afficheur est installé (A3, A4, A5).

Si la liaison série n'est pas utilisable pour la mise au point du programme cela risque d'être difficile. Mais ton application est vraiment très proche du logiciel de démonstration il n'y a aucune raison pour que tu n'arrives pas à le faire fonctionner.
Si le programme de démonstration fonctionnait correctement ce n'est peut être pas un problème de version d'IDE.