DS1820-Temperatursensor

pcprofi

Neues Mitglied
12. Apr. 2008
90
0
0
Sprachen
Hallo Leute,

nachdem ich diverse Programme aus dem INet und das schöne vom markus hier im Forum getestet habe, gebe ich auf.

Ich bekomme es nicht hin, irgendwelche Daten vom Sensor zu bekommen.

Kann jemand damit umgehen und mir das noch mal erklären? Im Moment möchte ich erstmal ncihts anderes, als irgendetwas über UART aus dem Sensor zu bekommen...

Egal was ich abfrage ich kriege immer nur "FFh"-Bytes, sprich der Bus ist anscheinend immer auf dem High-Pegel.

Die äußere Beschaltung stimmt hoffentlich: Sensor an Vcc und GND des µC, Datenleitung mit 4,7kOhm auf Vcc.

Gruß Rainer
 
Hab jetzt nach dem Datenblatt noch mal das hier erarbeitet... Leider ohne Erfolg. Alle Felder sind und bleiben immer "0".

Code:
$regfile = "m16def.dat"
$crystal = 1000000
$baud = 2400

Config 1wire = Portc.3

Dim Test(9) As Byte
Dim I As Byte
Dim X As Integer

Do

Print "Thermometer"

1wreset
Waitus 200
1wwrite &HCC
Waitus 200
1wwrite &H44
Waitms 750
1wreset
Waitus 200
1wwrite &HCC
1wwrite &HBE
Test(1) = 1wread(9)
1wreset

Waitms 200

For I = 1 To 9
  Print Test(i)
Next
X = Makeint(test(1) , Test(2))
Print X

Wait 5

Loop

End
 
Hallo Rainer,

ich sehe direkt keinen Fehler an deinem Programm, kenne mich allerdings mit Bascom nicht so gut aus. Hast du denn schonmal folgendes probiert oder überprüft:
  • größere Pause nach senden des Befehls "wandle Temperatur"
  • wird der AVR tatsächlich mit 1MHz getaktet?
  • Pullup-Widerstand ggf. vergrößern (10k)?!
Sehe dir vielleicht einmal den zweiten Beitrag von Markus aus diesem Thread an.

Grüße,
Dirk
 
Hallo Rainer,

ich sehe direkt keinen Fehler an deinem Programm, kenne mich allerdings mit Bascom nicht so gut aus. Hast du denn schonmal folgendes probiert oder überprüft:
  • größere Pause nach senden des Befehls "wandle Temperatur"


  • Das wird möglicherweise ein Grund mit gewesen sein - in einem Auszug aus einem Buch der mir zugesandt wurde wurde zum warten eine Abbruchschleife eingebaut - hänge den Code gleich mal an.

    [*]wird der AVR tatsächlich mit 1MHz getaktet?

    Ja, definitiv, habe mehrfach auch die Fusebits neu gesetzt

    [*]Pullup-Widerstand ggf. vergrößern (10k)?!

Nein, der ist im Datenblatt so angeben - sowohl in der Bascom-Hilfe als auch im Blatt des DS1820.

Sehe dir vielleicht einmal den zweiten Beitrag von Markus aus diesem Thread an.

Grüße,
Dirk

Genau den Code habe ich auch ausprobiert - leider ohne Erfolg.
Ich hänge jetzt mal ein funktionierendes! Thermometer an.

Code:
$regfile = "M8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40

'CONFIG 1WIRE - Temperatur
Config 1wire = Portc.5

'CONFIG LCD
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Lcd = 16 * 1a
Config Lcdbus = 4
'Deflcdchar 0 , 16 , 24 , 28 , 30 , 28 , 24 , 16 , 32
'Waitms 200
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32           ' replace ? with number (0-7)
Waitms 200
Initlcd
Cls
Cursor Off Noblink

' Temperaturmessungsvariablen/-konstanten
Const Ds1820 = &H10

Dim Family_code As Byte
Dim Serial_number(6) As Byte
Dim Crc As Byte
Dim Scratch(9) As Byte

Dim I As Byte
Dim Temp As Word
Dim Temp1 As Integer
Dim Stemp As Single
Dim Ausfuehren As Byte





