Forum: Mikrocontroller und Digitale Elektronik DS1820 reagiert garnicht, C Programm fehlerhaft? Sensor defekt?


von Megamax (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Ich hab einen DS18B20 (als Fühler im Edelstahlgehäuse) mit einem Atmega 
16 mit C programmiert und das Ergebnis auf einem LC-Display 2X16 Zeilen 
ausgeben. Der Sensor wird extern Versorgt(kein Parasit-Modus). An den 
Pull Up 4,7k hab ich auch gedacht.

Laut Oszilloskop werden sowohl die Function- wie auch die Rom-Commands 
in der Zeittoleranz des Sensors übertragen. Der Sensor schickt jedoch 
garnichts zurück. Selbst der 64 Bit Erkennungscode des Sensors wird 
nicht übertragen.

Das Programm ist sehr einfach gehalten, könnte das ein Problem sein? Am 
gesamten PortA ist nur der Sensor angeschlossen, deswegen wird der Port 
komplett Low gesetzt.
Die Ausgabe des Displays funktioniert soweit mit Test HEX-Werten. Die 
Hex-Werte rechne ich mit dem Befehl itoa() in dezimal um.

Ist Mein Programm korrekt? Ist der Sensor vielleicht defekt? Kann mir 
jemand Tipps, Lösungen geben?

von julian (Gast)


Lesenswert?

Guten abend,

Hab vor ein paar tagen auch meinen ersten ds1820 (jedoch 18s20) an einem 
atmega8 in betrieb genommen.

Anfangs hatte allerdings die selben schwierigkeiten jedoch lag es nur an 
verbindungsproblemen zum sensor und an der pin einstellung. Jetzt läuft 
alles problemlos.

Hast du die funktionen selbst nach datenblatt gesxhrieben oder aus einer 
bestehenden lib? Wenn ja, welche?

von Ursus P. (unwichtig)


Lesenswert?

Megamax schrieb:
> Das Programm ist sehr einfach gehalten, könnte das ein Problem sein? Am
> gesamten PortA ist nur der Sensor angeschlossen, deswegen wird der Port
> komplett Low gesetzt.
> Die Ausgabe des Displays funktioniert soweit mit Test HEX-Werten. Die
> Hex-Werte rechne ich mit dem Befehl itoa() in dezimal um.

Den Code selber geschrieben?

von Megamax (Gast)


Lesenswert?

Ja der Code ist selbst geschrieben. Julian kannst du deinen Code bitte 
Online stellen, damit ich den Sensor testen kann? Ich hab auch einen 
ds18s20 und einen atmega 8 hier.

von Megamax (Gast)


Angehängte Dateien:

Lesenswert?

julian schrieb:
> Anfangs hatte allerdings die selben schwierigkeiten jedoch lag es nur an
> verbindungsproblemen zum sensor und an der pin einstellung. Jetzt läuft
> alles problemlos.

Erstmal Danke für den Hinweis, der Sensor ist an PA2 angeschlossen und 
die Datenleitung über 4,7kOhm auf +5V angeschlossen.

Ich habe die Zeiten beim Ein- und Auslesen des Sensors jetz schon 
mehrmals geändert und anderen Beiträgen zu dem Sensor angepasst. Alles 
ohne Erfolg.

Die aktuellste Version meines Programms ist im Anhang.

von Pete K. (pete77)


Lesenswert?

China Fake-Sensor erwischt?

btw:
for (i=0; i<11; i++)  //200ms * 10 = 2000ms  --> das sind 11 Durchläufe

#define F_CPU 1000000L --> gehört ins Makefile

void init_sequnez() --> init_sequence()

Sensor ist auch gemäß Datenblatt angeschlossen?

: Bearbeitet durch User
von Megamax (Gast)


Lesenswert?

Danke du hast recht die Schleife war zu lang.

Pete K. schrieb:
> China Fake-Sensor erwischt?
Ich hab mitlerweile 3 DS18B20 hier, hoffentlich sind alle 3 keine Fake 
China Ware. Wo finde ich Produkte von seriösen Händler?

Pete K. schrieb:
> #define F_CPU 1000000L --> gehört ins Makefile
Makefile? Wie finde ich die?

Pete K. schrieb:
> void init_sequnez() --> init_sequence()
Wenn ich das ändere bekomme ich folgende Warnings:

Warning  4  control reaches end of non-void function [-Wreturn-type]

Warning  1  data definition has no type or storage class [enabled by 
default]

Warning  3  return type defaults to 'int' [enabled by default]

Warning  2  type defaults to 'int' in declaration of 'init_sequnez'

Pete K. schrieb:
> Sensor ist auch gemäß Datenblatt angeschlossen?
VDD an +5V, GND an GND und DQ an PA2 vom atmega16

von Maximilian S. (megamax21)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt sowohl einen ds18b20 wie auch einen ds18s20 bei Reichelt 
bestellt.

Bei meinen anderen Sensoren zeigt der Sensor jetzt nur noch 0xFF an. 
Vielleicht ein Timing Problem?

Außerdem schicke ich bei den Commands und Functions das LSB zuerst, ist 
das korrekt?

Anbei das geänderte Programm

: Bearbeitet durch User
von Peter R. (pnu)


Lesenswert?

Maximilian S. schrieb:
> Bei meinen anderen Sensoren zeigt der Sensor jetzt nur noch 0xFF an.
> Vielleicht ein Timing Problem?

Dann prüft man das, indem man eine Schleife macht. und das Einschalten 
einer LED in die Schleife mit einschließt. Dann  sieht man schon, ob die 
im sec-Rhythmus geschaltet wird.

Maximilian S. schrieb:
> Ich habe jetzt sowohl einen ds18b20 wie auch einen ds18s20 bei Reichelt
> bestellt.

Bei diesen Fehlermeldungen braucht man keine Ersatz-DS zu bestellen. 
Erst mal die Fehler in der Software beheben.

Maximilian S. schrieb:
> Ich habe jetzt sowohl einen ds18b20 wie auch einen ds18s20 bei Reichelt
> bestellt.

Auch fakes funktionieren fast immer. Ihre Datenblattwerte (Genauigkeit, 
Betriebsspannungsbereich, Stromverbrauch usw. ) dürften halt nicht immer 
eingehalten sein.
Das eher tückische bei fakes ist, dass sie unter Extrembedingungen ihren 
Geist aufgeben und im Normalbetrieb scheinbar richtig arbeiten.

Das timing beim DS18x20 ist halt diffizil. Da kommt es auf jede Flanke 
auf diesem Ein-Draht-Signal an. Ich selbst hab es erst nach einiger 
Zeit, mit Scope-Unterstützung, hinbekommen. Und zwar erstmal NUR den 
DS18x20 zusammen mit einer Ergebnisanzeige (Inhalt r3,r2 per I2C 
ausgeben) Erst diese fertige Funktion wurde dann ins eigentliche Projekt 
übernommen.

: Bearbeitet durch User
von Maximilian S. (megamax21)


Lesenswert?

Peter R. schrieb:
> Dann prüft man das, indem man eine Schleife macht. und das Einschalten
> einer LED in die Schleife mit einschließt. Dann  sieht man schon, ob die
> im sec-Rhythmus geschaltet wird.

Laut Oszilloskop stimmen die Zeiten der Signale 480us reset-Impuls, 
kurzes Pull-up, dann bekomme ich einen presence-Impulse von ca 110us und 
warte dann noch 300us. Danach werden die "0" Sequenzen mit 60us Low, 
dann 40us High und die "1" Sequenzen mit 8us Low und 92us High 
übertragen.

von Jörn P. (jonnyp)


Lesenswert?

Das timing ist ziemlich straff und deinen code habe ich auch nicht 
angesehen.
Wenn du ein scope hast, dann generiere erst mal einen exakten 
Resetimpuls und schau ob der DS18xx antwortet. Ist das der Fall kannst 
du darau aufbauen.
Alle Befehle beginnen mit Reset. Das timing ist ja im Gesangbuch des 
DS18xx beschrieben. Ich habe es so gemacht, das ich erst mal die 
einzelnen Routinen zusammen gestellt und geteste habe.

von Maximilian S. (megamax21)


Lesenswert?

Wie gesagt den presence Impuls bekomme ich vom Sensor. Hier der Teil 
indem der Reset- und Presence-Impuls initialisiert wird.

void init_sequnez()
{
    DDRA=0xFF;    // PortA als Ausgang
    PORTA=0x00;    //Pull low
    _delay_us(480);
    DDRA=0x00;    // PortA als Eingang
    _delay_us(480);
}

von Karl H. (kbuchegg)


Lesenswert?

1
  init_sequnez();      //initalisierungs sequenz
2
  write(skiprom);      //aktiviere slave
3
  write(convertt);    //temperatur umwandlung
4
  for (i=0; i<4; i++)    //190ms  * 4 = 760ms
5
  {  
6
    _delay_ms(190);    //ms delay schleife geht höchsten bis 262ms => 262 ms/F_CPU MHZ
7
  }    
8
  init_sequnez();
9
  write(skiprom);
10
  write(wscratchpad);    //slave beschreibt speicher

write Scratchpad?

Das hat hier nichts verlren. Mit write scratchpad kann dein Programm 
Werte an den DS1820 übergeben.

Warum probierst du denn nicht einfach mal eine andere, nachweislich 
funktionierende Lib aus? Ja ich weiss, du willst selber schreiben. Aber 
man kann auch einiges lernen, wenn man funktionierenden Code analysiert, 
wie die das machen.

von Maximilian S. (megamax21)


Lesenswert?

Ah ok Danke, es funktioniert aber ohne write scratchpad auch nicht. 
Welche Lib ist den zu empfehlen?

von Karl H. (kbuchegg)


Lesenswert?

Maximilian S. schrieb:
> Ah ok Danke, es funktioniert aber ohne write scratchpad auch nicht.
> Welche Lib ist den zu empfehlen?

Ursprünglich wollte ich dir die PeDa Version aus der Codeammlung 
nahelegen. Aber ein Blick ins Zip-File im ersten POsting zeigt, dass 
PeDa da wieder mal in die vollen gegenangen ist. Sein Code kann auch mit 
mehreren DS1820 am Bus umgehen.

Kurzes Goggeln brachte als einen der ersten Treffer die hier
http://sicklinger.com/microcontroller-avr/58-atmel-avr-atmega-ds18x20-library-in-c.html

Der zugehörige Code
http://sicklinger.com/downloads/func-startdown/4

sieht mir auf die Schnelle nicht so schlecht aus.

(PS: Und mach dir Hilfsfunktionen für deine LCD Ansteurung. So etwas
1
...
2
  schreibe('T');
3
  schreibe(':');
4
  schreibe(' ');
5
...
ist doch grober Unfug. Einen String an ein LCD auszugeben braucht 
praktisch jedes Programm. Daher schreibt man sich eine Funktion, die das 
kann
1
void lcd_string( const char* str )
2
{
3
  while( *str )
4
    schreibe( *str++ );
5
}

und benutzt die dann:
1
...
2
   lcd_string( "T: " );
3
...

aufbauend auf der String Funktion ist die nächste dann eine Funktion, 
die einen int ausgeben kann
1
void lcd_int( int value )
2
{
3
  char txt[8];
4
  itoa( value, txt, 10 );
5
  lcd_string( txt );
6
}

Auf die Art entstehen dann erst mal ein paar Hilfsfunktionen, die einem 
bei der eigentlichen Arbeit das Leben viel leichter machen)+
)

von Maximilian S. (megamax21)


Lesenswert?

Danke für die vielen Hinweise jetzt kann es weiter gehen! Ich melde mich 
wenn alles getestet ist.

von Karl H. (kbuchegg)


Lesenswert?

Sowas
1
    if (temp_lsb<0x0A)          // kleiner 10
ist doch Quatsch. Wenn dir nicht klar ist, dass 0x0A dasselbe wie 
dezimal Zehn (nur in einem anderen Zahlensystem) ist, dann ist das kein 
Beinbruch. Die Frage ist: warum verwendest du an dieser Stelle dann Hex? 
Schreib das doch gleich in Dezimal
1
    if (temp_lsb < 10)
und gut ists.

Welches Zahlensystem du benutzt um Konstanten hinzuschreiben, richtet 
sich nach dem was du in dieser Zeile vermitteln willst und was am 
natürlichsten ist! Dem Compiler ist das egal, denn sowohl 0x0A als auch 
10 münden im selben Bitmuster. Das eine ist durch das andere 
austauschbar!
1
   c = 0x61;
2
   c = 97;
3
   c = 'a';
4
   c = 0b01100001;

ist alles dasselbe! Die Variable c wird mit dem Bitmuster 01100001 
geladen. Lediglich die Art und Weise, wie du dieses Bitmuster in deinem 
Programm ausdrückst unterscheidet sich, aber es ist immer dieselbe 
Operation mit demselben Ergebnis. Je nachdem in welchem 'Umfeld' man 
diese Zuweisung einsetzt, wird man sich für eine der möglichen 
Darstellungen des Wertes entscheiden. Man nimmt die, die in diesem 
Umfeld die naheliegenste ist.

Du willst, dass dein Programm bei 24 Grad etwas macht, zum Beispiel die 
Heizung abschaltet. Für dich bedeutet an dieser Stelle der Zahlenwert 24 
etwas. Wie diese Zahl aufgebaut ist, welche Bits auf 1 sind und welche 
auf 0, das ist dir völlig gleichgültig. Wichtig ist, dass es 24 Grad 
sind. Dann schreib das auch so!
1
    if( temperatur > 24 )
2
      Heizung_aus();
Hier macht weder eine Angabe in Hex noch eine Angabe in Binär 
irgendeinen Sinn. Und auch das Zeichen, dessen ASCII Code 24 wäre, 
interessiert dich nicht. Daher nimmst du keine dieser Möglichkeiten 
sondern schreibst die 24 so wie sie sind einfach hin.
)

: Bearbeitet durch User
von Maximilian S. (megamax21)


Lesenswert?

Der Teil ist für die Ausgabe des Buffers, welcher mit der 
itoa()-Funktion beschrieben wird.

von Karl H. (kbuchegg)


Lesenswert?

Maximilian S. schrieb:
> Der Teil ist für die Ausgabe des Buffers, welcher mit der
> itoa()-Funktion beschrieben wird.

Ist mir schon klar. Und im Endeffekt wird das auch wegfallen, denn im 
Grunde braucht das keiner, wenn du eine String-Ausgabefunktion hast.
Mir geht es an dieser Stelle mehr darum, dass du etwas dabei lernst: Das 
verwendete Zahlensystem ist nicht in Stein gemeisselt sondern es wird 
situationsbezogen das "Zahlensystem" ausgewählt, welches der 
Aufgabenstellung an dieser Stelle im Code angemessen ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.