Temperaturanzeige mit + Zeichen

Wie kann ich mit der Funktion:

temperatur = sensors.getTempCByIndex(0);

das Plus Zeichen mit ausgeben?

Die Ausgabe erfolgt mit:

lcd.print( dtostrf( temperatur, 5, 2, stringbuffer ) );

Micky

Vielleicht einfach so:

if (temperatur>=0) lcd.print("+");
lcd.print( dtostrf( temperatur, 5, 2, stringbuffer ) );

-Micky:
Wie kann ich mit der Funktion:

temperatur = sensors.getTempCByIndex(0);

das Plus Zeichen mit ausgeben?

Die Ausgabe erfolgt mit:

lcd.print( dtostrf( temperatur, 5, 2, stringbuffer ) );

Erstmal mußt Du mit dtostrf breit genug formatieren, 5 Zeichen reichen bei 2 Nachkommastellen ja nur für einstellige Temperaturen mit Vorzeichen. Für zweistellige Temperaturen mit Vorzeichen wäre die Mindestbreite 6 Zeichen.

Und dann kannst Du die gewünschte Funktion realisieren, indem Du Dir nach der Formatierung das Zeichen vor der ersten Ziffer anschaust: Ist es ein Minuszeichen, dann ist das Vorzeichen vorhanden und Du machst weiter nichts, ist es aber ein Leerzeichen, setzt Du stattdessen ein Pluszeichen ein.

  dtostrf( temperatur, 6, 2, stringbuffer );
  int i=0;
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  Serial.println(stringbuffer);

Danke, funktioniert.

Bißchen merkwürdig ist, wenn ich bei allen:

dtostrf( temperatur, 9, 2, stringbuffer );

9 reinschreibe, mir bei 2 Displays die Erste Stelle nicht mehr angezeigt wird. Ich habe vier Displays dran. Mit zwei mal 8 und zwei mal 9 funktioniert das aber.

Micky

Nein!
Merkwürdig ist, dass noch nicht mal jurs schreibt, was 'stringbuffer' ist.

Wenn man über definierte Variablenbereiche hinausschreibt, funktioniert das manchmal trotzdem.

dtostrf( temperatur, 9, 2, stringbuffer );

Mit dieser einen geposteten Zeile hat dein Problem höchstens indirekt zu tun.

michael_x:
Merkwürdig ist, dass noch nicht mal jurs schreibt, was 'stringbuffer' ist.

Es reicht doch, wenn es in der Referenz zur Funktion steht: avr-libc: <stdlib.h>: General utilities

Außer, dass 'stringbuffer' in der Referenz 's' heißt, ist alles gleich:
value passed in val into an ASCII representationthat will be stored under s. The caller is responsible for providing sufficient storage in s.

'stringbuffer' muss also immer lang genug sein, um den String mit voller Länge plus das abschließende Nullzeichen aufzunehmen. D.h. bei:
dtostrf( temperatur, 9, 2, stringbuffer );
muss 'stringbuffer' deklariert sein als char Array mit 10 Zeichen:
char stringbuffer[10];

9 Zeichen Stringlänge plus abschließendes Nullzeichen = 10 Zeichen Gesamtlänge.

Ich muß ja nicht in jedem Posting einen Roman schreiben.
:wink:

Ich muß ja nicht in jedem Posting einen Roman schreiben.
smiley-wink

Nein, aber ich gehe davon aus, du weisst auch, dass Code ohne Variablendefinition nur Mist ist.
smiley-wink zurück :wink:

Hier ist der Code, kann ja was falsch sein:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Für I2C LCD Display

#define ONE_WIRE_BUS 3

LiquidCrystal_I2C lcd(0x20,16,2);  // I2C LCD Adresse auf 0x20 gesetzt, 16 Zeichen / 2 Zeilen LCD
LiquidCrystal_I2C lcd2(0x21,16,2);  // I2C LCD Adresse auf 0x21 gesetzt, 16 Zeichen / 2 Zeilen LCD
LiquidCrystal_I2C lcd3(0x22,16,2);  // I2C LCD Adresse auf 0x22 gesetzt, 16 Zeichen / 2 Zeilen LCD
LiquidCrystal_I2C lcd4(0x24,16,2); // I2C LCD Adresse auf 0x24 gesetzt, 16 Zeichen / 2 Zeilen LCD

char buffer[17] = "";                                     
OneWire oneWire(ONE_WIRE_BUS);                            
DallasTemperature sensors(&oneWire);

void setup(void) {
  
  lcd.init();
  lcd.backlight(); 
  
  lcd2.init();
  lcd2.backlight(); 
  
  lcd3.init();
  lcd3.backlight(); 
  
  lcd4.init();
  lcd4.backlight(); 
  
  byte addr[8];  
   
  sensors.begin();

  sensors.setResolution( 12 );
                               
}


