Print une suite de caractère (bonne façon pour du AsciiArt sur Sérial)

Bonjour à tous,

Exemple de code :

byte charForDrawingList[10]={0x20,0x5f,0x2d,0x3d,0x7c,0x2f,0x5c,0xc2,0xb0,0x4f};
Serial.println(char (charForDrawingList[5])+char(charForDrawingList[0])+char(charForDrawingList[6]));

En sortie Serial j'obtiens :
171

Comment dois je m'y prendre pour obtenir ceci :
/ \

Serial.print(charForDrawingList[5]);
Serial.print(charForDrawingList[0]);
Serial.println(charForDrawingList[6]);

salut plus court plus propre, je recherche.
ps : sans char () tu obtiendras : 47329 :smiley:

Je ne comprends pas ta réponse...

  byte charForDrawingList[10]={0x20,0x5f,0x2d,0x3d,0x7c,0x2f,0x5c,0xc2,0xb0,0x4f};
  Serial.print(char(charForDrawingList[5]));
  Serial.print(char(charForDrawingList[0]));
  Serial.println(char(charForDrawingList[6]));

ou ça

  Serial.write(charForDrawingList[5]);
  Serial.write(charForDrawingList[0]);
  Serial.write(charForDrawingList[6]);
  Serial.println();

Merci fdufnews

pas d'autres possibilités ?
Comme je disais un code plus contact visuellement, plus "classe" (on se comprend)?

ah oui avec write plus léger déjà...

Pourquoi chercher à compliquer ?
Tu peux faire :

#define W Serial.write
#define C charForDrawingList
W(C[5]);
W(C[0]);
W(C[6]);
W('\n');

:grin:

Ça dépend un peu de la finalité de la chose.
Si c'est juste un affichage ou si tu dois faire ça plusieurs fois avec des séquences de valeurs différentes

merci,
j aime bien quand y a le moins de texte possible c'est plus lisible (pour moi).
En gros pour un projet pédagogique je voudrais utiliser des asciiart
de ce type :

 _
/ \
|°|
\_/ 
/ \

    _ 
   /=\
[-- O --]
   \=/
    |
   / \ 
 

alors pour le moment j ai deux choix :
soit je fais comme marqué au dessus et me retrouve avec un Array simple mais une mise en place avec des serial (ou W :wink: ) en masse
ou j'utilise un convertisseur asciiart vers Hex et j arrive à ceci mais avec plein de array (un par dessin) avec des 'doublons'


byte asciiHexBot[]={0x20, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x0a, 0x20, 0x5b, 0x2e, 0x2e, 0x5d, 0x20, 0x0a, 0x2f, 0x7c, 0x5f, 0x5f, 0x7c, 0x5c, 0x0a ,0x20, 0x64, 0x20, 0x20, 0x62, 0x20, 0x0a, 0x2d, 0x2d, 0x5e, 0x2d, 0x2d, 0x20,
  };
  

byte len=sizeof(asciiHexBot)/sizeof(*asciiHexBot);

  for (int i =0; i<len; i++)
  { 
    Serial.print(char (asciiHexBot[i]));
  }

pour le moment j aurais + de 20 visuels

Il n'y a pas de doublons. Il faudra bien que tu décrives chacun des objets.

Tu peux aussi faire ça

char art1[] ={"\
    _ \n\
   /=\\\n\
[-- O --]\n\
   \\=/\n\
    |\n\
   / \\ "};
   
char art2[] ={"\
 _\n\
/ \\\n\
|°|\n\
\\_/ \n\
/ \\"};

void setup() {
  Serial.begin(115200);
  Serial.println(art1);
  Serial.println(art2);
}

void loop() {
  // put your main code here, to run repeatedly:

}

C'est un peu laborieux car il faut ajouter un \n\ à chaque fin de ligne pour indiquer le saut de ligne et aussi que la chaîne continue sur la ligne suivante et il faut en plus doubler tous les \ qui font partie du symbole

Merci pour ta rapidité et tes réponses généreuses

Quid : si j ai un tableau qui reprend disons les 5 char qui composent les asciiart
et que j'utilise la premier version posté cad

