www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik DS1820

Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: ThomasW (Gast)
Datum:

Hallo , ich verstehe nicht wie das funktioniert wenn man 2 DS1820 an
einem AVR abfrägt . Wenn ich nicht falsch liege muss man jeden DS1820
erst adressieren und dann kann man jeden über die adresse abfragen ,
vielleicht hat jemand ein Beispiel ( in Bascom ) , das was ich mir von
dieser Seite runtergeladen habe ist nur für einen DS1820 .

Danke Mfg Thomas
Autor: Peter Dannegger (Gast)
Datum:

Hallo Thomas,

ich hätte da nur was in C:

http://www.specs.de/~danni/appl/soft/c51/thclock/index.htm

in "1-wire.c51"

Der Aufruf erfolgt in "meastemp.c51"


Peter
Autor: Matthias (Gast)
Datum:

Hallo, Ich bin Neueinsteiger in Sachen Mikrocontroller, und
versuche mich auch gerade an den DS1820, aber das will nicht
so ganz klappen.
Hast du mittlerweile was gefunden?

Ich nutze auch Bascom Basic
und den AT90S4433

Bei mir gehts schon mit der Hardware los
http://www.canathome.de/Dokumentation/Kapitel2.htm
Wie dort beschrieben hab ich den DS1820 angeschlossen.

Ist das soweit korrekt??
Die Software die ich mir runtergeladen habe, melde dutzende von Fehlern,
wenn ich den port d durch c tausche!!
d mit b tauschen ist kein Thema!!
Woran kann das liegen??

Das Programm sieht so aus:

$regfile = "4433def.dat"
$crystal = 4000000

Config 1wire = Portb.4                                      'use this
pin

Dim Ar(2) As Byte , A As Byte , I As Byte , Temperatur As Integer
Dim Halb As Byte
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 ,
Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
'These settings are for the AVR-Ctrl in PIN mode

Config Lcd = 24 * 2                                         'configure
lcd screen
'other options are 16  4 and 20  4, 20 * 2 , 16 * 1a
'When you dont include this option 16 * 2 is assumed
'16 * 1a is intended for 16 character displays with split addresses over
2 lines
Config Portd = Output                                       'configure
portd as output
Config Portb = Input
Reset Portd.1                                               'write mode
for display
Initlcd                                                     'init
display again
Cursor On
Cls
Lcd "Temp:"
Do
  Wait 1
  1wreset                                                   'reset the
device
  1wwrite &HCC                                              'read ROM
command
  1wwrite &H44
  Waitms 100                                                'read ROM
command
  1wreset                                                   'reset the
device
  1wwrite &HCC                                              'read ROM
command
  1wwrite &HBE                                              'read ROM
command
  For I = 1 To 2
    Ar(i) = 1wread()                                        'place into
array
  Next

  Locate 2 , 1
  Temperatur = Ar(1)

  If Ar(2) > 0 Then Temperatur = 0 Else Shift Temperatur , Right

  Lcd Temperatur ; ".";

  Halb = Ar(1) And 1

  If Halb = 1 Then Lcd "5" Else Lcd "0"

  Lcd " C"
Loop

End

als Temperatur zeigt er nur 0.0 grad an!!

Kann mir da irgendeiner helfen??
Schon mal besten Dank!

Gruß
Matthias
Autor: Dieter Brüggemann (Gast)
Datum:
Angehängte Dateien:

Hallo Matthias

Habe dein Programm mal etwas geändert beim auslesen des ds1820. Bei
läuft das so ganz gut. Mach doch mal die Definitionen unter Optionen in
Bascom, dann sieht das oben nicht mehr so wild aus.

MFG
Dieter
Autor: Dieter Brüggemann (Gast)
Datum:

@ ThomasW

Jeder DS1820 hat eine feste Adresse "eingebrannt" die man erst mal
kennen muß, von jedem DS1820 die an dem Bus liegt.

Mit dem Read_rom ( &H33) Befehl, kann man die Adresse aus dem DS 1820
auslesen. Es darf dann aber nur ein Baustein am Bus hängen. Es können
dann 8 Bytes ausgelesen werden:

1. Family Code DS1820 = &H10
2. bis 7. Adresse des DS1820   48 Bit Adresse
8. CRC Prüfsumme

Wenn du nur 2 am Bus daran hast, lese doch beide Bausteine nacheinander
aus und schreibe dir die Adresse auf. Dann kannst du nachher über die
Adresse beide Bausteine direkt ansprechen und auslesen.

