DS18B20: Problem mit Temperaturauslesen

OP #2421248
Lesenswert?

Hallo zusammen,
ich weiß, dass schon mehrere Beiträge zu dem DS18B20 hier im Forum 
befinden. Leider komme ich aber kein Stück weiter. Bekomme immer bei 
therm_reset() den Rückgabewert 1, das heißt, dass kein Sensor erkannt 
wird. Arbeite mit einem ATMEGA32, Internen 8MHz Quarz (64ms) und 
F_CPU=1000000UL. Habe mit dem Oszi auch schon die Signale für den Reset 
gemessen, das sollte alles passen. Vielleicht hatte jemand einen 
ähnlichen Fehler und kann mir weiterhelfen??
Angehängte Dateien:
Gast #2421923
Lesenswert?

Helmut D. schrieb:
> wird. Arbeite mit einem ATMEGA32, Internen 8MHz Quarz (64ms) und
>
> F_CPU=1000000UL.

Abgesehen davon, dass ich gestern eine Diskussion gelesen hatte, die zum 
Ergebnis kam, dass die delay-Funktion nicht das hält was sie verspricht, 
ist mir aufgefallen. dass Du zwar die interne Takterzeugung 8MHZ 
verwendest und gleichzeitig die F_CPU auf 10 MHz definierst.

Wenn irgendwo F_CPU verwendet wird, die nicht mit der realen Taktrate 
übereinstimmt, würde ich vermuten, dass hier das Problem liegt.

Möglicherweise läuft Deine Delay-Funktion zu langsam und dann ist der 
Takt schon Resetimpuls schon zu Ende.

Tip: Setze vor dem Warten auf den Resetimpuls ein weiteres Ausgangspin, 
auf das Du dann mit Scope extern triggerst. Vor der Abfrageroutine setzt 
Du dieses Pin wieder zurück, dann weißt Du genau, ob Dein selbst 
organisiertes Abtast-Timming paßt.

Genau aus diessem Grund habe ich mir einen eigenen Scheduler 
geschrieben, der genau paßt. Die Abtastzeitpunkte habe ich mit einen 
2.Timer per Interupt gelöst. Dasnn läuft es zuverlässig.

Hoffe, konnte Dir helfen. Viel  erfolg
#2422284
Lesenswert?

cskulkw schrieb:

> Abgesehen davon, dass ich gestern eine Diskussion gelesen hatte, die zum
> Ergebnis kam, dass die delay-Funktion nicht das hält was sie verspricht,

Halte ich für irrelevant in diesem Fall. Ich betreibe meine 
Ätzbadsteuerung mit einem Atmega8 (interner 8 MHZ OSC) und einem 
DS18B20. Und ich erzeuge alle Wartezeiten für den 1Wire Bus direkt mit 
_delay_us().
1. Funktioniert das bis heute ohne Probleme, 2. sehen die Signalzeiten 
im Logic Analyzer sehr gut und stabil aus. Der 1Wire Bus ist ja nun auch 
nicht besonders kritsch und es werden relativ große Toleranzen 
akzeptiert in der Spezifikation.

gruß cyblord
Gast #2422314
Lesenswert?

cyblord ---- schrieb:
> cskulkw schrieb:
>
>> Abgesehen davon, dass ich gestern eine Diskussion gelesen hatte, die zum
>> Ergebnis kam, dass die delay-Funktion nicht das hält was sie verspricht,
>
> Halte ich für irrelevant in diesem Fall. Ich betreibe meine
> Ätzbadsteuerung mit einem Atmega8 (interner 8 MHZ OSC) und einem
> DS18B20. Und ich erzeuge alle Wartezeiten für den 1Wire Bus direkt mit
> _delay_us().
> 1. Funktioniert das bis heute ohne Probleme, 2. sehen die Signalzeiten
> im Logic Analyzer sehr gut und stabil aus. Der 1Wire Bus ist ja nun auch
> nicht besonders kritsch und es werden relativ große Toleranzen
> akzeptiert in der Spezifikation.
>
> gruß cyblord

Hi Cyblord,

hast die 1-Wire-Routine selbst geschrieben oder gibt es da eine Lib auf 
die ich zurückgreifen könnte? Die DS18B20 sollten auch bald bei mir 
aufschlagen. :-)

