Problème mémoire Arduino

Bonjour à tous, aujourd’hui, j’ai décidé de customiser un peu mon écran LCD afin qu’il affiche des chiffres en grand que j’ai moi-même dessiné. Mon code est une usine à gaz, c’est sûr, j’ai énormément de variables. Quand je téléverse, voici le message: “Le croquis utilise 10554 octets (32%) de l’espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 5920 octets (289%) de mémoire dynamique, ce qui laisse -3872 octets pour les variables locales. Le maximum est de 2048 octets.”

AH oui, 289% d’accord , …
Voici le code:

#include <avr/pgmspace.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif

//Site utilisé pour le code HEXA des pixels: https://maxpromer.github.io/LCD-Character-Creator/

uint8_t p1[100] = {0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x07};//0
uint8_t p2[100] = {0x00,0x00,0x00,0x00,0x00,0x18,0x1C,0x1C};
uint8_t p3[100] = {0x07,0x07,0x03,0x00,0x00,0x03,0x07,0x07};
uint8_t p4[100] = {0x1C,0x1C,0x18,0x00,0x00,0x18,0x1C,0x1C};
uint8_t p5[100] = {0x07,0x07,0x03,0x00,0x00,0x00,0x00,0x00};
uint8_t p6[100] = {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x1C};//5

uint8_t One1[100] = {0x00,0x01,0x07,0x0F,0x0F,0x00,0x00,0x00};
uint8_t One2[100] = {0x1E,0x1E,0x1E,0x1E,0x0E,0x0E,0x0E,0x0E};
uint8_t One4[100] = {0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E};
uint8_t One6[100] = {0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E};

uint8_t two1[100] = {0x00,0x07,0x07,0x0F,0x0C,0x0C,0x00,0x00};//10
uint8_t two2[100] = {0x00,0x18,0x1C,0x1C,0x0C,0x0E,0x0E,0x06};
uint8_t two3[100] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
uint8_t two4[100] = {0x06,0x06,0x0E,0x0E,0x0C,0x1C,0x1C,0x18};
uint8_t two5[100] = {0x03,0x03,0x07,0x07,0x0F,0x0F,0x0F,0x00};
uint8_t two6[100] = {0x10,0x10,0x00,0x00,0x1E,0x1E,0x1E,0x00};//15

uint8_t three1[100] = {0x00,0x07,0x07,0x0F,0x0C,0x0C,0x00,0x00};
uint8_t three2[100] = {0x00,0x18,0x1C,0x1C,0x0C,0x0E,0x0E,0x06};
uint8_t three3[100] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
uint8_t three4[100] = {0x06,0x06,0x0E,0x0E,0x0C,0x1C,0x1C,0x18};
uint8_t three5[100] = {0x03,0x03,0x07,0x07,0x0F,0x0F,0x0F,0x00};//20
uint8_t three6[100] = {0x10,0x10,0x00,0x00,0x1E,0x1E,0x1E,0x00};

uint8_t four1[100] = {0x00,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C};
uint8_t four2[100] = {0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06};
uint8_t four3[100] = {0x0C,0x0C,0x0F,0x0F,0x0F,0x00,0x00,0x00};
uint8_t four4[100] = {0x06,0x06,0x1F,0x1F,0x1F,0x06,0x06,0x06};//25
uint8_t four6[100] = {0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00};

uint8_t five1[100] = {0x00,0x0F,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C};
uint8_t five2[100] = {0x00,0x1E,0x1E,0x1E,0x00,0x00,0x00,0x00};
uint8_t five3[100] = {0x0C,0x0C,0x0E,0x0F,0x07,0x00,0x00,0x00};
uint8_t five4[100] = {0x06,0x06,0x0E,0x0E,0x0C,0x1C,0x1C,0x18};//30
uint8_t five5[100] = {0x03,0x03,0x07,0x07,0x0F,0x0F,0x0F,0x00};
uint8_t five6[100] = {0x10,0x10,0x00,0x00,0x1E,0x1E,0x1E,0x00};

