Sensor DHT11 mit Systemtakt 500kHz bis 2MHz

    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!

    • Sensor DHT11 mit Systemtakt 500kHz bis 2MHz

      Hallo zusammen

      Dieses Thema DHT11 Sensor bringt AtMega8 zum Reset hat mich dazu motiviert, eine Auslese-Routine für den DHT11 zu schreiben, die auch bei 1MHz Systemtakt und vielleicht auch bei geringerem Takt noch zuverlässig funktioniert.

      Das Problem war ja, dass die DHT11-Routine in obigem Thread in Basic geschrieben war, und daher einfach nicht mehr in der Lage war, den Sensor bei 1MHz Systemtakt auszulesen.

      Ich hab es selbst dann in Basic mal versucht, das funktioniert aber nicht mehr.
      Also habe ich gleich alles in Assembler gemacht habe.
      Also das Maximum an Geschwindigkeit rausgeholt habe, was geht. Vielleicht kann man noch bisschen dran feilen

      Das Ergebnis:
      Entstanden ist ein Modul Namens "DHT11.inc", welches einfach in eigene Projekte einzubinden ist und den DHT11 bei Systemtakten von 500kHz bis 2MHz verfügbar macht. Getestet habe ich bis Systemtakt 450kHz (ext. RC-Oszillator) runter, das hat bei mir noch fehlerfrei funktioniert.

      Ist doch erstaunlich!

      Um das zu erreichen, wurde Timer0 verwendet, aber keinerlei Interrupts.
      Interrupts sollten übrigens beim Lesen des Sensors abgeschaltet werden, da die Sache sehr zeitkritisch ist!

      Ich möchte für künftige Anwendungen dieses Demo mit Modul "DHT11.inc" (Lib im weiteren Sinne) zur Verfügung stellen.

      Damit man nicht gleich zum mal Reinschauen alles Herunterladen muss, hier mal die Demo und dann das Modul vorab.
      Am Schluss kann dann alles als Zip heruntergeladen werden. Enthalten ist da auch eine kleine Beschreibung und ein Datenblatt.

      Hier das Hauptprogramm:
      Man muss lediglich das "DHT11.inc" Modul einbinden (Zeile 51) und in der Hauptschleife 3 Funktionen aufrufen.
      Pin für DHT-Anschluss wird im Modul angegeben.

      BASCOM-Quellcode: Main.bas

      1. ' Demo DHT11
      2. ' Autor: Mitch64 (Bascomforum.de)
      3. ' Erstellt: Januar 2020
      4. ' Version : 1.0.0
      5. ' Beschreibung:
      6. ' Demonstriert die Einbindung und Verwendung des Modul DHT11.inc
      7. ' Mit der funktion DHT_Read wird der Sensor ausgelesen. Der Rückgabewert
      8. ' wird in Variable Result gespeichert und enthält ein Fehlercode (siehe DHT11.inc).
      9. ' Ist der Fehlercode = DHT_ERR_SUCCESS,
      10. ' war das Auslesen erfolgreich und die Werte für Feuchte und Temperatur
      11. ' konnen mit den Functionen DHT_Feuchte() und DHT_Temoeratur()
      12. ' aus dem internen DHT-Buffer extrahiert werden.
      13. ' Durch die Rückgabe des Fehlercodes kann im Programm entsprechend reagiert werden
      14. ' und beispielsweise dem Anwender mitteilen, dass der Sensor nicht funktioniert.
      15. ' Hinweis:
      16. ' Der Datenpin (DHT11) kann im Modul DHT11.inc im Abschnitt "Konfiguration"
      17. ' geändert werden.
      18. ' Die geringe Baudrate wurde gewählt, um die serielle Ausgabe
      19. ' bei 500kHz Systemtakt noch gewärleisten zu können.
      20. ' Der Source-Code wurde getestet und funktioniert von 500kHz bis 2MHz.
      21. ' Bei 450kHz habe ich aufgehört zu testen, da funktionierte der Code noch.
      22. ' Bei 4MHz funktionierte der code nicht mehr.
      23. $Regfile = "m8def.dat"
      24. $HWStack = 30
      25. $SWStack = 30
      26. $FrameSize = 30
      27. '$Crystal = 14745600
      28. $Crystal = 1000000 ' int. Oszillator
      29. '$SIM
      30. $Baud = 1200
      31. Config SubMode = New
      32. Config Base = 0
      33. Const FALSE = 0
      34. Const TRUE = 1
      35. Dim Result as Byte
      36. Dim Feuchte as Byte
      37. Dim Temperatur as Byte
      38. $Include "Include\DHT11.inc" ' Sensor DHT11 einbinden
      39. Wait 1
      40. Enable Interrupts
      41. Print "Start DHT11 Demo!"
      42. Print
      43. Do
      44. Print : Print "Takt: " ; _xtal
      45. Result = DHT_Read() ' DHT11 lesen
      46. Select Case Result
      47. Case DHT_ERR_SUCCESS ' Auslesen war erfolgreich
      48. Feuchte = DHT_Feuchte() ' Feuchte aus DHT-Buffer lesen
      49. Temperatur = DHT_Temperatur() ' Temperarur aus DHT-Buffer lesen
      50. Print "Temperatur: " ; Temperatur
      51. Print "Feuchte: " ; Feuchte
      52. Case DHT_ERR_NO_RESPONSE ' Keine Antwort von DHT
      53. Print "Fehler: Der DHT11 antwortet nicht!"
      54. Case DHT_ERR_CHECKSUM_FAIL ' Checksumme fehlerhaft
      55. Print "Fehler: DHT11 Checksumme nicht korrekt!"
      56. End Select
      57. Waitms 1000
      58. Loop
      Alles anzeigen
      Ich muss es aufteilen. Rest im nächsten Beitrag.
      Dateien

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

    • Und hier geht's weiter.

      Und hier das Modul "DHT11.inc", in dem auch der Pin angegeben werden muss, an dem der DHT11 hängt (Zeile 21 bis 23).
      Bei Fragen stehe ich natürlich zur Verfügung

      BASCOM-Quellcode: DHT11.inc

      1. ' Modul: DHT11.inc
      2. ' Autor: Mitch64 (Bascomforum.de)
      3. ' Erstellt: Januar 2020
      4. ' Version: 1.0.0
      5. ' Verwendete Resourcen:
      6. ' - Timer0
      7. ' - keine Interrupts verwendet
      8. ' Einschränkungen:
      9. ' - MCU-Takt: 0.5MHz bis 2MHz (getestet bis 450kHz)
      10. ' - Interrupts sollten vor Aufruf von DHT_Read() abgeschaltet werden (zeitkritisch)
      11. ' Beschreibung:
      12. ' Einbindung des Temperatur/Feuchte-Sensors DHT11.
      13. ' ----------------------------------------------
      14. ' Konfiguration
      15. ' ----------------------------------------------
      16. ' verwendeter DHT-Daten-Pin einstellen
      17. Const DHT_PIN_NR = 5 ' Pin-Nr am Port für Input
      18. DHT_PIN Alias PINC ' Input-Port
      19. DHT_DDR Alias DDRC ' Umschaltung des Pin Input/Output
      20. ' ----------------------------------------------
      21. ' Error-Codes
      22. ' ----------------------------------------------
      23. Const DHT_ERR_SUCCESS = 0 ' kein Fehler
      24. Const DHT_ERR_NO_RESPONSE = 1 ' keine Antwort von DHT11
      25. Const DHT_ERR_CHECKSUM_FAIL = 2 ' Checksumme falsch
      26. ' interne Konstanten/Variablen
      27. Const DHT_TIMEOUT = _xtal \ 2000 \ 6 ' 500µs Timeout für Response
      28. Const DHT_DATA_TIME = _xtal \ 10000 ' 100µs mittlerer Bit-Abstand
      29. Dim DHT_Buffer(5) as Byte ' Einlese-Buffer
      30. ' ----------------------------------------------
      31. ' 8-Bit Timer einstellen
      32. ' ----------------------------------------------
      33. Config Timer0 = Timer , Prescale = 1 ' Timer0 für Zeitmessung
      34. ' ----------------------------------------------
      35. ' Intern verwendete Makros
      36. ' ----------------------------------------------
      37. Macro DHT_WaitLow ' Auf Low-Pegel warten
      38. !SBIC DHT_PIN, DHT_PIN_NR
      39. !RJMP -1
      40. End Macro
      41. Macro DHT_WaitHigh ' Auf High-Pegel warten
      42. !SBIS DHT_PIN, DHT_PIN_NR
      43. !RJMP -1
      44. End Macro
      45. Macro WaitNegEdge ' Auf neg. Flanke warten
      46. DHT_WaitHigh
      47. DHT_WaitLow
      48. End Macro
      49. ' ----------------------------------------------------------------------------
      50. Goto Modul_DHT11_Exit
      51. ' ----------------------------------------------------------------------------
      52. ' ----------------------------------------------
      53. ' Liest den DHT11 aus und liefert einen
      54. ' Error-Code (siehe oben)
      55. ' ----------------------------------------------
      56. Function DHT_Read() as Byte
      57. ' 18ms Low-Puls ausgeben
      58. !SBI DHT_DDR,DHT_PIN_NR ' Daten-Pin DHT auf Ausgang schalten (Ausgang Low)
      59. Waitms 18
      60. !CBI DHT_DDR,DHT_PIN_NR ' Daten-Pin DHT auf Eingang schalten (High durch PullUp)
      61. ' Warten, bis Pegel wieder High ist
      62. DHT_WaitHigh
      63. ' Auf Response warten
      64. !CLR r16 ' Schleifenzäher für Timeout
      65. _dht_read_wait_response:
      66. !INC r16
      67. !SBIS DHT_PIN, DHT_PIN_NR
      68. !RJMP _dht_response ' DHT zielt Pegwel auf Low
      69. !CPI r16, DHT_TIMEOUT ' Timeout erreicht?
      70. !BRLO _dht_read_wait_response ' Timeout nicht erreicht
      71. ' Timeout, kein Response
      72. !LDI r16, DHT_ERR_NO_RESPONSE ' Rückgabewert laden
      73. !LDD ZL,y+0 ' Adresse Rückgabewert
      74. !LDD ZH,y+1
      75. !ST Z,r16 ' Rückgabewert schreiben
      76. !RET ' Function verlassen
      77. ' DHT hat geantwortet (neg. Flanke)
      78. _dht_response:
      79. !CLR r17 ' Timer0 auf 0, Zeitmessung beginnt
      80. !OUT TCNT0,r17
      81. !LDI r16,41 ' 41 Bit's einlesen (einschl. Response-Bit)
      82. !CLR r20 ' Platz schaffen für 5 Byte (Buffer)
      83. !CLR r21
      84. !CLR r22
      85. !CLR r23
      86. !CLR r24
      87. _dht_read_loop:
      88. WaitNegEdge ' Auf neg. Flanke warten
      89. !IN r18,TCNT0 ' Timerwert lesen
      90. !OUT TCNT0, r17 ' Timer auf 0 setzen
      91. !CPI r18,DHT_DATA_TIME ' Prüfen, ob 1-Bit oder 0-Bit
      92. !BRLO _dht_read_0 ' Sprung wenn 0-Bit
      93. !SEC ' Carry setzen (Datenbit=1)
      94. !RJMP _dht_read_shift_in
      95. _dht_read_0:
      96. !CLC ' Carry löschen (Datenbit=0)
      97. ' Datenbit in Buffer schieben (rechts nach links)
      98. _dht_read_shift_in:
      99. !ROL r24
      100. !ROL r23
      101. !ROL r22
      102. !ROL r21
      103. !ROL r20
      104. ' alle Bits eingelesen?
      105. !DEC r16 ' Bit's -1
      106. !BRNE _dht_read_loop ' nächstes Bit lesen
      107. ' Empfangene Bytes in DHT_Buffer() übertragen
      108. LoadAdr DHT_Buffer(_base) , Z ' Adresse auf Buffer nach Z
      109. !ST Z+,r20 ' Registerwerte in Buffer ablegen
      110. !ST Z+,r21
      111. !ST Z+,r22
      112. !ST Z+,r23
      113. !ST Z+,r24
      114. ' Check-Summe berechnen in r17
      115. !MOV r17,r20
      116. !ADD r17,r21
      117. !ADD r17,r22
      118. !ADD r17,r23
      119. ' Checksumme prüfen
      120. !CP r17,r24 ' Berechnete Summe simmt mit gesendeter überein?
      121. !BREQ _dht_read_ok
      122. ' Checksumme falsch
      123. !LDI r24,DHT_ERR_CHECKSUM_FAIL ' Rückgabewert laden
      124. !RJMP _dht_read_result
      125. ' Checksumme OK
      126. _dht_read_ok:
      127. !LDI r24,DHT_ERR_SUCCESS ' Rückgabewert laden
      128. ' Error-Code an Aufrufer (Rückgabewert)
      129. _dht_read_result:
      130. !LDD ZL,y+0 ' Adresse Rückgabewert
      131. !LDD ZH,y+1
      132. !ST Z,r24 ' Rückgabewert schreiben
      133. End Function
      134. ' ----------------------------------------------
      135. ' Gibt die Feuchte zurück [%]
      136. ' Zuvor muss DHT_Read() erfolgreich ausgeführt worden sein!
      137. ' ----------------------------------------------
      138. Function DHT_Feuchte() as Byte
      139. DHT_Feuchte = DHT_Buffer(_base)
      140. End Function
      141. ' ----------------------------------------------
      142. ' Gibt die Temperatur zurück [°C]
      143. ' Zuvor muss DHT_Read() erfolgreich ausgeführt worden sein!
      144. ' ----------------------------------------------
      145. Function DHT_Temperatur() as Byte
      146. DHT_Temperatur = DHT_Buffer(_base + 2)
      147. End Function
      148. ' ----------------------------------------------------------------------------
      149. Modul_DHT11_Exit:
      150. ' ----------------------------------------------------------------------------
      Alles anzeigen
      Bei Fragen stehe ich natürlich zur Verfügung!

      Viel Spaß damit

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