LG
Ernst
Gast #2422332
Lesenswert?

> Hi Cyblord,
>
> hast die 1-Wire-Routine selbst geschrieben oder gibt es da eine Lib auf
> die ich zurückgreifen könnte? Die DS18B20 sollten auch bald bei mir
> aufschlagen. :-)
>
> LG
> Ernst

Hallo,
hab selber eine lib geschrieben, einfach stur nach Datenblatt.  Also 
erstmal eine lib nur für die 1wire kommunikation. Nicht explizit für den 
DS18B20.
Aber da ich vorher noch nie was mit 1wire gemacht habe, wollte ich da 
selber duchsteigen und keine fertigen libs benutzen. Nach einer Stunde 
lief die Kommunikation. Kann ich dir gern mal anhängen ist sehr 
minimalistisch. Aber dafür sollte es sowieso schon min. 10 libs geben.

gruß cyblord
#2422355
Lesenswert?

Also hier mal der 1wire code.

Kurz zur Erläuterung:

in ow.h stellt man den Port ein welcher als 1wire dient.

zu beginn sollte man ow_init() aufrufen, hierbei werden die Portrichtung 
und idle states korrekt gesetzt. es wird auch gleich der interne Pullup 
aktiviert. Dieser ersetzt bei mir erfolgreich einen externen.

So wird der Code dann benutzt um direkt den 16 Bit Temp Wert des DS18B20 
auszulesen.
1
uint16_t readRawTemp() {
2
  uint16_t raw;
3

4
  ow_reset();
5
  ow_write(0xCC);
6
  ow_write(0x44);
7

8
  _delay_ms(1500);
9

10
  ow_reset();
11
  ow_write(0xCC);
12
  ow_write(0xBE);
13

14
  raw=ow_read(16);
15
  return raw;
16
}
Angehängte Dateien:
#2422365
Lesenswert?

Hallo Helmut,

bei mir gab es mit den "Dannegger Routinen" timing-Probleme, weil die 
Wartezeiten irgendwie grenzwertig waren. Aufgefallen ist mir der kurze 
Delay von 1 µS in deiner Read-Bit routine.

Hier ist die Version, die bei mir auf einem ATMega2560 letztlich 
funktioniert hat, wobei ich hoffe, dass ich die Einzelteile hier richtig 
zusammenkopiert habe:

1
#define W1_PIN  PE0
2
#define W1_IN  PINE
3
#define W1_OUT  PORTE
4
#define W1_DDR  DDRE
5
#define DELAY_US(x)  ((uint)( (x) * 1e-6 * XTAL/1 )) //x=1..65535 for XTAL=4 MHz and prescaler=1
6
#define DELAY(x)  delay(x)
7

8

9
void delay( uint d )      
10
// Waits for d * 1/XTAL (with Timer1 prescaler=1)
11
// Uses TCNT1 which is incremented with frequency XTAL/1
12
{
13
  d += TCNT1;        // d = d0+ TCNT1
14

15
  while( (TCNT1 - d) & 0x8000 );  // while TCNT1 - TCNT1_Anfang < d0
16
}
17

18

19
uchar w1_bit_io( bit b )
20
{  //changed 2 µs into 4 µs everywhere in this function
21
  cli();
22
  W1_DDR |= 1<<W1_PIN;
23
  DELAY( DELAY_US( 4 ));
24
  
25
  if( b ) {
26
    W1_DDR &= ~(1<<W1_PIN);
27
    DELAY( DELAY_US( 10 - 4 ));
28
  } else
29
  DELAY( DELAY_US( 15 - 4 ));
30
  
31
  if( (W1_IN & (1<<W1_PIN)) == 0 )
32
    b = 0;
33
  DELAY( DELAY_US( 70 - 15 ));  //changed 60 µs into 70 µs here
34
  W1_DDR &= ~(1<<W1_PIN);
35
  sei();
36
  return b;
37
}
Gast #2422402
Lesenswert?