uint8_t six1[100] = {0x00,0x03,0x07,0x06,0x0E,0x0C,0x0C,0x0C};
uint8_t six2[100] = {0x00,0x1C,0x1E,0x06,0x00,0x00,0x00,0x00};
uint8_t six3[100] = {0x0C,0x0C,0x0D,0x0F,0x0E,0x0C,0x0C,0x0C};//35
uint8_t six4[100] = {0x00,0x00,0x18,0x1C,0x0C,0x06,0x06,0x06};
uint8_t six5[100] = {0x0C,0x0C,0x0C,0x06,0x07,0x03,0x03,0x00};
uint8_t six6[100] = {0x06,0x06,0x06,0x0C,0x1C,0x18,0x18,0x00};

uint8_t seven1[100] = {0x00,0x07,0x0F,0x0C,0x0C,0x00,0x00,0x00};
uint8_t seven2[100] = {0x00,0x1E,0x1E,0x06,0x06,0x06,0x06,0x0E};//40
uint8_t seven3[100] = {0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x01};
uint8_t seven4[100] = {0x0C,0x1E,0x1E,0x0C,0x1C,0x18,0x18,0x18};
uint8_t seven5[100] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00};
uint8_t seven6[100] = {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00};

uint8_t eight1[100] = {0x00,0x07,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C};//45
uint8_t eight2[100] = {0x00,0x1C,0x1E,0x06,0x06,0x06,0x06,0x06};
uint8_t eight3[100] = {0x0C,0x0C,0x0E,0x07,0x07,0x07,0x0E,0x0C};
uint8_t eight4[100] = {0x06,0x06,0x0E,0x1C,0x1C,0x1C,0x0E,0x06};
uint8_t eight5[100] = {0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x07,0x00};
uint8_t eight6[100] = {0x06,0x06,0x06,0x06,0x06,0x1E,0x1C,0x00};//50

uint8_t nine1[100] = {0x00,0x07,0x07,0x0E,0x0C,0x0C,0x0C,0x0C};
uint8_t nine2[100] = {0x00,0x1C,0x1C,0x0E,0x06,0x06,0x06,0x06};
uint8_t nine3[100] = {0x0C,0x0C,0x0C,0x06,0x07,0x03,0x00,0x00};
uint8_t nine4[100] = {0x06,0x06,0x06,0x0E,0x1E,0x16,0x06,0x06};
uint8_t nine5[100] = {0x00,0x00,0x00,0x00,0x0C,0x0F,0x07,0x00};//55
uint8_t nine6[100] = {0x06,0x06,0x06,0x0E,0x0C,0x1C,0x18,0x00};

uint8_t zero1[100] = {0x00,0x07,0x07,0x0F,0x0E,0x0C,0x0C,0x0C};
uint8_t zero2[100] = {0x00,0x1C,0x1C,0x1E,0x0E,0x06,0x06,0x06};
uint8_t zero3[100] = {0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C};
uint8_t zero4[100] = {0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06};//60
uint8_t zero5[100] = {0x0C,0x0C,0x0C,0x0E,0x0F,0x07,0x07,0x00};
uint8_t zero6[100] = {0x06,0x06,0x06,0x0E,0x1E,0x1C,0x1C,0x00};
 
void setup() {
 lcd.init();
 lcd.backlight(); // Turn on the lcd backlight
 lcd.begin(20, 4); // Set up the lcd to have 20 char on 4 lines
 
 }
 
