Forum: Mikrocontroller und Digitale Elektronik LCD Anzeige und DS18B20


von Socke (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

benutze das Beispielprojekt von Sicklinger 
(http://www.sicklinger.com/atmel-avr-atmega-ds18x20-library-in-c.html). 
Und möchte eine Temperatur über ein LCD Display ausgeben. Das Display 
benutze ich auch mit dem Beispielcode von hier (HD44780). Allerdings 
gibt mir das Display nur ?C anstatt der Temperatur aus.

Ich dachte eigentlich, das es so passen müsste:

for(;;){
    //-----------------------------------------
    // Read temperature
    //-----------------------------------------
    temp_po = ds1820_read_temp(DS1820_pin_po); //Get temperature from 
DS1820 "sensor #1"


    sprintf(temp_po_str,"%.1f C",temp_po); //Convert temp. "sensor #1" 
to string

    lcd_setcursor( 0, 1 );
    lcd_string(temp_po_str);
    //void lcd_string( const char *data );
  }

Die Änderungen dezüglich des verwendeten Pins in der DS18X20LIB_h
habe ich natürlich gemacht.


Über eine Idee zur Lösung des Problems wäre ich sehr dankbar.

Verwenden tue ich einen ATMega16


Gruß

: Verschoben durch User
von Falk B. (falk)


Lesenswert?

@Socke (Gast)

>Und möchte eine Temperatur über ein LCD Display ausgeben. Das Display
>benutze ich auch mit dem Beispielcode von hier (HD44780). Allerdings
>gibt mir das Display nur ?C anstatt der Temperatur aus.

Was wohl daran liegt, daß deine Version von printf keine float-Werte 
anzeigen kann/will. Mit Festkommaarithmetik geht das auch ohne 
float.
1
int temperature;
2
3
for(;;){
4
    //-----------------------------------------
5
    // Read temperature
6
    //-----------------------------------------
7
    temperature = 10*ds1820_read_temp(DS1820_pin_po); //Get temperature from 
8
DS1820 "sensor #1"
9
10
    sprintf(temp_po_str,"%d.%dC",temperature/10, abs(temperature%10)); //Convert temp. "sensor #1" 
11
to string
12
13
    lcd_setcursor( 0, 1 );
14
    lcd_string(temp_po_str);
15
    //void lcd_string( const char *data );
16
  }

Oder du musst in deiner IDE eine andere printf Bibliothek zum Linken 
angeben.

von Socke (Gast)


Lesenswert?

Vielen Dank Falk,

habe deinen geänderten Quellcode übernommen, jedoch zeigt er mir nun 
0.0C an!?

Gruß

von Falk B. (falk)


Lesenswert?

Dann klappt das Auslesen der Temperatur nicht.

von Socke (Gast)


Lesenswert?

Hast auch eine Idee woran das liegen könnte?

von Socke (Gast)


Lesenswert?

Habe auch einmal den Sensor getauscht, daran lag es nicht!
Gibt es noch andere Ideen?

Gruß

von Falk B. (falk)


Lesenswert?

Eine systematische Fehlersuche.

Old school, baby!

von Socke (Gast)


Lesenswert?

@Falk oder auch gerne jemand anderes

Hallo nochmal,langsam wird nen Schuh draus.

Der bisherige Fehler mit der 0.0C anzeige, lag an der vorhandenen 
delay-Funktion. Habe es durch _delay_us vom Controller ersetzt und nun 
scheint es "zu klappen"

Folgendes Problem habe ich leider jetzt:

Jetzt zeigt mir der Display eine Temperatur von ca. -76C an, berühre ich 
den Fühler reduziert sich die Temp auf ca. -60C. Und nun bin ich 
überfragt, da der Fühler ja eigentlich gar nicht solche Werte ausgeben 
kann?!?




Gruß

von Bomie (Gast)


Lesenswert?

Problem gelöst, die Berechnung der Temperatur wahr nicht korrekt.

Trotzdem danke für eure Hilfe

von Wolfgang (Gast)


Lesenswert?

Bomie schrieb:
> Problem gelöst, die Berechnung der Temperatur wahr nicht korrekt.

Nur für die Nachwelt: Wie sieht dein heiler Code jetzt aus?

Ohne den kann der bisherige kaputten Code dieses Threads bestenfalls als 
warnendes Beispiel dienen.

von Murmelchen (Gast)


Lesenswert?

Und als weitere Warnung:

Der Sensor DS18B20 liefert 2 Bytes, welche als 16 Bit Integer den 
Temperaturwert als vorzeichenbehafteten 12 Bit Wert in Sechzehntel Grad 
Celsius enthalten. Enthalten ist in dem 16 Bit Integer also eine 
vorzeichenbehaftete Festkommazahl im Zweierkomplement, deren 
Nachkommateil in den unteren 4 Bits enthalten ist.

Lösungen wie

sprintf(temp_po_str,"%d.%dC",temperature/10, abs(temperature%10));

liefern deshalb auch keine sauber gerundeten Werte, wobei hier der 
Teiler 10 auch noch zusätzlich falsch ist.

Will man die Temperatur hingegen nur in ganzen Grad darstellen, liefert 
/16 zwar den ganzzahligen Teil, aber eben auch nur abgetrennt und nicht 
für alle Fälle richtig gerundet.

Und Modula 10 oder gar 16 führt in diesem Fall allein auch nie zu einer 
korrekten Lösung des Nachkommateils, weder auf eine Stelle nach dem 
Komma noch auf eine Lösung mit vollständiger Auflösung und schon gar 
nicht auch noch richtig gerundet.


Natürlich kann man die gelieferten Temperaturwerte auch nur allein mit 
Hilfe der Festwertarithmetik sauber umwandeln und darstellen, nur ganz 
so einfach ist es dann doch nicht, und die vielen Ein- oder Zweizeiler, 
die ich bisher so gesehen habe, waren alle schlicht falsch. Und wenn man 
schon einen (größeren) Aufwand betreiben muss, dann kann man auch gleich 
den einfacheren Weg über float und (s)printf gehen und bei den 
heutzutage gängigen Controllern mit 32K oder mehr für 2 EUR tut der 
dadurch etwas vergrößerte Code auch nicht mehr mehr wirklich weh, 
zumindest nicht im Hobbybereich. Will man es hingegen wirklich wissen, 
dann ist Assembler für die vorliegende Aufgabe möglicherweise sogar eher 
zielführender als die zusätzliche Abstraktion der Hochsprache.

Und ich behaupte jetzt mal, manche der (billigen) kommerziell 
angebotenen Digitalthermometer zeigen oft auch deshalb Abweichungen an, 
weil die Entwickler da auch ein bisschen geschlampt haben.


Egal und allen (dogmatischen) Behauptungen, wie man das doch angeblich 
'richtig' macht, zum Trotz, eine saubere und dazu auch noch halbwegs 
elegante Lösung nur mit Festwertarithmetik und Schiebung habe ich für 
das obige Problem noch nicht gesehen.


Mit besten Grüßen

Murmelchen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.