cyblord ---- schrieb:
> Halte ich für irrelevant in diesem Fall. Ich betreibe meine
>
> Ätzbadsteuerung mit einem Atmega8 (interner 8 MHZ OSC) und einem
>
> DS18B20. Und ich erzeuge alle Wartezeiten für den 1Wire Bus direkt mit
>
> _delay_us().
>
> 1. Funktioniert das bis heute ohne Probleme, 2. sehen die Signalzeiten
>
> im Logic Analyzer sehr gut und stabil aus. Der 1Wire Bus ist ja nun auch
>
> nicht besonders kritsch und es werden relativ große Toleranzen
>
> akzeptiert in der Spezifikation.
>
>
>
> gruß cyblord

Tu wichtig ...

Ich weiß nicht, ob die Delay-Funktion Genauigkeitsprobleme hat.

Wenn aber die Constante FCPU mit 10 Mhz eingestellt ist und der 
Taktgenerator mit 8 MHZ laufen sollte, dann kann die delay-Funktion 
nicht richtig zählen. Das und nur DAS war mein Hinweis.

Vielleicht sollte man bestimmte Aussagen nicht aus dem Zusammenhang 
reißen. Dann gäbe es auch keine Mißverständnisse.
Gast #2422623
Lesenswert?

cskulkw schrieb:

> Wenn aber die Constante FCPU mit 10 Mhz eingestellt ist und der
> Taktgenerator mit 8 MHZ laufen sollte, dann kann die delay-Funktion
> nicht richtig zählen. Das und nur DAS war mein Hinweis.

Nein nicht nur DAS.

> Vielleicht sollte man bestimmte Aussagen nicht aus dem Zusammenhang
> reißen. Dann gäbe es auch keine Mißverständnisse.

Habe nichts aus dem Zusammenhang gerissen. Du hast sowohl auf die 
falsche F_CPU Einstellung ALS AUCH auf eine generelles Problem mit der 
delay.h hingewiesen.
Und ich habe auch nicht gesagt dass du damit falsch liegst, ich habe nur 
darauf hingewiesen dass dieses Problem (sofern es besteht) für eine 
1wire Kommunikation irrelevant ist, weil es eben trotzdem funktioniert.

gruß cyblord
Gast #2422826
Lesenswert?

Er meint wahrscheinlich den C2 in der Schaltung im zweiten Post?
Und der kommt nicht aus dem Datenblatt. Denn der macht ja alles kaputt 
und gehört deshalb da weg! Wie sollen denn da noch saubere Flanken 
möglich sein? Das beeinflußt natürlich auch das Timing, da die 
erforderlichen Pegelstände sich erst später einstellen.

Übrigens: Die Aussage interner Oszillator mit 8 MHz (einen Quarz hat das 
Ding natürlich nicht, sondern einen RC-Oszillator!) und F_CPU mit 
1000000UL stellt noch keinen widerspruch dar, da 1 MHZ (und nicht 10 MHz 
wie behauptet) ja die Standardfuse ist.
Was auch immer das (64ms) bedeuten soll, ist mir aber schleierhaft.
Gast #2423307
Lesenswert?

> Lutz schrieb:
> Was auch immer das (64ms) bedeuten soll, ist mir aber schleierhaft.

habe bei den Fuses folgendes ausgewählt: INTRCOSC_8MHz_6CK_64MS

> Lutz schrieb:
> Er meint wahrscheinlich den C2 in der Schaltung im zweiten Post?
> Und der kommt nicht aus dem Datenblatt. Denn der macht ja alles kaputt
> und gehört deshalb da weg! Wie sollen denn da noch saubere Flanken
> möglich sein? Das beeinflußt natürlich auch das Timing, da die
> erforderlichen Pegelstände sich erst später einstellen.

das könnte ich mir durchaus vorstellen, das das ein Problem ist. Ich 
habe das mit dem Kondensator wohl falsch rausgelesen aus dem Datenblatt. 
Habe gedacht, ich brauche ihn zum entstören.
Gast #2425265
Lesenswert?

> Horst Hahn schrieb:
> wenn er sich bei seinem 4,7 kOhm Widerstand auf Figure 1 + 5  im
> Datenblatt des 18B20 bezieht ist sein Vo == DQ also die Datenleitung und
> Vi ist Vdd.
> Dann wäre C2 sehr unpassend.
> Also wäre Vi und Vo vertauscht.

Habe den Kondensator entfernt, hat aber nichts gebracht. Sobald ich 
irgendwo ein Oszi auftreiben kann, werde ich mal meine Delay-Zeiten 
seitens des Mikrocontrollers nachmessen.
Gast #2429008
Lesenswert?