MFG
Dieter
Autor: Dieter Brüggemann (Gast)
Datum:
Angehängte Dateien:

Hallo Matthias

So, sollte jetzt so laufen wie gewünscht.

MFG
Dieter
Autor: Matthias (Gast)
Datum:

Ich danke dir !!

Ich habe in der Hardware einen Fehler gefunden, da habe ich einen 4,7k
Widerstand vergessen.

Dumme Sache, direkt danach ging es.
Ich danke dir trotzdem für die Überarbeitung des Programms.

Gruß

Matthias
Autor: A.Füßer (Gast)
Datum:

> da habe ich einen 4,7k Widerstand vergessen
"Verbesserungsvorschlag" angenommen und Widerstand beschriftet.

Danke & tschüß,
 André.
Autor: Matthias (Gast)
Datum:

@Dieter Brüggemann

Wie meinst du das genau mit der Adresse auslesen?
Ich habe nämlich auch vor 2 von ds1820 an einem Bus zu hängen.

1wreset
1wwrite Read_rom                                             Ar(1) =
1wread()
1wreset
Enable Interrupts
Lcd Ar(1)

Wenn ich das mache zeigt mir das Display 16 an.
Auch wenn ich den anderen Sensor an den Bus angeschlossen habe!
Autor: Matthias (Gast)
Datum:

Hallo!

Ich konnte das Problem zum Glück selber "lösen",
allerdings habe ich das denke ich mal ziemlich umständlich gemacht, also
für Komprimierungsvorschläge wäre ich nach wie vor dankbar.

Das mit dem auslesen der nummer hat dann doch noch geklappt, dank dem
Datenblatt.
Es ist eine 64Bit Nummer und ich hatte wie oben beschrieben nur 8 bit
ausgelesen.




Const Read_rom = &H33                                       ' DS1820
Commands
Const Skip_rom = &HCC
Const Convertt = &H44
Const Read_ram = &HBE
Const Match_rom = &H55
Const Write_ram = &H4E
Const Copy_ram = &H48
Const Recall_ee = &HB8
Const Read_power = &HB4
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 ,
Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
Config Lcd = 24 * 2                                         'configure
lcd screen
Config Portd = Output                                       'configure
portd as output
Config Portb = Input
Config 1wire = Portb.4
Reset Portd.1                                               'write mode
for display
Initlcd                                                     'init
display again
Cursor On
Timer1 = 65536 - 62500                                      ' Reload
Timer1 for Period of 1 sec
Config Timer1 = Timer , Prescale = 64
On Timer1 Timer1_isr                                        ' Jump to
Timer1 ISR
Enable Timer1                                               ' Enable the
timer interrupt
Enable Interrupts                                           ' Enable
Global Interrupt
Cls
Do
Start:
Do
   Wait 1
   Disable Interrupts                                       'soltte man
machen, falls man mal Interrupts benutzt .Können aber beim auslesen
stören
   1wreset                                                  '1wire Reset
    1wwrite Match_rom
    1wwrite 16
    1wwrite 129
    1wwrite 204
    1wwrite 60
    1wwrite 0
    1wwrite 8
    1wwrite 0
    1wwrite 9                                               'Read ROM
command
   1wwrite Convertt                                         'Measure
Temperature
   Do                                                       'warten bis
fertig mit der Umwandlung
      Busy = 1wread()
   Loop Until Busy = &HFF                                   ' Wait for
end of conversion
   1wreset                                                  ' 1wire
Reset
    1wwrite Match_rom
    1wwrite 16
    1wwrite 129
    1wwrite 204
    1wwrite 60
    1wwrite 0
    1wwrite 8
    1wwrite 0
    1wwrite 9                                               'Read ROM
command
    1wwrite Read_ram
    Ar(1) = 1wread()                                        'und
auslesen
    Ar(2) = 1wread()
    1wreset                                                 ' 1wire
Reset, fertig mit auslesen
     Enable Interrupts                                      'und wieder
einschalten
   Temperatur = Ar(1)
   Temperatur = Temperatur / 2
   Locate 2 , 5
   Lcd Temperatur ; ".";
   Halb = Ar(1) And 1
   Locate 2 , 8
   If Halb = 1 Then Lcd "5" Else Lcd "0"
   Lcd " C"
   Wait 1
   Disable Interrupts                                       'soltte man
