(Neu) |
(kein Unterschied)
|
Version vom 23. August 2008, 02:16 Uhr
In diesem Artikel folgen einige Programmbeispiele, in denen gezeigt wird wie Bascom über den 1-Wire-Bus kommuniziert.
1-Wire (Eindraht) ist eine serielle Schnittstelle, die mit nur einer Datenleitung auskommt, die gleichzeitig auch noch als Stromversorgung genutzt werden kann. Aufgrund der Einfachheit kann diese Schnittstelle leicht in Software auf einem Mikrocontroller nachgebildet werden.
In Bascom sind Befehle für die 1-Wire-Kommunikation enthalten, sodass der Programmierer sich nicht um das Protokoll und das Timing der Übertragung kümmern muss.
Es gibt 1-Wire-Geräte mit verschiedenen Funktionen, in der Roboterwelt dürfte einer der bekanntesten der Temperatursensor DS18S20 (bzw. DS18B20) sein, deswegen wird dieser in den Beipielen verwendet.
Inhaltsverzeichnis
Beschaltung
Die Beschaltung rund um den DS18B20 sieht so aus:
Ablauf der Kommunikation
Die Kommunikation mit dem 1-Wire-Gerät muss immer diesen Ablauf haben:
- Initialisierung
- "ROM Function" Befehl
- "Memory Function" Befehl
- Übertragung/Daten
Aus diesem Ablauf ergeben sich die beiden folgenden Programmabläufe.
Kommunikation mit nur einem Gerät
Wenn sich nur ein einziges Gerät am Bus befindet kann man diese kurze Version der Kommunikation verwenden. Ein ROM-Befehl ist dabei nicht notwendig und kann übersprungen werden, dies muss aber dem Gerät mitgeteilt werden.
Beispiel:
' Minimalprogramm für Temperaturmessung Config 1wire = Portc.7 Dim Sp(9) As Byte 1wreset ' Initialisierung 1wwrite &HCC ' überspringe ROM-Befehl 1wwrite &H44 ' Temperaturmessung anstoßen Waitms 500 ' warten bis Messung fertig 1wreset ' Initialisierung 1wwrite &HCC ' überspringe ROM-Befehl 1wwrite &HBE ' Temperatur auslesen Sp(1) = 1wread(9) ' Daten in ein Array lesen Wait 1
Im Array Sp() stehen die Daten des Gerätes die dann Anhand des Datenblattes ausgewertet werden.
Kommunikation mit mehreren Geräten
Wenn sich mehrere Geräte am 1-Wire-Bus befinden, müssen diese jeweils Adressiert werden um mit dem gewünschten Gerät in Kontakt zu treten. Zum Adressieren wird die Seriennummer verwendet, die in jedem 1-Wire-Gerät eindeutig vorhanden ist. Um an diese Seriennummer zu kommen gibt es zwei Strategien.
Entweder man liest bei allen Geräten vorher einzeln diese Nr. aus, um diese in das eigentliche Programm einzutragen (kürzer), oder man sucht beim Programmstart jedesmal nach vorhandenen Geräten (flexibler).
SerienNr einzeln auslesen
Config 1wire = Portc.7
Dim Ar(8) As Byte
1wreset
1wwrite &H33 ' ROM-Befehl zum lesen der SerienNr
Ar(1) = 1wread(8) ' 8 Bytes lesen
For I = 1 To 8
Print Hex(ar(i)); ' Ausgeben
Print " ";
Next
Print
Wait 1
Im Array Ar() befindet sich somit die SerienNr des Gerätes.
SerienNr aller Geräte
$regfile = "M32def.dat"
$crystal = 16000000
$baud = 38400
Config 1wire = Portc.7
Dim Ar(8) As Byte ' Array für SerienNr.
Dim I As Byte
Dim W As Word
Sound Portd.7 , 400 , 450 ' BEEP bei RN-Control
Print
Print "1-Wire"
Wait 1
Ar(1) = 1wsearchfirst()
' gibts überhaupt ein Gerät
If Err = 0 Then
For I = 1 To 8
Print Hex(ar(i)); ' Ausgabe der ersten SerienNr.
Print " ";
Next
Print
Do
' Nach weiteren Geräte suchen
Ar(1) = 1wsearchnext()
' war noch ein weiteres Gerät da
If Err = 0 Then
For I = 1 To 8
Print Hex(ar(i)); ' Ausgabe der letzten SerienNr.
Print " ";
Next
Print
End If
Loop Until Err = 1 ' solange bis sich kein weiteres Gerät mehr meldet.
End If
Print "Fertig"
W = 1wirecount() ' Anzahl der gefundenen Geräte zählen
Print "Anzahl ";
Print W
Do
Loop
End
Am ersten Byte der SerienNr ist zu erkennen um welches Gerät es sich handelt, beim DS18B20 ist es die &H28.
Bestimmtes Gerät ansprechen
Um bei mehreren vorhandenen Geräten ein bestimmtes anzusprechen muss es mit der SerienNr adressiert werden.
Do
1wverify Ar(1) ' Gerät mit der SerienNr. aus Ar() auswählen
' Gerät vorhanden
If Err = 0 Then
1wwrite &H44 ' Temperaturmessung anstoßen
Waitms 500 ' warten bis Messung fertig
1wverify Ar(1) ' Gerät mit der SerienNr. aus Ar() auswählen
1wwrite &HBE ' Temperatur auslesen
Sp(1) = 1wread(9) ' Daten in ein Array lesen
For I = 1 To 9
Print Hex(sp(i));
Next
Print
' Nur für die Temperatur wichtige Daten ausgeben
Print Hex(sp(2));
Print Hex(sp(1))
Else
Print "Fehler"
End If
Wait 1
Loop
Die SerienNr. des gewünschten Gerätes muss im Array Ar() stehen, bevor es mit 1wverify gesucht wird, dies ist auch gleichzeitig der ROM-Befehl, diesem kann der Memory-Befehl folgen, und anschließend die Daten übertragen werden.
Prüfsumme
Da wegen der einen Datenleitung durchaus mit Störungen zu rechnen ist, wird jeder Übertragung ein Prüfbyte angehängt, mit dem sich die Korrektheit der Daten überprüfen lässt.
Config 1wire = Portc.7
Dim Ar(8) As Byte ' Array für SerienNr
Dim I As Byte
1wreset
If Err = 0 Then
1wwrite &H33 ' ROM-Befehl zum lesen der SerienNr.
For I = 1 To 8
Print Hex(ar(i)); ' Ausgabe der SerienNr.
Print " ";
Next
Print
Print Hex(crc8(ar(1) , 7) ) ' Prüfsumme ausgeben
If Ar(8) = Crc8(ar(1) , 7) Then ' Prüfsumme vergleichen
Print "Daten OK"
Else
Print "Fehler"
End If
End If
Wenn das letzte Byte der Übertragung und die berechnete Prüfsumme aus den Bytes 1-7 übereinstimmt, war die Übertragung erfolgreich, und die Daten können weiterverarbeitet werden. Beim auslesen der Temperatur werden 9 Bytes übertragen, deshalb müssen zum berechnen der Prüfsumme Byte 1-8 einbezogen werden.
Parasitäre Stromversorgung
Da bei der Schaltung von oben eigentlich drei Leitungen benötigt werden, statt der einen wie man vermuten könnte, ist es mit der folgenden Schaltung immerhin möglich die Anzahl auf zwei Leitungen zu reduzieren.
Es ist aber Abhängig vom Gerät und den Umgebungsbedingungen ob es sich immer so lösen lässt. Ein Blick ins Datenblatt hilft da weiter.
Siehe auch
Weblinks
- [1] - Datenblatt zu DS18B20
--Linux 80 03:16, 23. Aug 2008 (CEST)