void loop(void) {

  float temperatur = 0;
  char stringbuffer[10];
 
  sensors.requestTemperatures();                                         
   
  int i=0;
  
  lcd.setCursor(0, 0); 
  lcd.print( "Tiefkuehltruhe 1" );
  lcd.setCursor(10, 1); 
  lcd.print((char)223);
  lcd.print("C "); 
  lcd.setCursor(3, 1); 
  temperatur = sensors.getTempCByIndex(0);
  dtostrf( temperatur, 8, 2, stringbuffer );
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  lcd.setCursor(1, 1); 
  lcd.print(stringbuffer);
    
  lcd2.setCursor(0, 0); 
  lcd2.print( " Kuehlschrank 1" );
  lcd2.setCursor(10, 1); 
  lcd2.print((char)223);
  lcd2.print("C "); 
  lcd2.setCursor(3, 1);  
  temperatur = sensors.getTempCByIndex(1);
  dtostrf( temperatur, 8, 2, stringbuffer );
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  lcd2.setCursor(0, 1); 
  lcd2.print(stringbuffer);
  
  lcd3.setCursor(0, 0); 
  lcd3.print( "Innentemperatur" );
  lcd3.setCursor(10, 1); 
  lcd3.print((char)223);
  lcd3.print("C "); 
  lcd3.setCursor(3, 1);  
  temperatur = sensors.getTempCByIndex(2);
  dtostrf( temperatur, 9, 2, stringbuffer );
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  lcd3.setCursor(0, 1); 
  lcd3.print(stringbuffer);
    
  lcd4.setCursor(0, 0); 
  lcd4.print( "Aussentemperatur" );
  lcd4.setCursor(10, 1); 
  lcd4.print((char)223);
  lcd4.print("C "); 
  lcd4.setCursor(3, 1); 
  temperatur = sensors.getTempCByIndex(3);
  dtostrf( temperatur, 9, 2, stringbuffer );
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  lcd4.setCursor(0, 1); 
  lcd4.print(stringbuffer);
 }

Micky

 while (!isdigit(stringbuffer[i])) i++;

kommt vier mal vor ( für jede lcd ) , i wird aber nur einmal ganz am Anfang auf 0 gesetzt

Ich weiss zwar nicht, ob das wirklich das Problem ist, das ist jedenfalls nicht der Sinn von jurs Idee, wie man den Anfang der Zahl findet um dort das '+' zu setzen .

Das ist es! Danke.

Wäre nicht darauf gekommen das es daran liegt.

Micky

-Micky:
Das ist es! Danke.

Wäre nicht darauf gekommen das es daran liegt.

Kleiner Exkurs zum Schreiben von übersichtlichem Code.

Wenn Du praktisch immer dieselben Codeabschnitte wieder und wieder ausführen mußt mit nur ganz geringen Änderungen, dann bietet es sich an, dafür geeignete Funktionen zu schreiben. Getestete Funktionen, die dann immer wieder aufgerufen werden können, ohne dass was vergessen wird, wenn Codeabschnitte mehrfach kopiert und eingefügt werden.

Wie wäre es z.B. mit so einer aufgeräumten loop-Funktion:

void loop(void) {
  sensors.requestTemperatures();      
  printOnLCD(lcd, "Tiefkuehltruhe 1",sensors.getTempCByIndex(0));
  printOnLCD(lcd2," Kuehlschrank 1",sensors.getTempCByIndex(1));
  printOnLCD(lcd3,"Innentemperatur",sensors.getTempCByIndex(2));
  printOnLCD(lcd4,"Aussentemperatur",sensors.getTempCByIndex(3));
}

Statt dass da haufenweise unübersichtlich (und womöglich fehlerhaft) zusammenkopierter Code drinsteht, steht da viel weniger, aber dafür aufgeräumter Code drin, nämlich hauptsächlich vier fast gleiche Funktionsaufrufe:

  • gib auf "lcd" den Text "Tiefkuehltruhe 1" mit Temperaturindex 0 aus
  • gib auf "lcd2" den Text " Kuehlschrank 1" mit Temperaturindex 1 aus
  • gib auf "lcd3" den Text "Innentemperatur" mit Temperaturindex 2 aus
  • gib auf "lcd4" den Text "Aussentemperatur" mit Temperaturindex 3 aus

Dann sieht die loop doch schon mal aufgeräumter aus als bei Dir, oder?

Und nun brauchst Du natürlich die Funktion "printOnLCD()", die einige Parameter übergeben bekommt, nämlich

  • auf welchem lcd ausgegeben werden soll
  • welcher Text ausgegeben werden soll
  • welche Temperatur ausgegeben werden soll
void printOnLCD(LiquidCrystal_I2C einlcd, char* text, float temp)
// Funktion gibt auf einem LCD einen Text und eine Temperatur aus
{
  char stringbuffer[10];
  einlcd.setCursor(0, 0); 
  einlcd.print( text );
  einlcd.setCursor(10, 1); 
  einlcd.print((char)223);
  einlcd.print("C "); 
  dtostrf( temp, 8, 2, stringbuffer );
  int i=0;
  while (!isdigit(stringbuffer[i])) i++;
  if (i>0 && stringbuffer[i-1]!='-') stringbuffer[i-1]='+';
  einlcd.setCursor(1, 1); 
  einlcd.print(stringbuffer);
}

Stichwort: "Wiederverwertbarkeit von Code"

Du schreibst also nur einmal Code, wie Text und Temperatur auf einem LCD ausgegeben werden soll. Dieser Code wird gründlich getestet.

Aber Du kannst diesen kompletten Code dieser einen Funktion dann mit einem Einzeiler und einigen übergebenen Parametern beliebig oft ausführen lassen, ohne dass beim Kopieren von Codeabschnitten Fehler passieren können.

Ist nur ein Vorschlag, mehr Struktur und Übersicht zu bekommen.