Do

      1wreset
      If Err = 1 Then
        Cls
        Lcd "Sensorfehler"
        Wait 5
      End If
      1wwrite &H33
      Family_code = 1wread()
      For I = 1 To 6
        Serial_number(i) = 1wread()
      Next
      Crc = 1wread()
      If Family_code <> Ds1820 Then
        Cls
        Lcd "Sensorfehler"
        Wait 5
      End If
      1wwrite &H44
      Do
        Temp = 1wread()
      Loop Until Temp = &HFF
      1wreset
      If Err = 1 Then
        Cls
        Lcd "Sensorfehler"
        Wait 5
      End If
      1wwrite &HCC
      1wwrite &HBE
      For I = 1 To 9
        Scratch(i) = 1wread()
      Next
      Temp = Scratch(2)
      Shift Temp , Left , 8
      Temp = Temp + Scratch(1)
      Temp1 = Temp
      Temp1 = Temp1 / 2
      Stemp = Scratch(8) - Scratch(7)
      Stemp = Stemp / Scratch(8)
      Stemp = Stemp + Temp1
      Stemp = Stemp - 0.25

      Cls
      Lcd "Temp: " ; Fusing(stemp , "#.#") ; Chr(0) ; "C"

      Wait 2


Loop

Der Code läuft jetzt mit 8 MHz - ob bei 1MHz evt das Timing nicht ausreicht?

Gruß Rainer
 
Ich werde das dumme Gefühl nicht los, dass ich hier schlicht und einfach Timing-Probleme habe...

Folgendes: Ich habe seinerzeit die RTC gebaut - steht ja auch hier im Forum. Für die ist der Sensor. Also hab ich den auf die Platine dazugelötet.

Den Code hab ich im Sectic mit rein, aber immer nur wenn _sec Mod 15 = 0 ist - sprich alle 15 Sek einmal ausgeführt wird.

Dummerweise passieren wahlweise 2 Sachen:

  1. Das Ergebnis der Temperaturberechnung ist -7°C (im Zimmer!!) und ändert sich nicht, auch beim anfassen des Sensors
  2. Wesentlich häufiger: Der Chip hängt sich schlichtweg auf und ist nur durch einen Reset wieder zum Leben zu erwecken.

Gehe ich aber hin und kommentiere die Softclock aus - dann läuft das Thermometer - aber die Uhr nciht mehr.

Meine Vermutung ist nun, dass die Softclock das 1w-Bustiming durcheinander bringt. Im Prinzip könnte das sein, wenn zum Beispiel ein Interrupt genau dann ausgelöst wird. Die Temperaturmessung dauert aber wesentlich unter einer Sekunde - der Sectic fällt also raus.

Wie könnte ich diese Möglichkeit prüfen?
Würde es im Prinzip reichen, während der Kommunikation die Interrupts einfach mal zu disablen? Nur dürfte dann die Uhr falsch gehen...

Gruß Rainer
 
Um das ganze noch mal wieder aufzuwärmen:

NUR Thermometer: funktioniert!
NUR Uhr: funktioniert!

Thermometer UND Uhr: funktioniert nicht.

Weiß der Geier warum... Habe die Routine im Sectic mit drinne - hier kommen man die wichtigsten Code-Schnippsel:

Code:
'Config internal Clock
Config Clock = Soft , Gosub = Sectic
Config Date = Dmy , Separator = .
Code:
'CONFIG 1WIRE - Temperatur
Config 1wire = Portc.5

Code:
If Timedate = 0 Then
  If Edit_enable = 0 Then
    Cls
    Lcd Time$ ; " " ; Fusing(stemp , "#.#") ; Chr(1) ; "C"
    Ausfuehren = _sec Mod 5
    If Ausfuehren = 0 Then
      Disable Interrupts
             1wreset
      If Err = 1 Then
        Cls
        Lcd "Sensorfehler 1"
        Wait 2
      End If
      1wwrite &H33
      Family_code = 1wread()
      For I = 1 To 6
        Serial_number(i) = 1wread()
      Next
      Crc = 1wread()
      If Family_code <> Ds1820 Then
        Cls
        Lcd "Sensorfehler 2"
        Wait 2
      End If
      1wwrite &H44
      Do
        Temp1 = 1wread()
      Loop Until Temp1 = &HFF
      1wreset
      If Err = 1 Then
        Cls
        Lcd "Sensorfehler 3"
        Wait 2
      End If
      1wwrite &HCC
      1wwrite &HBE
      Enable Interrupts
      For I = 1 To 9
        Scratch(i) = 1wread()
      Next
      Temp1 = Scratch(2)
      Shift Temp1 , Left , 8
      Temp1 = Temp1 + Scratch(1)
      Temp2 = Temp1
      Temp2 = Temp2 / 2
      Stemp = Scratch(8) - Scratch(7)
      Stemp = Stemp / Scratch(8)
      Stemp = Stemp + Temp2
      Stemp = Stemp - 0.25

      'Cls
      'Lcd "Temp: " ; Fusing(stemp , "#.#") ; Chr(0) ; "C"
    End If
  End If
