Problème avec sprintf

Avec ce code

  if (gps.time.minute() != bMinOld)
  {
    bMinOld = gps.time.minute();
    char cHeu[9];
    sprintf(cHeu, "%02d:%02d", gps.time.hour() + bHeureEte, bMinOld);
    Serial.println(cHeu);
    Serial.println(bMinOld);
    //for (int a = 0; a < 35; a++)
      ssn.printSegNum(X2, 16 + BOXSIZE * 5, cHeu);//Ora
    uiBatt = (analogRead(PINBATTERIE) );//- 640 ) / 9;//630 860    uiBatt 0 24
    uiBatt = map(uiBatt, 785, 1023, 0, 24);
    Serial.println(analogRead(PINBATTERIE));
    tft.fillRect(X2 + 65, 41, 10, 24, RED);//Batteria
    Serial.print("uiBatt: ");
    Serial.println(uiBatt);
    for (int b = 65 ; b > 65 - uiBatt; b--)
      tft.drawFastHLine(X2 + 65, b, 9, GREEN);
    Serial.println("Time");

  }

Dans le monitor j'ai

17:21:59.968 -> 17:702d
17:21:59.968 -> 22
17:22:00.001 -> 973
17:22:00.001 -> uiBatt: 18
17:22:00.001 -> Time

17:702d!!!!!
Je n'arrive pas à voir l'erreur!
Ce n'ai pas la première fois que j'utilise cette fonction pour afficher l'heure.

En effet, c'est cheulou ! En plus les minutes commencent par un 7 !!!
Je vois deux possibilités :

  • Es-tu sûr que bMinOld est un int ?
  • Vérifie s'il n'y a pas un caractère caché dans ton format : retape au clavier le format "%02d:%02d"

J'ai trouvé!!
l'erreur venais d’ailleurs:

  if (fDistance != fDistanceOld)
  {
    fDistanceOld = fDistance;
    sprintf(cAlt, "%02d.%02d", (int)fDistance, (int)(fDistance * 100) % 100); 
    //for (int a = 0; a < 35; a++)
      ssn.printSegNum(X1, 16 + BOXSIZE * 3, cAlt);//Dist
    Serial.println("fDistance");
  }

un . au lieu de :
Cette erreur a influencé le code une trentaines de lignes plus bas!

Par contre je n'ai pas compris pourquoi? On peux pas utiliser le point?

Tu ne montres pas tes déclarations de variables. Difficile d'expliquer.

byte bVitMax = 0, bMinOld = 61, bSecOld = 61, bHeureEte = 0, bVitMoy = 0, uiVitFraOld = 1, uiVitOld = 1, bVitMoyOld = 1, bVitGPSOld = 1;// bSetEEPROMAdr;
double dHeureDepart = 0;
float fDistance = 0.00f, fOdo = 0.00f, fOdoOld = 1.00f, fVitesse = 0.0f, fDistanceOld = 1;//, fTrip, fTripBis;
boolean boSauvegardeODO = false;
uint16_t uiDiametro = 2000, uiBatt;
uint32_t lPulseTime, lTimeStart = 0, cont = 0;
uint64_t lDis = 0, lOdo = 0;
int iAltDep = 0, iAltOld = 1, iRoll = 0, iPitch = 0, iRollOld = 1, iPitchOld = 1, iPitchAdj;

Et cAlt ?

void loop(void)
{
  GPS();
  if (gps.time.second() != bSecOld)
  {
    //FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.
    bSecOld = gps.time.second();
    PrintLCD();
    Serial.println("LCD");
  }
  TouchScreen();
}

