mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik einen einzigen DS18s20 auslesen + LCD


Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey liebe User,

ich habe vor mir einen einzigen DS18s20 auszulesen und nur auf einem LCD 
anzuzeigen. Das ganze wollte ich in C machen.
Am besten so knapp wie möglich.
Es ist ja möglich das irgendwie genauer als 0,5 Grad auflösung zu 
berechnen. Das würde ich auch noch gerne machen.
Nun habe ich aber mit dem Sensor noch keine Erfahrung.
Ich habe schon einige Codes im Internet angeschaut aber nie etwas wie 
ich meine gefunden.
Könnt ihr mir bei meinem Vorhaben helfen?
Datenblatt habe ich auch schon gelesen, aber nichts für mich hilfreiches 
gefunden.
Ich würde mich sehr freuen wenn ich hier hilfe bekomme.

Ganz liebe Grüße
Newby

Autor: ich_eben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, in der RoBue Firmware für das AVR Net-IO ist eine Ausleseroutine für 
den DS18S20 dort könntest du mal schauen

Autor: Silvan König (silvan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:
> Ich würde mich sehr freuen wenn ich hier hilfe bekomme.

Das kriegen wir hin. Aber auf Groß- und Kleinschreibung achten ;)

An was für einen Mikrocontroller hattest du denn gedacht? Schon mal ins 
AVR-GCC-Tutorial geguckt? Gibts Vorerfahrung?

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay. Entschuldigung wegen der Groß- und Kleinschreibung.

Ich dachte an einen Atmega32 (habe ich daheim).

Ein bisschen Vorerfahrung mit C und AVR habe ich schon.

