Hallo --> Hiorica (Gast)
also irgend etwas läuft bei dir schief.
1
byte 0 Temperature LSB (AAh)
2
byte 1 Temperature MSB (00h) EEPROM
3
byte 2 TH Register or User Byte 1
4
byte 3 TL Register or User Byte 2
5
byte 4 Reserved (FFh)
6
byte 5 Reserved (FFh)
7
byte 6 COUNT REMAIN (0Ch)
8
byte 7 COUNT PER °C (10h)
9
byte 8 CRC*
wenn ich nun die 10 (byte0 = 0001 0000) und die 57 (byte1 = 0101 0111)
mal als temperatur nehme.
kommt da keine zimmertemperatur raus.
MSB + LSB
0101 0111 0001 0000
1
TEMPERATURE/DATA RELATIONSHIP Table 2
2
+85.0°C* 0000 0000 1010 1010 00AAh
3
+25.0°C 0000 0000 0011 0010 0032h
4
+0.5°C 0000 0000 0000 0001 0001h
5
0°C 0000 0000 0000 0000 0000h
6
-0.5°C 1111 1111 1111 1111 FFFFh
7
-25.0°C 1111 1111 1100 1110 FFCEh
8
-55.0°C 1111 1111 1001 0010 FF92h
zur info byte 7 ist immer 10h nur bei dir nicht?
1
2
Note that the COUNT PER °C register is hard-wired to
3
16 (10h)
sind deine angaben in HEX oder dezimal ?
aber bit 7 muss 10H (dezimal 16) sein.
prüfe das mal bitte und sende mal den code zu als zip!
sebastian
NACHTRAG :
ändert sich was an deinem code bei temperaturwechsel ?
wenn nicht dann könnte es sein das du hier die Seriennummer vom Chip
darstellst oder so.
prüfe das mal bitte
Hallo,
es kommen keine Änderung, wenn sich die Temperatur ändert. Leider
verstehe ich den Code von Peter noch nicht so ganz. Die Temperatur in
0.5 Schritten klappte damals soweit.
Hallo
Hatte ich mir fast gedacht.
Warum eigentlich 0.1 grad ?
Ich habe 20 Sensoren auf eine metall Platte geklebt.
Alle ausgelesen und Werte von - + 2 grad erhalten.
Die sensoren haben auch leichte eigenerwärmung.
Für mein Projekt weiter oben hier im forum (Bilder mit gelben gehäuse)
habe ich von den 20 Sensoren die besten zwei genommen. Ich guck mal
deinen Code heute Abend durch.
Ja es geht mir nicht um das genauere messen. Das bekomme ich mit den
DS18S20 nie hin, ich will nur das die Anzeige in 0.1 Schritten sich
ändert.
Soweit ich das nun verstehe, ist das wirklich die ID vom Chip die ich
auslese.
Hiorica schrieb:> Soweit ich das nun verstehe, ist das wirklich die ID vom Chip die ich> auslese.
nein du hast ID[0] bis [id8] nie eingelesen.
Du hast ID oben definiert aber dann nie werte da hin geschrieben.
die temp werte liegen in der Variable temp.
viel spaß beim bauen ...
NACHTRAG nach 10 minten denken ....
kann es sein das der code von dir aus zwei codes zusammengeschmissen
ist?
du legst die Variable "ID" fest. und fragst dann ab ob ID[0] 10 oder 28
ist. Ohne aber vorher den chip zu lesen und ID[0] zu befüllen?
wenn ich richtig liegen sollte das du code zusammengeschmissen hast dann
sollte man den ganzen code berichtigen. aktuell ist es nur zufall das
der code geht, weil ID[0] mit 10 gefüllt ist ...
:-)
Hallo,
der Code ist Original von Peter. Ich habe es nur für meine Zwecke auf
ein LCD umgeschrieben.
Die Werte für ID werden in der Funktion w1_rom_search( diff, id )
beschrieben. Gibt es vielleicht ein besser Beispiel?
Hallo
w1_rom_search( diff, id ) ließt nur die ID ein.
das Scratchpad wird nicht von peter komplett gelesen.
Sebastian hat recht der Code sieht ganz gut aus.
grüße
stefan
hallo.
hab mich jetzt im Forum so durchgelesen aber nichts gefunden, was man
für einen PIC 18F4550 verwenden könnte. könnte jemand vielleicht codes
bereitstellen.
ich versuche derzeit über ds1820 treiber mit vorgefertigten Funktionen
den Befehl für eine Temperaturmessung zu geben, doch mein µC hängt sich
auf dabei.
1
sensor_count=0;
2
3
if(DS1820_FindFirstDevice())
4
{
5
do
6
{
7
// Die Rohtemperatur des DS18B20 erhalten (Aufloesung 1/256°C)
8
temperature_raw=DS1820_GetTempRaw();
9
10
// Konvertiere die Rohdaten in ein String fuer die Ausgabe
Ich habe versucht über Matlab mir den String "Test" ausgeben zu lassen,
aber offensichtlich kommt er gar nicht erst ins if- rein.
2. wie kann ich dem Sensor (ohne die Treiber zu verwenden) befehlen,
eine Messung durchzuführen?
Ich schätze dass es am delay liegt, weil er den PIC abschaltet. die
verbindung über USB wird damit auch unterbrochen. wie könnte man das
noch machen, ohne ein delay zu benutzen.
Danke im Voraus.
Lg,
alptech
Ich denke mal du bist falsch hier. In diesem Beitrag geht es immer um
atmega CPU's.
Ich habe hier auch schon viel getippt aber bei deinem Problem kann ich
dir nicht helfen.
Sebastian xxlxx
Versuche doch mal teile von deinem grundcode zu suchen.
Ich denke mal du hast fertige Teile genommen.
Wenn du dann im Forum was findest - schliese sich Diesem Beitrag an.
Dein Thema ist sehr komplex USB ds1820 + pic.
Für die ds1820 gibt es gute pdf beim Hersteller.
Bekommst du eine datenverbundung hin?
Daten vom pic zum pc senden ? Wenn ja dann ccersuche dir doch einen code
helper zu bauen.
Jeder step eine Ausgabe und an jeder Position was anzeigen. Dann siehst
du schnell wo der Fehler liegt. Ich mache das oft mit nur einer LED. 1 x
blinken = in der Schleife usw.
Viel spaß
Sebastian xxlxx
verbindung zum pc funktioniert. doch wenn ich die fertigen funktionen
für den ds1820 aufrufe hängt es sich auf, die leds blinken dann nicht
mehr.
ich probier es mal so wie du es sagst. danke.
lg,
alptech
Was mir noch einfällt : ein ds1820 kann auch falsch angeschlossen sein.
Wie versorgst du ihn ? Hast du einen oszi? Verlass dich nicht auf
fertigen Code. Ich denke auch dein Code muss wie beim atmega an die
Hardware angepasst werden.
Sebastian
Xxlxx
hallo.
ist alles richtig angeschlossen. hab jetzt auch den code fürs abrufen
der temperatur. ich kriege auch werte in den PIC geschrieben, doch wie
gebe ich die aus. die usb-verbindung zum PIC funktioniert seit dem
aufrufen der Temperatur nicht mehr. kann man mit dem PIC18F4550 an eine
R232 gehen und dann von hier mit einem USB-Adapter zum PC.
hier ist der Code für die USB-Ansteuerung:
1
// USBTasks()
2
// "Service loop for USB tasks."
3
voidUSBTasks(void)
4
{
5
/*
6
* Servicing Hardware
7
*/
8
USBCheckBusStatus();// Must use polling method
9
if(UCFGbits.UTEYE!=1)
10
USBDriverService();// Interrupt or polling method
11
12
#if defined(USB_USE_CDC)
13
CDCTxService();
14
#endif
15
}
16
17
// High priority interrupt vector
18
#pragma code InterruptVectorHigh = 0x08
19
voidInterruptVectorHigh(void)
20
{
21
_asm
22
gotoInterruptHandlerHigh//jump to interrupt routine
23
_endasm
24
}
25
26
// High priority interrupt routine
27
// Hier Behandlung von Trigger- und Timer-Interrupt
Nachtrag:
Ich habe einen Oszi an dem 1-wire-bus angeschlossen. dabei habe ich
gemerkt, dass der bus nie auf 0 gezogen wird. wenn ich den ds1820
rausnehmen, sehe ich die flanken usw. aber mit dem ds1820 wird es nur
auf 5V-480mV runter gezogen. offenbar verhindert er dass die leitung
komplett auf 0 gezogen wird. warum ist das so?
angeschlossen habe ich (wie im Datenblatt steht) Gnd-> Gnd, mittleren
Pin (DQ)-> Port des PIC und den VDD-> 5V.
Bin für jede Hilfe dankbar. Lg,
malptech
Hallo
Ich habe den Code von Peter aus dem ersten Post eingebunden und zum
Laufen bekommen - allerdings sind die angezeigten Werte etwas mysteriös:
Bei einem Sensor bekomme ich die Zahl "10.6250" angezeigt, welche auch
bei Temperaturänderungen gleich bleibt - ich gehe davon aus, dass dieser
Sensor kaputt ist (?), denn:
Zwei andere liefern "3.xxx", wenn ich sie einsetze und sinken dann
langsam auf exakt "3.000".
Hat jemand eine Idee, was hier schief läuft (denn hier ist es definitiv
wärmer als 3 Grad :-))?
Ich benutze einen DS1820 (ohne S, Jahre altes Sample) an einen ATmega8
(16 MHz Quarz). VDD ist direkt verbunden, also kein Parasite Power. Als
Pullup verwende ich einen 5kOhm-Widerstand (2x 10kOhm), da ich 4,7kOhm
nicht parat habe. Könnte hier die Ursache liegen? Oder klingt das eher
nach einem Software-Fehler?
hört sich an wie software fehler.
pullup ist unkritisch.
hast du ein display oder wie machst du die ausgabe ?
versuche doch mal das scratchpad in Hex zu lesen.
es kann sein das du da einfach die falschen hexwerte nimmst.
ich habe damit viel gebaut und code selber geschrieben.
ließ mal beitrag von mir 16.2.2011 da hatte einer glaub ich auch so ein
problem. ich kann dir nur das pdf vom hersteller empfehlen da steht drin
wie sich das scratchpad zusammen setzt. also viel erfolg
Versuche seit Stunden die Datei 1wire.zip zum laufen zu bringen. Die
Verschachtelung ist ein Alptraum. Es ist kaum was Beschriftet. Ich
könnte heulen.
Im Main wird auf "#include "main.h" "hingewiesen. im "main.h" wird auf:
#include "1wire.h"
#include "delay.h"
#include "tempmeas.h"
#include "timebase.h"
#include "uart.h"
hingewiesen und zu jeder header datei exestiert eine .c datei. Ein
Alptraum. Das AVR Studio erkennt die .c Dateien nicht obwohl ich diese
ins Verzeichnis kopiert habe. Habe versucht alles in eine main zu
stopfen aber nun is das ganze kommplett unübersichtlich.
Hat jemand eine Version die auch mit AVR Studio 5.0 geht oder ein Tip
warum die Dateien trotz #include Befehl nicht erkannt werden.
Danke im vorraus
Software: AVR Studio 5.0
Programmiersprache: C
IC: Atmega16
Board: Pollin Eva Board v.2.01
Hallo
Ich habe inzwischen eine 1wire Lösung die aus ca 8 Funktionen besteht
und man kann sie einfach in die Main kopieren ohne Zusatz Daten.
Leider kann sie nur einen Sensor pro Portpin.
Reicht dir das ?
Simon K. schrieb:> Alle die sowas machen sind natürlich gemeint.
Ein Code der nur 50 Zeilen hat wird doch in die Main.c gehören.
Warum sollte ich so etwas auslagern ?
Hab den Fehler gefunden. Es lag an dem Programm AVR Studio 5.0.
Die Verschachtelung wird in das Projekt nicht aufgenommen wenn man die
zusatz Header Dateien (.h) in das verzeichnis kopiert und im Programm
#include .... eingibt.
In dem "Solution Explorer" Fenster (rechtses extra Fenster) muss man
erst auf "Show all files" klicken und dann unter "Output files" die
ganzen .h dateien mit rechter maus taste ins Projekt hinzufügen. Schwups
es wird alles gefunden und ausgeführt.
Würde mich trotzdem über eine einfachere Lösung freuen. Möchte nur den
einen Temp. Sensor zum laufen bringen und danach versuchen die
Funktionsweise zu erkunden.
MfG ede
Mal ne Frage an alle Temperaturmesser: Ich benutze auch die hier
veröffentlichten Routinen, um 3 Sensoren auszulesen, die mit maximal 15
Meter langen Zwillingslitzen im parasite power Modus angeschlossen sind.
Normalerweise funktioniert dies auch wunderbar. Ich starte alle 20
Sekunden eine Konvertierung. Das geht meist gut, aber so etwa alle 3-15
Minuten bekomme ich nach einer Messung von allen drei Sensoren den Wert
85 °C zurück. Also wie nach dem Start, bevor eine Messung eingeleitet
wurde. Ich habe schon mit dem Pullup-Widerstand experimentiert von 1
kOhm bis 3,3 kOhm - aber immer das selbe. Auch das Timing der Funktionen
w1_reset(), w1_rom_search() und w1_bit_io() habe ich leicht geändert -
ebenfalls ohne Erfolg. Auch habe ich die Wartezeit zwischen der
Initialisierung der Messung und dem Auslesen des Scratchpads bis zu 2
Sekunden verlängert. Auch ohne Erfolg.
Hat jemand ähnliche Probleme oder eine Idee, woran das liegen könnte?
Lassen sich bei euch alle Sensoren immer fehlerfrei auslesen? Ich bin
etwas ratlos. Dass immer ALLE 3 Sensoren hin und wieder 85 Grad
zurückmelden ist seltsam, denn dann muss es doch eigentlich ein
systemisches Problem sein und kann keine Störung bei der Übertragung
sein.
Danke schon vorab für spannende Ideen oder Kommentare! :-)
Tschö, Volker
ede schrieb:> Würde mich trotzdem über eine einfachere Lösung freuen. Möchte nur den> einen Temp. Sensor zum laufen bringen und danach versuchen die> Funktionsweise zu erkunden.
Hallo
diesen code verwende ich.
Hier die Grundlage :
http://www.mikrocontroller.net/attachment/highlight/20338
Volker U. schrieb:> Hat jemand ähnliche Probleme oder eine Idee, woran das liegen könnte?
Hi
85 grad kommt ja oft vor. Ich habe im haus ca 20 sensoren. und hatte
dieses problem sehr oft. ich habe dann 3 adern 5V - Ground - Daten
gemacht. der fehler war weg. kannst du aber testen. hänge doch in 15
metern einfach 3x1,5V Zellen dran um erstmal zu prüfen. Was für kabel
benutzt du ( mm²)?
ich habe netzwerkkabel - Telefonkabel verdrillt genommen.
grüße
Sebastian
Hi Sebastian!
Vielen Dank für deine Hinweise! Erstmal beruhigt es mich, dass das
Problem nicht nur bei mir auftritt.
sebastian xxlxx schrieb:> 85 grad kommt ja oft vor. Ich habe im haus ca 20 sensoren. und hatte> dieses problem sehr oft. ich habe dann 3 adern 5V - Ground - Daten> gemacht. der fehler war weg. kannst du aber testen. hänge doch in 15> metern einfach 3x1,5V Zellen dran um erstmal zu prüfen.
Ja, ich hatte auch schon die Vermutung, dass es mit der Beschaltung über
Parasite Power zusammenhängt.
> Was für kabel benutzt du ( mm²)?
Leider muss ich ein sehr dünnes Spezialkabel verwenden, da die Leitung
auf Putz über Wände geht und nicht groß auffallen darf. Daher habe ich
eine hochflexible Zwillingslitze mit 2 x 0,14 mm² (Spezialkabel von
Klasing) genommen, die auch nicht verdrillt ist. Der Schleifenwiderstand
des Kabels beträgt bei 15 Meter Anschlusslänge (also 30 m Kabellänge)
ca. 5 Ohm. Der Widerstand kann hier also keine Rolle spielen. Kämen noch
elektromagnetische Störungen in Frage.
Was die Störungen betrifft, gibt es aber ein sehr gewichtiges Argument
dagegen: Wenn Störungen auftreten würden, warum dann nur beim
Konvertierungskommando (CONVERT_T) und niemals beim Auslesen des
Scratchpads? Das Auslesen des Scratchpads mit 9 Bytes ist doch viel
aufwändiger und störanfälliger als das kurze CONVERT_T-Kommando! Ich
habe aber noch NIEMALS einen CRC-Fehler gehabt! Und das spricht
erheblich gegen irgendwelche Störungen als Ursache der Probleme.
Prüfst du auch die CRC-Summe, oder liest du nur die Temperaturwerte aus?
Ich denke, es hat nur was mit der Parasite Power zu zun und nicht mit
den Kabeln. Ich fürchte, es ist ein systemischer Fehler in den Sensoren,
da ja wohl alle das gleiche Problem haben.
Gruß, Volker
hi
ja das mit dem kabel sollte kein problem sein. teste doch mal das mit
dem power. so musst du erstmal kein kabel verlegen wenn du 3x1,5V Zellen
nimmst. Das sollte reichen ging ja bei mir auch :-)
aus dem Datenbaltt : The power-on reset value of the temperature
register is +85°C.
was ich auch schon hatte : bei temperaturen um 10-40 grad war alles ok.
alles was über 40 grad lag zeige der sensor 85 grad an. da reicht die
power nicht aus. 5V an den sensor und schon ging es wieder.
viel spaß
und berichte über deine ergebnisse
sebastian
sebastian xxlxx schrieb:> ja das mit dem kabel sollte kein problem sein. teste doch mal das mit> dem power. so musst du erstmal kein kabel verlegen wenn du 3x1,5V Zellen> nimmst. Das sollte reichen ging ja bei mir auch :-)
Joa, aber bei allen drei Sensoren einen Batterieklotz dranhängen ist
auch keine besonders elegante Lösung ;-). Die Sensoren sollen ja nicht
groß auffallen. Aber zum Testen ist das auf jeden Fall mal eine
Maßnahme. Im Notfall muss ich eben damit leben, dass nicht jede
Konvertierung okay ist. Ich mache es auch jetzt schon so, dass ich, wenn
alle drei Sensoren +85,0°C melden, die Werte verwerfe und sofort eine
erneute Konvertierung einleite. Meist klappt das dann auch sofort beim
nächsten Mal.
> was ich auch schon hatte : bei temperaturen um 10-40 grad war alles ok.> alles was über 40 grad lag zeige der sensor 85 grad an. da reicht die> power nicht aus. 5V an den sensor und schon ging es wieder.
Ich habe einen Sensor mal zum Testen in einen Kochtopf gehängt und im
Wasser gekocht. Da gab es keine Probleme bis 100°C. Begeisternd ist
wirklich die hohe Genauigkeit der Sensoren. Diese ist bei mir deutlich
höher als im Datenblatt angegeben. Ich löse auf 0,1°C auf und die
Temperatur ist von 0 bis 100 Grad etwa auf 0,2°C genau. In meinem
kochenden Wasser wurden bei geschlossenem Topfdeckel und nach einigen
Minuten Kochen exakt 100,0 Grad angezeigt. Damit hatte ich absolut nicht
gerechnet! Und im Eiswasser wurden exakt 0,0° angezeigt. Die Genauigkeit
entschädigt allemal für die kleinen Fehler.
> viel spaß> und berichte über deine ergebnisse
Vielen Dank! Das werde ich tun!
Tschaui, Volker
Sodele, das Problem ist gelöst!!! Mein System läuft seit mehreren
Stunden ohne eine einzige Fehl-Konvertierung! Und Schuld war (wie so
oft) nicht die Hardware, sondern die Software.
Unsere ganzen Vermutungen waren völlig richtig: Es hatte nichts mit
Störungen auf der Leitung zu tun, sondern lediglich mit einem nicht
korrekt verarbeiteten CONVERT_T Kommando und mit falscher Parasite
Power.
Die Hersteller-Dokumentation ist in dem Punkt leider etwas unzureichend.
Und so ist mal wieder nicht der Hardware-Produzent schuld, sondern der
Software-Entwickler. Die Parasite Power muss SOFORT nach dem CONVERT_T
Kommando geschaltet werden. Da darf man keine 10 us warten. Im
vorliegenden Fall wird sie in der Funktion start_meas() in tempmeas.c
geschaltet. Das ist aber VIEL zu spät, weil zwischen der Übertragung des
letzten Bit von CONVERT_T (0x44) und dem Schalten des Ausgangs auf High
viel zu viel Zeit vergeht!
Die Parasite Power muss schon in der Funktion w1_bit_io() in 1Wire.c
geschaltet werden. Und zwar sofort nach der Übertragung des letzten Bit
zur Konvertierung. Da darf nicht vorher erst wieder der Ausgang
hochohmig geschaltet und noch zahlreiche weitere Operationen ausgeführt
werden.
D.h. die Funktionen w1_bit_io(), w1_byte_wr() und w1_rom_search() müssen
modifiziert werden.
w1_bit_io() könnte so aussehen:
1
ucharw1_bit_io(bitb,bitpull)
2
{
3
cli();
4
W1_DDR|=1<<W1_PIN;
5
DELAY(DELAY_US(2));
6
if(b)
7
W1_DDR&=~(1<<W1_PIN);
8
DELAY(DELAY_US(10-2));
9
if((W1_IN&(1<<W1_PIN))==0)
10
b=0;
11
DELAY(DELAY_US(60-10));
12
if(pull){
13
W1_OUT|=(1<<W1_PIN);
14
W1_DDR|=(1<<W1_PIN);
15
}else
16
W1_DDR&=~(1<<W1_PIN);
17
sei();
18
returnb;
19
}
Wenn das "pull"-Flag True ist, wird der W1_PIN nicht erst hochohmig
geschaltet, sondern sofort auf Ausgang und auf High, damit die Parasite
Power anliegt. Zu beachten ist auch, dass ich das Timing DELAY_US()
etwas verändert und den Spezifikationen besser angenähert habe.
w1_byte_wr() ist natürlich entsprechend zu modifizieren:
1
uintw1_byte_wr(ucharb)
2
{
3
uchari=8,j;
4
bitcnv=(b==CONVERT_T);
5
do{
6
j=w1_bit_io(b&1,cnv&&i==1);
7
b>>=1;
8
if(j)
9
b|=0x80;
10
}while(--i);
11
returnb;
12
}
Wurde ein CONVERT_T Kommando abgesetzt, wird beim letzten zu
übertragenden Bit (i == 1) das "pull"-Flag gesetzt.
Alle weiteren Aufrufe von w1_bit_io() müssen jetzt natürlich um den
zweiten Parameter (das "pull"-Flag) ergänzt werden, das dann immer auf
"0" steht. Diese Aufrufe finden nur noch in w1_rom_search() statt:
1
ucharw1_rom_search(uchardiff,ucharidata*id)
2
{
3
uchari,j,next_diff;
4
bitb;
5
6
if(w1_reset())
7
returnPRESENCE_ERR;// error, no device found
8
w1_byte_wr(SEARCH_ROM);// ROM search command
9
next_diff=LAST_DEVICE;// unchanged on last device
10
i=8*8;// 8 bytes
11
do{
12
j=8;// 8 bits
13
do{
14
b=w1_bit_io(1,0);// read bit
15
_delay_us(2);
16
if(w1_bit_io(1,0)){// read complement bit
17
if(b)// 11
18
returnDATA_ERR;// data error
19
}else{
20
if(!b){// 00 = 2 devices
21
if(diff>i||
22
((*id&1)&&diff!=i)){
23
b=1;// now 1
24
next_diff=i;// next pass 0
25
}
26
}
27
}
28
w1_bit_io(b,0);// write bit
29
*id>>=1;
30
if(b)// store bit
31
*id|=0x80;
32
i--;
33
}while(--j);
34
id++;// next byte
35
}while(i);
36
returnnext_diff;// to continue search
37
}
Bei mir konvertiert er nun schon stundenlang ohne einen einzigen Fehler.
Und das mit 3 Sensoren an insgesamt 30 Meter langen, unverdrillten und
unabgeschirmten Leitungen, die quer durch die Gegend laufen. Selbst ein
kräftiges Gewitter, das vorhin war, konnte da nix stören!
Nun ist meine Begeisterung für den DS18S20 wirklich komplett :-).
Tschö, Volker
sebastian xxlxx schrieb:> Perfekt & super erklärt !!!
Danke, es freut mich, wenn ich hilfreich sein konnte :). Ich habe
übrigens in mittlerweile 24 Stunden nur einmal einen
Konvertierungsfehler gehabt. Dies war aber kein 85-Grad-Fehler, sondern
ein DATA_ERR in w1_rom_search(). Beim Lesen des Complement Bits ist wohl
was schief gelaufen. Aber ich denke, bei 10000 Lesevorgängen darf ruhig
mal ein Fehler auftreten ;-). Das ist schon enorm wenig.
Übrigens habe ich nochmal ins Datenblatt geschaut und festgestellt, dass
Maxim sehr wohl exakte Angaben über das Pullup macht! Dort steht:
Time to Strong Pullup On (Start Convert T Command issued): 10 us.
10 us sind also maximal erlaubt zwischen CONVERT_T und dem Pullup am
Ausgangs-Pin. Mein Controller läuft "nur" mit 4 MHz. D.h. jeder
Taktzyklus ist 0,25 us lang. Nach CONVERT_T dürfen also bis zum Pullup
nur 40 Taktzyklen vergehen. Und das war bei 4 MHz mit dem "alten" Code
von Peter Dannegger nicht gewährleistet. Wenn man den Controller mit 8
oder 10 MHz taktet, tritt das Problem vermutlich nicht auf.
Grüßle, Volker
Ich bekomme beim kompilieren immernoch diese Fehler, hab mir den Beitrag
hier schon 5 mal durchgelesen. Ich weiß nicht was ich machen soll. Was
führt zu dem Fehler?
Hi
4 nutze ich auch. Bei nur ging es sofort.
Ich meine schon einmal etwas gelesen zu haben das das ".C" am Ende der
Datei klein sein muss damit der Code richtig erkannt wird.
Leider kann ich dir da aber auch nicht weiterhelfen.
Gib doch mal den output in die Suche ein.
Sebastian
Also normalerweise sollte die implizite typkonvertierung von unsigned
auf signed char kommentarlos erfolgen. Vielleicht hilft ja ein
expliziter cast. Also vor die variable s überall ein (signed char *)
setzen?!
Gruß, volker
Da wird aber kein (signed char *) erwartet sondern ein (char *).
Normalerweise sollte das kein Fehler sonder eine Warnung sein.
Mal die Compileroptions anschauen.
(char *) und (signed char *) sind das selbe. Normalerweise ist (char *)
immer vorzeichenbehaftet, es sei denn, es wurde anders deklariert.
printf erwartet einen zeiger auf einen vorzeichenbehafteten string. Du
hast aber recht, dass das höchstens eine warnung erzeugen sollte.
Volker U. schrieb:> Normalerweise ist (char *)> immer vorzeichenbehaftet, es sei denn, es wurde anders deklariert.
Du schreibst es ja selber, man kann char (per Compileroption) auch
anders deklarieren. Dann ist dein (signed char *) aber falsch. Das (char
*) aber richtig.
Da wird ein char* verlangt, also kommt auch nur ein (char *) als cast in
Frage.
DirkB schrieb:> Da wird ein char* verlangt, also kommt auch nur ein (char *) als cast in> Frage.
Aber nicht, wenn (char *) aus irgendeinem grund als unsigned umdefiniert
wurde, wie du ja selbst schriebst. Dann wäre (char *) falsch, weil
printf immer einen signed erwartet. Es sei denn, man hat auch seine
printf-funktion umdefiniert, wovon ich aber mal nicht ausgehe! Die
diskussion ist aber akademisch, weil im vorliegenden fall aller
wahrscheinlichkeit nach beides richtig wäre. (char *) ebenso wie (signed
char *).
Hi
Das wird beks nicht weiter helfen. Er nimmt den Code von der Seite hier
und bekommt diesen Fehler. Da der Code ob Char hin oder her bei den
anderen und mir geht. Muss wohl etwas bei den Optionen nicht stimmen.
Oder ?
Sebastian
Wo du recht hast, hast du recht, sebastian. :-)
Ich benutze winavr und nicht avr studio. Das wäre vielleicht nochmal ne
maßnahme: Winavr, "programmers notepad" und dann ein nativ generiertes
makefile... dann klappt es auch mit dem übersetzen. ;-)
Hallo
Ich nutz Avr Studio 4.
@ Beks kannst du den Code mal gezippt schicken?
Bzw. Welchen Code von der Seite hier nutzt du. Hier gibt es viele Files
inzwischen.
Sebastian.
Tja, ohne fleiß kein preis. Das muss der gute wohl noch lernen. Bei der
heutigen jugend muss ja alles immer sofort klappen, sonst wirds
hingeschmissen. Da ist man dann allerdings in der elektro- und
softwaretechnik ganz falsch, weil man nur misserfolge erntet. ;-)
Wie jetzt :) grinse gerade da ich 24 Jahre bin.
Aber ein Vollblut Elektroniker & It Mensch im Beruf.
Und dieses Forum hier ist echt Klasse!
Habe gerade meine erste heizungssteuerung gebaut.
Wärmepumpe + Solar Kopplung und alles mit einem atmega.
So macht optimieren Spaß ... Den die Buderus und alpha Inotec
steuerteile hatten viele kleine Macken die ich jetzt nicht mehr habe.
Ds1820 ist da ein super Sensor!
Sebastian
:-) Ausnahmen bestätigen die regel. Aber es ist schon so, dass natur-
aber vor allem ingenieurwissenschaften zunehmend unbeliebter wurden.
Kein wunder, wenn die kids sehen, dass man auch ganz ohne mühe viel geld
verdienen kann.
Ich habe dieses forum zu nutzen begonnen, als ich mit atmel mcs
angefangen habe. Vorher hatte ich motorola benutzt. Aber die waren käse.
Deshalb habe ich fast nur analogtechnik entwickelt.
Mein erstes projekt zum kennenlernen von atmels war eine
temperaturmessstation mit 3 sensoren ds18s20 (innen- u.
außentemperatur), lc-display, dcf-empfänger, datenspeicher,
untertemperaturwarnung und pc-ankopplung über rs232. Damit mache ich
jetzt klimadiagramme. ;-) Ganz lustig und sogar nützlich.
Hast du technische unterlagen zu dem heizungssystem gehabt? Denn aus dem
stehgreif ist es ja sicher kaum möglich, so eine anlage sinnvoll zu
regeln, oder?
Ja so schlimm war das gar nicht. Die Anlage hatte ich mit meinem Bruder
geplant.
Dann erstmal so gebaut wie es sein sollte. Dann eine Wetterstation in
der Nähe gefragt um jeden Tag Daten zu bekommen. Nach ca 1 Jahr hatte
ich so viele Daten die ich auswerten konnte. Viele Daten habe ich mit
ds1820 und atmel + sd Card geloggt. Dann bemerkte ich die Fehler in der
Steuerung der wärmepumpe. Es gab Tage wo die Sonne schien aber die
Leistung im Puffer Stillstand. Eine wärmepumpe zu steuern ist gar nicht
so schwer. Es gibt 3 Sensoren ( Vorlauf - Rücklauf - Kompressor temp )
der Rest sind Pumpe und Mischer. Ich kenne meine Anlage sehr genau. Das
reine steuern war recht einfach. Was echt krass war ist eine menu
Steuerung. Ich habe ca 40 Werte im original gerät die man ändern kann.
Diese ganzen Werte mussten im atmel auch gemacht werden. So Werte wie
bei 2 grad ausen muss der Vorlauf immer laufen damit das Wasser im
ausenbereich nicht in der wärmepumpe einfriert.
Es waren ca 100 Tage Planung - 10 Tage bauen - einbauen und dem original
zuschalten ( Vorteil notsteuerung ).
War aber ein schönes Projekt für kalte Regentage :)
Es gibt da noch ein super Forum für haustechnik wo sich viele wie ich
treffen.
Meine Heizung kostet im Jahr ca 400 Euro das gleiche haus nebenan
benötigt 1400€. Da macht das sparen mehr Spaß :)
peter dannegger schrieb:> Die Routine muß für negative Werte leicht geändert werden.
Weiss jemand, wie man die Routine ändern muss, damit positive und
negative Werte angezeigt werden können?
Hi
Das kann man im Handbuch sehen. Ich glaube ich hab's so gemacht.
Ist das erste Bit ff ff ff ff dann ist das plus. Ist es 00 00 00 00 dann
war's Minus. Sieht man aber anhand der Tabelle in der PDF ganz gut.
Einfach das erste Bit auswerten. Meine Routinen sind immer so aufgebaut.
Wenn es nicht klappt Schau ich mal nach.
Viel Spaß
Sebastian unterwegs vom iPhone :)
Hi!
Danke für die schnelle Antwort.
Das die Bits 8 bis 15 das Vorzeichen bestimmen habe ich schon verstanden
:)
Bei 1111 1111 xxxx xxxx wäre laut dem Handbuch negativ.
Ich denke mal im Code müsste man dann in der Funktion void
read_meas(void)
etwas ändern?
Ich bin nur noch nicht dahinter gestiegen, wie ich die ersten Bits
bekomme und dann prüfen kann.
Gruß Robin
so lese ich alle bits ein. jetzt kann ich auswerten und spielen.
ich mache damit eine luftfeuchtemessung.
hier die ganze datei. ist aber viel formel für Wetterberechnung
1
#include"main.h"
2
#include"util/delay.h"
3
#include<stdio.h>
4
5
voidstart_meas(void){
6
if(W1_IN&1<<W1_PIN){
7
w1_command(CONVERT_T,NULL);
8
W1_OUT|=1<<W1_PIN;
9
W1_DDR|=1<<W1_PIN;// parasite power on
10
11
}else{
12
set_cursor(0,2);
13
lcd_string("Short Circuit !");
14
}
15
}
16
17
voidread_meas(void)
18
{
19
ucharid[8],diff;
20
uintbite1;
21
uintbite3;
22
uintcount_remain;
23
uintcount_per_c;
24
uchari;
25
uchars[30];
26
floattemper1;
27
floattemper2;
28
floattemp_all;
29
floattemp_komma;
30
floatmuell;
31
floatmuell1;
32
charoutput[20];
33
34
35
for(diff=SEARCH_FIRST;diff!=LAST_DEVICE;){
36
diff=w1_rom_search(diff,id);
37
38
39
if(diff==PRESENCE_ERR){
40
set_cursor(0,2);
41
lcd_string("No Sensor found");
42
break;
43
}
44
if(diff==DATA_ERR){
45
set_cursor(0,2);
46
lcd_string("Bus Error");
47
break;
48
}
49
if(id[0]==0x28||id[0]==0x10){// temperature sensor
Hallo
Schau dir die PDF an. Dort siehst du Beispiele. Du Must nur das Byte
auswerten ich glaube ff oder 00 ist - oder +. War eigentlich ganz
einfach. Guck dir die Beispiele an.
Also das geht in C doch automatisch. Der Sensor liefert den Wert als
Zweierkomplement. D.h. man steckt die 2 Bytes, also den 16 Bit Wert in
ein int16_t Datentyp und hat automatisch das korrekte Vorzeichen. Wenn
man die Temperatur in Grad haben möchte kann man das auch in einen
double stecken und durch 16 Teilen. Fertig. Da muss absolut nichts
selber rumgerechnet werden mit dem Vorzeichen. Selbst wenn die
eigentliche 1Wire-Routine nur einen Unsigned Typ liefert reicht ein Cast
nach int16_t aus.
Hier mal ein Auszug aus meinem Code. Die ow_read_word Funktion liefert
auch nur einen unsigned typ:
HALLO,
vielen Dank erstmal,aber bei mir haut das nicht hin.
ich bekomme nur eine vorkommastelle und eine nachkommastelle angezeigt,
2,9 und ohne vorzeichen.
vielleicht kann mir hier von ihnen jemand weiterhelfen
mfg
1
// --- lokale Variablen -------------------------------------------------------
2
3
// --- lokale Funktionen ------------------------------------------------------
Leider mal wieder nicht das komplette Programm gepostet.
Die fehlende '2' könnte durch eine fehlerhafte Ausgabefunktion
verursacht sein, die ich nicht kenne.
Bist du sicher, dass DS18B20_convert_temperatur() das macht, was du
erwartest (besonders für negative Zahlen)?
Vorschlag: für alle möglichen Werte in einer Schleife testen.
Vermutlicher Fehler:
ow_buffer[1] += (ow_buffer[0] >> 4);
ow_buffer ist vermutlich signed char (im Post nicht definiert).
Wenn das höchst Bit gesetzt ist, werden bei >> 1en eingefügt, die hier
vermutlich falsch wären.
Der DS18B20 liefert das Ergebnis in 16-tel Grad vorzeichenbehaftet als
16-bit-Zahl, die bei dir in ow_buffer[0] und ow_buffer[1] ankommt.
Du möchtest aber 10-tel Grad haben.
Also musst du nur doch nur die beiden Bytes richtig auf eine int16_t
zuweisen, mit 10 multiplizieren und durch 16 dividieren
(bitte selbst testen):
Josef D. schrieb:> Der DS18B20 liefert das Ergebnis in 16-tel Grad vorzeichenbehaftet als> 16-bit-Zahl, die bei dir in ow_buffer[0] und ow_buffer[1] ankommt.> Du möchtest aber 10-tel Grad haben.> Also musst du nur doch nur die beiden Bytes richtig auf eine int16_t> zuweisen, mit 10 multiplizieren und durch 16 dividieren> (bitte selbst testen):>
1
>int16_ttemp16=(uint16_t)ow_buffer[0];// low-Byte
2
>temp16|=((uint16_t)ow_buffer[1]<<8);// high-Byte
3
>temp16*=10;// Anzeige als 10-tel Grad
4
>temp16/=16;// Sensor liefert 16-tel
5
>
Steht btw genau so in dem Code den ich hier gepostet habe.
Moin moin,
vielleicht kann ja jemand was mit dem Code anfangen, den ich seit über
einem Jahr sehr zuverlässig zum Auslesen meiner Sensoren benutze. Er
basiert auf dem Code von Peter Dannegger (*.h Dateien sowie 1wire.c)
sowie meiner weiter oben vorgestellten Anpassung zur Verhinderung von
Fehlkonvertierungen durch zu langsam zugeschaltete Parasite Power. Er
liest sämtliche am Bus angeschlossene Sensoren aus (egal ob DS18S20 oder
DS18B20). Für die Zwischenspeicherung der in temp zurückgelieferten
Werte muss man bei Anschluss mehrerer Sensoren allerdings selbst sorgen.
Die Routine arbeitet mit Komplementbildung, ist aber mit allen
Temperaturen getestet (auch nahe 0°, also -0.1, 0.0, +0.1 etc.) und
arbeitet absolut sauber. Außerdem kann sie von selbst erkennen, ob ein
DS18S20 oder DS18B20 Sensor angeschlossen ist. Der DS18B20 kann
konfiguriert werden auf 9, 10, 11 oder 12 Bit Auflösung. Der
Rückgabewert in der Integer-Variablen Temp ist in 1/10 Grad. Also -456
für -45.6 Grad oder 237 für +23.7 Grad.
1
#define DS_TEMP_LS 0
2
#define DS_TEMP_MS 1
3
#define DS_TH 2
4
#define DS_TL 3
5
#define DS_RES1 4
6
#define DS_RES2 5
7
#define DS_REM 6
8
#define DS_PER 7
9
#define DS_CRC 8
10
11
// Initialisierung der Sensoren
12
voidinit_meas(unsignedcharresolution){// resolution in Bit (9-12)
13
ucharid[8],diff;
14
15
for(diff=SEARCH_FIRST;diff!=LAST_DEVICE;){
16
diff=w1_rom_search(diff,id);
17
if(diff==PRESENCE_ERR)
18
return;
19
if(diff!=DATA_ERR&&id[0]==0x28){
20
w1_byte_wr(WRITE);// write command
21
w1_byte_wr('\0');
22
w1_byte_wr('\0');
23
w1_byte_wr((uchar)(resolution<<5));
24
}
25
}
26
27
temp_buffer[DS_TEMP_ERR]=0;/* Error-Register */
28
}
29
30
// Messung starten
31
voidstart_meas(void)
32
{
33
if(W1_IN&1<<W1_PIN){
34
w1_command(CONVERT_T,NULL);
35
//W1_OUT |= 1<< W1_PIN;
36
//W1_DDR |= 1<< W1_PIN; // parasite power on
37
}else{
38
temp_buffer[DS_TEMP_ERR]=1;/* Error-Register */
39
//softuart_puts( "DS1820: Short Circuit !\r\n" );
40
}
41
}
42
43
// Daten auslesen (vorher ausreichend Zeit warten - je nach
44
// Sensor-Auflösung zwischen 100 und 800 ms)
45
voidread_meas(void)
46
{
47
ucharid[8],diff;
48
ucharscratchpad[9];
49
inttemp;
50
51
for(diff=SEARCH_FIRST;diff!=LAST_DEVICE;){
52
diff=w1_rom_search(diff,id);
53
54
temp_buffer[DS_TEMP_ERR]=0;/* Error-Register */
55
if(diff==PRESENCE_ERR){
56
temp_buffer[DS_TEMP_ERR]=2;/* Error-Register */
57
//softuart_puts( "DS1820: No Sensor found\r\n" );
58
break;
59
}
60
if(diff==DATA_ERR){
61
temp_buffer[DS_TEMP_ERR]=3;/* Error-Register */
62
//softuart_puts( "DS1820: Bus Error\r\n" );
63
break;
64
}
65
if(id[0]==0x28||id[0]==0x10){// temperature sensor (10h = DS18S20, 28h = DS18B20
Bei meinem obigen Beispiel ist der Parameter "resolution" bei
init_meas() etwas missverständlich beschrieben. Für 9 bit Auflösung muss
als Wert in resolution 0 übergeben werden, für 10 Bit eine 1, für 11 Bit
2 und für 12 Bit 3. Also nicht etwa der Wert 9-12, wie man vermuten
könnte. Sorry!
Volker
Der Beitrag von Sebastian ist zwar schon über ein Jahr alt, aber bisher
wurde er nicht kommentiert. Aus meiner Erfahrung heraus ist dazu aber
was zu sagen:
Sebastian xxlxx schrieb:> Warum eigentlich 0.1 grad ?> Ich habe 20 Sensoren auf eine metall Platte geklebt.> Alle ausgelesen und Werte von - + 2 grad erhalten.> Die sensoren haben auch leichte eigenerwärmung.
Also das mit der Eigenerwärmung stimmt, ist aber nur relevant, wenn man
bei sehr niedrigen Temperaturen (unter -10 Grad) in Luft arbeitet und
jede Sekunde eine Messung mit 12 Bit Auflösung durchführt. Nur dann
kommt es meiner Erfahrung nach zu Abweichungen von mehr als 0,1 Grad.
Wenn der Sensor auf einer Metallplatte klebt, ist eine so extreme
Abweichung von 2 Grad (oder gar 4 Grad absolut) für mich nicht
nachvollziehbar! Ich habe 10 Sensoren aus 3 unterschiedlichen Chargen
nebeneinander liegend (in Luft) getestet und keiner zeigte eine größere
Abweichung als 0,1 Grad an. Die Auflösung war dabei 12 Bit und das
Messintervall 5 Sekunden.
Die großen Abweichungen müssen meiner Meinung nach andere Ursachen haben
und liegen sicher nicht an der Hardware der Sensoren.
Es sei denn, die von dir getesteten Sensoren sind sehr alt und Maxim hat
vor einigen Jahren die Produktion geändert. Neuere Sensoren sind m.E.
nicht so extrem ungenau.
Tschö, Volker
ich nutze den DS18S20 Temperratur wird auch richtig ausgegeben wie
Volker es beschrieben hat.
nun meine Frrage,
ich wollte das gerne so lösen das ich als ausgabe bei Plus-Temperraturen
zB. +22.3 oder +05.3 als Ausgabe erhalte und bei den Minuswerten das
gleiche.
nur bei der Umsetzung tu ich mich ein bischen schwer.
so wie ichs jetzt habe bekomme ich ein minus und plus als Vorzeichen und
der Temperraturwert stimmt auch nicht mehr
vielleicht kann von euch mir da noch weiterhelfen.
mfg
Also erst einmal:
Vorkommastelle ist ein char und temp ein Integer. Das Zuweisen von temp
an Vorkommastelle fürt zu einer unzulässigen Datenkonvertierung.
Vorkommastelle muss also auch ein Integer sein (int16_t).
temp enthält zudem die Temperatur in 1/100 Grad.
So wird ein Schuh draus:
1
int16_tVorkommastelle;
2
3
[..]
4
5
Vorkommastelle=temp/100;
6
temp1=temp;
7
8
Nachkommastelle=(temp1%100);
9
Nachkommastelle=(Nachkommastelle/10);
10
11
printf("%2d,%1d",Vorkommastelle,Nachkommastelle);
Zu beachten ist, dass temp auch negativ sein kann. Wenn du das
Vorzeichen also manuell erzeugst, musst du entweder die Zeile
"temp *= -1;" weglassen, oder auf temp bzw. auf die daraus erzeugten
Daten später die Funktion abs() anwenden.
Gruß, Volker
Volker U. schrieb:> Zu beachten ist, dass temp auch negativ sein kann. Wenn du das> vorzeichen also manuell erzeugst, musst du entweder die Zeile "temp *=> -1;" weglassen, oder auf temp später die Funktion abs() anwenden.>
ich wollte nur das Plus zeichen separat ausgeben aber leider
funktiniert das bei mir nicht.
der sensor liegt grad im eisfach dort sinds -9.0grad aber das
Pluszeichen wird mitausgegeben.
Laut Datenblat;
The sign bits (S) indicate if the
temperature is positive or negative: for positive numbers S = 0 and for
negative numbers S = 1.
if( scratchpad[DS_TEMP_MS] == 1 ) // Negativer Temperaturwert
{
temp *= -1;
}
else
{
Vorzeichen = '+'; //
}
Vorkommastelle = temp / 100;
temp1= temp;
Nachkommastelle = (temp1 % 100);
Nachkommastelle = (Nachkommastelle / 10);
sprintf(gs,"%2d,%1d", Vorkommastelle, Nachkommastelle);
put_c(Vorzeichen);
put_s( gs);
Alex schrieb:> nun meine Frrage,> ich wollte das gerne so lösen das ich als ausgabe bei Plus-Temperraturen> zB. +22.3 oder +05.3 als Ausgabe erhalte und bei den Minuswerten das> gleiche.> nur bei der Umsetzung tu ich mich ein bischen schwer.
Das sollte doch printf schon können:
printf("%+03d,%1d", Vorkommastelle, Nachkommastelle)
^^^
Alex schrieb:> ich wollte nur das Plus zeichen separat ausgeben aber leider> funktiniert das bei mir nicht.
HALT, HALT, HALT!
Erst jetzt sehe ich, dass du meinen Code unzulässig verändert hast! Der
Test auf negative Temperaturwerte lautete bei mir
if( scratchpad[DS_TEMP_MS] ) { // Negativer Temperaturwert
bei dir aber
if( scratchpad[DS_TEMP_MS] == 1 ) { // Negativer Temperaturwert
Das MS-Byte im Scratchpad kann niemals 1 sein!!! Entweder stehen alle 8
Bit auf 1 oder alle 8 Bit auf 0! Der Test muss also so lauten, wie bei
mir oben, oder alternativ
if( scratchpad[DS_TEMP_MS] == 0xFF ) { // Negativer
Temperaturwert
Und was machst du, wenn der Temperaturwert negativ ist? Die Variable
"Vorzeichen" wird ja nur gesetzt, wenn die Temperatur positiv ist, wenn
sie negativ ist, bleibt "Vorzeichen" unverändert, kann also irgendein
beliebiges (unbekanntes) Zeichen enthalten. Das ist nicht so sinnvoll.
Sollte es nicht eher so aussehen?:
if( scratchpad[DS_TEMP_MS] ) // Negativer Temperaturwert
{
temp *= -1;
Vorzeichen = '-';
}
else
{
Vorzeichen = '+'; //
}
Hallo,
Ich komme nicht weiter den Code habe ich im Anhang.
wenn ich mehr als einen sensor anschliesse bekomme ich als ausgabe
Fehler,
der erste Sensor der am Bus hängt wird korregt angezeigt.
vielleicht kahn vohn ihnen wer weiterhelfen
mfg
Hast du denn im EEPROM auch die richtigen ROM-Codes aller
angeschlossenen Sensoren liegen?
Ich würde mal ein paar Debug-Ausgaben auf die serielle Schnittstelle in
den Code einfügen, um den Ablauf mitzuverfolgen und das Programm
debuggen zu können! Vor allem in OW_read_scratchpad, OW_read_rom_code
und OW_rom_code_exists. So auf dem Trockenen dürfte das sonst extrem
schwierig werden!
Gruß, Volker
Im EEprom stehen die richtigen ROM-Codes drin.
ich habe jetzt mal zwei nagelneue DS18S20 Genommen,sie werden aber nur
sporadischerkannt.
Stecke ich nur einen von beiden DS18S20 ande Bus Wird dieser sofrt
erkannt.
mfg
Guten Tag
hallo peter dannegger geniales Projekt habs mir grad
nachgebaut,allerdings hätt ich da noch ne Frage bezüglich zum
unterscheiden der Sensoren.
zB.ich habe 5Sensoren am Bus angeschlossen und hätte dann gern bei der
Temperraturausgabe 1 24,5 für den ersten und 5 32,0 für den fünften
Sensor
wie kann mann dass in ihren code Realiesieren.
vielleicht könnte mir da einer von euch unter die arme greifen.
mfg
Alex schrieb:> Im EEprom stehen die richtigen ROM-Codes drin.> ich habe jetzt mal zwei nagelneue DS18S20 Genommen,sie werden aber nur> sporadischerkannt.> Stecke ich nur einen von beiden DS18S20 ande Bus Wird dieser sofrt> erkannt.
Du verwendest die Sensoren im "parasite power" Modus? Wenn ja: Was für
einen Pullup-Widerstand hast du an dem Bus liegen? Und sorgst du auch
dafür, dass der Bus nach dem CONVERT_T Kommando innerhalb von 10 µs ein
"strong pullup" erfährt? Datenblatt: "Time to Strong Pullup On (Start
Convert T Command issued): 10 us." Falscher Pullup-Widerstand und/oder
Timing könnten das seltsame Verhalten erklären.
Hallo Volker,
Also als Pullup verwende ich 4,7K .
Den Parasitären Modus verwende ich nicht bei dem Programm was ich
gepostet habe nicht.
Da ich noch nicht ganz fit bin in C dachte ich mir könnte jemannd bei
der Fehleranalyse weiterhelfen.
Mfg
Wenn du nicht den Parasite Power Modus nutzt, ist das Strong Pullup zur
Konvertierung egal. Dann sind deine Sensoren ja nicht über zwei Drähte
angeschlossen, sondern über drei (VDD auf positiver Versorgungsspannung,
GND auf Minus und Datenleitung DQ mit 4,7 k Pullup).
Beim DS18S20 musst du nach dem CONVERT_T Kommando mindestens 800 ms
warten, bevor du das Scratchpad ausliest! Denn so lange dauert die
Messung im Sensor.
Dein Programm ist relativ umfangreich. Sich da einzuarbeiten, um "auf
dem Trockenen" dann einen Fehler zu finden, ist mit einem gewissen
Zeitaufwand verbunden. Deshalb ist es einfacher, erstmal mögliche
offensichtliche Fehlerursachen auszuschließen.
Volker U. schrieb:> sondern über drei (VDD auf positiver Versorgungsspannung,> GND auf Minus und Datenleitung DQ mit 4,7 k Pullup).
Genauso sind die Sensoren Angeschlossen
> Beim DS18S20 musst du nach dem CONVERT_T Kommando mindestens 800 ms> warten, bevor du das Scratchpad ausliest! Denn so lange dauert die> Messung im Sensor.
Hier wird ja 800ms gewartet
void OW_convert_all(void)
{
uint8_t i = 80;
OWReset();
OWWriteByte(SKIP_ROM);
OWWriteByte(CONVERT);
while(i--) _delay_ms(10);
}
wenn ich die wartezeit etwass erhöhe ändert sich nichts.
Es bleibt dabei das nur ein Sensor am Bus erkannt wird
mfg
Alex schrieb:> wenn ich die wartezeit etwass erhöhe ändert sich nichts.>> Es bleibt dabei das nur ein Sensor am Bus erkannt wird
Und wie sieht es damit aus, mal ein paar Debug-Ausgaben (auf die
serielle Schnittstelle) in die entsprechenden Prozeduren einzustreuen,
um dem Fehler auf die Spur zu kommen? Wie schon oben von mir
vorgeschlagen.
Wenn du aber sagst, dass die Sensoren sporadisch mal erkannt und
ausgelesen werden können und dann wieder nicht, deutet das eher auf ein
Timing-Problem im 1wire-Protokoll hin. Die Sensoren sind da recht
pingelig, was das Timing betrifft. Ich würde dann vielleicht nochmal die
Wartefunktionen und das Timing überprüfen. In jedem Falle hilfreich sind
aber Debug-Ausgaben an den entscheidenden Stellen im Programm!
Hallo Leute!
Es ist wieder gerade 2:40 Nacht.... Gestern ist es 6:00 morgens
geworden.
Das zieht sich schon seit ein paar Tagen so, aber ich kann es nicht
lassen.
Erstmal danke sehr an alle die hier Die ganze Arbeit geleistet haben.
Solche Sachen stehen in keinem Buch. Ich denke ich habe schon das ganze
Internet durchgelesen um eine Lösung für mein Problem zu finden- leider
vergeblich...
Aber zu meinem Problem... Zu viel nicht labern , sonst wird jemand hier
böse..:)
Ich nutze die Tempmes.c Routine von Josef D die ich hier im Forum
gefunden habe. Hut ab, Respekt und Anerkennung . Sowas tolles findet man
sehr selten.
Sehr hilfreich und sehr vorbildlich beschrieben. Ich habe die wie folgt
an meine Bedürfnisse angepasst:
1
#include"main.h"
2
#define DS18B20_12bit 0x7F
3
#define THERMOanzahlMax 2 // auch thermoNamen anpassen!
Alles lässt sich wunderbar ohne Fehler und Warnungen Compilieren,
bekomme auch klare Temperaturwerte auf dem Display.
Die Probleme aber, die ich habe sind folgende:
1. wird die lcd_setcursor Zeile direkt über lcd_string ((Char*)s) Zeile
gesetzt, wird am Display nichts angezeigt ... Warum ?
2. Ich muss die Thermometer einzeln auslesen, nicht alle zusammen in
einen String, und einzeln mit Lcd_print ausgeben. Da hackt es bei mir
Ich benutze auch nur drei stück und hätte die Namen gerne einzeln
definieren können- da stehen die wieder aber in einem Array. Später
müssen die Werte andere Prozesse steuern wie Lüfter und Kontrolllampen.
Natürlöich kann man auch den fertigen String zerlegen, aber ich denke
dass ist keine gute Lösung. Vielleicht kann mir jemand helfen und sagen
wie ich die Werte in einzelne Variablen bekomme mit den ich dann
weitermachen kann ?
Ich bedenke mich in voraus für jede brauchbare Hilfe und schönen Grüss
an alle...
Ups..3:06 ... Ich denke ich gehe heute ein wenig früher schlafen.
mfg
Jan
Hallo,
nachdem ich die Sourcen gestern problemlos in Betrieb nehmen konnte und
sie super funktionieren vorab mal ein riesiges Dankeschön. Da ich nicht
so der C-Guru bin und ich Peters Code in meine Spären nur ansatzweise
folgen kann habe ich noch eine große Frage ;-)
Wo/Wann muss ich TCNT1H restoren. Die ISR von Peter verstehe ich auch
nicht, aber sie funktioniert. Ich hätte es anders gemacht, aber Peter
hat definitv die exaktere Sekunde herausbekommen!
Hintergrund : Ich möchte auf dem ATMega8 noch eine Soft-PWM laufen
lassen. Bitte nicht schmunzeln, das Thema Soft-PWM ist mir bewusst, aber
ich brauche 4 oder 5 Kanäle und der Mega8 hat ja nur 3 Hardware PWMs -
und ein Timer ist eh schon für die 1s und den Delay weg. Anderen µC mit
mehr HW PWMs tue ich mir erst mal nicht an. Ich bin mir auch nicht
sicher, ob die HW PWM bzgl. der Frage einen Unterschied macht, da der
TCNT1H ja von der HW PWM vermtl. auch geändert würde.
Peter schreibt in seinem Code:
"// Attention !!!
// take care, that during delay no interrupt access a timer register
// or restore TCNT1H
"
Wie das sichern bzw. rücksichern geht ist mir denke ich klar - siehe
Peters ISR. Warum nur TCNT1H ist mir nur zum Teil bewusst
1
/*EDIT: , vermtl. aber wegen der Maskierung auf 0x8000.
2
Mist, RTFM, gemeinsame Verwendung 16 Bit Register, Sorry!
3
EDIT*/
Die große Frage die sich mir stellt, WO muss ich TCNT1H sichern
- zu Beginn/Ende meiner zus. ISR z.B. vom Timer 2? Wenn ja warum, die
Ausführungszeit der ISR ist doch alle mal futsch?
- in der Delay Routine, wenn ja, wo? In der Schleife?
- In der ISR vom Original, aber da wird der TCNT1H schon gesichert und
zurückgesichert?
Ich hatte auch schon überlegt, den Delay direkt in meinem PWM interrupt
(der dann für 1-wire deutlich schneller sein müsste als für die nackte
PWM) runter zu zählen und auszuwerten, und im Hauptprogramm nichts
anders zu machen (bzw. in der Endlosschleife) als dass in der ISR
generierte Flag abzufragen. Bin mit meinen Versuchen aber noch nicht so
weit, dass ich weiß wie weit ich mit dem Delay runter komme, ob das von
der Auflösung her passt.
1
inetwaso:
2
volatileint8_tiDelay
3
volatileuint8_tfDelay
4
5
ISR(alle5µs)?-->Auflösung5µs
6
{
7
If(iDdelay--)<=0Delay.flag=TRUE;
8
else
9
{
10
PWM;
11
}
12
}
13
14
voidMyDelay(int8_tDelay)
15
{
16
Delay.flag=FALSE;
17
iDelay(Delay);//1/5 des us Wertes
18
while(Delay.flag==0);
19
}
gelaufen ist das ganze schon mal testweise ohne 1-wire und ich habe die
Grenzen der kürze nicht ausgelotet. Letztendlich bin ich mir nicht
sicher ob die Befehlszahl der ISR nicht zu groß wird und mit der
Auflösung des Delays in Konflikt kommt. Letzendlich ist mir auch noch
nicht klar, warum ich den TCNT1H restoren muss, Timer 2 greift doch auf
den Wert gar nicht zu, er müsste als beim Interrupt von Timer 2 einfach
weiterzählen?
Den ATMega lasse ich übrigens bei 8MHz laufen. Die DCF Uhr kriege ich
hin, alle 10min abwechselnd DCF lesen und 1-wire messen reicht mir.
Leider bin ich zu diesem Thema in keinem anderen Thread zum 1-wire
fündig geworden, und die Leuchten PWM ist auch was anderes als eine
langsame Temp-Steuerung.
Wäre super, wenn mir Anfänger das näher gebracht werden könnte.
Vielen Dank im Voraus!
//hufnala
Hi Lars,
der Code von Peter ist schon einigermaßen veraltet. Er unterstützt z.B.
nicht die heute gebräuchlichen DS18B20 Sensoren, deren Auflösung man
frei konfigurieren kann (dazu gibt es eine zusätzliche Prozedur
init_meas()). Außerdem hat er Probleme bei Parasite Power und
niedrigeren Taktraten (z.B. 4 MHz), da funktioniert das Auslesen der
Sensoren nicht mehr zuverlässig, wie man hier im Thread nachlesen kann.
Es gibt dann regelmäßig Fehler.
Ich habe den Code über die Zeit weiter entwickelt und angepasst. Er
läuft mittlerweile seit Jahren absolut zuverlässig. Z.B. benutze ich
überhaupt keinen Interrupt mehr und auch keine Timer-Register. Damit
fallen auch alle von dir genannten Probleme weg. Die Wartezeiten werden
einfach mit einer Assembler-Routine (wait.S) generiert. Derzeit sind die
Werte für wait_x_075u() auf 4 MHz eingestellt. Bei anderen Taktraten
müssen einfach nur die Werte beim Aufruf von wait_x_075u() entsprechend
vergrößert oder verkleinert werden. Während der 1wire-Operationen dürfen
ohnehin keine Interrupts auftreten, da du die Ergebnisse sonst wegwerfen
kannst. Das muss sichergestellt sein. Die Sensoren sind äußerst
zeitkritisch. Wenn sie angesprochen werden, darf nichts anderes
passieren.
Anbei mal meine Routinen zum Angucken und vielleicht Ausprobieren (bitte
das zweite Archiv benutzen, im ersten fehlt tempmeas.h!). Sie
ermöglichen den Betrieb von DS18S20 und DS18B20 Sensoren (auch
gemischt). Außerdem sind sie zeitunkritisch, d.h. auch bei 2 oder 4 MHz
Takt gibt es keine Probleme, da die Parasite-Power nicht erst mit einer
(zu) großen Zeitverzögerung in start_meas() geschaltet wird, sondern
immer sofort in w1_bit_io().
Die Routine zum Auslesen der Sensoren und zum Konvertieren der Werte
fehlt im beiliegenden Archiv, weil sie sehr individuell gestaltet werden
kann und sollte. Ein Beispiel dazu findest du hier weiter oben im
Thread:
Beitrag "Re: DS1820, DS18B20 in C"
Gruß, Volker
Hallo Volker,
vielen Dank, schaue ich mir gerne an, und schön dass sich das ganze a)
weiterentwickelt und b) auch in einem alten Tread immer mal wieder
jemand rein schaut.
Habe gerade noch etwas gebastelt, und vordergründig tut es erst mal am
Board.
--> PWM auf Timer2, Taktrate so um 20us -> Auflösung PWM
PWM liegt bei ca. 160Hz
--> das Timerregister in meiner Routine gesichert und Restored
--> 1 Wire läuft, aktuell problemlos
--> USART zu einem angeschlossenen uC 250k
Sensoren habe ich ein paar DS18S20 vom Pollin, vielleicht sind die ja
unkritischer. Für meine Zwecke reicht es. Was ich mir noch anschauen
muss, ist die negative Temp. Aber immer eines nach dem anderen, momentan
ist es hier warm, und vom Eisfach bis zur Schaltung war der Sensor
gestern jedes mal schon wieder auf +15°C bei RT.
Ob Deine Aussage
"Während der 1wire-Operationen dürfen
ohnehin keine Interrupts auftreten, da du die Ergebnisse sonst wegwerfen
kannst. Das muss sichergestellt sein." damit stimmt weiß ich nicht, hier
kann ich erst mal ändernde Temperaturen (Sensor von Hand erwärmen,
reicht für ein paar Grad). Die Werte/das Verhalten ist aktuell auch
stabil ggü. vorher ohne Soft-PWM.
Werden soll das ganze eine Außenlampe mit Groß-Anzeige (habe ich über
einen extra Tiny gemacht). Abwechselnd Hausnummer, Temp, Uhrzeit, Datum.
Die PWM für eine Bunte Effektbeleuchtung (Temp-abhängig?), und die zus.
PWM Kanäle für etwas Power für ein paar Hochleistungs-LED. Dann noch der
PIR für das hochschalten der Leuchte.
Nochmals Danke und einen schönen Abend.
Bevor ich den Code Poste (falls es je dazu kommt) muss ich erst mal
aufräumen und ordentlich machen - Anfänger halt :-), ich glaube aber das
wird dann endgültig off-topic...
Gruß Lars
Lars Hufnagel schrieb:> Habe gerade noch etwas gebastelt, und vordergründig tut es erst mal am> Board.
Klar, Peters Teil tut es, keine Frage :-). Und ab 8 MHz gibts i.d.R.
auch keine Probleme. Aber bei niedrigeren Taktraten kommen zwischendurch
gern mal 85 Grad zurück, weil die Parasite Power nicht schnell genug
zugeschaltet wurde.
> Sensoren habe ich ein paar DS18S20 vom Pollin, vielleicht sind die ja> unkritischer.
Nein, vom Timing her unterscheiden sie sich nicht vom DS18B20. Die
DS18B20 haben den Vorteil, dass man sie auf eine geringere Auflösung
schalten kann. Nicht immer braucht man ja eine Auflösung von 1/16 °C.
Und bei geringeren Auflösungen verringert sich die Wartezeit zwischen
CONVERT_T-Kommando und der fertigen Konvertierung erheblich. Jedes Bit
weniger Auflösung bedeutet nur halbe Wartezeit. Wenn einem also eine
Genauigkeit von 0,5 °C ausreicht, muss man nur noch 100 ms warten. Das
spart Zeit und Energie.
> Für meine Zwecke reicht es. Was ich mir noch anschauen> muss, ist die negative Temp.
Wie gesagt, dort bietet sich die Konvertierungs-Routine an, auf die ich
oben verlinkt habe. Sie arbeitet mit Komplementbildung, was manche hier
unsinnig finden, aber von der Rechenzeit her ist es der schnellste Weg.
> Ob Deine Aussage> "Während der 1wire-Operationen dürfen> ohnehin keine Interrupts auftreten, da du die Ergebnisse sonst wegwerfen> kannst. Das muss sichergestellt sein." damit stimmt weiß ich nicht,
Das Problem ist, dass die Wartezeiten im Mikrosekundenbereich liegen
beim Lesen der Sensoren. Die Leitungen müssen da ganz exakt getaktet
werden. Wenn nur ein paar falsche Takte dazwischen kommen, sind die
Ergebnisse unbrauchbar. Deshalb schaltet Peter ja in w1_bit_io() auch
schon das Interruptssystem sicherheitshalber vorübergehend ab und
verhindert somit jede Unterbrechnung. Das muss man berücksichtigen, wenn
man Timer-Interrups benutzt. Ich hatte zuerst nicht daran gedacht und
wunderte mich, wieso meine Timer-Interrupt-gesteuerte Real-Time-Clock
mal vor- und mal nachging. Dafür war natürlich die vorübergehende
Abschaltung des Interrupt-Systems verantwortlich, die die Ereignisse
unzulässig verzögerte.
Es ist darüberhinaus auch nicht ganz unsinnig, die gelesenen Daten mit
der CRC-Routine auf Plausibilität zu überprüfen, wie es der Hersteller
empfiehlt.
> Werden soll das ganze eine Außenlampe mit Groß-Anzeige (habe ich über> einen extra Tiny gemacht). Abwechselnd Hausnummer, Temp, Uhrzeit, Datum.
Hoffentlich verwechselt der Briefträger dann die Temperatur nicht mit
der Hausnummer. ;-)
Frohes Basteln!
Volker
Volker U. schrieb:> ... Dafür war natürlich die vorübergehende> Abschaltung des Interrupt-Systems verantwortlich, die die Ereignisse> unzulässig verzögerte.>
Das kann aber nur dann der Fall sein, wenn du nicht den richtigen
Timer-Modus verwendet hast.
Solange die ISR-Sperre nicht dazu führt, dass ein Timer-Interrupt ganz
übersehen wird, spielt die Verzögerung für eine RTC überhaupt keine
Rolle. Die Sperre beträgt, wenn ich mich recht erinnere, nur ca. 60 µs.
So kurze Timer-Intervalle wirst du vermutlich nicht haben.
Josef D. schrieb:> Solange die ISR-Sperre nicht dazu führt, dass ein Timer-Interrupt ganz> übersehen wird, spielt die Verzögerung für eine RTC überhaupt keine> Rolle.
Nicht immer kann man das automatische Rücksetzen des Counters auf 0
verwenden. Wenn man die Uhr sehr genau justieren will (z.B. auf weniger
als 1 Sekunde Abweichung pro Monat), muss man den Counter in der ISR
selbst setzen. Der Interrupt tritt dann zeitlich verzögert ein und zwar
erst dann, wenn die Interrupts mit sei() wieder freigegeben wurden. Erst
dann wird das Counter-Register zurückgesetzt und ein neues
Zähl-Intervall beginnt. Auf diese Weise summieren sich die Verzögerungen
im Laufe der Zeit zu ganz erheblichen Abweichungen. Und zwar abhängig
davon, wie häufig der Interrupt zeitlich verzögert auftritt. Daher darf
der Counter in der ISR in diesem Fall nicht auf 0 gesetzt werden,
sondern es muss ein konstanter Betrag vom aktuellen Zählerstand
subtrahiert werden.
Es ging ja auch nur darum zu sagen, dass man aufpassen muss, weil das
Interruptsystem bei der Kommunikation mit dem Sensor zwischendurch immer
wieder mal deaktiviert wird. Was die Uhr betrifft, kann man alternativ
zum Counterwert natürlich auch den Compare-Wert entsprechend ändern und
den Counterwert automatisch auf 0 setzen lassen. Man muss ihn dann aber
immer wieder auf den Ausgangswert zurücksetzen, weshalb ich die Änderung
des Counterwerts bevorzuge.
Man kann auch den anderen Weg gehen und Interrupts nicht deaktivieren.
Wenn dann in die 1Wire Kommunikation ein Interrupt reinfunkt dann gibts
eben Datensalat, erkennbar am falschen CRC. Wenn man dann den Zugriff
auf den Sensor noch ein wenig zufällig gestaltet, so kann man mit hoher
Wahrscheinlichkeit eine ausreichende Anzahl von erfolgreichen Zugriffen
pro Zeiteinheit erhalten. Damit hätte der Interrupt immer prio.
gruß cyblord
Nuja, das Konzept finde ich aber sehr unschön: Datensalat bewusst in
Kauf zu nehmen, um nachträglich anhand von Prüfsummen die fehlerhaften
Daten rauszuwerfen. Man muss mal bedenken, dass ein 8-Bit-CRC auch nur
begrenzte Sicherheit bietet. Wenn zu häufig Datensalat auftritt, steigt
die Wahrscheinlichkeit nicht unerheblich, dass der CRC zufällig doch
richtig ist, obwohl die Daten falsch sind. Ich würde daher immer auf
sichere Übertragung setzen.
Das Konzept kommt häufig zum Einsatz. Bei Ethernet z.B. ebenso WLAN.
Aber auch in Datenbank- und Betriebssytemen werden oft Deadlocks o.ä.
nicht aktiv verhindert, sondern falls etwas passiert, dann halt unter
größerem Aufwand wieder ausgebügelt. Wenn aber dieser Aufwand geringer
als der sonst benötigte Overhead ist, dann lohnt das.
Etwas seltener allerdings bei Atomkraftwerken oder in der
Luft/Raumfahrt.
gruß cyblord
Ähm, Ethernet arbeitet aber nicht mit 8 Bit CRCs und Deadlocks sind auch
was anderes als Datenfehler. Es kommt darauf an, wie hoch die zu
erwartende Fehlerquote ist und welche Quote toleriert werden kann. Es
gibt auch Anwendungen, da darf es keine Fehler geben. Keine heißt in
diesem Fall eine Quote gegen Null.
Volker U. schrieb:> Ähm, Ethernet arbeitet aber nicht mit 8 Bit CRCs und Deadlocks sind auch> was anderes als Datenfehler.
Dir ist der Begriff "Konzept" klar?
> Es kommt darauf an, wie hoch die zu> erwartende Fehlerquote ist und welche Quote toleriert werden kann.
Ja, das muss man vorher ausrechnen ob es passt.
gruß cyblord
Hi,
zunächst verspätet noch vielen Dank. Also bisher läuft das ganze
anscheinend stabil. Endausbau ist noch lange nicht fertig, und wenig
Zeit momentan, aber ich probiere immer mal wieder. Momentan sieht es
nicht so aus als hätte ich Datensalat empfangen bisher alle Werte
zwischen 18 - 24°C, und die PWM LED flackert auch nicht.
"Hoffentlich verwechselt der Briefträger dann die Temperatur nicht mit
der Hausnummer. ;-)"
Yepp, auf die Idee bin ich noch gar nicht gekommen, Mal sehen wann hier
was für 36C ankommt statt 20b - könnte sich auch zur Marktlücke bzgl.
unerwünschter Werbung & Rechnungen entwickeln ;-)
CU //hufnala
cyblord ---- schrieb:> Dir ist der Begriff "Konzept" klar?
Also ich finde, der Vorschlag, Daten zu verwerfen, weil der
Übertragungskanal unzureichend ausgelegt ist, ist ein anderes Konzept
als das der unvermeidbaren Kollisionsvermeidung bei gemeinsamer Nutzung
einer Transportschicht z.B. im Ethernet oder WLAN ;).
Aber unabhängig davon, ist dieses Konzept untauglich bei Nutzung von
8-Bit-CRC. Und darum ging es hier ja eigentlich.
Volker U. schrieb:> cyblord ---- schrieb:>> Dir ist der Begriff "Konzept" klar?>> Also ich finde, der Vorschlag, Daten zu verwerfen, weil der> Übertragungskanal unzureichend ausgelegt ist, ist ein anderes Konzept> als das der unvermeidbaren Kollisionsvermeidung bei gemeinsamer Nutzung> einer Transportschicht z.B. im Ethernet ;).
Das ist genau dasselbe. Der Kanal ist nicht unzureichend ausgelegt, es
kann nur eben vorkommen dass die Übertragung kurz stockt (durch
Interrupt) und daher die Daten fehlerhaft sind, genauso wie beim
Ethernet eben auch mal 2 gleichzeitig senden und dadurch die Daten
fehlerhaft werden. Dies wird erkannt, und kurze Zeit später nochmal
versucht.
Und Kollisionen in einem Netzwerk sind nicht unvermeidbar, es gibt auch
Protokolle die das anders machen. z.B. TokenRing.
Aber egal, ich würde den Interrupt auch abschalten. Wollte nur mal eine
weitere Option einbringen.
Und btw: Ethernet != Transportschicht ;-)
cyblord ---- schrieb:> Das ist genau dasselbe.
Ich glaube, das ist Interpretationssache ;-).
> Der Kanal ist nicht unzureichend ausgelegt, es> kann nur eben vorkommen dass die Übertragung kurz stockt (durch> Interrupt) und daher die Daten fehlerhaft sind,
Das sehe ich z.B. als unzureichende Auslegung. Unzureichend ist eben
auch subjektiv.
> genauso wie beim> Ethernet eben auch mal 2 gleichzeitig senden und dadurch die Daten> fehlerhaft werden.
Auch das ist für mich unzureichend. Weshalb man ja auch keine Hubs mehr
benutzt, sondern Switches, wodurch auch beim Ethernet Kollisionen
vermieden werden.
> Aber egal, ich würde den Interrupt auch abschalten. Wollte nur mal eine> weitere Option einbringen.
Nur halte ich diese Option bei einer 8-Bit-Prüfsumme für keine solche
:-).
> Und btw: Ethernet != Transportschicht ;-)
Eben! Das Ethernet ist aber nicht für die Stauvermeidung zuständig, um
die es uns ja ging, sondern die Transportschicht, also TCP oder UDP.
Deshalb war dein Beispiel nicht so sinnvoll.
Volker U. schrieb:> cyblord ---- schrieb:>> Das ist genau dasselbe.>> Ich glaube, das ist Interpretationssache ;-).
Ach je
>> Der Kanal ist nicht unzureichend ausgelegt, es>> kann nur eben vorkommen dass die Übertragung kurz stockt (durch>> Interrupt) und daher die Daten fehlerhaft sind,>> Das sehe ich z.B. als unzureichende Auslegung. Unzureichend ist eben> auch subjektiv.>>> genauso wie beim>> Ethernet eben auch mal 2 gleichzeitig senden und dadurch die Daten>> fehlerhaft werden.>> Auch das ist für mich unzureichend. Weshalb man ja auch keine Hubs mehr> benutzt, sondern Switches, wodurch auch beim Ethernet Kollisionen> vermieden werden.
Also beides für dich(!) unzureichend, also passt doch mein Beispiel.
Das nun Ethernet heute nicht mehr per Koax oder Hub läuft ist doch hier
absolut egal.
> Nur halte ich diese Option bei einer 8-Bit-Prüfsumme für keine solche> :-).
Nur weil du die CRC als einzige Möglichkeit siehst. Der Interrupt könnte
auch ein Flag setzen wenn er auftritt, und die 1Wire Routine könnte
dieses Flag am Ende abfragen und weiß dann dass ein Interrupt irgendwo
während der Übertragung aufgetreten ist.
>>> Und btw: Ethernet != Transportschicht ;-)>> Eben! Das Ethernet ist aber nicht für die Stauvermeidung zuständig, um> die es uns ja ging, sondern die Transportschicht, also TCP oder UDP.> Deshalb war dein Beispiel nicht so sinnvoll.
Was eben? Du hast Ethernet als Transportschicht bezeichnet was falsch
ist.
Und natürlich brauchen auch die physikalischen Schichten immer eine
Sicherung ihrer Daten auch gegen Kollision. Bei Ethernet CSMA/CD, bei
WLAN CSMA/CA. Deine Aussage, das bräuchte man nicht, weil ja dafür TCP
zuständig ist und deine Gleichsetzung mit Staukontrolle, entlarvt dich
leider als wenig qualifiziert für diese Diskussion.
Du magst meinen Ansatz nicht, kannst aber nicht artikulieren warum.
Lassen wirs doch dabei, das ist mir zu anstrengend.
gruß cyblord
cyblord ---- schrieb:>> Nur halte ich diese Option bei einer 8-Bit-Prüfsumme für keine solche>> :-).> Nur weil du die CRC als einzige Möglichkeit siehst. Der Interrupt könnte> auch ein Flag setzen wenn er auftritt, und die 1Wire Routine könnte> dieses Flag am Ende abfragen und weiß dann dass ein Interrupt irgendwo> während der Übertragung aufgetreten ist.
Das ist jetzt aber ein völlig neues Konzept, über das hier bisher nicht
einmal gesprochen wurde!
> Was eben? Du hast Ethernet als Transportschicht bezeichnet was falsch> ist.
Wiebitte? Wo habe ich das denn getan? Ich habe geschrieben "[..] als das
der unvermeidbaren Kollisionsvermeidung bei gemeinsamer Nutzung
einer Transportschicht z.B. im Ethernet oder WLAN ;)." Du wirst wohl
nicht abstreiten, dass es im Ethernet und WLAN eine Transportschicht
gibt, oder?
> Und natürlich brauchen auch die physikalischen Schichten immer eine> Sicherung ihrer Daten auch gegen Kollision. Bei Ethernet CSMA/CD, bei> WLAN CSMA/CA. Deine Aussage, das bräuchte man nicht, weil ja dafür TCP> zuständig ist und deine Gleichsetzung mit Staukontrolle, entlarvt dich> leider als wenig qualifiziert für diese Diskussion.
Sie brauchen es nicht immer. Man kann in der Sicherungsschicht eine
Kollisionsvermeidung implementieren, aber es ist für die
Sicherungsschicht nicht zwangsläufig vorgeschrieben. Fehlererkennung und
Kollisionsvermeidung sind ja zwei ganz unterschiedliche Dinge. Du
sprachst von Fehlererkennung und ich von Kollisionsvermeidung.
> Du magst meinen Ansatz nicht, kannst aber nicht artikulieren warum.
Ich denke, ich habe mehrfach gesagt, warum ich diesen Ansatz für
unbrauchbar halte: Weil eine 8-Bit-CRC zur Fehlererkennung nicht
ausreicht. Wenn du jetzt noch zusätzliche Mechanismen einführst, um die
Erkennung zuverlässiger zu machen, kannst du das gerne tun, aber es war
zu Beginn nicht Gegenstand dieser Diskussion!
Wenn du mich nicht als qualifiziert für diese Diskussion hältst, warum
diskutierst du dann mit mir? ;-)
Lars Hufnagel schrieb:> "Hoffentlich verwechselt der Briefträger dann die Temperatur nicht mit> der Hausnummer. ;-)">> Yepp, auf die Idee bin ich noch gar nicht gekommen, Mal sehen wann hier> was für 36C ankommt statt 20b - könnte sich auch zur Marktlücke bzgl.> unerwünschter Werbung & Rechnungen entwickeln ;-)
Das dürfte nur problematisch werden, wenn der Briefträger nicht nur
Werbung, sondern auch wichtige Post für dich hat ;-).
Hallo Peter,
herzlichen Dank für die 1-wire-Sources.
Funktionierte auf Anhieb nachdem ich den DS18S20 richtig verkabelt hatte
(hatte den Pullup-Widerstand vergessen...).
Was m.E. noch nicht drin ist oder für den DS18S20 nicht funktioniert
hat, war die Auflösungserhöhung via "count per C" und "count remain"
Register.
(datasheet S.3)
Falls es jemand braucht, sieht bei mir im Code so aus (ersetzt die
READ-passage):
Hallo,
ich bedanke mich für die Codes hier, das hat mir viel Zeit erspart.
Ich habe für meinen Projekt auch mehrere Sensoren DS18B20 verwenden
wollen, und habe auch ohne große Probleme erstmal 2 Sensoren an einer
Leitung zum Laufen gebracht. Allerdings gefiel mir eben nicht die
Tatsache, daß die negativen Temps nicht korrekt angezeigt wurden.
Erste Versuche mit kleinen Änderungen am vorhandenen code haben nicht
gebracht.
Dann habe ich "richtig" umgebaut und hier ist das Ergebnis:
/***********************************************************************
ein Vorschlag vom Josef: Beitrag "DS1820, DS18B20 in C"
Allerdings: korrigiert von mir bei Ausgabe von negativen Temperaturen
***********************************************************************/
#include "main.h"
#include "HD44780_2.h"
#define MIT_NAMEN 1 // 0= ohne, 1=mit Namen in DS1820
void start_meas( void ){
if( W1_IN & 1<< W1_PIN ){
w1_command( CONVERT_T, NULL );
W1_OUT |= 1<< W1_PIN;
W1_DDR |= 1<< W1_PIN; // parasite power on
_delay_ms(600); // Verzögerung wg parasite power
}
}
#if MIT_NAMEN
#define DS18B20_12bit 0x7F
// #define THERMOanzahlMax 3 // auch thermoNamen anpassen!
#define THERMOanzahlMax 2 // auch thermoNamen anpassen!
// "123456123456123456"
// #define THERMO1WNAMEN " T1 T2 T3" // Überschrift,
rechtsbündig
#define THERMO1WNAMEN " T1 T2" // Überschrift, rechtsbündig
#define THERMO1NameLen 6
#define THERMO1NameOffset (THERMO1NameLen-2) // hier steht das 1.
Zeichen
static char thermoNamen[] = THERMO1WNAMEN; // ToDo PROGMEM
static float thermoValues[THERMOanzahlMax];
static uint8_t initReady;
#if (THERMOanzahlMax<=8)
static uint8_t valid; // Indizes mit gültigen Namen merken, je 1 bit
#else
static uint16_t valid;
#endif
static uint8_t NameValid( char * name ) {
// prüft, ob Name aus scratch mit Name aus Tabelle übereinstimmt
// wenn ja, ret = index+1!!!; andernfalls 0
uint8_t ret = 0;
char * pC = thermoNamen+THERMO1NameOffset;
while (ret++ < THERMOanzahlMax) {
if ( *(int16_t*) name== *(int16_t*) pC) // 2 Byte vergleichen
return ret;
pC += THERMO1NameLen;
}
return 0;
}
#endif
void read_meas( void )
{
uchar id[8], diff;
char s[30];
uchar i;
int16_t temp1,temp2;
float temp=0;
for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){
diff = w1_rom_search( diff, id );
if( diff == PRESENCE_ERR ){
break;
}
if( diff == DATA_ERR ){
break;
}
if( id[0] == 0x28 || id[0] == 0x10 ){ // temperature sensor
#if !MIT_NAMEN
//Wert der ID ausgeben
for( i = 0; i < 8; i++ ){
sprintf (s, "ID: %02X ", id[i] );
LCD_GoTo_2(0);
LCD_WriteText(s);
}
#endif
w1_byte_wr( READ ); // read command
temp1 = w1_byte_rd(); // low byte
temp2 = w1_byte_rd(); // high byte
temp=(float)(temp1+(temp2*256))/16;
#if MIT_NAMEN
char name[2]; uint8_t nIndex;
name[0] = w1_byte_rd(); // high Index
name[1] = w1_byte_rd(); // low Index
if (!initReady) { // nur beim 1. Durchgang
// PrintId( id, name ); // erkannte Sensoren mit Namen ausgeben,
z.B. auf Uart
/*************************************
LCD_GoTo_2(5);
LCD_WriteText(name);
LCD_WriteText(" ");
**************************************/
}
if ((nIndex = NameValid(name))) {
thermoValues[--nIndex] = temp;
valid |= (1<<nIndex);
} else if (initReady==1){ // alle im 0. Durchgang als gültig
erkannten sind ausnahmsweise noch gesetzt
i = 0;
while ((1<<i++) & valid); // 1. freien Platz finden (i ist dann
1 zu groß)
if (--i<THERMOanzahlMax) { // also vorher 1 abziehen
valid |= (1<<i); // jetzt belegt
i *= THERMO1NameLen;
i += THERMO1NameOffset;
w1_command( WRITE, id );
w1_byte_wr( name[0]=thermoNamen[i++] );
w1_byte_wr( name[1]=thermoNamen[i] );
w1_byte_wr( DS18B20_12bit ); // ggf. anpassen für anderen
Sensor!
w1_command( EE_WRITE, id );
// PrintId( id, name ); // Namensänderung protokollieren
}
}
#else
//Messwert in Grad Celsius auf LCD ausgeben
dtostrf(temp, 3, 1, s);
LCD_GoTo_3(2);
LCD_WriteText(s);
LCD_WriteData (2); // " Grad "
LCD_WriteText("C");
LCD_WriteText(" ");
#endif
}
}
#if MIT_NAMEN
for( i=0; i<THERMOanzahlMax; i++) { // Error-Detection
/***********************************************************************
**
* es treten gelegentlich Lesefehler auf (Detektor wird nicht
gefunden).
* Ausgelassene Werte machen viel Arbeit in Excel und verunstalten
die Grafik.
* Deshalb jetzt: alten Messwert +/- Konstante, z.B. 1°=0x10 (1*16).
* und das letzte Bit gibt an, ob addiert oder subtrahiert werden
muss (abwechselnd)
* Wenn man das nicht braucht, kann man auch einfach einen sonst nicht
vorkommenden
* Wert einsetzen, z.B. 0.
************************************************************************
*/
temp=thermoValues[i];
if (!(valid &(1<<i))) { // keinen neuen Wert gelesen ?
// dann den alten nehmen
thermoValues[i]=temp;
}
dtostrf(temp, 3, 1, s);
// die Überschrift muss ggf. an die Stellenzahl dieser Ausgabe
angepasst werden
LCD_GoTo_4(i*10);
LCD_WriteText(" ");
LCD_WriteText(s);
LCD_WriteData (2); // " Grad "
LCD_WriteText("C");
LCD_WriteText(" ");
}
if (initReady)
valid = 0;
// d.h. beim ersten Durchgang stehen lassen für Erkennung der freien
Plätze für unbekannte Sensoren
if (initReady<255) // Überlauf verhindern
++initReady;
#endif
}
und hier bitte das Bild vom Versuchsaufbau.
Die Ausgabe funktioniert jetzt ohne "fremde" Zeichen
und bei negativen Temperaturen absolut einwandfrei:
P.S.: leider habe ich keinen Kältespray mehr um die negativen zu zeigen
...;)..
Richard S. schrieb:> da ich zwischen 4 Sprachen "umschalten" muß, kommt manchmal dazu,> daß ein Buchstabe fehlt .....
Und wenn man "Digital-Thermometer" schreibt, ist das Wort außerdem nicht
mehr so schön zentriert, bei einem 20-Zeichen-Display :-p
Hallo Zusammen,
erst mal recht herzlichen Dank, für die ganzen Codes zu diesem Thema.
Ich habe den Sensor nun endlich ausgelesen,dann jedoch feststellen
müssen, dass er ab einer Temperatur über 53°C nicht mehr erkannt wird.
Komischerweise springt das Programm dann immer in die Anweisung:
if( diff == PRESENCE_ERR ){
lcd_clear();
lcd_setcursor(0,2);
lcd_string( " Sensor fehlt!" );
break;
}
(Befindet sich in der tempmeas.c)
kann mir jmd sagen woran das liegt? Alles andere scheint zu
funktionieren.
Lutz schrieb:> kann mir jmd sagen woran das liegt?
Am fehlenden Schaltplan und Angaben zum Aufbau? Parasitärer Betrieb und
Leckströme vielleicht? Das Datenblatt spricht zwar erst ab 100°C von
Problemen ("The use of parasite power is not recommended for
temperatures above +100°C"), aber vielleicht liegt noch mehr im Argen.
Lutz schrieb:> if( diff == PRESENCE_ERR ){> kann mir jmd sagen woran das liegt? Alles andere scheint zu> funktionieren.
Falls der Sensor im Parasite-Power-Modus betrieben wird, hängt dies fast
immer damit zusammen, dass das nötige "strong pullup" nicht schnell
genug nach dem Absetzen des CONVERT_T Kommandos zugeschaltet wird. Dazu
sind nur 10 Mikrosekunden Zeit. Siehe auch hier:
Beitrag "Re: DS1820, DS18B20 in C"
Hallo,
ich habe das Projekt mit dem Tiny84 realisiert und jetzt für konkrete
Aufgabe vorbereitet - unser Kühlschrank.
Das Gehäuse ist noch nicht ganz fertig, aber bald.
Die Anzeige funktioniert einwandfrei, wie man sehen kann.
@Volker
Dein Vorschlag ist natürlich auch drin....Danke!
Gruß,
Richard
Wie schön! :-)
Wie hast du deine Messleitungen in den Kühlschrank geführt? Ich hatte
auch mal ein Thermometer im Gefrierschrank. Da hatte ich eine ganz dünne
Zwillingslitze zwischen Türrahmen und Dichtung entlang geführt. Das
Problem war: An dieser Stelle kommt Luft von außen in den Schrank, auch
wenn es nur sehr wenig ist. Im Laufe der Zeit hat sich die Dichtung an
der Stelle zudem verformt, also dem Kabel angepasst und blieb auch
undicht, wenn das Kabel entfernt war. Dort wo diese Undichtigkeit
bestand, war der Gefrierschrank innen immer erheblich dicker mit Eis
befroren, als im übrigen Innenraum. Das heißt, dass selbst so eine
kleine Undichtigkeit nicht unerhebliche Auswirkungen auf das Innenleben
eines Gefrierschranks und damit auch auf den Energieverbrauch hat.
Vermutlich müsste man ein kleines Loch in die Dichtung bohren, das Kabel
dann dort durchführen und alles mit Silikon abdichten, um es perfekt zu
machen.
Schöne Grüße, Volker
Volker U. schrieb:> Vermutlich müsste man ein kleines Loch in die Dichtung bohren, das Kabel> dann dort durchführen und alles mit Silikon abdichten, um es perfekt zu> machen.
Das hat Conrad vielleicht ein passendes Kabel (943358). Die 0.1mm dürfte
auch die Kühlschrankdichtung nicht zu sehr aus der Fassung bringen.
Interessantes Kabel! Allerdings ist es mit 34 mm ganz schön breit. Und
wie hoch der spezifische Widerstand ist, darüber schweigt sich das
Datenblatt leider völlig aus. Für NF-Anwendungen ist es sicher gut
geeignet, für Temperatursensoren auch. Im HF-Bereich dürfte es
allerdings sehr schnell versagen, weil es eine große Fläche und keine
Abschirmung bietet.
Es sieht aus wie ein Klebeband, daher wäre es eigentlich perfekt, wenn
es auf der einen Seite eine Klebefläche hätte und auch wie ein Klebeband
befestigt werden könnte. Aber das geht leider nicht, man muss es wohl
mit Klebstoff festkleben.
Da fällt mir auf, dass es sowas noch gar nicht gibt: Eine ultraflache
Zwillingslitze in Form eines Klebebandes, die man wie ein Tesa-Klebeband
verarbeiten und überall aufkleben kann. Das wäre genial, um unsichtbare
Kabel auf Fußleisten oder über Türrahmen zu verlegen. Scheint eine
Marktlücke zu sein...
Hi
Hauchdünner Kupferlackdraht auf Tixo kleben ginge auch.
Ich hab mal 0,01mm gekauft. Das muss ich teilweise unter der Lupe löten,
sonst sehe ich den Draht nicht. Vor und nach der Dichtung kann man ja
mit "normalem" Kabel weiterleiten.
Aber bei über 1KM könnte man auch lange Verbindungen herstellen.
Preis ist ja nicht ohne für 1m bei dem "Flachband" Kabel.
Ciao T.A.
Ich wusste bis jetzt gar nicht, dass der Tesafilm in Österreich Tixo
heißt :-).
Das ist aber eine ziemliche Fummelei, einen dünnen Kupferlackdraht
manuell auf Klebefilm aufzutragen. Klar, für kleine Strecken ist es kein
Problem. Das Problem ist dann eher der Übergang vom hochempfindlichen
Lackdraht zum normalen Kabel. Da muss man den Draht auf jeden Fall
irgendwie fixieren, z.B. mit einem Klebepad, weil er sonst schnell
abreißt.
Hallo,
ich habe ein ca. 10 cm-Stück vom Flachbandstreifen (ca. 0.2 mmm dick)
eines alten Tintenstrahlers genommen und zwischen zwei kleinen Stücken
Epoxyplatinnen (durchkontaktierten) gelötet. Da dran ist dann normales
dünnes kabel angelötet. Somit ist der Übergang an den Türen absolut
akzeptabel, denke ich.
Ja, das ist eine interessante und gute Idee! Allerdings würde ich trotz
der geringen Dicke von nur 0,2 mm ab und zu mal die Türdichtung an der
Durchführungsstelle beobachten.
#define OW_GET_MASK(x) x = GPIO_ReadValue(OW_PORT)
14
15
16
#define OW_IN OW_PORT->FIOPIN
17
#define OW_PIN_NR 29
18
19
#ifndef W1_PIN
20
#define W1_PIN OW_PIN_NR
21
#define W1_IN OW_IN
22
#define W1_OUT OW_SET
23
#define W1_DDR OW_DIR
24
#endif
weiters habe ich noch die delayfunction portiert.. diese funktioniert...
als ergebnis für den DS18B20 bekomme ich immer
1
BUS ERROR
leider weiß ich nicht mehr weiter..
am Oszilloskop kann ich waveforms erkennen vom UC und auch vom Ds18b20
also falsch verdrahtet ist es nicht. ich verwende 3v3 und den 4k7
Widerstand..
mfg
Hallo Zusammen
Nach etwas probieren kompiliert der Code von Peter nun bei mir mit
AVR-Studio 4 und WinAVR problemlos und fehlerfrei. (Ich hatte teilweise
die gleichen Compiler-Errors wie weiter oben beschrieben)
Der Code funktioniert wunderbar. Tolle Sache, Peter.
Damit andere sich andere das Gestolper sparen können anbei das gezippte
Projekt für AVR-Studio, inkl. Quellcode.
Verwendet habe ich einen ATMega16 @8MHz (int. Oszillator), 19200 Baud am
Uart und 2 DS18S20. Beide Sensoren werden automatisch erkannt und anhand
ihrer Seriennummer ausgelesen. Beide Sensoren sind an der gleichen
1Wire-Leitung, 4k7 Pullup nicht vergessen!
Viel Spaß damit.
Hallo, habe mich hier grob mal durchgelesen.. irgendwie zeigen bei mir
alle DS18B20 ca 2-3° zuviel.. am arduino als Test waren diese alle
gleich, soweit genau und identisch.
Habe ich hier vielleicht eine zu alte Vorlage genutzt ?
Hi
Das hatte ich auch so. Durch die permanente Spannung wird das
eigenerwärmung sein. Meine Sensoren kleben aber an Flächen da war das
dann egal. Diese Flächen Werden nicht warm.
Philipp K. schrieb:> irgendwie zeigen bei mir> alle DS18B20 ca 2-3° zuviel.. am arduino als Test waren diese alle> gleich, soweit genau und identisch.
Entweder zeigen die was an oder nicht, aber zu viel oder zu wenig geht
nicht, da sie ab Werk kalibriert sind. Natürlich haben die Abweichungen,
aber nicht mehrere Grad.
Schon mal überlegt, ob dein Vergleichsthermometer genau ist?
In meinem Raum hier sind zwei Uhren mit Thermometer, eines zeigt 22.9°C
und das andere 23.3°C. Die üblichen Abweichungen liegen bei einem halben
Grad im Maximum.
DS18..., die ich auch ausschließlich verwende, haben bei mir alle bis
jetzt höchstens 0.3 Grad Abweichung gehabt.
dann muss ich nochmal schauen ..
Aber habe mehrere DS18B20 in mehreren Geräten über eine ArduinoLib in
Benutzung und diese zeigen alle den gleichen Wert wie praktisch jedes
andere Thermometer.. egal welchen ich nun in mein Avr-C Projekt mit dem
Beispiel hier benutze zeigt der mindestens 2° mehr an..
Ich vermutete das ich vielleicht etwas wichtiges nicht beachtet habe.
Gruß,
Philipp
Hallo
Ich versuche jetzt schon seit einer Ewigkeit den 1wire Code von Peter
Dannegger zum Laufen zu bekommen. Da ich mich wahrscheinlich einfach nur
dumm anstelle, hoffe ich auf eure Hilfe.
Ich will einfach ein integer bekommen und dann auf einem LCD anzeigen.
Wie mache ich das?
Noch eine schöne Woche!!!!
mfg
Ich möchte diesen alten Thread noch einmal aufwärmen, da ich nun leider
auch das Problem habe mehrere (3 Stück) DS18B20 am 1Wire-Bus ausgelesen
zu bekommen.
Vorweg: Ich benutze nun schon seit langer Zeit erfolgreich die Routinen
mit CRC-Berechnung von Volker U., die wiederum auf dem Code von Peter
Dannegger beruhen. Beitrag "Re: DS1820, DS18B20 in C"
Das Auslesen eines Temperatursensors läuft absolut stabil.
Nun möchte ich allerdings 3 (max. 5) Sensoren an dem gleichen 1Wire-Bus
auslesen und ich habe dabei große Probleme.
Interessanterweise funktioniert das Auslesen von 3 Sensoren problemlos
im Laborbetrieb auf dem Schreibtisch!
In eingebautem Zustand sind die Sensoren aber über ein ca. 5m langes
CAT5 Kabel angeschlossen, von dem 3 Leitungen benutzt werden. 5V, Data
und GND (Schirmung ist ebenfalls an GND).
Am Ende des CAT5 Kabel sind noch 300 nF Blockkondensatoren und von dort
aus gehen jeweils 3 Leitungen mit ca. 1m zu jeweils einem Sensor.
Beim auslesen der Sensoren (read_meas()) werden immer nur max. 2
Sensoren erkannt - ganz selten auch Mal alle 3 Sensoren.
Manchmal bekomme ich dabei den Fehler "DS1820: Bus Error" zurück.
Ich habe schon alles ausprobiert. Seitdem ich am Ende des CAT5 einen
weiteren 4K7 Pullup installiert habe, werden zumindest recht stabil 2
Sensoren erkannt.
Scheinbar ist es schwierig die Sensoren stabil ausgelesen zu bekommen.
Beitrag "Re: DS1820, DS18B20 in C"
TEMPMES.c : "Es treten gelegentlich Lesefehler auf (Detektor wird nicht
gefunden)."
Mir ist nicht ganz klar warum hier die Funktion NameValid( char * name )
eingeführt worden ist?
Liegt es wirklich nur am Kabel (was kann man hier evtl. ändern)?
Oder kann es auch am Timing liegen?
Ich hatte damals die Warteroutinen in 1wire.c durch delay-Makros
ersetzt:
1
bit w1_reset(void)
2
{
3
bit err;
4
5
W1_OUT &= ~(1<<W1_PIN);
6
W1_DDR |= 1<<W1_PIN;
7
// wait_x_075u( 216 ); // 599,5 us
8
_delay_us(600);
9
cli();
10
W1_DDR &= ~(1<<W1_PIN);
11
// wait_x_075u( 23 ); // 68,75 us
12
_delay_us(69);
13
err = W1_IN & (1<<W1_PIN); // no presence detect
14
sei();
15
// wait_x_075u( 136 ); // 379,5 us
16
_delay_us(380);
17
if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit
18
err = 1;
19
return err;
20
}
21
22
23
uchar w1_bit_io( bit b, bit pull )
24
{
25
cli();
26
W1_DDR |= (1<<W1_PIN);
27
// wait_x_1u(); // 1 us
28
// wait_x_1u(); // 1 us
29
_delay_us(2);
30
if( b )
31
W1_DDR &= ~(1<<W1_PIN);
32
// wait_x_075u( 0 ); // 7,5 us
33
_delay_us(8);
34
if( (W1_IN & (1<<W1_PIN)) == 0 )
35
b = 0;
36
// wait_x_075u( 17 ); // 52,25 us -> Gesamtzeit 61,75
Hallo zusammen,
ich habe mich dazu entschlossen, nach früheren Gehversuchen in Bascom
auf die C_ Schiene zu wechseln.
Ich habe es in C noch nicht ans laufen bekommen, hänge Gedanklich noch
fest.
Wenn ich den Code im Anhang verwende, kann ich auf dem Scope den Reset,
die Meldung des 1820, Presence-Impuls,und auch meine Anfrage nach hex33
00110011 auf dem Datenbus sehen.
Nun mein Frage, sollte der 1820 nicht direkt darauf reagieren, und
hinter meiner Anfrage den ROM Code im Telegramm darstellen??
Um einen Hardwaredefekt auszuschliessen, habe ich die Anwendung in
Bascom geschrieben, und diese hex mit AVR Studio 4.19 geschossen,
funktioniert.
Vielen Dank für eure Hilfe.
Schöne Ostertage
Hans Peter