void loop() 
{
 //:
 lcd.createChar(0, p1);
 lcd.createChar(1, p2);
 lcd.createChar(2, p3);
 lcd.createChar(3, p4);
 lcd.createChar(4, p5);
 lcd.createChar(5, p6);
 
 lcd.setCursor(0,0);
 lcd.printByte(0);
 lcd.setCursor(1,0);
 lcd.printByte(1);
 lcd.setCursor(0,1);
 lcd.printByte(2);
 lcd.setCursor(1,1);
 lcd.printByte(3);
 lcd.setCursor(0,2);
 lcd.printByte(4);
 lcd.setCursor(1,2);
 lcd.printByte(5);

 delay(1000);
 lcd.clear();
 
 //1
 lcd.createChar(6, One1); // Sends the custom char to lcd
 lcd.createChar(7, One2);
 lcd.createChar(8, One4);
 lcd.createChar(9, One6);
 
 lcd.setCursor(0,0); // Set lcd cursor to the start of the first row
 lcd.printByte(6); // Custom char
 lcd.setCursor(1,0);
 lcd.printByte(7);
 lcd.setCursor(1,1);
 lcd.printByte(8);
 lcd.setCursor(1,2);
 lcd.printByte(9);

 delay(1000);
 lcd.clear();

 //2

 lcd.createChar(10, two1);
 lcd.createChar(11, two2);
 lcd.createChar(12, two3);
 lcd.createChar(13, two4);
 lcd.createChar(14, two5);
 lcd.createChar(16, two6);

 lcd.setCursor(0,0);
 lcd.printByte(10);
 lcd.setCursor(1,0);
 lcd.printByte(11);
 lcd.setCursor(0,1);
 lcd.printByte(12);
 lcd.setCursor(1,1);
 lcd.printByte(13);
 lcd.setCursor(0,2);
 lcd.printByte(14);
 lcd.setCursor(1,2);
 lcd.printByte(15);

 delay(1000);
 lcd.clear();

 //3

 lcd.createChar(16, three1);
 lcd.createChar(17, three2);
 lcd.createChar(18, three3);
 lcd.createChar(19, three4);
 lcd.createChar(20, three5);
 lcd.createChar(21, three6);

 lcd.setCursor(0,0);
 lcd.printByte(16);
 lcd.setCursor(1,0);
 lcd.printByte(17);
 lcd.setCursor(0,1);
 lcd.printByte(18);
 lcd.setCursor(1,1);
 lcd.printByte(19);
 lcd.setCursor(0,2);
 lcd.printByte(20);
 lcd.setCursor(1,2);
 lcd.printByte(21);

 delay(1000);
 lcd.clear();

 //4

 lcd.createChar(22, four1);
 lcd.createChar(23, four2);
 lcd.createChar(24, four3);
 lcd.createChar(25, four4);
 lcd.createChar(26, four6);

 lcd.setCursor(0,0);
 lcd.printByte(22);
 lcd.setCursor(1,0);
 lcd.printByte(23);
 lcd.setCursor(0,1);
 lcd.printByte(24);
 lcd.setCursor(1,1);
 lcd.printByte(25);
 lcd.setCursor(1,2);
 lcd.printByte(26);

 delay(1000);
 lcd.clear();

 
}

J’ai du couper un bout du code, ça ne passait pas (trop long) en messages.

J’ai entendu parler de la fonction F (flash) mais cela ne marche qu’avec le Serial.print, pas avec l’écran ni avec la bibliothèque i2c.
Merci d’avance, passez une bonne journée

Pourquoi tu déclares des tableaux de longueur 100 et tu n'utilises que 8 valeurs ?

Ah, chaques tableaux sont indépendants ? C'est pas un espèce de grand tableau qui répertorie toutes les valeurs ?? J'ai choisis 100 pour être tranquille si jamais j'agrandis le nombre de variables

9 suffira

Un tableau constant peut aussi se gérer en progmem.

Autre pb : tu ne peux definir au maximum que 8 caractères personnalisés à un instant t. Cette limite provient du lcd lui-même

