1-wire Temperaturmessung mit DS18B20 für TINY2313 in C (ROM-Search-free)
Das 1-wire-Protokoll an sich ist leicht verständlich - wäre da nicht die
Implementation des ROM-Searchens. Das ist schwer verdauliche Kost.
Dabei ist das ROM-Searchen für Temperaturmessungen nicht notwendig und
kann sogar in kritischen Netzwerken der Auslöser der ersten Störungen
sein.
Daher wird hier ein anderer Weg zum Auslesen der DS18B20 gegangen -
garantiert rom-search-free.
Und hoffentlich auch verständlich dokumentiert.
Das Programm benötigt weniger als 2048 Byte, somit reicht ein TINY2313
aus.
Die Steuerung und die Datenausgabe erfolgt über die serielle
Schnittstelle.
Die Umsetzung sind wie folgt aus:
1. Die Sensoren werden zunächst einzeln an den Bus angeschlossen und per
Kommando angelernt (dabei wird ihr ROM-Code im EEprom gespeichert).
2. Es ist ein Messintervall vereinbart.
3. Der Timer setzt nach dem Ablauf des Messintervalls ein Flag.
4. Bei gesetztem Flag wird ein SKIP_ROM/CONVERT an alle Sensoren
geschickt.
Nach ca. 800ms werden die Sensoren einzeln mit ihrer ROM-Adresse
angesprochen, ihr Scratchpad ausgelesen, die CRC geprüft und die
Temperatur in lesbarer Form via RS232 ausgegeben.
Weiter geht's dann mit 3).
Mit einem TINY2313 sind bis zu 15 Sensoren anlernbar.
Bei einem Umzug auf einen ATMEGA48/88 kann man die Zahl der Sensoren auf
63 erhöhen - und hat genug Pins und Flash frei, um ein LCD anzusteuern.
Einige weitere Hinweise gibt's in der beigefügten readme.pdf.
Viel Spaß beim Messen,
Michael S.
Genial!
Beim Tausch eines Sensors sind alle anderen abzuklemmen und neu
Anzulernen.
Endlich mal eine sinnvolle Beschäftigung die sich nicht in Software
erledigen lässt.
@klaus,
wenn du über eine funktionierende Lösung verfügst und dich andere
Ansätze nicht interessieren, dann ignoriere diese Ansätze doch einfach.
Sollte dir an einem anderen Ansatz ein Haken aufgefallen sein, dann
kannst du das im Sinne von konstruktiver Kritik gerne einbringen.
Zu deinem Einwand:
Um einen Sensor zu tauschen, ziehe ich den alten ab und lerne einen
neuen an:
Dazu trenne ich den Bus (mit den x anderen Sensoren) am Controller,
verbinde den neuen Sensor mit dem Controller ... und stecke den Bus
wieder an.
Dann tausche ich die beiden Sensoren aus.
Alle Sensoren müsste ich allenfalls dann neu anmelden, wenn das Eeprom
bereits voll ist.
Andererseits ist dein Problem keines, das sich mir gestellt hat oder
sich mir stellen wird.
Würde es sich mir stellen, dann würde ich wenige Zeilen Code ergänzen,
so dass der ROM-Code eines neu angelernten Sensors den ROM-Code des
auszutauschenden Sensors überschreibt.
Oder ich würde das Eeprom patchen. Lösungen findet man immer, naja
meistens - wenn man will.
Im Übrigen muss der Schritt einer eindeutigen Identifikation eines
Sensors in jeder Lösung erfolgen - dieses Problem löst ja das
ROM-Searchen nicht.
Ob ich dazu den ROM-Code verwende oder etwas, was ich manuell in ein
Register des Sensor einschreiben muss, das erscheint mir zunächst
gleichgültig.
Wobei der ROM-Code sich einfach anbietet: er ist definitiv eindeutig und
ausserdem bereits vorhanden.
Aber wie wir wissen, führen viele Wege nach Rom.
Ich wollte einfach mal die Autobahn verlassen ...
Michael S.
Die beiden vergangenen, frostigen Nächte haben es ans Tageslicht
gezerrt:
Ich habe die Routine zur Konvertierung der Temperaturwerte nicht bei
negativen Temperaturen getestet ...
Und schon findet sich ein Fehler (die Sign-Bits sind nicht vollständig
ausgewertet).
Als Anlage die korrigierten Dateien - und diesmal mit einem separaten
Testprogramm für die Temperaturkonvertierung.
Michael S.
Tolles Projekt, tolle Beschreibung!
Würdest du einem " nicht C Programmierer " das Hex-File und die Fuse-Bit
Einstellung zur Verfügung stellen?
Vielen Dank für die Mühe
Michael S. schrieb:
> Das 1-wire-Protokoll an sich ist leicht verständlich - wäre da nicht die> Implementation des ROM-Searchens. Das ist schwer verdauliche Kost.
Nö, so schlimm ist das überhaupt nicht.
Sag einfach mal, was Du daran nicht verstehst.
Fragen kostet nichts.
Peter
Achja, einen kleinen Test für die Leserschaft hatte ich noch eingebaut:
- als Nachkommastelle wird immer '0' ausgegeben.
Die Auflösung des Rätsels:
Datei: owi_lib.c, DS18B20_convert_temperatur()
anstelle
186: ow_buffer[0] &= 0x0F;
187: temp16 += (int16_t)(ow_buffer[0] & 0xF0) * 640 / 1024;
muss es lauten:
entweder
186: ow_buffer[0] &= 0x0F;
187: temp16 += (int16_t) ow_buffer[0] * 640 / 1024;
oder
186: entfällt
187: temp16 += (int16_t)(ow_buffer[0] & 0x0F) * 640 / 1024;
In der Bitmaske ist einerseits ein Verdreher (0xFO statt 0x0F),
andererseits ist eine zweifache Maskierung natürlich überflüssig.
Wer sich das Archiv 'test.zip angesehen hat, der wird dort die Lösung
bereits gefunden haben.
Zugegeben:
Das Problem ist entstanden, Weil das SRAM im TINY2313 wieder mal knapp
wurde.
Daher habe ich unterschiedliche Formulierungen ausprobiert um zu sehen,
ob sich dadurch der Codeumfang verkleinert.
Der Versuch, die Berechnung '* 640 / 1024', durch eine Tabelle zu
ersetzen, war unter diesem Aspekt kontraproduktiv.
Am Ende habe ich die Tests nicht sauber entfernt - und noch einen
Verdreher eingebaut.
Michael S.
@ Peter Dannegger,
'schlimm' ist natürlich ein sehr relativer Begriff.
Auf mein Niveau bezogen ist die Implementation des ROM-Searchens schwer
verständlich.
Nicht das Prinzip - das ist nachvollziehbar und erscheint genial.
Auffällig ist, dass Maxim in zahlreichen App-Notes und auf vielen,
vielen Seiten versucht, der Kundschaft die Lösung des ROM-Searchens zu
verklickern.
Warum die vielen Worte, wenn der Inhalt doch so trivial sein soll ???
Wenn ich mir etwa in der AN187.pdf die das ROM-Searchen erläuternden
Flussdiagramme ansehe, dann muss ich erst einmal tief Luft holen.
Und traue mir nicht so ohne weiteres zu, diese Logik in ein (wirklich
funktionierendes) Programm umzusetzen.
Aber warum sollte ich derart komplizierte Wege gehen, wenn das Ziel auf
einfacher, verständlicher und überprüfbarer Weise erreichbar ist ?
Eben darum habe ich auf das ROM-Searchen verzichtet.
mfg
Michael S.
@ Helmut(Gast)
hier ist das gewünschte hex-file.
Was man nicht sehen kann ist, dass die Kommandos 0x60/0x70 im
Programmcode auskommentiert sind (das SRAM auf dem TINY2313 reichte
nicht aus).
Die Fuse-Bits sind so gesetzt, dass der Controller mit einem XTAL
(3.686400 MHz) zusammenarbeitet.
Vielleicht noch das Bit/die Bits für die Brown Out Detection setzen.
Michael S.