Habe jetzt einen externen Quarz 8MHz eingefügt. Nun habe ich das 
Problem, dass ich selbst bei den folgenden Befehlen bei niedrigen 
delay-Zeiten nicht das erwartete messen kann.

DDRC=0xFF;
  while(1)
  {
     PORTC=0x00;
     _delay_us(1);
     PORTC=0xFF;
     _delay_us(1);
  }

 Dort kann nur jeweils eine reale Zeit von 265µs gemessen werden mit dem 
Oszi?? Obwohl ja eine Delayzeit von 1µs erwartet wird. Wie kann das 
sein?
Gast #2429330
Lesenswert?

> Karl Heinz Buchegger schrieb:
> Optimizer nicht aktiviert?
> F_CPU falsch angegeben?
> Quarz ist zwar physisch drann, ist aber nicht aktiviert?
>
> Kombination aus allen 3?

Wo kann ich den Optimizer aktivieren?
Habe F_CPU mit 8000000UL und auch schon mit 1000000UL angegeben, aber 
funktioniert trotzdem nicht.
Die Fuse EXTMEDFXTALRES_16KCK_64MS wurde ausgewählt für einen 8MHz 
Quarz.
#2440817
Lesenswert?

cyblord ---- schrieb:
> Also hier mal der 1wire code.
>
> [...]

Hi!

Heute kamen endlich die Sensoren und ich habe Deinen Code ausprobieren 
können. Funktioniert auf anhieb. Und ist auch gut zu durchschauen. Jetzt 
überlege ich ob ich bei Deinem weiter aufbaue für Rom-Search und so 
weiter oder ob ich mir den Dannegger-Code mal anschaue...

Sag, warum verwendest Du noch die deprecated.h? Hat das einen bestimmten 
Grund?

Lg
Ernst
#2440871
Lesenswert?

Ernst B. schrieb:
> cyblord ---- schrieb:
>> Also hier mal der 1wire code.
>>
>> [...]
>
> Hi!
>
> Heute kamen endlich die Sensoren und ich habe Deinen Code ausprobieren
> können. Funktioniert auf anhieb.
Das freut mich!

> Sag, warum verwendest Du noch die deprecated.h? Hat das einen bestimmten
> Grund?

Ich benutze gerne die sbi() und cbi() Makros und die sind da halt drinn 
weil deprecated ;-)
#2441276
Lesenswert?

Ernst B. schrieb:

> Jetzt kämpfe ich gerade mit der Umrechnung. Versuche mich da in
> Festkommarithmetik aber nach einer Multiplikation bekomme ich plötzlich
> ein Minus vor meine Zahl... :-))

In der Codesammlung habe ich letztens erst Code für ein "1Wire Display" 
eingestellt, dort ist eine Funktion drinn welches die Temperatur in 
einen String umwandelt. Mit einer Nachkommastelle.

gruß cyblord
#2441282
Lesenswert?

cyblord ---- schrieb:
> In der Codesammlung habe ich letztens erst Code für ein "1Wire Display"
> eingestellt, dort ist eine Funktion drinn welches die Temperatur in
> einen String umwandelt. Mit einer Nachkommastelle.
>
> gruß cyblord


Danke, werde ich mir anschauen. Aber ich habe es gestern eh noch lösen 
können. Ich stolpere immer wieder in die Überlauf-Falle. (in dem Fall 
war es itoa) :-) Habe die Temp jetzt zwei Nachkommastellen und die 
letzte Stelle kaufmännisch gerundet.

Was meinst, sollte ich den Rom-Search einbauen in meinen Code obwohl ich 
in der praktischen Umsetzung eh nur 1 one-wire Produkt dran hängen habe? 
G'hörat sich das?
#2441395
Lesenswert?

@Cyblord:

Ich habe jetzt zwar ein bisl gebraucht um zu durchschauen was Du da 
eigentlich machst bei der Umrechnung aber ich bin ziemlich begeistert. 
Vor allem, weil ich wohl selbst nicht auf die Idee gekommen wäre das so 
anzugehen und wieder eine Menge gelernt habe. Danke dafür!

LG
Ernst

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren