Hallo,
es gibt ja oft Fragen zum DS18B20, aber zu diesem Problem hab ich leider
keinen Thread gefunden:
Wenn ich mehrere Sensoren an einem Bus betreibe, stimmt nur beim zuletzt
gewandelten die Temperatur.
Einzeln funktionieren meine Sensoren, insbedondere auch individuell
addressiert (also mit CMD_MATCHROM statt CMD_SKIPROM) passt alles mit
ID,Temperatur und CRC.
Via SEARCH_ROM baue ich ein Array mit den IDs zusammen, das funktioniert
auch.
Zu jeder geraden Sekunde ewird ine Temperaturwandlung gestartet und zwar
für alle Sensoren am Bus gleichzeitig:
RESET,CMD_SKIPROM,CMD_CONVERTTEMP.
(Das Datenblatt des DS18B20 schlägt das auch genauso vor)
Zu jeder ungeraden Sekunde werden dann alle Temperaturwerte eine
Schleife durch das ID-Array ausgelesen:
for i ...: RESET,MATCHROM ID[i],READSCRATCHPAD.
Problem ist, dass die Temperaturen nur noch beim letzen Sensor in der
Liste stimmen.
Mein Verdacht: RawTemp=0x0550 bedeutet ja nach Datenblatt
default-Temperatur, also irgendwas in Richtung "Temperatur ausgelesen
ohne vorher Wandlung anzustossen".
Ich hab doch aber für alle Sensoren eine Wandlung angestossen, und eine
Sekunde später lese ich von jedem Sensor individuell addressiert die
Temperatur. Wieso stört sich das ganze trotzdem?
Danke für Hinweise,
Mario
Hallo,
sorry, ich poste gerne den ganzen Code (Anhang).
Habe mich im ersten Post jedoch bewusst zurückgehalten mit dem Code, da
die dort aufgerufenen Funktionen für sich ja alle korrekt sind.
Ich hatte einfach den Verdacht, dass es eher ein Problem der
Kommandoreihenfolge ist.
Kurz zur übersicht (das Angehängte ist trotz Beschränkung aufs
wesentliche recht lang),
oben stehen die OneWire basics (Read/Write/Bit/Byte),
dann das ganze ID-Handling (Read/Skip/SearchROM).
Dann die DS18-spezifischen Dinge, und ganz unten das Auslesen aller
Sensororen.
In Letzterem vermute ich halt auch den Fehler.
Im Prinzip fahre ich diese Endlosschleife ab:
1
OneWire Reset
2
OneWire SkipROM
3
OneWire StartConvertTemperature
4
5
Warte 2 Sekunden
6
7
für alle Sensoren ID[i]
8
OneWire Reset
9
OneWire MatchROM ID[i]
10
OneWire ReadScratchpad // RawTemp = erste 2 Bytes davon
Hat zwar mir dem Problem nichts zu tun, aber:
Mario Fischer schrieb:> Zu jeder geraden Sekunde ewird ine Temperaturwandlung gestartet> Zu jeder ungeraden Sekunde werden dann alle Temperaturwerte ... ausgelesen
Das ist für die Sensorgen schon recht kritisch. Wenn sie so oft
angesprochen werden, erzeugen sie selber zu viel Wärme. Die Temperaturen
sind dann immer mindestens 5°C zu hoch.
Um einem Sensor das Convert-Cmd zu schicken, muss er selektiert sein.
Der letzte ist noch durch die Search-Routine selektiert.
Es fehlt also ein Skip-Rom.
Der Code ist verbesserungswürdig.
Hast Du parasite-Power? Hoffentlich nicht, denn die Sensoren brauchen
schon etwas Strom für die Wandlung.
Das war jetzt ein Eigentor, denn SkipRom ist vorgesehen, aber ob es
wirklich ausgesendet wird?
Stimmt die Quarzfrequenz, also die Wartezeiten?
Wenn mehrere Sensoren anschlossen sind, darf der PullUp stärker sein,
z.B. 1 kOhm.
Warum wandelst Du jede Sekunde in jedem Sensor? Ich würde nur den Sensor
wandeln lassen, den ich auch danach auslese.
Als Anfänger bin ich natürlich für konkrete Vorschläge wie "Der Code ist
verbesserungswürdig" herzlich dankbar, da ich erst seit 15 Jahren C
programmiere ;-)
Aber in Ernst, dass die Delays stimmen hab ich eigentlich schon anfangs
gesagt (hab sogar mitm Oszi draufgeschaut), und es funktinieren ja alle
onewire-Funktionen (sinnvolle Temperaturen, CRC ok,
Search/Match/SkipROM, ...) korrekt.
Nur das startconvert und readscratchpad beeinflusst sich scheins
irgendwie.
Die Methode mit dem startconvert-Broadcast ist eleganter als lauter
einzelne startconverts, schliesslich will ich den BusTraffic bzw die
delay_us() gering halten.
Ausserdem ist der Fall, dass man an vielen Messstellen die Temperatur
exakt gleichzeitig messen will durchaus nicht ungewöhnlich und wird
deshalb im DS18-Datenblatt auch explizit so erwähnt.
Und ja, ich hab Parasite-Power (also nicht ich sondern die Sensoren ;-)
) - Einen kleineren Pullup werd ich mal probieren, für den Fall dass 2
DS18er zusammen zuviel Strom saugen wenn sie gleichzeitig wandeln -
könnte das echt der Fall sein? Die Leitungslängen sind gerade mal 30+30
cm...
Trotzdem hab ich irgendwie den Verdacht dass es eine
startconvert/readscratchpad-Beeinflussung sein könnte.
Tut mir leid, hatte nur kurz Zeit, Deine sehr ausführlich gestellte
Frage (Lob!) zu überfliegen.
Während der Wandlung (und bei anderen 1W-Bausteinen beim
Eeprom-Schreiben) muss für Parasite-Power DQ aktiv hochgezogen werden,
der PullUp reicht für die Versorgung i.d.R. nicht aus.
Ich schau mir Deinen Code gleich nochmal an.
Deshalb ist ja auch die Zeile, in der Busy überprüft wird, bei Parasite
unwirksam. Vcc der DS18 muss mit Gnd verbunden sein, damit sie sicher im
Parasite-Mode sind.
Kannst Du ein Oszillogramm vom Wandeln posten?
danke fürs Lob und nix für ungut :-)
Also "StrongHi" schalte ich den OneWire nie.
Es gibt nur (angelöteter 4k7 nach VCC) und am OneWirePin die Zustände
DriveLo := {PortBit=0; DdrBit=1; }
oder
Release := {DdrBit=1; }.
Das hab ich so aus der Atmel-Applicationnote für OneWire-Master
( http://www.atmel.com/dyn/resources/prod_documents/doc2579.pdf )
und der onewire.c aus dem Ethersex-Projekt übernommen.
Ob dort Parasite gefahren wird schreiben beide leider nicht.
Es funktioniert ja auch nahezu alles bei meinem Code, also auch mit
mehreren Sensoren am Bus.
Insbesondere sensorlist_searchrom() und ds18b20_test() liefern korrekte
Ergebnisse - keine davon benutzt allerdings einen
startconvert-broadcast.
Es könnte schon sein, dass ein startconvert-broadcast zu viel Strom
zieht, ich schau mir das morgen mal aufm Oszi an.
Laut Datasheet ist der grösste Strom, den ein DS18 ziehen kann 1,5mA.
Liegt zwar auch für 2 Sensoren weit unter den 20mA die ein AtmelPin
kann, aber der ist ja nie "StrongHi" sondern immer nur HiZ(Relase) oder
GND(DriveLo). Mein Pullup ist 4k7, also das was das Dataseet für einen
Sensor empfiehlt. Für MehrSensorBetrieb hab ich keine empfohlenen Werte
gefunden.
in Zeile 249 fehlt eine Klammer:
if (eeprom_read_byte((uint8_t*)&(e_onewire_sensors[i].name[0]) !=
0x00)
--->
if (eeprom_read_byte((uint8_t*)&(e_onewire_sensors[i].name[0])) !=
0x00)
> Also "StrongHi" schalte ich den OneWire nie.
Solltest Du aber, wenn Du Parasite verwendest.
8. Active current refers to supply current during active temperature
conversions or EEPROM writes.
> Laut Datasheet ist der grösste Strom, den ein DS18 ziehen kann 1,5mA.
und woher sollen die kommen? Der 4,7k begrenzt den Strom auf 1,0mA, wenn
DQ ganz low ist. Der DS braucht die max. 1,5mA jedoch im High-Zustand.
Auf StrongHi kannst Du nur verzichten, wenn keine Parasite-Versorgung
verwendet wird.
Versorge doch testweise die DS18 mit 5V.
Außerdem wäre es recht hilfreich, wenn Du ein lauffähiges Projekt posten
könntest, also mit main(), PRINTHEX etc.
Viel Erfolg
Mario Fischer schrieb:> Und ja, ich hab Parasite-Power (also nicht ich sondern die Sensoren ;-)> )> Also "StrongHi" schalte ich den OneWire nie.
Warum sagste das denn nicht gleich, daß Du das Datenblatt mißachtest.
Läßt lieber die Leute wie blöd rumraten.
Aus meinem Code:
Beitrag "DS1820, DS18B20 in C"
Mario Fischer schrieb:> Also "StrongHi" schalte ich den OneWire nie.
Und das dann auch noch mit mehreren gleichzeitig messenden Sensoren.
Ergibt bei 2 Stück bis zu 3mA und bei 1K also bis zu 3V Spannungsabfall
- von 4K7 ganz zu schweigen.
Peter Dannegger schrieb:> Warum sagste das denn nicht gleich, daß Du das Datenblatt mißachtest.> Läßt lieber die Leute wie blöd rumraten.
Sorry, ich hab das mit dem Parasite nicht absichtlich verschwiegen, um
die Leute in eine falsche Richtung zu locken.
Hatte eben den starken Verdacht, dass das Problem auf Ebene der
Kommando-Reihenfolge liegt und hab es auch deswegen eher in diese
Richtung detaillierter beschrieben.
Aber, um aufs Thema zurück zu kommen: Ich hab das ganze mit einem
kleineren Pullup ausprobiert (470 Ohm => 10 mA max), und siehe da, alle
Sensoren wandeln gleichzeitig korrekt. Aktiv auf Hi mit dem AVR-Port zu
ziehen wollte ich nicht, da er sonst kaputt gehen kann wenns mal einen
permanenten Kurzschluss auf dem Bus gibt.
Insofern also Danke an allen hier, die mir geholfen haben!
Da ich nicht schon wieder das Datenblatt missachten will hab ich
nachgesehen, ob die Sensoren die 10mA denn sinken können, wenn sie die
Leitung auf GND ziehen beim Senden einer 0.
Das Datenblatt listet aber bei Sink Current nur einen _Minimal_Wert von
4mA auf - das verstehe ich nicht: Ich dachte limitierend wäre eher,
wieviel Amp der Sensor maximal nach Gnd runterleiten kann ohne Schaden
zu nehmen (oder auch nur zu warm zu werden und damit die nächste Messung
evtl zu verhageln).
Sind die 470 Ohm denn ok? Insbesondere wenns mehr Sensoren und eine
lange Leitung werden?
Wo liegt mein Denkfehler, dass es für den SinkCurrent des DS18 nur einen
Min-Wert gibt?
Das ist so zu verstehen: es können mindestens 4 mA gedrained werden,
ohne dass die Spannung über 0,4 V steigt.
Wenn Du um Dein Port besorgt bist: schalte einen 100 Ohm in Reihe zum
Portpin. 50mA hält er sicher aus, auch wenn das Datenblatt nur 20mA
angibt (diese gelten ja über den gesamten Temp-Bereich). Dadurch wird
nebenbei das Ringing gedämpft, was bei einer langen Leitung ein großer
Vorteil ist.
Einge stabile Versorgung (über active PullUp) verbessert die Genauigkeit
der Wandlung:
Auszug aus dem DS1820-Datasheet:
PARASITE POWER
The block diagram (Figure 1) shows the parasite powered circuitry.
This circuitry "steals" power whenever the I/O or VDD pins are high.
I/O will provide sufficient power as long as the specified timing and
voltage requirements are met (see the section titled "1-Wire Bus
System").
The advantages of parasite power are two-fold:
1) by parasiting off this pin, no local power source is needed for
remote sensing of temperature, and
2) the ROM may be read in absence of normal power.
In order for the DS1820 to be able to perform accurate temperature
conversions, sufficient power must be provided over the I/O line when a
temperature conversion is taking place.
Since the operating current of the DS1820 is up to 1 mA, the I/O line
will not have sufficient drive due to the 5K pull-up resistor.
This problem is particularly acute if several DS1820’s are on the same
I/O and attempting to convert simultaneously.
There are two ways to assure that the DS1820 has sufficient supply
current during its active conversion cycle.
The first is to provide a strong pull-up on the I/O line whenever
temperature conversions or copies to the E2 memory are taking place.
This may be accomplished by using a MOSFET to pull the I/O line directly
to the power supply as shown in Figure 2.
The I/O line must be switched over to the strong pull-up within 10 ms
maximum after issuing any protocol that involves copying to the E2
memory or initiates temperature conversions.When using the parasite
power mode, the VDD pin must be tied to ground.
Another method of supplying current to the DS1820 is through the use of
an external power supply tied to the VDD pin, as shown in Figure 3.
The advantage to this is that the strong pull-up is not required on the
I/O line, and the bus master need not be tied up holding that line high
during temperature conversions.
This allows other data traffic on the 1-Wire bus during the conversion
time.
In addition, any number of DS1820’s may be placed on the 1-Wire bus, and
if they all use external power, they may all simultaneously perform
temperature conversions by issuing the Skip ROM command and then issuing
the Convert T command.
Note that as long as the external power supply is active, the GND pin
may not be floating.
The use of parasite power is not recommended above 100°C, since it may
not be able to sustain communications given the higher leakage currents
the DS1820 exhibits at these temperatures.
For applications in which such temperatures are likely, it is strongly
recommended that VDD be applied to the DS1820.
For situations where the bus master does not know whether the DS1820’s
on the bus are parasite powered or supplied with external VDD, a
provision is made in the DS1820 to signal the power supply scheme used.
The bus master can determine if any DS1820’s are on the bus which
require the strong pull-up by sending a Skip ROM protocol, then issuing
the read power supply command.
After this command is issued, the master then issues read time slots.
The DS1820 will send back "0" on the 1-Wire bus if it is parasite
powered; it will send back a "1" if it is powered from the VDD pin.
If the master receives a "0", it knows that it must supply the strong
pull-up on the I/O line during temperature conversions.
See "Memory Command Functions" section for more detail on this command
protocol.
Mario Fischer schrieb:> Aktiv auf Hi mit dem AVR-Port zu> ziehen wollte ich nicht, da er sonst kaputt gehen kann wenns mal einen> permanenten Kurzschluss auf dem Bus gibt.
Schau Dir meinen Code doch einmal an.
Ich teste vorher, ob ein Kurzschluß vorliegt.
Und falls genau wärend der Wandlung ein Kurzschluß erfolgt, der AVR
sollte die 1s überstehen.
Kannst aber noch nen Pin-Change-Interrupt aufsetzen, der bei Kurzschluß
sofort abschaltet.
Das mit dem 470R Widerstand ist Murx. Weder ist damit die Wandlung
garantiert, noch ausreichender Low-Pegel vom Slave.
Peter