Icones 96x96 et const unsigned short

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.

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

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?

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.

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);*
  • }*
    }

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]

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

bricoleau:
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?

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

Rigolo:
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.

pepe:
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) :frowning:

pepe:
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.

pepe:
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.