kein Minuszeichen (Altimeter with Arduino Pro mini, OLED display 128x64, BMP180)

Ich hab dieses Projekt nachgebaut:
Altimeter with Arduino Pro mini, OLED display 128x64, BMP180 pressure sensor

Ich konnte es unter IDE1.6.6 kompilieren nachdem ich einige uint8_t Bezüge in den externen Dateien zu const uint8_t verändert habe.

Die Anzeige auf dem OLED erfolgt unter anderem mit einem generierten Font Font24x40.c welcher große Ziffern von 0 bis 9 enthält aber kein Minuszeichen ( kann ich aber selbst hinzufügen oder mit der drawRectangle Funktion sicher auch erzeugen).

Mein Problem ist, daß der Programmcode an der Stelle für mich zu schwer zu verstehen ist um das Müllzeichen welches bei negativer Höhe (Altitude in m) erscheint zu korrigieren. ( z.B. _-0.1 m bis -99.9 m )

So wie ich es bisher verstehe wird aus einem Buffer eine double Zahl gelesen, in einen String gewandelt, die Länge bestimmt und Stück für Stück ein Zeichen in eine Ziffer des Font24x40 übersetzt. Wenn das nicht möglich ist wird der Dezimalpunkt gezeichnet. Aber wie kommt man nun an eine Minuszeichen Erkennung?

In Zeile 298 // Affiche un gros caractére en x, y beginnt das Zeichnen von den großen Zeichen.

ab Zeile 312 // Affiche un nombre decimal werden die Dezimalziffern und der Dezimalpunkt geschrieben.

#include <SFE_BMP180.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Button.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
.
.
.


Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

.
.
.

extern uint8_t Font24x40[];
extern uint8_t Symbol[];
extern uint8_t Splash[];
extern uint8_t Battery[];
.
.
.

/* ------------------------------------ loop ------------------------------------------ */
.
.
.


// Affiche un gros caractére en x, y
void drawBigCar(int sx, int sy, int num) {
  drawCar(sx, sy, num, Font24x40, 24, 40, WHITE) ;
}

void drawDot(int sx, int sy, int h) {
  display.fillRect(sx, sy-h, h, h, WHITE);
}

// Affiche un symbole en x, y
void drawSymbol(int sx, int sy, int num) {
  drawCar(sx, sy, num, Symbol, 16, 16, WHITE) ;
}

// Affiche un nombre decimal
void drawFloatValue(int sx, int sy, double val, int unit) {
  char charBuf[15];
  if (val < 10000) {
    dtostrf(val, 3, 1, charBuf); 
    int nbCar = strlen(charBuf);
    if (nbCar > 5) { // pas de decimal keine Dezimalziffer
      for (int n=0; n<4; n++) drawBigCar(sx+n*26, sy, charBuf[n]- '0');
      drawSymbol(108,sy, unit);
    }
    else {
      drawBigCar(sx+86, sy, charBuf[nbCar-1]- '0');
      drawDot(78, sy+39, 6);
      nbCar--;
      if (--nbCar > 0) drawBigCar(sx+52, sy, charBuf[nbCar-1]- '0');
      if (--nbCar > 0) drawBigCar(sx+26, sy, charBuf[nbCar-1]- '0');
      if (--nbCar > 0) drawBigCar(sx, sy, charBuf[nbCar-1]- '0');
      drawSymbol(112,sy, unit);
    }
  }
}

Für jede Hilfe bin ich dankbar.

Tiny_altimeter_v1_04.zip (56.3 KB)

EDIT: Ich habe wahrscheinlich erst falsches geschrieben. Ich glaube man muss den unteren Fall behandeln.

Das kann man auch so umschreiben, dass er es von links her zeichnet und nicht von rechts nach links wie im Moment. Dann kann man es auch einfach mit einer for-Schleife machen. So ähnlich:

byte xOffset = 0;
for (int n=0; n < nbCar; n++)   //über alle Zeichen iterieren
{
      if(charBuf[n] == '-')   //Minus-Zeichen
      {
         ...
         xOffset += ...;    //Breite des Minuszeichens
      }
      else if(charBuf[n] == '.')   //Punkt?
      {
         drawDot(sx + xOffset, sy+39, 6);   //Hier muss man evtl. die x-Koordinate noch etwas anpassen
         xOffset += 8;
      }
      else      //Ziffern
      {
        drawBigCar(sx + xOffset, sy, charBuf[nbCar] - '0');
        xOffset += 26;   
      }
}

drawSymbol(sx + xOffset,sy, unit);

Aber keine Garantie dass es so geht. Habe das nicht getestet. Eventuell musst du auch das Leerzeichen noch extra abfragen
Und bei der x-Koordinate des Minuszeichens musst du auch xOffset addieren, da vor dem Minuszeichen ein Leerzeichen kommen kann.

Aber vom Prinzip er sollte es so ähnlich gehen. Also über den String iterieren ob man ein Minuszeichen oder eine Ziffer hat (eventuell wie gesagt noch Leerzeichen). Und jeweils die x-Koordinate entsprechend der Breite der Zeichen erhöhen oder direkt setzen.

Hier was ich zuerst hatte:

for (int n=0; n<4; n++) 
{
 if(charBuf[n] == '-')
 {
    ...
 }
 else
   drawBigCar(sx+n*26, sy, charBuf[n] - '0');
}

Da ist aber gar nichts mit dem Dezimalpunkt

Vielen Dank - mit der ersten Variante hab ich es hinbekommen sowohl für die Integeranzeige als auch die mit Dezimalstelle.

11tes Zeichen erstellt im Zeichensatz. Ansonsten nicht chick aber es funktioniert:
nbCar--;
if ((--nbCar > 0) && (charBuf[nbCar-1] != '-')) drawBigCar(sx+52, sy, charBuf[nbCar-1]- '0');
if(charBuf[nbCar-1] == '-') drawBigCar(sx+52, sy, 10); // Minus

if ((--nbCar > 0) && (charBuf[nbCar-1] != '-')) drawBigCar(sx+26, sy, charBuf[nbCar-1]- '0');
if(charBuf[nbCar-1] == '-') drawBigCar(sx+26, sy, 10); // Minus

if ((--nbCar > 0) && (charBuf[nbCar-1] != '-')) drawBigCar(sx, sy, charBuf[nbCar-1]- '0');
if(charBuf[nbCar-1] == '-') drawBigCar(sx, sy, 10); // Minus

Meine alten Hirnwindungen fingen schon an zu rauchen ;-))