Go Down

Topic: Icones 96x96 et const unsigned short (Read 2182 times) previous topic - next topic

Rigolo

Je cherche à afficher des icônes sur un TFT avec une Méga. Elles sont stockées dans "const unsigned short Zoom_In[0x2400] PROGMEM ={ ..." . Elles font 96x96. Je peux en avoir deux. Lorsque je cherche à en afficher une troisième, c'est un plantage. Est ce qu'il y a une limite?
j'arrive à 101996 octets 40% de mémoire avec 3 icônes.
merci.

trimarco232

Bonjour,

ce qu'il faut faire :
lire puis afficher les icônes une à une

ce qu'il ne faut pas faire :
lire toutes les icônes, puis les afficher

Rigolo

C'est probablement ce qui se passe, vu que mon programme fonctionnait très bien avec 3 icônes 32x32.
Il y a un problème sur l'adressage de mémoire.
J'avoue que là je cale, n'étant pas informaticien.
Quelqu'un a t il un lien d'un exemple de programme pour m'éclairer?

bricoleau

Bonjour

Merci de montrer le bout de code dans lequel le tableau zoom_in est utilisé, c'est-à-dire l'appel à une fonction ou méthode prenant ce tableau en paramètre.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Rigolo

sous programme récupéré d'ici:
http://forum.arduino.cc/index.php?topic=372075.0


void drawIcon(const unsigned short* icon, int16_t x, int16_t y, int8_t width, int8_t height) {
  uint16_t  pix_buffer[BUFF_SIZE];   // Pixel buffer (16 bits per pixel)
  // Set up a window the right size to stream pixels into
  tft.setWindow(x, y, x + width - 1, y + height - 1);
  // Work out the number whole buffers to send
  uint16_t nb = ((uint16_t)height * width) / BUFF_SIZE;
  // Fill and send "nb" buffers to TFT
  for (int i = 0; i < nb; i++) {
    for (int j = 0; j < BUFF_SIZE; j++) {
      pix_buffer[j] = pgm_read_word(&icon[i * BUFF_SIZE + j]);
    }
    tft.pushColors(pix_buffer, BUFF_SIZE);
  }
  // Work out number of pixels not yet sent
  uint16_t np = ((uint16_t)height * width) % BUFF_SIZE;
  // Send any partial buffer left over
  if (np) {
    for (int i = 0; i < np; i++) pix_buffer = pgm_read_word(&icon[nb * BUFF_SIZE + i]);
    tft.pushColors(pix_buffer, np);
  }
}

bricoleau

#5
Feb 29, 2016, 07:02 pm Last Edit: Feb 29, 2016, 07:03 pm by bricoleau
Bonjour

Ton problème se situe dans l'utilisation de pgm_read_word()

Cette fonction lit le contenu de la flash à une certaine adresse, pour le recopier en ram (dans un buffer), à partir d'où les données peuvent être utilisées par d'autres fonctions (en l'occurrence tft.pushColors)

Le problème est qu'en standard, les adresses des données en flash sont gérées sur 2 octets = 16 bits => valeur max 65535.

Sur une mega, pour aller au-delà des 64 ko, il faut utiliser la notion d'adresse lointaine (far) et la fonction pgm_read_word_far().
Mais c'est un peu galère, voire rédhibitoire si tu n'es pas un peu musclé en programmation, car tu risques de ne trouver aucun exemple de code prêt à l'emploi.

La principale difficulté est de récupérer l'adresse far d'une constante en flash.
Perso je n'ai trouvé à le faire qu'en passant par un peu d'assembleur.

Voir ce topic

Après c'est facile : l'adresse elle-même est stockée en ram dans un uint_farptr_t (sur 4 octets il me semble), que tu peux manipuler pour calculer l'adresse d'un élément de ton tableau constant, et la passer à la fonction pgm_read_word_far()

PS : quand tu publies du code ici sur le forum, merci de le placer entre une balise [code] et une balise [/code]
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Rigolo

Pas simple tout çà pour moi.
Merci quand même.

Rigolo

La principale difficulté est de récupérer l'adresse far d'une constante en flash.
Ne peut on pas imposer une adresse fixe de stockage au départ?

Rigolo

Et existe t il une instruction pour obliger le stockage d'une icône en mémoire haute au delà des 128k?

guix

Et existe t il une instruction pour obliger le stockage d'une icône en mémoire haute au delà des 128k?
Ce n'est pas nécessaire. Voici un exemple d'usage ICI.

guix

#10
Mar 07, 2016, 09:02 am Last Edit: Mar 07, 2016, 09:05 am by guix

En effet, en plaçant les tableaux au début du croquis, c'est tout le code exécutable du programme et les bibliothèques (exécutable et constantes) qu'on déplace en mémoire haute, avec pour conséquences
Très intéressant _pepe_, je n'avais pas pensé à cela. Es-tu sûr que le code exécutable est stocké après les variables progmem? Si c'est vraiment le cas, il va falloir que je repense certains de mes programmes (bien que je n'ai pas constaté de bug, ce qui m'inquiète un peu c'est la perte de performances) :(

Rigolo

et le risque de ne plus pouvoir utiliser certaines bibliothèques prévues pour fonctionner uniquement en mémoire basse (i.e. conçues pour les autres Arduinos AVR, avec pointeurs sur 16 bits).
Ca doit être mon cas actuellement, plantage de l'affichage TFT. D'où ma question de vouloir stocker en mémoire haute.

Rigolo

Mais comme je l'ai expliqué, cela nécessite d'apporter des modifications à l'environnement Arduino
Cela pourrait peut être faire l'objet d'une amélioration du programme Arduino. C'est quand même bête de ne pas pouvoir maitriser un minimum la gestion de la mémoire haute.
En tout cas, merci pour votre aide et éclairement.

Go Up