Optimiser code avec snprintf et déclarations char*

Boinjour,
J'utilise un code qui appelle la fonction:

//line 0:
                    snprintf((char *)&hott_txt_msg->text[0],21,"  PRESSURE SENSOR   ");

Le problème c'est que ces manipulations de chaine plus des chaines que je dois mettre en mémoire me prennent une place énorme dans la RAM.
Y a t'il un moyen pour que ça prenne moins de place?

J'ai essayé avec F() mais ça me dit:

snprintf((char *)&hott_txt_msg->text[0],21,"  PRESSURE SENSOR   ");

error: cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '3' to 'int snprintf(char*, size_t, const char*, ...)'

J'ai ça aussi qui prend de la place comment je peux faire:

char* alarm_on_off_batt[11];      // For Radio OSD
char* alarm_on_off_pressure[11];  // For Radio OSD
char* init_on_off_pressure[11];   // For Radio OSD
char* init_pressure_ok[10];       // For Radio OSD

Qu'est ce qui change entre :

snprintf((char *)&hott_txt_msg->text[0],21," PRESSURE SENSOR ");

et

snprintf((char *)&hott_txt_msg->text[0],21," PRESSURE SENSOR ");

??

Tout ce que je sais c'est qu'avec le print du Serial tu transformes :

ça

Serial.println("Helo world");

en

Serial.println(F("Helo world"));

au lieu de sotcker la chaine hello world en RAM ça la met en flash

Bonjour

john_lenfr:
J'ai essayé avec F() mais ça me dit:

snprintf((char *)&hott_txt_msg->text[0],21,"  PRESSURE SENSOR   ");

error: cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '3' to 'int snprintf(char*, size_t, const char*, ...)'

On ne peut pas utiliser F() directement à la place d'un char*

Si ça marche pour Serial.print() (par exemple) c'est parce qu'une des méthodes print de la classe Print prend pour argument un const __FlashStringHelper*

À partir de ce pointeur sur la mémoire programme, les octets de la chaîne doivent être recopiés dans un buffer.

Par exemple voici le code de print()

size_t Print::print(const __FlashStringHelper *ifsh)
{
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    n += write(c);
  }
  return n;
}

Il faudrait donc écrire un snprintf (appelons le psnprintf) qui prend comme 3e argument un const __FlashStringHelper *ifsh, alloue un buffer en variable locale pour y recopier la chaine à partie de la mémoire programme puis appelle snprintf avec ce buffer comme 3e argument.

Merci grace à vos remarques j'ai fouiné un peu et je suis tombé sur:
snprintf_P utilisé conjointement avec PSTR()

ce qui donne par exemple:

snprintf_P((char *)&hott_txt_msg->text[0],21,PSTR("  PRESSURE SENSOR   "));

Pour l'instant ça me fait passer de 141 à 845 de RAM dispo donc c'est pas mal!
:wink:

Hello,

Pourquoi utiliser une construction alambiquée (char *)&hott_txt_msg->text[0]
alors que ceci devrait fonctionner:hott_txt_msg->text ?

Parce qu'il y a d'autres valeurs du type:

// Affichage de la page 1
//line 0:
snprintf_P((char *)&hott_txt_msg->text[0],21,PSTR(" VALEUR "));
//line 1:
snprintf_P((char *)&hott_txt_msg->text[1],21,PSTR("" VALEUR ": %i.%iv"),(int) Lipo_total, ((int) (Lipo_total*100)) % 100);
//line 2:
snprintf_P((char *)&hott_txt_msg->text[2],21,PSTR("" VALEUR " : %iS"),nb_Lipo);
//line 3:
snprintf_P((char *)&hott_txt_msg->text[3],21,PSTR("" VALEUR " :"));
//line 4:
snprintf((char *)&hott_txt_msg->text[4],21,*alarm_on_off_batt);
//line 5:
if (((int) (alarm_min1 % 100)) == 5 || ((int) (alarm_min1 % 100)) == 0)// gestion affichage pour mettre un 0 apres la virgule des valeurs X.05v et X.00v car le modulo renvoi 0 ou 5 pour les valeurs types 100,105,200,205,300,305,etc...
snprintf_P((char *)&hott_txt_msg->text[5],21,PSTR(" Alarm value : %i.0%i v."),(int) (alarm_min1/100),(int) (alarm_min1 % 100)); // adding a 0
else // affichage normal
snprintf_P((char *)&hott_txt_msg->text[5],21,PSTR(" Alarm value : %i.%i v."),(int) (alarm_min1/100),(int) (alarm_min1 % 100)); // no need of adding 0
//line 6:
snprintf_P((char *)&hott_txt_msg->text[6],21,PSTR(" Alarm repeat: %i s."),(alarm_interval/1000));
//line 7:
snprintf_P((char *)&hott_txt_msg->text[7],21,PSTR("" VALEUR " %d/1"),page_settings); //Affichage numero page courant en bas de l'écran à droite

Et surtout parce que ce n'est pas moi qui ait écrit ce code d'origine et que je ne comprends pas tout