machen, falls man mal Interrupts benutzt .Können aber beim auslesen
stören
   1wreset                                                  '1wire Reset
    1wwrite Match_rom
    1wwrite 16
    1wwrite 196
    1wwrite 174
    1wwrite 60
    1wwrite 0
    1wwrite 8
    1wwrite 0
    1wwrite 5
   1wwrite Convertt                                         'Measure
Temperature
   Do                                                       'warten bis
fertig mit der Umwandlung
      Busy = 1wread()
   Loop Until Busy = &HFF                                   ' Wait for
end of conversion
   1wreset                                                  ' 1wire
Reset
    1wwrite Match_rom
    1wwrite 16
    1wwrite 196
    1wwrite 174
    1wwrite 60
    1wwrite 0
    1wwrite 8
    1wwrite 0
    1wwrite 5
    1wwrite Read_ram
    Ar(3) = 1wread()                                        'und
auslesen
    Ar(4) = 1wread()
    1wreset                                                 ' 1wire
Reset, fertig mit auslesen
     Enable Interrupts                                      'und wieder
einschalten
   Temp2 = Ar(3)
   Temp2 = Temp2 / 2
   Locate 1 , 1
   Lcd Temp2 ; ".";
   Halb = Ar(4) And 1
   Locate 1 , 5
   If Halb = 1 Then Lcd "5" Else Lcd "0"
   Lcd " C"
   If K = 5 Then
   K = 0
   Goto Start
   End If
      While New_time = 1
       K = K + 1
       New_time = 0
      Wend
Loop
Loop
Timer1_isr:
    Timer1 = 65536 - 62576                                  ' Reload
Timer1 for Period of 1 sec
    New_time = 1                                            ' 76 cycles
correction
    Return
End
Autor: Dieter Brüggemann (Gast)
Datum:

Hallo Matthias

Ist doch schonmal gut, daß du weitergekommen bist. Routinen die man
öfter braucht, sollte man in Funktionen packen. Schau mal in der Hilfe
nach wie das geht. Damit wird der Code nachher übersichtlicher und
meistens auch kürzer. Die Adressen der 2 DS1820 würde ich ins EEPROM
schreiben und über eine Schleife auslesen, wenn ich sie brauche.

Schau dir mal folgende Befehle näher an.

Readeeprom, Writeeeprom  die gehen jetzt auch mit "Labels"

Oder ein kleiner Einstieg in Funktionen
Aufruf nachher hiermit, irgendwo im Programm
Temp = ds1820_read(1)
Temp = ds1820_read(2)

Function DS1820_read(byval nr As Integer) As word
  Hier kommt der Code rein z.B.:
  IF nr = 1 then adresse 1
  IF nr = 2 then adresse 2
 DS1820_read = ausgelesener Wert des Chip, wird zurückgegeben.
End Function

So nun an Werk. Bei Fragen melden. Die Funktion muß am Anfang noch
deklariert werden, steht aber alles in der Hilfe.

MFG Dieter
Autor: Matthias (Gast)
Datum:

Danke für die Antwort,

Eine Funktion brauche ich daraus eigendlich nicht zu machen.
Also ich habe vor mir eine Lüftersteuerung für meinen PC zu basteln, mit
2 Temperatursensoren und 2 Lüftern mit Drehzahlüberwachung.
Je nach Temperatur werden die Lüfter aus bzw.auf 6V bzw. auf
12V geschaltet.

Lange rede kurzer Sinn.
ich lasse einfach nur eine Schleife ablaufen:
1. Beide Temperaturen einlesen
2. erste Drehzahlüberwachung
3. zweite Drehzahlüberwachung

Wie sieht das denn mit dem Match_rom befehl aus,
ich muß den ja für jede Temperatur 2mal audführen, kann man das nicht
irgendwie auch als Doppelwort bzw. long vergleichen
um den Code zu kürzen?

Gruß

Matthias

Also die Temperatur wird nur einmal in der Schleife aufgerufen, und die
Funktion würde den Code denke ich mal nicht verkürzen.
Autor: Dieter Brüggemann (Gast)
Datum:

Hallo

Das ist ja gerade der Sinn der Funktion oder von subroutine.



sub match_1 ()
    1wwrite Match_rom
    1wwrite 16
    1wwrite 196
    1wwrite 174
    1wwrite 60
    1wwrite 0
    1wwrite 8
    1wwrite 0
    1wwrite 5
end sub

oben schreibst du dann nur noch call match_1. Dann hast du den Code nur
noch einmal da stehen.

snip
1
   Disable Interrupts 'soltte man machen, falls man mal Interrupts