void PrintLCD()
{
  char cAlt[9];
  if (fDistance != fDistanceOld)
  {
    fDistanceOld = fDistance;
    sprintf(cAlt, "%02d:%02d", (int)fDistance, (int)(fDistance * 100) % 100); 
    //for (int a = 0; a < 35; a++)
      ssn.printSegNum(X1, 16 + BOXSIZE * 3, cAlt);//Dist
    Serial.println("fDistance");
  }

Je ne vois pas pourquoi un . à la place de : poserait problème.

Oui, il doit y avoir un problème autre part, vérifie les dimensions des tableaux, on ne sait jamais...

Dans ma librairie SavSegNum, la fonction pour imprimer est:

void SavSegNumFast::printSegNum(uint16_t posX, uint16_t posY, char charToPrint[])
{
  _posY = posY;
  size_t c = strlen(charToPrint);
  uint8_t a;
  for (uint8_t b = 0; b < c; b++)
  {
    _posX = posX + b * _l + (_inr * b);
    switch (charToPrint[b])
    {
      case '0': { for (a = 0; a < 7; a++) draw0(a); break; }
      case '1': { for (a = 0; a < 7; a++) draw1(a); break; }
      case '2': { for (a = 0; a < 7; a++) draw2(a); break; }
      case '3': { for (a = 0; a < 7; a++) draw3(a); break; }
      case '4': { for (a = 0; a < 7; a++) draw4(a); break; }
      case '5': { for (a = 0; a < 7; a++) draw5(a); break; }
      case '6': { for (a = 0; a < 7; a++) draw6(a); break; }
      case '7': { for (a = 0; a < 7; a++) draw7(a); break; }
      case '8': { for (a = 0; a < 7; a++) draw8(a); break; }
      case '9': { for (a = 0; a < 7; a++) draw9(a); break; }
      case ' ': { for (a = 0; a < 7; a++) drawSP(a); break; }
      case '-': { for (a = 0; a < 7; a++) drawMinus(a); break; }
      case '+': { for (a = 0; a < 7; a++) drawPlus(a); break; }
      case '=': { for (a = 0; a < 7; a++) drawEQ(a); break; }
      case '/': { for (a = 0; a < 7; a++) drawDiv(a); break; }
      case '.': { for (a = 0; a < 7; a++) drawDot(a); break; }
      case ':': { for (a = 0; a < 7; a++) drawTP(a); break; }
      case '*': { for (a = 0; a < 7; a++) drawMult(a); break; }
    }
  }
}
;

Peut_il y avoir un problème avec charToPrint[]?

bMinOld Est un byte donc un uint8_t
Essayez avec %02[color=red][b]u[/b][/color] ou %02hhu

La spec dit

...If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

Peut_il y avoir un problème avec charToPrint[]?

Je ne sais pas comment est dérini _posY. La spec dit un truc du genre

In addition, some identifiers are reserved for use by C ++ implementations and shall not be used otherwise; no diagnostic is required. (a) Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use. (b) Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace

donc si c’est une variable globale c’est un souci (mais si c’est une variable d’instance c’est OK).

Sinon c’est toujours bien de prévoir un default dans les switch() pour attraper les erreurs

donc si c'est une variable globale c'est un souci (mais si c'est une variable d'instance c'est OK).

Quelle règle utilisez vous si c'est une variable globale?
le .h:

private:
void verticalC(uint16_t posx, uint16_t posy);
void horizontalC(uint16_t posx, uint16_t posy);
void vertical(uint16_t posx, uint16_t posy);
void horizontal(uint16_t posx, uint16_t posy);
void swSeg(char charToPrint);
void draw0(byte nrSeg);
void draw1(byte nrSeg);
void draw2(byte nrSeg);
void draw3(byte nrSeg);
void draw4(byte nrSeg);
void draw5(byte nrSeg);
void draw6(byte nrSeg);
void draw7(byte nrSeg);
void draw8(byte nrSeg);
void draw9(byte nrSeg);
void drawSP(byte nrSeg);
void drawDiv(byte nrSeg);
void drawMult(byte nrSeg);
void drawMinus(byte nrSeg);
void drawPlus(byte nrSeg);
void drawDot(byte nrSeg);
void drawTP(byte nrSeg);
void drawEQ(byte nrSeg);
void drawPixel(uint64_t uiCarattere);
int8_t _segW [20];
uint8_t _segH0, _segH1, _segH2, _segL0, _segL1;
uint8_t _contSeg, _contNum;
int16_t _l, _h, _hs, _inr;
uint16_t _color, _bColor;
uint16_t _posX, _posY;
#ifdef SAVSSD1306
Adafruit_SSD1306 _tft;
#endif
#ifdef MCUFRIEND
MCUFRIEND_kbv _tft;
#endif
#ifdef MYUTFTX
MYUTFT _tft;
#endif

Sinon c'est toujours bien de prévoir un default dans les switch() pour attraper les erreurs

Dans la future version, j'ai déjà pensé à ça!

f any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

Intéressant! je vais essayer.[/quote]

Quelle règle utilisez vous si c'est une variable globale?

et bien je ne mets pas de _ au début :). J'utilise simplement du camelCase.