Autor: Silvan König (silvan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:
> Datenblatt habe ich auch schon gelesen, aber nichts für mich hilfreiches
> gefunden.

Sehr interessant. Dann hast du doch sicher auch die Formel gesehen, mit 
der man genauer als 0,5°C rechnen kann, oder?

Autor: BvB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Newby,
schau einmal hier hin:

Beitrag "1-Wire-Bus-Projekt: DS1820  DS18S20  DS2450  DS2408  unter C und 8051"

Hier haben wir den kompletten 1-Wire-Bus ausführlichst beschrieben mit 
DS18S20, DS2450 und DS2408er.
Hier kannst Du alles wichtige zum DS18S20er nachlesen und Dir auch die 
Software-Treiber incl.Demo-Programme runter laden.
Die Software ist in C geschrieben (zwar für 8051er), kann aber sehr 
einfach auf Atmegas umgesetzt werden.
Ab Mitte August gibt es auch die Applikationen und Demos zum Anschluss 
eines LC-Displays (4 Zeilen á 20 Zeichen) an den 1-Wire-Bus, incl. 
Ansteuerung von Relais, LEDs, Abfrage von Tastern, alles über den einen 
einzigen µC-Port -Pin.

Viel Spaß mit dem 1-Wire-Bus.

Bernd

Autor: Newby (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich habe zwar ne Formel gesehen wusste auch das die dafür ist aber 
ich kann sie nicht in Verbindung mit der Abfrage bringen. Habe hier im 
Forum einen Code gefunden weiß aber nicht ob der so funktioniert. Ich 
poste ihn mal hier unter den Dateianhängen. Soweit ich das dort sehe 
funktioniert es dort ohne die Rechnung. Wie könnte man die da einbauen?

Ist das insgesamt ein sinnvoller Ansatz?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:

> funktioniert es dort ohne die Rechnung. Wie könnte man die da einbauen?

Na, dort wo sie jetzt auch ist. In main() nach dem Auslesen.
Allerdings müsste man das etwas geschickter angehen als dort. Dort 
werden ja alle Kommastellen generell weggeworfen.

Wie du das genau machen willst, hängt natürlich auch davon ab, wie du 
eigentlich in deinem Programm eine Temperatur auf, sagen wir mal, 1 
Nachkommastelle speichern willst.

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt mit dem Sensor kenn ich mich noch nicht aus habe den Code nur 
hier aus dem Forum gezogen.

Ja eine Nachkommastelle wäre ok.
Was meinst du mit speichern?
Dafür würde sich doch ein Double-Wert eignen oder?
Oder ich nehme einen Integer-Wert und tuhe ihn durch 10 teilen.

Oder was meinst du mit speichern?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:

> Ja eine Nachkommastelle wäre ok.

Ist doch schon mal eine Aussage

> Was meinst du mit speichern?

Welchen Datentyp soll denn die Variable haben, in der du die Temperatur 
speicherst?

> Dafür würde sich doch ein Double-Wert eignen oder?

Kann sein. Kann auch nicht sein.
Nachkommastelle heisst nicht zwangsläufig double oder float.
Manchmal reicht es ja auch, wenn man bei der Ausgabe einfach nur an der 
richtigen Stelle ein Komma einschmuggelt, damit an der Anzeige 20,45 
Euro steht. Programmintern speichert (und rechnet´) man aber alles in 
EuroCent, so dass dann nach der Berechnung 2045 Cent rauskommen, die 
eben nur für die Anzeige zu 20,45 Euro (durch Einschmuggeln eines Kommas 
an der richtigen Stelle) umgeformt werden.

> Oder ich nehme einen Integer-Wert und tuhe ihn durch 10 teilen.

Yep. zb

(PS: mag dich interessieren. In deinem Testprogramm wird die fertige 
Temperatur mit 0.0625 multipliziert. 0.0625 ist aber genau 1/16. D.h. 
vom Sensor wird die Temperatur als 16-faches Vielfaches ausgelesen. 
Misst du im Winter und hat es +1°C dann liefert der Sensor den Wert 16. 
Hat es 2°C dann eben 32 usw.

PS2: und bitte. Du tust nicht teilen und du tust nicht sprechen und du 
tust nicht lesen. Sondern du teilst, du sprichst und du liest. Achte ein 
wenig auf deine Muttersprache.

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah Ok.
Stimmt das dann mit der Multiplikations um 0.0625 oder ist das falsch?

Ich habe jetzt folgendes in ds18s20.c geändert:
unsigned char read_scratchpad (void) {
  //for (i=0; i<9; i++)
  scratchpad [0] = read_byte ();
  scratchpad [1] = read_byte ();
  
  scratchpad [6] = read_byte ();
  scratchpad [7] = read_byte ();
  reset (); //terminate transfer (read 2bytes)
      return 1;

  return 0;
}
Und in ds18s20test.c das:
int main(void)
{
  DDRB = 0x00;
  PORTB= 0xFF;
  

  int temperature = 0;

  for (;;) 
    {
        read_scratchpad ();
          temperature = (scratchpad [1] << 8) + scratchpad [0];
          temperature = temperature - 0.25;
          temperature = temperature + ((scratchpad[7] - scratchpad[6]) / scratchpad[7];
          temperature *= 0.0625; //für 12bit
  }
}
Würde die Berechnung so stimmen?
Was würde der temperature dann zum Schluss für einen Wert angeben also 
beispielsweiße?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:
> Ah Ok.
> Stimmt das dann mit der Multiplikations um 0.0625 oder ist das falsch?

Lies anstelle von *0.0625 einfach /16.

Grundsätzlich stimmt das schon. Nur verlierst du alle Kommastellen.

>           temperature = (scratchpad [1] << 8) + scratchpad [0];
>           temperature = temperature - 0.25;
>           temperature = temperature + ((scratchpad[7] - scratchpad[6]) /
> scratchpad[7];
>           temperature *= 0.0625; //für 12bit

Was um alles in der Welt rechnest du da?

Warum so kompliziert?

Den Teil brauchst du auf jeden Fall um die beiden 8 Bit Register zu 
einer 16-Bit Temperatur zusammenzusetzen

          temperature = (scratchpad [1] << 8) + scratchpad [0];

So. jetzt hast du in temperatur einen Wert, der dem 16 fachen der 
richtigen Temperatur entspricht (für +1°C würde da jetzt 16 rauskommen, 
für +2°C w+rden 32 rauskommen, etc).

Du willst 1 Nachkommastelle, also für +1°C hättest du gerne 10 (weil du 
das Komma bei der Ausgabe einschmuggelst)

      temperatur = temperatur * 10 / 16;

Bsp für 2°C:
Der Sensor liefert 32.   32 * 10 -> 320; 320 / 16 -> 20. Oder nach 
Einfügen eines Kommas zwischen 'Zehner und Einer':  2,0

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ok danke.

Aber wie genau ist jetzt die Ausgabe?
Wenn ich den Wert jetzt ausgeben würde, würde er doch nur in 0,5er 
Schritten ausgegeben werden oder?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:
> Ah ok danke.
>
> Aber wie genau ist jetzt die Ausgabe?

So wie sie dir der Sensor liefert

> Wenn ich den Wert jetzt ausgeben würde, würde er doch nur in 0,5er
> Schritten ausgegeben werden oder?

Wenn dir der Sensor tatsächlich 1/10 Grad liefert, dann stehen die auch 
auf der Ausgabe. Wenn der Sensor nur in 0.5 Grad Schritten auflöst, dann 
stehen auf der Ausgabe auch nur 0.5°

NOchmal: wo hast du das hier
         temperature = temperature - 0.25;
          temperature = temperature + ((scratchpad[7] - scratchpad[6]) / scratchpad[7];
her? Ich hab jetzt das Datenblatt für diesen Sensor nicht im Kopf.

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich Datenblatt steht folgende Formel:

                                   count_per_c - count_remain
temperature = temp_read - 0,25 +   --------------------------
                                         count_per_c

Wobei Byte 6 Count_remain und Byte 7 count_per_c ist.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Newby schrieb:
> Ich Datenblatt steht folgende Formel:

OK. Dann wird das schon stimmen.

Nur, du kannst das nicht so in C umsetzen.

    ((scratchpad[7] - scratchpad[6]) /  scratchpad[7]

das ist eine Integer Division und keine Gleitkommadivision.
Und ausserdem muss temperatur dann eine double Variable sein, so wie du 
das hast.

Ich kenn jetzt deine Anwendung nicht, für meine Anwendungen würde dieser 
Genauigkeitsboost keine Rolle spielen. Wenn ich eine Raumtemperatur 
messe, dann ist die sowieso nicht über den kompletten Raum hinweg 
überall auf 1/10 Grad gleich. Eine Anzeige auf 1/10 sugeriert daher eine 
Genauigkeit, die schon physikalisch gesehen gar nicht möglich ist. Aber 
das ist meine Anwendung. Bei dir mag das anders aussehen.

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ok und wie muss ich das dann machen, dass es mit Integern 
funktioniert?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: wb1 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank?

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok dann werde ich das erstmal nur in 0,5 Grad Genauigkeit laufen lassen.

@wb: was meinst du mit Frank?

Autor: wb1 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Syntax in den Beiträgen erinnert mich an einen Kollegen, dachte du 
wärst es. Aber ist wohl nicht so.

Autor: Newby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein dem ist nicht so.

Wenn jemand für mich noch einen Vorschlag für die 0,1 Grad Genauigkeit 
dann bin ich dafür offen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.