Go Down

Topic: Temperaturanzeige mit + Zeichen (Read 3980 times) previous topic - next topic

-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 ) );


Micky

sth77

Vielleicht einfach so:
Code: [Select]
if (temperatur>=0) lcd.print("+");
lcd.print( dtostrf( temperatur, 5, 2, stringbuffer ) );
Mein verwaister Arduino-Blog: http://www.sth77.de/ - letzter Eintrag: Diamex-ISP in der irgendwann mal aktuellen Arduino-IDE 1.6.4

jurs


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.

Code: [Select]

  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);


-Micky

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

michael_x

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

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

Quote
dtostrf( temperatur, 9, 2, stringbuffer );

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


jurs

#5
Jun 14, 2013, 04:28 pm Last Edit: Jun 14, 2013, 04:54 pm by jurs Reason: 1

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


Es reicht doch, wenn es in der Referenz zur Funktion steht: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

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.
;)

michael_x

Quote
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 ;)


-Micky

Hier ist der Code, kann ja was falsch sein:

Code: [Select]
#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

michael_x

Code: [Select]
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 .

-Micky

Das ist es! Danke.

Wäre nicht darauf gekommen das es daran liegt.


Micky

jurs


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:
Code: [Select]

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

Code: [Select]

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.

Go Up