1-Wire Erfahrungen, Tipps und Beispiele

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • 1. 1-Wire-Slaves erkennen

      Befehle: Config 1wire, 1wirecount, 1wsearchfirst(), 1wsearchnext(), 1wreset


      Wenn man 1-Wire-Bausteine ("Slaves") korrekt an einen AVR angeschlossen hat (s.o.),
      dann stellt sich die Frage, wie der AVR sie überhaupt erkennt.
      Zum Glück hat BASCOM einen 1-Wire-Befehlssatz.
      Man muss sich also nicht den eigenen Kopf zerbrechen :)

      Zuerst muss man aber BASCOM sagen, an welchem Port der 1-Wire-Bus hängt.
      Dies geschieht mit dem Befehl "Config 1wire":

      BASCOM-Quellcode

      1. ' INIT-Bereich
      2. ' ************
      3. ' - Port festlegen
      4. Config 1wire = Portd.4
      (Es sind auch mehrere Ports möglich, dazu evtl. später mehr)

      Der nächste Schritt wäre nun, dass man herausbekommt, wie viele Slaves am Bus hängen.
      Auch das übernimmt BASCOM mit dem Befehl "1wirecount()"

      BASCOM-Quellcode

      1. Dim Ow_zahl as Byte
      2. Ow_zahl = 1wirecount()
      3. Print Ow_zahl ; " 1-Wire-Slaves"

      Okay, die Zahl der Sensoren kennt man jetzt.

      Aber nun will man ja die einzelnen Slaves auch ansprechen können.
      Jeder dieser Slaves hat eine eindeutige "ID",
      mit der er angesprochen werden kann.
      Die ID besteht aus 8 Bytes.
      Dabei ist das 1. Byte der sog. "Family-Code".
      Er gibt Auskunft über die Funktion des Slaves (z.B. &H28 -> DS18B20 Temp.-Sensor)
      Das 8. Byte ist die CRC8-Prüfsumme von Byte 1-7.
      Es dient als Sicherheitsfaktor bei der Übermittlung.

      Auch dafür hat BASCOM Funktionen:
      "1wsearchfirst()" für den 1. Slave und
      "1wsearchnext()" für die folgenden

      BASCOM-Quellcode

      1. ' INIT-Bereich
      2. ' ************
      3. Dim I As Byte
      4. Dim J As Byte
      5. Const Ow_sensoren_max = 12
      6. ' - allgemeine Variablen:
      7. ' -> Array fuer IDs ALLER 1-Wire-Sensoren (abhaengig von "Ow_sensoren_max"):
      8. Dim Ow_id(96) As Byte
      9. ' -> Array fuer ID EINES Sensors
      10. Dim Ow_id_sensor(8) As Byte
      11. ' -> Schleifenindex fuer Array "ow_id"
      12. Dim Ow_index As Byte
      13. ' -> Nummer eines einzelne Sensors (ID steht in "ow_id_sensor")
      14. Dim Ow_nummer As Byte
      15. ' ...
      16. ' HAUPTPROGRAMM
      17. ' *************
      18. ' ...
      19. ' UNTERROUTINEN
      20. ' *************
      21. ' Nach 1-Wire-Sensoren suchen
      22. ' Ausgabe:
      23. ' - "Ow_zahl" enthaelt die Anzahl der gefundenen Sensoren
      24. ' - Das Array "Ow_id" enthaelt die 8Byte/64Bit-IDs der Sensoren
      25. Id_auslesen:
      26. ' Anzahl der Sensoren bestimmen
      27. Ow_zahl = 1wirecount()
      28. If Ow_zahl = 0 Then Return
      29. ' Keine Sensoren?
      30. If Ow_zahl > 0 Then
      31. ' 1. Sensor:
      32. Ow_id(1) = 1wsearchfirst()
      33. End If
      34. ' weitere Sensoren:
      35. If Ow_zahl > 1 Then
      36. J = 9
      37. For Ow_nummer = 2 To Ow_zahl
      38. Ow_id(j) = 1wsearchnext()
      39. J = J + 8
      40. Next Ow_nummer
      41. End If
      42. Return
      43. ' ID ausgeben
      44. Id_ausgabe:
      45. Print "OW-" ; Ow_nummer ; "_ID=" ;
      46. Print Hex(ow_id_sensor(1));
      47. Print "-";
      48. For Ow_index = 2 To 8
      49. Print Hex(ow_id_sensor(ow_index)) ;
      50. Next Ow_index
      51. Print
      52. Return
      Alles anzeigen
      (Der obige Code ist für max. 12 Slaves ausgelegt. Wer mehr möchte, muss die Variablen anpassen.)

      Nun wäre es natürlich auch geschickt,
      wenn man nicht nur die ID hat,
      sondern auch zum Family-Code die entsprechende Funktion ausgibt.
      Das hat BASCOM nicht auf Lager, das muss man selbst erledigen.

      BASCOM-Quellcode

      1. ' UNTERROUTINEN
      2. ' *************
      3. ' Typenbezeichnung der ID zuordnen
      4. ' Eingabe:
      5. ' Im Array "Ow_id_sensor" muss die ID (8 Byte) des Sensors stehen
      6. Ow_typ:
      7. ' *************************************************
      8. If Ow_id_sensor(1) = &HFE Then
      9. Print " Device RoBue (Weather)"
      10. Elseif Ow_id_sensor(1) = &HFD Then
      11. Print " Device RoBue (Counter)"
      12. ' *************************************************
      13. Elseif Ow_id_sensor(1) = &H28 Then
      14. 'Gosub Ds18b20_robue
      15. 'If Ow_robue = 255 Then
      16. Print " DS18B20: Digital Thermometer"
      17. 'Else
      18. 'Print " Device RoBue"
      19. 'End If
      20. ' *************************************************
      21. Elseif Ow_id_sensor(1) = &H01 Then
      22. Print " DS2401: Silicon Serial Number"
      23. Elseif Ow_id_sensor(1) = &H05 Then
      24. Print " DS2405: One Channel Addressable Switch"
      25. Elseif Ow_id_sensor(1) = &H10 Then
      26. Print " DS18S20: Digital Thermometer"
      27. Elseif Ow_id_sensor(1) = &H20 Then
      28. Print " DS2450: Quad A/D Converter"
      29. Elseif Ow_id_sensor(1) = &H21 Then
      30. Print " DS1921: Thermochron iButton"
      31. Elseif Ow_id_sensor(1) = &H26 Then
      32. Print " DS2438: Smart Battery Monitor"
      33. Elseif Ow_id_sensor(1) = &H29 Then
      34. Print " DS2408: 8-Channel Addressable Switch"
      35. Elseif Ow_id_sensor(1) = &H1D Then
      36. Print " DS2423: 4k Ram with Counter"
      37. Elseif Ow_id_sensor(1) = &H2C Then
      38. Print " DS2890: Digital Potentiometer"
      39. Elseif Ow_id_sensor(1) = &H3A Then
      40. Print " DS2413: Dual Channel Addressable Switch"
      41. Elseif Ow_id_sensor(1) = &H42 Then
      42. Print " DS28EA00: Digital Thermometer with ... PIO"
      43. End If
      44. Return
      Alles anzeigen

      Aus diesen Routinen kann man nun eine Art 1-Wire-Scanner entwickeln,
      mit dem auch die Slaves vom 1-Wire-Slave-Baukasten erkannt werden.
      -> 1-Wire-Slave-Baukasten V.2

      BASCOM-Quellcode

      1. ' HAUPTPROGRAMM
      2. ' *************
      3. ' - 1-Wire-Sensoren finden und ID ausgeben
      4. 1wreset
      5. Gosub Id_auslesen
      6. Print "-> One-Wire-Bus: " ; Ow_zahl
      7. ' Nur die in in "Ow_sensoren_max" eingestellte Anzahl von Sensoren aufnehmen
      8. If Ow_zahl > Ow_sensoren_max Then
      9. Ow_zahl = Ow_sensoren_max
      10. End If
      11. ' Sensoren ausgeben
      12. If Ow_zahl > 0 Then
      13. J = 0
      14. For Ow_nummer = 1 To Ow_zahl
      15. For Ow_index = 1 To 8
      16. J = J + 1
      17. Ow_id_sensor(ow_index) = Ow_id(j)
      18. Next Ow_index
      19. Print "- ";
      20. Gosub Id_ausgabe
      21. ' Beschreibung ausgeben
      22. Gosub Ow_typ
      23. Next Ow_nummer
      24. End If
      25. End
      Alles anzeigen
      Anmerkung:
      Mit dem Befehl "1wreset" werden die 1-Wire-Funktionen gestartet und beendet.

      Soweit mal,
      LG RoBue

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von RoBue ()

    • 2. 1-Wire-Slaves aufrufen

      Befehle: 1wwrite, 1wread(), 1wverify


      Wir haben nun herausgefunden, wie viele Slaves im System herumwerkeln
      und wir haben deren ID eingelesen
      und in einem Array abgelegt ("Ow_array").
      Nun geht es darum, diese Slaves anzusprechen.

      Dafür gibt es 2 Möglichkeiten:

      a) Man kann alle zugleich ansprechen

      Dies macht Sinn,
      wenn man z.B. alle Temperatursensoren zur gleichen Zeit dazu aufforden will,
      mit der Temperaturmessung zu beginnen.

      Dieser gemeinsame Aufruf geschicht so:

      BASCOM-Quellcode

      1. ' Alle Temperatursensoren zur Temperaturmessung auffordern
      2. Temp_messung_alle:
      3. 1wreset
      4. 1wwrite &HCC
      5. 1wwrite &H44
      6. ' Achtung:
      7. ' Bei parasitaerer Stromversorgung Reset erst NACH den 700ms,
      8. ' die zum Messen noetig sind.
      9. waitms 750
      10. 1wreset
      11. Return
      Alles anzeigen
      "1wreset" meldet den Slaves, dass der Master etwas von ihnen will.
      Das heißt so viel wie "Achtung, aller Klappe halten und aufpassen!"
      "1wwrite" schickt Werte über den Bus.
      "&HCC" heißt "Was jetzt kommt, gilt allen!"
      "&H44" heißt für manche Bausteine (z.B. DS18B20; Slaves RoBue): "Messen und Berechnen!"
      Dann muss man den Slaves auch etwas Zeit geben
      und dann schließt man das Ganze wieder mit einem "1wreset" ab.

      b) Man will nur einen konkreten Baustein ansprechen

      Das macht man, wenn man z.B. bestimmte Messwerte eines Slaves haben will.
      Da macht es ja keinen Sinn, wenn alle zugleich mit dem Quasseln loslegen.

      BASCOM-Quellcode

      1. ' Bestimmten OW-Sensor ansprechen
      2. ' Eingabe:
      3. ' - Im Array "Ow_id_sensor" muss die ID des Sensors stehen (8 Byte)
      4. ' (z.B. Ow_nummer = 2 ; Gosub Id_bestimmen ...)
      5. Match_rom:
      6. Err = 0
      7. 1wreset
      8. 1wwrite &H55
      9. 1wwrite Ow_id_sensor(1) , 8
      10. Ow_error = Err
      11. Return
      12. ' Bestimmten OW-Sensor ansprechen
      13. ' Im Array "Ow_id_sensor" muss die 64Bit/8Byte-Kennung des Sensors stehen
      14. ' (Ermoeglicht Fehlermeldungen, falls Sensor nicht mehr ansprechbar ist.
      15. ' Macht aber nur Sinn, wenn diese auch irgendwie abgefragt und ausgegeben werden.)
      16. Verify_rom:
      17. Err = 0
      18. 1wreset
      19. Err = 0
      20. 1wverify Ow_id_sensor(1)
      21. Ow_error = Err
      22. Return
      Alles anzeigen

      Diesen Aufruf kann man auf zwei Arten machen:
      Einmal "zu Fuß", indem man "&H55" gefolgt von der ID über den Bus jagt,
      oder indem man die BASCOM-Routine "1wverify" nutzt.
      Man muss auch hier mit "1wreset" beginnen,
      aber eben noch kein zweites "1wreset" schicken,
      denn man will ja noch etwas von den Slaves haben.
      Das muss jetzt angefordert werden.

      Das einfachste Beispiel ist das Auslesen eines DS18B20:

      BASCOM-Quellcode

      1. ' Auslesen DS18B20 (Temperatursensoren, Aufloesung bis 12Bit)
      2. ' 12Bit Aufloesung bei (Neu-)Start. Dies wird nicht veraendert!
      3. ' Ausgabe:
      4. ' - der (10-fache) Temperaturwert(Integer) steht im Array Temperatur(ow_nummer)
      5. Ds18b20_read:
      6. ' Slave von RoBue?
      7. Gosub Ds18b20_robue
      8. ' Scatchpad auslesen
      9. Gosub Match_rom
      10. If Ow_error <> 0 Then Goto Readtemperror
      11. Gosub Ds18x20_read_srcatchpad
      12. If Ow_error <> 0 Then Goto Readtemperror
      13. ' Temperatur/Werte berechnen
      14. If Ow_robue = 255 Then
      15. ' Erzeuge daraus Integer
      16. Temperatur(ow_nummer) = Makeint(scratchpad(1) , Scratchpad(2))
      17. ' Umwandlung in Single zum besseren Rechnen
      18. Temp_18b20 = Temperatur(ow_nummer)
      19. Temp_18b20 = Temp_18b20 * 10
      20. Temp_18b20 = Temp_18b20 / 16
      21. ' Rückwandlung in Integer
      22. Temperatur(ow_nummer) = Round(temp_18b20)
      23. ' -> ja
      24. Else
      25. Gosub Ow_robue_rechnen
      26. End If
      27. Return
      28. Readtemperror:
      29. Temperatur(ow_nummer) = 9999
      30. Return
      31. Ds18x20_read_srcatchpad:
      32. ' Scratchpad anforden
      33. 1wwrite &HBE
      34. ' Scratchpad auslesen
      35. Scratchpad(1) = 1wread(8)
      36. ' crc-Byte lesen
      37. Ds1820_crc = 1wread()
      38. If Crc8(scratchpad(1) , 8) = Ds1820_crc Then
      39. Ow_error = 0
      40. Else
      41. Ow_error = 1
      42. End If
      43. 1wreset
      44. Return
      Alles anzeigen
      Bei vielen Bausteinen werden die Daten über einen 8-Byte-Block mit Namen "Scratchpad" ausgelesen,
      an dessen Ende noch ein 9. Byte als CRC8-Prüfsumme abgehängt wird.
      Dies geschieht unter BASCOM mit dem Befehl "1wread(x)"
      Zuvor muss man natürlich dem Slave sagen, dass man diese 8 Werte auch will.
      Dafür schickt man mit "1wwrite" den Befehl "&HBE".
      Je nach Baustein muss man nun aus diesen 8 Werten seine Messdaten generieren.
      Beim DS18B20 braucht man dazu eigentlich nur die ersten beiden.

      Das vorliegende Beispiel ist schon für die Nachbau-Slaves vom Slave-Baukasten erweitert.
      Auch die arbeiten mit dem Scratchpad wie ein DS18B20,
      aber diese Werte müssen dann anders interpretiert und umgerechnet werden.

      BASCOM-Quellcode

      1. ' ****************************************************************************
      2. ' OW-Devices von RoBue
      3. ' (wird im Grunde wie ein DS18x20 ausgelesen)
      4. ' Ausgabe:
      5. ' - der (10-fache) Temperaturwert(Integer) steht im Array Temperatur(ow_nummer)
      6. ' - der (10-fache) Feuchtewert steht in der Word-Variable "Ow_hum"
      7. ' - Ow_ausgabewert enthaelt einen ADC- oder Counterwert (16 Bit = Word)
      8. ' - Ds1820_scratchpad(8) enthaelt eine Statusabfrage zur Fehlerfeststellung
      9. Ow_robue_read:
      10. ' Berechnung der Daten erfolgt ueber Befehl "Temp_messung_alle"
      11. Gosub Match_rom
      12. Gosub Ds18x20_read_srcatchpad
      13. Gosub Ow_robue_rechnen
      14. Return
      15. Ow_robue_rechnen:
      16. ' Counter
      17. If Ow_id_sensor(1) = &HFD Then
      18. ' 32-Bit-Counter auslesen
      19. Zaehler1 = Scratchpad(4)
      20. Shift Zaehler1 , Left , 8
      21. Zaehler1 = Zaehler1 + Scratchpad(3)
      22. Shift Zaehler1 , Left , 8
      23. Zaehler1 = Zaehler1 + Scratchpad(2)
      24. Shift Zaehler1 , Left , 8
      25. Zaehler1 = Zaehler1 + Scratchpad(1)
      26. ' 9-Bit-Counter auslesen
      27. Zaehler2 = Scratchpad(6)
      28. Shift Zaehler2 , Left , 8
      29. Zaehler2 = Zaehler2 + Scratchpad(5)
      30. ' Umweltsensor
      31. Else
      32. ' - Temperatur
      33. Temperatur(ow_nummer) = Makeint(scratchpad(1) , Scratchpad(2))
      34. ' - Feuchte
      35. ' Ow_hum = Ds1820_scratchpad(4)
      36. ' Shift Ow_hum , Left , 8
      37. ' Ow_hum = Ow_hum + Ds1820_scratchpad(3)
      38. ' Ow_ausgabewert = Ds1820_scratchpad(6)
      39. A_feuchte = Scratchpad(4)
      40. Shift A_feuchte , Left , 8
      41. A_feuchte = A_feuchte + Scratchpad(3)
      42. ' 3. Wert (Luftdruck, ...)
      43. Ow_ausgabewert = Scratchpad(6)
      44. Shift Ow_ausgabewert , Left , 8
      45. Ow_ausgabewert = Ow_ausgabewert + Scratchpad(5)
      46. End If
      47. Return
      48. Ds18b20_robue:
      49. ' Ist der Slave in Wirklichkeit ein Slave Marke RoBue?
      50. ' (Ow_robue hat dann einen Wert <> 255/FF)
      51. Gosub Match_rom
      52. 1wwrite &H10
      53. Ow_robue = 1wread()
      54. 1wreset
      55. Return
      56. ' ****************************************************************************
      Alles anzeigen

      Wenn alles fertig ist, kann ein "1wreset" nicht schaden.
      In der Regel reicht aber auch der "1wreset" eines neuen Aufrufs.

      Fortsetzung folgt,
      LG RoBue

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von RoBue ()

    • Also dann machen wir mal wie versprochen weiter.

      Wir haben die 1-Wire-Befehle kennen gelernt
      und die ersten Sensoren (DS18x20 und 1-Wire-Slaves von RoBue) ausgelesen.

      Nun möchte ich Euch einen weiteren, äußerst interessanten Baustein vorstellen:

      3. DS2438 - Smart Battery Monitor

      Datenblatt: datasheets.maximintegrated.com/en/ds/DS2438.pdf

      Eigentlich ist er für die Überwachung von Akkus gedacht.
      Er hat dafür eine ganze Menge an Messmöglichkeiten:
      - Temperatursensor
      - Messeingang für 0 - 10V (VAD, Pin 4)
      - Messung der eigenen Versorgungsspannung (GND und VCC/VDD)
      - Messung des Lade- und Entladestromes (Vsens+ und Vsens-, Pin 2 und 3)
      Dazu kann er sogar den Ladezustand des Akkus errechnen und ausgeben.

      Man kann den DS2438 z.B. nicht nur für Akkus,
      sondern auch für Netzteile gebrauchen,
      indem man ihn z.B. auf dem Kühlblech befestigt.
      Dann lässt sich die Temperatur des Spannungsreglers überwachen,
      dazu die Stromstärke (Vsens+,Vsens-),
      die Ausgabespannung des Reglers (GND,VCC/VDD)
      und Versorgungsspannung (VAD).
      Auf diese Weise kann man ein 1-Wire-Netzteil bauen,
      das über die Plus-Leitung des 1-Wire-Kables (VDD/VCC) nicht nur den eingebauten DS2438,
      sondern zugleich das ganze Messystem mit Spannung versorgt.

      Falls man "Fremdspannungen" oder "Fremdstromstärken" messen will,
      also Messwerte von Schaltungen,
      die nicht zugleich die 1-Wire Bauteile mit Spannung/strom versorgen,
      muss man GND des 1-Wire-Systems mit GND des zu messenden Systems verbinden.

      Falls man nur die Vsens-Eingänge nutzt,
      muss man zumindes Vsens- mit GND des DS2438 verbinden.

      Die Berechnung der Stromstärke ist dabei etwas "tricky":
      An einem sog. "Shunt" (=Widerstand mit geringem Ohm-Wert und hoher Leistung)
      wird der Spannungsabfall gemessen.
      Die Werte müssen zwischen -300 und +300mV liegen.
      Damit kann man Lade- und Entladeströme (je nach Vorzeichen) messen.
      Die Berechnung erfolgt über die Formel: I = U/R.
      Wenn man für für den Shunt dem Wert 1Ohm nimmt,
      entspricht der Augabewert der Stromstärke in mA (geht dann aber nur bis 300mA!!!).
      Der Shunt wird in die GND-Leitung eingebaut.

      1wire_DS2438_Batmon.jpg
      Beispiel für einen Schaltungsaufbau mit einem DS2438.
      R1 ist der sog. "Shunt", C1 dient zu Stabilisierung, R2 und 3 zur Entkoppelung.

      Leider haben viele Akkus (z.B. KFZ) eine höhere Spannung (12V und mehr).
      Darum muss man den Eingang anpassen.
      Es gibt dafür bereits von Maxim eine App-Note:
      -> pdfserv.maximintegrated.com/en/an/AN125.pdf

      Neben demEinsatzals Batterie- bzw. Akkumonitor wird der DS2438 mit einem HIH4000 o.ä. als Temperatur- und Feuchtesensor genutzt. Die zwei Dioden (BAT54S) und der Kondensator C1 ermöglichen den "parasitären" Betrieb.

      1wire_DS2438_HIH.jpg

      Nun wollt Ihr sicher auch ein Code-Beispiel haben?
      Okay.
      Hier ist er:

      BASCOM-Quellcode

      1. ' INIT-Bereich
      2. ' ************
      3. ' -> DS2438
      4. Dim Ds2438_statusreg As Byte
      5. Dim Ds2438_crc As Byte
      6. Dim Ds2438_temp1 As Byte , Ds2438_temp2 As Byte , Tempfix As Byte , Minus As Byte
      7. Dim Ds2438_ad1 As Byte , Ds2438_ad2 As Byte
      8. Dim Ds2438_adsens1 As Byte , Ds2438_adsens2 As Byte
      9. Dim Ds2438_uvin As Word
      10. Dim Ds2438_uvcc As Word
      11. Dim Ds2438_isum As Long
      12. Dim Ds2438_uvsens As Integer
      13. Dim Ds2438_sens As Single
      14. Dim Ds2438_hum As Single
      15. ' ...
      16. ' HAUPTPROGRAMM
      17. ' *************
      18. ' ...
      19. ' UNTERROUTINEN
      20. ' **************
      21. ' DS2438 auslesen
      22. ' Ausgabe:
      23. ' - Spannungswert steht in den beiden Byte-Variablen "Ad1" und "Ad2"
      24. ' - Spannung (in mV) berechnen: (Ds2438_Ad2 * 256 + Ds2438_Ad1) * 10 -> Ds2438_vin
      25. ' - Spannungswert an Vsens steht in "Ds2438_Adsens1" und "Ds2438_Adsens2"
      26. ' - Spannung (in mV) berechnen: makeint(Adsens1 * Adsens2) * 0,2441 -> Ds2438_vsens
      27. ' - Temperatur steht in den Byte-Variablen "Ds2438_Temp1" und "Ds2438_Temp2"
      28. Ds2438_read:
      29. Gosub Match_rom
      30. ' Recall Memory - EEPROM/SRAM -> scratchpad
      31. 1wwrite &HB8
      32. ' page 0 -> scratchpad page 0
      33. 1wwrite &H00
      34. 1wreset
      35. '
      36. Gosub Match_rom
      37. 'Read Scratchpad page 0 - Seite 0 auslesen (insges. 8 Bytes)
      38. 1wwrite &HBE
      39. 1wwrite &H00
      40. ' 1. Byte -> Statusregister
      41. Ds2438_statusreg = 1wread()
      42. ' 2.+3. Byte -> Temperatur
      43. ' LSB -> Nachkommastellen
      44. Ds2438_temp2 = 1wread()
      45. ' MSB -> Temperaturwert
      46. Ds2438_temp1 = 1wread()
      47. ' 4. und 5. Byte -> AD-Wert
      48. Ds2438_ad1 = 1wread()
      49. Ds2438_ad2 = 1wread()
      50. ' 6. und 7. Byte -> AD-Wert von Vsens
      51. Ds2438_adsens1 = 1wread()
      52. Ds2438_adsens2 = 1wread()
      53. 1wreset
      54. Return
      55. ' Nur Spannung an Pin 4 auslesen
      56. Ds2438_read_ad:
      57. Gosub Match_rom
      58. ' Recall Memory - EEPROM/SRAM -> scratchpad
      59. 1wwrite &HB8
      60. ' page 0 -> scratchpad page 0
      61. 1wwrite &H00
      62. 1wreset
      63. '
      64. Gosub Match_rom
      65. 'Read Scratchpad page 0 - Seite 0 auslesen (insges. 8 Bytes)
      66. 1wwrite &HBE
      67. 1wwrite &H00
      68. ' 1. Byte -> Statusregister
      69. Dummybyte = 1wread()
      70. ' 2.+3. Byte -> Temperatur
      71. ' LSB -> Nachkommastellen
      72. Dummybyte = 1wread()
      73. ' MSB -> Temperaturwert
      74. Dummybyte = 1wread()
      75. ' 4. und 5. Byte -> AD-Wert
      76. Ds2438_ad1 = 1wread()
      77. Ds2438_ad2 = 1wread()
      78. 1wreset
      79. Return
      80. ' Temperatur berechnen
      81. Ds2438_temp:
      82. Minus = 0
      83. If Ds2438_temp1 > 127 Then
      84. Ds2438_temp1 = 256 - Ds2438_temp1
      85. Ds2438_temp2 = 32 - Ds2438_temp2
      86. Minus = 1
      87. End If
      88. Temperatur(ow_nummer) = Ds2438_temp1 * 10
      89. ' Nachkommastellen
      90. Tempfix = Ds2438_temp2 * 3125
      91. ' nur eine Nachkommastelle
      92. Tempfix = Tempfix / 10000
      93. Temperatur(ow_nummer) = Temperatur(ow_nummer) + Tempfix
      94. If Minus = 1 Then
      95. Temperatur(ow_nummer) = -temperatur(ow_nummer)
      96. End If
      97. Return
      98. ' DS2438 Spannung am Messeingang berechnen
      99. Ds2438_vin:
      100. Ds2438_uvin = Ds2438_ad2 * 256
      101. Ds2438_uvin = Ds2438_uvin + Ds2438_ad1
      102. Ds2438_uvin = Ds2438_uvin * 10
      103. Return
      104. ' DS2438 Versorgungsspannung berechnen
      105. Ds2438_vcc:
      106. Ds2438_uvcc = Ds2438_ad2 * 256
      107. Ds2438_uvcc = Ds2438_uvcc + Ds2438_ad1
      108. Ds2438_uvcc = Ds2438_uvcc * 10
      109. Return
      110. ' DS2438 Spannung an Vsens berechnen
      111. Ds2438_vsens:
      112. Ds2438_uvsens = Makeint(ds2438_adsens1 , Ds2438_adsens2)
      113. ' Ds2438_uvsens = Ds2438_uvsens * 0.2441
      114. ' Geht aber nicht!
      115. ' Darum:
      116. Ds2438_uvsens = Ds2438_uvsens * 24
      117. Ds2438_uvsens = Ds2438_uvsens / 100
      118. ' Diesen Wert muss man dann durch den Shunt-Winderstandswert teilen,
      119. ' um die Stromstärke in mA zu bekommen.
      120. Return
      Alles anzeigen
      Anmerkung:
      Da das Scatchpad mit seinen 8 Bytes nicht mehr ausreicht,
      alle Messwerte aufzunehmen,
      muss man dem DS2438 immer zuerst sagen,
      welche Daten er dort ablegen soll.

      Fortsetzung folgt.

      LG RoBue

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von RoBue ()

    • Die Fortsetzung kommt schneller als gedacht.
      Ich habe leider ein paar Code-Zeilen vergessen.

      Hier kommt der Rest:

      BASCOM-Quellcode

      1. ' UNTERROUTINEN
      2. ' *************
      3. ' Im Array "Ow_id_sensor" muss die ID des Sensors stehen (8 Byte)
      4. ' Ds2438 zur Temperaturmessung auffordern
      5. ' erfolgt schon ueber die Routine "Temp_messung_alle"
      6. ' DS2438 zur AD-Messung (Pin 4) auffordern
      7. Ds2438_messung_ad:
      8. Gosub Match_rom
      9. ' AD-Wandlung, nicht VCC-Wandlung
      10. ' Write Scratchpad
      11. 1wwrite &H4E
      12. ' Page 0
      13. 1wwrite &H00
      14. ' Wert=0 -> AD-Wandlung
      15. ' Wert=8 -> Batterie-Monitor = Grundeinstellung
      16. 1wwrite &H00
      17. ' Copy Scratchpad -> EEPROM/SDRAM
      18. 1wwrite &H48
      19. ' Page 0
      20. 1wwrite &H00
      21. ' Warten wegen Schreiben ins EEPROM
      22. Waitms 50
      23. '1wreset
      24. Gosub Match_rom
      25. ' AD-Wandlung durchfueren
      26. 1wwrite &HB4
      27. Waitms 10
      28. 1wreset
      29. Return
      30. ' DS 2438 zur Messung der Betriebsspannung (VCC = Pin 5) auffordern
      31. Ds2438_messung_vcc:
      32. Gosub Match_rom
      33. ' Write Scratchpad
      34. 1wwrite &H4E
      35. ' Page 0
      36. 1wwrite &H00
      37. ' Wert=0 -> AD-Wandlung
      38. ' Wert=8 -> Batterie-Monitor = Grundeinstellung
      39. 1wwrite &H0F
      40. ' Copy Scratchpad -> EEPROM/SDRAM
      41. 1wwrite &H48
      42. ' Page 0
      43. 1wwrite &H00
      44. ' Warten wegen Schreiben ins EEPROM
      45. Waitms 50
      46. 'Achtung
      47. '1wreset
      48. Gosub Match_rom
      49. ' AD-Wandlung durchfueren
      50. 1wwrite &HB4
      51. Waitms 10
      52. 1wreset
      53. Return
      54. ' DS2438 Luftfeuchte mit HIH40xx-Sensor berechnen
      55. Ds2438_humidity:
      56. Ds2438_hum = Ds2438_uvin / Ds2438_uvcc
      57. Ds2438_hum = Ds2438_hum - 0.16
      58. Ds2438_hum = Ds2438_hum / 0.0062
      59. Return
      Alles anzeigen

      Hier nun noch ein Beispiel, wie man die Messwerte abruft und ausgibt:

      BASCOM-Quellcode

      1. ' HAUPTPROGRAMM
      2. ' *************
      3. ' AD-Messung fuer Versorgungsspannung (Pin 5)
      4. ' einstellen und durchfuehren
      5. Gosub Ds2438_messung_vcc
      6. ' Scatchpad (Page 0) wird komplett ausgelesen ...
      7. Gosub Ds2438_read
      8. ' Print "OW-" ; Ow_nummer ; "_STATUS=" ; Bin(Ds2438_statusreg)
      9. Gosub Ds2438_temp
      10. Print "OW-" ; Ow_nummer ; "_T=" ; Temperatur(ow_nummer)
      11. Gosub Ds2438_vsens
      12. Print "OW-" ; Ow_nummer ; "_VSENS=" ; Ds2438_uvsens
      13. Gosub Ds2438_vcc
      14. Print "OW-" ; Ow_nummer ; "_VCC=" ; Ds2438_uvcc
      15. Gosub Ds2438_messung_ad
      16. Gosub Ds2438_read_ad
      17. Gosub Ds2438_vin
      18. Print "OW-" ; Ow_nummer ; "_VAD=" ; Ds2438_uvin
      Alles anzeigen

      Anmerkung:
      Die Code-Stücke setzen teilweise Routinen voraus, die weiter oben schon zu finden sind,
      wie z.B. die Routine "Match_rom",
      die mittels der ID im Array "Ow_id_sensor" einen einzelnen 1-Wire Slave anspricht,
      um ihn auszulesen oder zu bestimmten Aktionen aufzufordern.

      Anmerkung 2:
      David Bray hat mit einem DS2438 einen Barometer verwirklicht.
      -> davidbray.org/onewire/barometer.html

      LG RoBue

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RoBue ()