benutzt .Können aber beim auslesen stören
   1wreset '1wire Reset
   call match_1
   1wwrite Convertt 'Measure Temperature
   Do 'warten bis fertig mit der Umwandlung
   Busy = 1wread()
   Loop Until Busy = &HFF ' Wait for end of conversion
   1wreset ' 1wire Reset
   call match_1
   1wwrite Read_ram
    Ar(1) = 1wread()
snip

MFG
Dieter
Autor: Matthias (Gast)
Datum:

Danke noch mal!
So hatte ich das noch nicht gesehen.
Autor: Dubbster Dubbster (dubbster)
Datum:
Angehängte Dateien:

hey peter,du genie!

ich hab ebenfalls ein problem mit dem ds1820,bin ned wirklich weit
gekommen,vielleicht könntest du mir ebenfalls weiter helfen! Ich füge
mal hinzu,was ich schon habe,oder vielleicht jemand andere kann mir
dabei helfen??


ich bring das nicht mit dem 1-wire port nicht,bzw weiss ich gar
nicht,wann low oder high ist.
Autor: Kay R. (trafowickler)
Datum:

Ich habe ein Problem mit der Adressierung des DS1820.
Ich habe dieses Beispielprogramm hier genutzt, welches mir die Adresse
"100E0CDD01080088" auf dem LCD ausgibt.

' Beispiel für das myAVR Board 1 & 2 mit LCD und 1wire Temperatursensor an Pin 5 von Port C
$regfile = "m8def.dat"
$crystal = 10000000

' LCD konfigurieren Port auf Ausgabe setzten und Pin's entsprechend zuordnen
Ddrd = &HFF
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portd.1 , _
   Db7 = Portd.0 , E = Portc.3 , Rs = Portc.2
Config Lcd = 16 * 2
Cursor Off
Cls

' Pin für 1wire Schnittstelle festlegen, Schnittstelle wird von BASCOM durch Software realisiert
Config 1wire = Portd.3

Dim Dsid(8) As Byte
Dim I As Byte
Dim Nr As Byte

Nr = 1
Cls

' Ersten angeschlossenen DS1820 finden und Adresse auslesen
Dsid(1) = 1wsearchfirst()

Locate 1 , 1 : Lcd "DS1820 Nr " ; Nr : Nr = Nr + 1
Locate 2 , 1
For I = 1 To 8
 Lcd Hex(dsid(i))
Next

' 10 Sekunden warten
Wait 10

Do
 ' Nächsten DS1820 suchen
 Dsid(1) = 1wsearchnext()
 ' Wenn kein Fehler, dann ausgeben
 If Err = 0 Then
  Locate 1 , 1 : Lcd "DS1820 Nr " ; Nr : Nr = Nr + 1
  Locate 2 , 1
  For I = 1 To 8
   Lcd Hex(dsid(i))
  Next
  Wait 15
 End If
Loop Until Err = 1


Do
 Waitms 100
Loop

End


Diese ist natürlich zu lang für meine als Byte deklarierte Variable in
meinem Thermostatproggie.
Was davon ist nun der Teil, den ich als Adresse angeben muss?
Nicht schlagen, bin Neuling.
Autor: G ast (Gast)
Datum:

Den Aufbau der Adresse findst du im Datenblatt.
Aber in ein Byte wird die nicht reinpassen.
Autor: Kay R. (trafowickler)
Datum:

So, Problem gelöst.
Nun ist es ein Byte-Array "Dsid(8)".

Dabei gab es nun ein weiteres Problem.
Ich hole mir die Adresse mit "Dsid(1) = 1wsearchfirst : Dsid2(1) =
1wsearchnext".
Da ich aber zu Testzwecken nur einen Sensor angeschlossen habe,
antwortet er scheinbar auch auf das "1wsearchnext". Deshalb zeigten
beide LCD - Zeilen, also Innen und Außen, den gleichen Wert.
Das habe ich nun so gelöst:
Dsid(1) = 1wsearchfirst
Dsid2(1) = 1wsearchnext

...

Temp1 = T
If Dsid(1) = Dsid2(1) Then
Temp2 = 0
Else
Temp2 = T2
End If

Das ist die Zusamenfassung von Codeschnipseln, daher die drei Punkte.

Das kann zwar für Verwirrung bei einem Sensorentausch sorgen, wenn sich
plötzlich ein anderer als "First" meldet, aber so spare ich mir das
Auslesen der Adresse vor Einbau des Sensor.
Wenn der Fall auftritt, werde ich einfach die Positionen der Werte im
LCD tauschen und gut is'. ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net