End If

Return

Der Code zum auslesen des DS1820 ist der selbe, der nur mit dem Thermometer funktioniert.

Ich hab jetzt gedacht, es wäre vll ein Timing-Problem. Also (wie im Code zu sehen) die Interrupts wärend der Kommunikation mal deaktiviert... Half ncihts....

Dann ist das nächste Problem: Der µC hängt sich sporadisch offenbar in der ISR auf bzw macht einfahc einen Reset - aber sporadisch, es ist keine Regelmäßigkeit zu erkennen...

Wäre nett, wenn ihr da mal drübersehen könntet.

Achja: Die Config des µC:

Code:
$regfile = "M8def.dat"
$crystal = 8000000 'internal RC
$hwstack = 32
$swstack = 10
$framesize = 40

achja: Es kommt immer der Fehler "Sensorfehler 2" - offenbar stimmt also der Familycode nicht... Fragt sich nur warum...

Gruß, ein überaus frustrierter Rainer...
 
Hallo Rainer,

ich vermute der größere Code-Schnippsel ist die Routine Sectic?!

So wie ich das verstanden habe wird die Routine Sectic einmal die Sekunde aufgerufen. Die aufrufende Routine wird die Interruptserviceroutine des Timers der asynchron mit TOSC1/2 läuft sein (Bascom-intern).

Die Ausführungszeit von Sectic muss kleiner 1s sein.

Wenn Bascom hier in einer Interruptprioritätsebene arbeitet, wird die Interruptserviceroutine des Timers (Uhrfunktion) verzögert oder nicht immer alle 1s aufgerufen, es kommt zu Uhrzeitfehler.

Wenn Bascom in mehreren Interruptprioritätsebenen arbeitet, kann es vorkommen, dass die Routine Sectic quasi parallel ausgeführt wird, selbst wenn das dem 1WireBus nichts ausmachen würde, Bascom sichert hier bestimmt jedesmal vor Aufruf von Sectic die Arbeitsregister r0 bis r31 auf dem Stack. Dies führt nun irgendwann dazu, dass der Stack in den Speicherbereich der Arbeitsregister im SRAM läuft, es kann zum Absturz kommen.

Versuche einmal folgendes:
Verlege die komplette Sensorabfrage (1wire) in die Hauptroutine. In Sectic setzt du ein Bit oder Byte, wenn der Sensor abgefragt werden soll. In der Hauptroutine fragst du das Byte ab, wenn zB nicht 0x00, dann Sensor abfragen und danach das Byte auf 0x00 setzen.

Wichtig ist bei Interruptroutinen:
So kurz wie möglich, nur Code ausführen, der zeitkritisch ist.

Andere Ursache könnte sein, dass Bascom durch Wait-Routinen oder 1Wire-Interface oder irgendwelchen anderen Sachen die du nutzt, den selben Timer verwendet wie die Softclock, das würde sich natürlich beissen.

Grüsse,
Dirk
 
Hallo Rainer,

ich vermute der größere Code-Schnippsel ist die Routine Sectic?!

korrekt - hab ich vergessen dran zu schreiben...

So wie ich das verstanden habe wird die Routine Sectic einmal die Sekunde aufgerufen. Die aufrufende Routine wird die Interruptserviceroutine des Timers der asynchron mit TOSC1/2 läuft sein (Bascom-intern).

Die Ausführungszeit von Sectic muss kleiner 1s sein.

Wenn Bascom hier in einer Interruptprioritätsebene arbeitet, wird die Interruptserviceroutine des Timers (Uhrfunktion) verzögert oder nicht immer alle 1s aufgerufen, es kommt zu Uhrzeitfehler.

Treffer versenkt.

Ich habs mal in die Mainloop mit rein, und wie du gesagt hast das ganze mit nem Steuerbit gemacht. Funktioniert einwandfrei. Ich schätze also mal, dass tatsächlich schlichtweg die sectic-ISR zu lange gedauert hat. Es funktioniert auch ohne deaktivierung der Interrupts - sie haben offenbar also nicht gestört.

Jetzt muss ich das Ding nur noch entbuggen - Display ummodeln ist net immer sinvoll :(

VIelen Dank an Dirk.

Gruß Rainer
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)