#define W Serial.write
#define C charForDrawingList
void ascii1(){
W(C[5]);
W(C[0]);
W(C[6]);
W('\n');
}
void ascii2(){
W(C[1]);
W(C[0]);
W(C[1]);
W('\n');
}
etc

j 'aurais la même "prise" de mémoire sur le UNO que si j'effectue ta dernière proposition ?

non.
Dans le cas que je propose tu utilises un octet pour chaque caractère et le code qui fait l'affichage n'existe qu'une fois.
Si tu utilises la macro W() le code représenté par W() sera dupliqué autant de fois.

Il faut voir de quelle mémoire tu parles.
Si on conserve l'écriture actuelle les tableaux utilisent de la RAM et la macro W() utilises de la mémoire programme.
Maintenant les tableaux peuvent être placés en mémoire programme si on utilise progmem dans la déclaration des tableaux.
L'avantage que je vois dans l'écriture que j'ai proposé c'est pour la maintenance car on a un petit aperçu du motif qui sera plus facile à modifier s'il y a une erreur de saisie.

ok

chouette proposition.

La question de la mémoire est, tu as touché juste, le point chaud de ce projet.
Il y a aussi bcp de String ( "lignes de dialogue").
il y aura aussi un peu d'EEPROM pour mémoriser des info (nom utilisateur, choix, avancement des étapes) pour garder en mémoires entre chaque les ateliers.

je ne connaissais pas progmem c'est intéressant

Voir là

donc si j ai bien compris

void setup() {
  Serial.begin(9600);
  while (!Serial); 
Serial.println(F("Something"));

est = à

const char signMessage[] PROGMEM = {"Something"};

void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB
char myChar ;
  // read back a char
  for (byte k = 0; k < strlen_P(signMessage); k++) {
  myChar = pgm_read_byte_near(signMessage + k);
    Serial.print(myChar);
  }
Serial.println();

?

Quelque chose comme ça

const char art1[] PROGMEM ={"\
    _ \n\
   /=\\\n\
[-- O --]\n\
   \\=/\n\
    |\n\
   / \\ "};
   
const char art2[] PROGMEM ={"\
 _\n\
/ \\\n\
|°|\n\
\\_/ \n\
/ \\"};

const char art3[] PROGMEM ={"\
                \\||/\n\
                |  @___OO\n\
      /\\  /\\   / (__,,,,|\n\
     ) /^\\) ^\\/ _)\n\
     )   /^\\/   _)\n\
     )    _/  / _)\n\
 /\\  )/\\/ ||  | )_)\n\
<  >      |(,,) )__)\n\
 ||      /    \\)___)\\\n\
 | \\____(      )___) )___\n\
 \\_______(______;;; __;;;\n\
"};

const char art4[] PROGMEM ={"\
             \\|||/\n\
             (o o)\n\
   |----ooO---(_)---------|\n\
   |     Arduino rocks    |\n\
   |                      |\n\
   |----------------Ooo---|\n\
            |__|__|\n\
             || ||\n\
            ooO Ooo\n\
"};

void printArt(const char* ptrS ){
  char myChar;
  unsigned int k=0;
  while((myChar = pgm_read_byte_near(ptrS + k++))){
    Serial.print(myChar);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  printArt(art1);
  printArt(art2);
  printArt(art3);
  printArt(art4);
}

void loop() {
  // put your main code here, to run repeatedly:

}

La compilation retourne

Le croquis utilise 2042 octets (6%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 188 octets (9%) de mémoire dynamique, ce qui laisse 1860 octets pour les variables locales. Le maximum est de 2048 octets.

RAM consommée pas grand chose et il reste beaucoup de mémoire programme.

une nouvelle fois merci pour ton retour.

peux tu me dire si j ai bien compris le rôle de F()
ceci sert à stoker ds la mémoire FLASH (ou RAM) un String par exemple?
Comme dans cet exemple :

Serial.println(F("Something"));

PS :tres jolis AcsiiArt :slight_smile:

F() permet de faire afficher une chaîne de caractères qui sera stockée en Flash.
Un inconvénient de cette macro c'est que si tu répètes 10 fois la ligne Serial.println(F("Something")); dans ton programme la chaîne sera écrite 10 fois en Flash. Dans ce cas il est plus intéressant d'utiliser un tableau avec PROGMEM.

j ai plus de question

un grand merci sensei @fdufnews

De rien