J'ai un dernier problème. Après avoir réussi à afficher correctement tous les nombres uns à uns (et honnêtement, le résultat est génial), je me suis rendu compte que lorsque j'affiche 2 nombres sur le même écran, ça déconne complètement. Les chiffres sont "mixés". Je pense que cela vient du fameux tableau qui est assez limité. Lorsque j'affiche le "bloc" de caractère, celui ci rentre en conflit avec les blocs des autres nombres. J'espère qu'il est possible de rétablir cela ... Merci beaucoup en tout cas

Peux tu poster un code simplifié, par exemple pour afficher le nombre 10 ? Et une photo de ce que tu obtiens ?

Quand vous refaites un lcd.createChar sur une entrée déjà utilisée à l’écran ça rafraîchit l’écran... vous ne pouvez avoir à un instant T que 8 caractères personnalisés comme l’a dit @bricoleau.

si vous affichez par exemple le caractère N° 1 à l’écran puis changez sa définition, il,change instantanément aussi sur l’écran.

Trouver un compromis , écran par écran et pour chaqu'un d'eux faire un jeu unique de 8 caractères personnalisés.

Ça veut dire que je ne pourrais pas afficher deux nombres différents sur le même écran ?..

iFrostizz: Ok, c'est bien ce que je pensais .... Comment puis-je faire dans ce cas ?? :/

Ce que vous avez s'appelle un "character LCD" en gros il ne vous permet que d'afficher des caractères prédéfinis en ROM (CGROM = Character Generator ROM)) et correspondant aux codes envoyés. les adresses du début sont en fait de la RAM (CGRAM ) et donc c'est pour cela que vous pouvez y charger le masque que vous voulez mais tout le reste est câblé en dur...

de nombreux LCD sont pilotés par le HD44780

|500x223

--> bref pour avoir tout vos caractères il faudrait changer la CGROM de votre LCD pour y mettre vos caractères... et ça ne se fait pas trop...

si vous voulez jouer un peu plus finement, il faut prendre un "graphical LCD" qui permet d'adresser chaque pixel de l'écran indépendamment des autres - ce qui vous permet de peindre ce que vous voulez.

a veut dire que je ne pourrais pas afficher deux nombres différents sur le même écran ?..

Afficher des nombres différents sur le même écran ?

Oui si l'affichage utilise des chiffres 5x7 pixels ou 5x8 pixels dont le dessin figure en CGROM

Non probablement s'il s'agit d'utiliser des grands chiffres dessinées à l'aide des 8 seuls motifs définissables dans le code .... à moins de trouver un ensemble de 8 motifs permettant de composer de manière satisfaisante les 10 chiffres

Passer comme indiqué par J-M-L à un afficheur LCD graphique , afficheur géré pixel par pixel et non bloc par bloc.

Ces afficheurs LCD graphiques sont en général gérables avec des librairies comportant des jeux de caractères de tailles diverses.

iFrostizz: Mince alors... Je ne sais pas comment faire dans ce cas

Vous avez pris une solution matérielle avant d'écrire les specifications... donc maintenant vous avez deux options: changer les spécifications (et comment vous dessinez) ou changer le matériel...

Bonjour,

Google "Arduino lcd big char" > images, il y a tout ce que tu cherches !!

Jacques

Bonjour,

Il faut faire avec les 8 caractères graphiques. Ici tu as un exemple de ce qu'on peut faire

ou dans cette conversation (listée plus haut)

|500x286 |500x278 |500x286

iFrostizz:
D’accord, merci beaucoup de vos solutions. Je vais alors réfléchir afin d’avoir les chiffres de 0 à 9 avec seulement 8 blocs différents.

voilà ceux proposés dans le lien de kamill

Pas de soucis pour les caractères en ROM - vos appellez simplement un write(‘:’) et ça marchera (mais faut plutôt faire un point sur la ligne du haut et un sur la ligne du bas ou avec avec les caractères rouges prédéfinis ce serait le premier en haut à gauche et celui en bas à gauche)