Bascom DHT-22 Sensor für Luftfeuchtigkeit und Temperatur

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
So langsam nimmt die Wetterstation Form an.

Nachfolgend ein Codeschnipsel für den DHT-22 Sensor. Der Sensor nutzt eine Art 1-Wire Protokoll zur Kommunikation, das natürlich nicht 1-Wire kompatibel ist und deshalb die BASCOM-Befehle für das 1-Wire Protokoll nicht genommen werden können. Das Datenblatt beschreibt, wie eine Kommunikation auszusehen hat. Der Sensor sendet kurze ( etwa 26 µs) und lange Impulse / Signale (etwa 70 µs), deren Zeitdauer ausgewertet werden muss, da diese dann als 0 und 1 im Sinne eines Bits zu interpretieren sind. Die Zeitdauer eines Signals wird mit Hilfe eines Timers ermittelt. Es werden 40 Bits übertragen, die die Luftfeuchtigkeit (RH), die Temperatur (T) und eine Prüfsumme enthalten. Diese Zeiten werden in Bits umgerechnet, fertig. Aus 40 Bits werden 2 x Word (RH und T) und 1 x Byte. Ich weiß nicht, ob meine Methode besonders elegant ist, aber sie scheint zu funktionieren. Die gemessenen Werte scheinen plausibel. Der Code muss noch an T < 0°C angepasst werden, das kann ich so auf dem Steckbrett momentan nicht testen.

Code:
'######################## DHT-22 Humidity & Temperature Sensor####################
' DHT-22
'
'  |-----o-- Vcc
'  |     |
'  |     -
'  |     10k
'  |     -
'  |     |
'  |-----o-- Data ~~~ PC0 (µC)
'  |
'  |-------- NC
'  |
'  |-------- GND
'
'  Timings: Bit = 0 ~ 28 µs / Bit = 1 ~ 70 µs
'  Min_time = 28 µs < TCNT0 Value (ticks) < 70 µs  (in ticks)
'  every time > Min_time >>> Bit = 1
'  every time < Min_time >>> Bit = 0
'
'  Min_time ~ 20 (ticks) for 3.6864 MHz
'
' ~ ticks for Bit = 0: 26 µs * $crystal (in MHz) / Prescale
' ~ ticks for Bit = 1: 70 µs * $crystal (in MHz) / Prescale
'
'######################## DHT-22 Humidity & Temperature Sensor####################


$regfile = "m8def.dat"
$crystal = 3686400
$baud = 115200

$hwstack = 64
$swstack = 64
$framesize = 64

'#####################################

Config Pinc.0 = Input
Config Timer0 = Timer , Prescale = 8

'#####################################

Const Min_time = 20                                         'this has to be changed according to your frequency settings in $crystal

Dim Count As Byte
Dim Signaltime(43) As Byte
Dim Humidityw As Word
Dim Temperaturew As Word
Dim Humsens_chksum As Byte

Dim Humiditys As String * 16
Dim Temperatures As String * 16

'#####################################

Declare Sub Read_timings
Declare Sub Humtemp_values
Declare Function Compare_chksum(byval Hsens_humidity As Word , Byval Hsens_temperature As Word , Byval Hsens_chksum As Byte) As Byte

'##################################### Main loop

Do

  Call Humtemp_values

  If Compare_chksum(humidityw , Temperaturew , Humsens_chksum) = 1 Then

   Humiditys = Str(humidityw)
   Temperatures = Str(temperaturew)

   Print "Humidity: " ; Format(humiditys , "0.0") ; " %"
   Print "Temperature: " ; Format(temperatures , "0.0") ; " deg"

  Else

   Print "Read Error"

  End If

Loop

End

'#############################################################  Read timings
' measure time (in ticks) for signal = high (Start / Stop  TIMER0)
' 1st two measurements do not contain sensor values

Sub Read_timings

   Wait 3

   Count = 1

   Config Pinc.0 = Output : Portc.0 = 0                     ' request data
   Waitms 20                                                ' wait 20 ms
   Config Pinc.0 = Input                                    ' wait for data, receive data

   While Count < 43                                         'collect 42 timings / signals

      Bitwait Pinc.0 , Set                                  'signal goes high > start timer
      Start Timer0
      Bitwait Pinc.0 , Reset                                'signal goes low  > stop timer
      Stop Timer0
      Signaltime(count) = Tcnt0                             'store number of ticks per signal in Signaltime byte

      Tcnt0 = 0
      Incr Count

  Wend


End Sub

'############################################################# Humidity and temperature values
'  transform timings into bits (40 timings > 40 Bits)
'  every time (in ticks) > Min_time >>> Bit = 1
'  every time (in ticks) < Min_time >>> Bit = 0
'  first word contains humidity
'  second word contains temperature
'  last byte contains checksum

Sub Humtemp_values

   Local X As Byte

   Humidityw = 0
   Temperaturew = 0
   Humsens_chksum = 0

   Call Read_timings

   For Count = 3 To 42                                      ' skip first two

      Select Case Count

         Case 3 To 18
            X = 18 - Count
            If Signaltime(count) > Min_time Then Toggle Humidityw.x

         Case 19 To 34
            X = 34 - Count
            If Signaltime(count) > Min_time Then Toggle Temperaturew.x

         Case 34 To 42
            X = 42 - Count
            If Signaltime(count) > Min_time Then Toggle Humsens_chksum.x

      End Select

  Next

End Sub

'############################################################# Calculate Checksum and compare with trasnmitted value


Function Compare_chksum(byval Hsens_humidity As Word , Byval Hsens_temperature As Word , Byval Hsens_chksum As Byte) As Byte

   Local Chksum As Byte

   Chksum = Low(hsens_humidity ) + High(hsens_humidity )
   Chksum = Chksum + Low(hsens_temperature)
   Chksum = Chksum + High(hsens_temperature)

   If Chksum = Hsens_chksum Then
      Compare_chksum = 1
   Else
      Compare_chksum = 0
   End If

End Function
 

dino03

Aktives Mitglied
27 Okt 2008
6,755
17
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo,

kurze und lange Impulse ... das erinnert irgendwie an die Übertragung der DCF77-Zeit ;)
Wenn du meinst das deine Methode nicht besonders elegant ist könntest du da ja eventuell etwas abkupfern ;) (Ähhh Anregungen holen)

Gruß
Dino
 

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
H
Wenn du meinst das deine Methode nicht besonders elegant ist könntest du da ja eventuell etwas abkupfern ;) (Ähhh Anregungen holen)

Hallo Dino,

elegant im Sinne von "Habe ich vorhandene BASCOM Anweisungen gut ausgenutzt", "Könnte ich noch ein paar Befehle
oder Schleifen einsparen?". Im Netz gibt es nur den Code in C für diesen Sensor, weiß nicht, ob der unbedingt aufgeräumter wirkt. ;) Ein wenig kürzer ist er schon.

Gruß,
Sebastian
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hallo avrkarl

Ich bastle an einem DHT11 (sollte vom Protokoll her ja kompatible sein zum DHT22) herum und habe dazu
mal deinen Code angeschaut. Ich finde ihn sehr elegant, zumindest ist er verständlich, das ist meiner Meinung
viel wichtiger, als nur elegant.

Gleichwohl eine Frage zur Zeile "Const Min_time = 20". Diese müsste an die Quarzfrequenz angepasst
werden, aber wie? Wenn ich einen 8MHz oder gar 16MHz Quarz verwende, wie müsste der Wert sein?

Freundliche Grüsse
Thomas
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hallo zusammen

Habe nun den Wert Const Min_time = 98 mal gesetzt, anhand der Angaben im Code.
Der Sensor wird auch gelesen, es erscheint kein Checksum-Fehler. Aber die gelesenen
Werte sind komisch, sie liegen in den Bereich 600 - 700. Wie erwähnt, verwende ich
einen DHT11.

Hat da jemand einen Tipp?

Grüsse
Thomas
 

Sebastian.Heyn

Neues Mitglied
9 Nov 2009
4
0
0
Sprachen
Finaler Code

Hallo,

dein Code lief bei mir übrigens auf Anhieb. Bei 16mhz habe ich das timing auf 70 gesetzt. Läuft. Rechnerisch sollte es aber bei 84 liegen.

Ich habe deinen Code mal fertig gebaut. Da du so nett warst deinen Code mit allen zu teilen dache ich es wäre fair dies auch zu tun.
Ich habe nicht getestet wie er bei 3.8Mhz läuft aber der Case aufruf und folgend kostet nur ca 50 Zyklen, sollte also passen.

Änderungen:
- code unterstützt negative temperaturen
- code nicht mehr so übersichtlich aufgeteilt ;-)

Speedups:
- Das Auslesen und in variablen schreiben wird on the fly erledigt, das spart 40 bytes RAM
- Alles in einer SUB (du vergleichst zb nicht zweimal ob chksum=1 ist etc)
- Nur globale variablen (Das spart das Umspeichern beim Aufruf)


Code:
'######################## DHT-22 Humidity & Temperature Sensor####################
' DHT-22
'
'  |-----o-- Vcc
'  |     |
'  |     -
'  |     10k
'  |     -
'  |     |
'  |-----o-- Data ~~~ PD2 (µC)
'  |
'  |-------- NC
'  |
'  |-------- GND
'
'  Timings: Bit = 0 ~ 28 µs / Bit = 1 ~ 70 µs
'  Min_time = 28 µs < TCNT0 Value (ticks) < 70 µs  (in ticks)
'  every time > Min_time >>> Bit = 1
'  every time < Min_time >>> Bit = 0
'
'  Min_time ~ 20 (ticks) for 3.6864 MHz
'
' ~ ticks for Bit = 0: 26 µs * $crystal (in MHz) / Prescale
' ~ ticks for Bit = 1: 70 µs * $crystal (in MHz) / Prescale
'
'######################## DHT-22 Humidity & Temperature Sensor####################


$regfile = "m328pdef.dat"
$crystal = 16000000
$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

'#####################################

Config Pind.2 = Input
Config Timer0 = Timer , Prescale = 8

'#####################################

Const Min_time = 70                                         'this has to be changed according to your frequency settings in $crystal

Dim Count As Byte
dim timec as byte
dim x as byte
dim chksum as byte

Dim Humidityw As Word
Dim Temperaturew As word
dim tneg as byte 'indicate if temperature<0
Dim Humsens_chksum As Byte

Dim Humiditys As String * 16
Dim Temperatures As String * 16

Do

gosub Read_sensor 'takes 3 seconds

Print Format(humiditys , "0.0") ; " "; Format(temperatures , "0.0")


Loop

End


' measure time (in ticks) for signal = high (Start / Stop  TIMER0)
' 1st two measurements do not contain sensor values
'  transform timings into bits (40 timings > 40 Bits)
'  every time (in ticks) > Min_time >>> Bit = 1
'  every time (in ticks) < Min_time >>> Bit = 0
'  first word contains humidity
'  second word contains temperature
'  last byte contains checksum

Read_sensor:
 Humidityw = 0
 Temperaturew = 0
 Humsens_chksum = 0
 Wait 3
 Count = 1

Config Pind.2 = Output : Portd.2 = 0                     ' request data
Waitms 20                                                ' wait 20 ms
Config Pind.2 = Input                                    ' wait for data, receive data

   While Count < 43                                         'collect 42 timings / signals

      Bitwait Pind.2 , Set                                  'signal goes high > start timer
      Start Timer0
      Bitwait Pind.2 , Reset                                'signal goes low  > stop timer
      Stop Timer0
      timec=tcnt0
      Tcnt0 = 0

      Select Case Count

         Case 3 To 18
            X = 18 - Count
            If timec > Min_time Then Toggle Humidityw.x

         Case 19 To 34
            X = 34 - Count
            If timec > Min_time Then Toggle Temperaturew.x

         Case 34 To 42
            X = 42 - Count
            If timec > Min_time Then Toggle Humsens_chksum.x

      End Select

      Incr Count

  Wend


'############################################################# Calculate Checksum and compare with trasnmitted value
Chksum = Low(humidityw) + High(humidityw)
Chksum = Chksum + Low(temperaturew)
Chksum = Chksum + High(temperaturew)

If chksum=Humsens_chksum Then

'reset the temperature string
temperatures=""
   if temperaturew.15=1 then 'if this bit is set, temperatur is negative
    temperaturew.15=0 'Reset the indicator bit for later conversion
    temperatures="-" 'Add a negative sign to the temperature string
   endif

   Humiditys = Str(humidityw)
   Temperatures = Temperatures+ Str(temperaturew)

end if

return

DHT22 AM2303 AM2305 HUMIDITY TEMPERATUR FEUCHTIGKEIT SENSOR BACOM CODE EXAMPLE LIBRARY BEISPIEL LIB
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hallo Sebastian

Vielen Dank für dein Code-Sharing, werde diesen gerne mal testen. Hast du ev. auch
Erfahrung mit einem DHT-11. So nach dem Datenblatt sieht das Daten-Diagramm gleich
aus, aber ich erhalte da keine sinnvollen Werte aus dem Teil ...

Grüsse aus der Schweiz
Tghomas
 

Sebastian.Heyn

Neues Mitglied
9 Nov 2009
4
0
0
Sprachen
Protokoll ist anscheinend das gleiche (PULLUP nicht vergessen!) und auch inhalt scheint gleich zu sein

du kannst ja mal testen, und wenns nicht geht änderst du mal den code


Code:
   Case 34 To 42
            X = 42 - Count
            If timec > Min_time Then Toggle Humsens_chksum.x

      End Select

      Incr Count

  Wend


'############################################################# Calculate Checksum and compare with trasnmitted value

um in folgendes

Code:
   Case 34 To 42
            X = 42 - Count
            If timec > Min_time Then Toggle Humsens_chksum.x

      End Select

      Incr Count

  Wend


print bin(humidityw);" "; bin(Temperaturew);" ";bin(Humsens_chksum)


'############################################################# Calculate Checksum and compare with trasnmitted value

und postest den output des controllers
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hallo Sebastian

Hier mein Output:
793.6 665.6
0001111000000000 0001100100000000 00110111
768.0 640.0
0001111000000000 0001100100000000 00110111
768.0 640.0
0001111100000000 0001100100000000 00111000
793.6 640.0
0010000000000000 0001110000000000 00111100
819.2 716.8
0001111100000000 0001100000000000 00110111
793.6 614.4
0001111100000000 0001100000000000 00110111
793.6 614.4
0010000000000000 0001110000000000 00111100
819.2 716.8
0010000000000000 0001110000000000 00111100
819.2 716.8
0010000000000000 0001101100000000 00111011
819.2 691.2
0010000000000000 0001110000000000 00111100
819.2 716.8
0001111100000000 0001100000000000 00110111

Kannst du da was rauslesen? :)

Vielen Dank und Grüsse
Thomas
 

Sebastian.Heyn

Neues Mitglied
9 Nov 2009
4
0
0
Sprachen
Was waren da in etwa deine temperaturen? Zimmertemperatur? (20°C??)

Finde es komisch das die werte sich so schnell ändern.
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hallo Sebastian

Die Temperatur war noch sommerlich um die 24 Grad. Ich habe dann mit der Hand etwas
gewärmt und wieder abkühlen lassen, darum die rasche Änderung. Hast du auch mal mit
einem DHT11 gearbeitet? Habe ürbrigens verschiedene Sensoren gesteckt, die zeigen
alle etwa das gleiche Bild. Da müsste also schon die ganze 5er Serie an Sensoren defekt
sein. Brauchen die ev. einen andern Pull-up? Aber dann würde ja die Checksum nicht
stimmen, oder?

Vielen Dank für Dein Mitdenken!!

Freundliche Grüsse
Thomas
 

Sebastian.Heyn

Neues Mitglied
9 Nov 2009
4
0
0
Sprachen
Nein habe ich noch nicht.

Ich kann nur soviel sagen:

Simuliert man das die Bits versetzt eingelesen werden (dht22 fängt ha 2 bits versetzt an) und verschiebt man alle empfnagenen bits um 2 stellen, bleibt die checksumme korrekt.
kannst du dir also sparen, die zu prüfen. eine addition ist kein zuverlässiges mittel

verschieb mal in der empfangsroutine die bits einzeln und guck ob das was bringt

also zb


Code:
  While Count < 43                                         'collect 42 timings / signals

      Bitwait Pind.2 , Set                                  'signal goes high > start timer
      Start Timer0
      Bitwait Pind.2 , Reset                                'signal goes low  > stop timer
      Stop Timer0
      timec=tcnt0
      Tcnt0 = 0

      Select Case Count

         Case 2 To 17
            X = 17 - Count
            If timec > Min_time Then Toggle Humidityw.x

         Case 18 To 33
            X = 34 - Count
            If timec > Min_time Then Toggle Temperaturew.x

         Case 33 To 41
            X = 41 - Count
            If timec > Min_time Then Toggle Humsens_chksum.x

      End Select

      Incr Count

  Wend
 

riesen

Mitglied
10 Sep 2010
108
1
16
Habe getestet, hat nichts gebracht, die Werte werden noch grösser :)

Eine Verständnisfrage:
Case 3 To 18
X99 = 18 - Count
If Timec > Min_time Then Toggle Humidityw.x99

Case 19 To 34
X99 = 34 - Count
If Timec > Min_time Then Toggle Temperaturew.x99

Case 34 To 42
X99 = 42 - Count
If Timec > Min_time Then Toggle Humsens_chksum.x99

Wird da beim Original-Code nicht zwei mal die Position 34 abgefüllt? Sollte
der dritte Case nicht bei 35 starten?

Werde da mal weitertesten, irgendwo muss der DHT11 noch was anders
machen ... Timing?

Abermals danke!

Gruss
Thomas
 

riesen

Mitglied
10 Sep 2010
108
1
16
Erneuter Nachtrag:

Habe da mal den "wilden" Code etwas versucht in den neuen Code einzupflegen.

Der Vorkommawert ist nun vom Wert her in Ordnung, im Nachkommawert wird 0
zurückgemeldet. Das Datenblatt ist etwas verwirrlich, bei der Auflösung steht
1 Grad und 8 Bit, und in der 40Bit-Stream Beschreibung steht auch was von
Vorkomma- und Nachkomma-Stellen. Denke, der Sensor gibt keine Kommastellen
her. Oder übersehe ich da was?

Folgender Code liefert den korrekten Vorkomma-Wert, die Nachkomma-Variablen
"Temperaturewk" und "Humiditywk" bleiben auf 0. Die kursiven Zeilen können
gelöscht werden. Der Code von Sebastian kann mit den kleinen Änderungen
auch für den DHT11 verwendet werden.


Code:
      Select Case Count

         Case 3 To 10
            X99 = 10 - Count
            If Timec > Min_time Then Toggle Humidityw.x99

[I]         Case 11 To 18
            X99 = 18 - Count
            If Timec > Min_time Then Toggle Humiditywk.x99[/I]

         Case 19 To 26
            X99 = 26 - Count
            If Timec > Min_time Then Toggle Temperaturew.x99

         [I]Case 27 To 34
            X99 = 34 - Count
            If Timec > Min_time Then Toggle Temperaturewk.x99[/I]

         Case 35 To 42
            X99 = 42 - Count
            If Timec > Min_time Then Toggle Humsens_chksum.x99

      End Select
 

mohammad

Neues Mitglied
4 Apr 2014
4
0
0
30
Sprachen
help me

Hi
The sensors dht11 & 22 do have friends who can help me if you can
My problem is that 40-bit code is sent by the sensor should be included in the integer part and a decimal integer part and decimal humidity as well as temperature 8-bit code is sum of these two
But I've seen an LCD that the code you've calculated the correct humidity was right next to mine 42 but 8 bits is 00000000 decimal indicates why Friends can you help me :mad:
Thank you
 

riesen

Mitglied
10 Sep 2010
108
1
16
Hi Mohammed

Please remark that only the DHT22 delivers "after-comma-values", the DHT11 returns only the integer value,
the decimal part is always zero. For the most applications is an integer resolution ok.

Regards Thoms
 

mohammad

Neues Mitglied
4 Apr 2014
4
0
0
30
Sprachen
Hi Mohammed

Please remark that only the DHT22 delivers "after-comma-values", the DHT11 returns only the integer value,
the decimal part is always zero. For the most applications is an integer resolution ok.

Regards Thoms

Hi
Thank you for the answer
Both my practical test I got the answer
One problem I had was that I thought the dht22 8-bit data to integer
And the next 8 bits to decimal
While both 16-bit integers and decimals are
Thank you dear friend who answered
 

mohammad

Neues Mitglied
4 Apr 2014
4
0
0
30
Sprachen
Hello again
I have a question that is
What is the order of
Why water is connected to the variable x
The data could not normally sing it.
Please tell me that I could do x؟:stupido2:
 

Phantomias2006

Mitglied
10 Jan 2010
56
0
6
Sprachen
Hallo,

vielen Dank für den Testcode :)
Der Sensor hat auf anhieb Funktioniert.
Ich verwende einen DHT21 (Ist Softwaretechnisch gleich mit den DHT22).
Was mir am Code nicht so gut gefallen hat war das "BITWAIT". Somit hat sich das Programm immer aufgehängt wenn kein Sensor angeschlossen war oder unter Betrieb ausgesteckt wurde.
Für mein Aktuelles Projekt ist dies aber ein No-Go.

Hab den Code deshalb etwas abgeändert.
Ausserdem hab ich noch eine Softclock eingebaut damit man auch sieht dass das Programm weiter läuft. Falls jemand noch Verbesserungen hat immer her damit ;-)

Lange rede kurzer Sinn:
Hier der Code falls ihn jemand brauchen kann.



CodeBox BascomAVR
$regfile = "m16def.dat"
$crystal = 8000000                                          ' 8MHz Quarz (interner Takt)
$framesize = 128
$swstack = 168
$hwstack = 128
Osccal = 179                                                ' Internen Oscillator vom Mega16 Kalibrieren (steht in den Fuse Bits)

'_______________________________________________________________________________
'LCD Display Einstellungen #####################################################
'-------------------------------------------------------------------------------
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Lcd = 16 * 2

Deflcdchar 1 , 32 , 4 , 14 , 21 , 4 , 4 , 4 , 32            ' hoch
Deflcdchar 2 , 32 , 4 , 4 , 4 , 21 , 14 , 4 , 32            ' runter

Cursor Off Noblink
Cls
Dim New_lcd_data_flag As Bit
'_______________________________________________________________________________
'TIMER1 Einstellungen ##########################################################
'-------------------------------------------------------------------------------
Config Timer1 = Timer , Prescale = 256
   On Timer1 Isr_timer1
      Enable Timer1
         Timer1 = 34286
            Start Timer1
               Enable Interrupts

Dim Timer1_counter As Byte
   Dim Sec_flag As Bit

Dim Mod_return As Byte
'_______________________________________________________________________________
'Variablen für die Softclock ###################################################
'-------------------------------------------------------------------------------
Dim Sekunde As Word
   Dim Minute As Word
      Dim Stunde As Word
Dim Sekunde_s As String * 2
   Dim Minute_s As String * 2
      Dim Stunde_s As String * 2
Dim Double_point_flash As Bit
   Dim Double_point As String * 1
'_______________________________________________________________________________
'Uhrzeit Einstellen ############################################################
'-------------------------------------------------------------------------------
Sekunde = 00
   Minute = 00
      Stunde = 16
'_______________________________________________________________________________
'DHTxx Sensor - PIN Einstellungen ##############################################
'-------------------------------------------------------------------------------
Config Pinc.3 = Input
   Config Timer0 = Timer , Prescale = 8
'_______________________________________________________________________________
'Variablen für den DHTxx Sensor ################################################
'-------------------------------------------------------------------------------
Const Min_time = 50                                         'this has to be changed according to your frequency settings in $crystal

Dim Count As Byte
   Dim Timec As Byte
      Dim X As Byte
         Dim Chksum As Byte

Dim Humidityw As Word
   Dim Temperaturew As Word
      Dim Tneg As Byte                                      'indicate if temperature<0
         Dim Humsens_chksum As Byte

Dim Humiditys As String * 16
   Dim Temperatures As String * 16
      Dim Temp1 As String * 5
         Dim Temp_dht_offset As Integer
            Dim Humidity_dht_offset As Integer
               Dim Read_temp_flag As Bit

Dim Dht_error As Bit
   Dim Dht_error_counter As Byte

Temp_dht_offset = 00                                        ' Offset für DHT Temp (1°=10 1,1° = 11)
Humidity_dht_offset = 00                                    ' Offset für DHT Luftfeuchtigkeit (1% =10 1,1% = 11)
'_______________________________________________________________________________
' LCD Hintergrundbeleuchtung ###################################################
'-------------------------------------------------------------------------------
Config Portd.6 = Output
Portd.6 = 1
'_______________________________________________________________________________
'###############################################################################
'-------------------------------------------------------------------------------

'_______________________________________________________________________________
'Selbstcheck ###################################################################
'-------------------------------------------------------------------------------
Locate 1 , 1
Lcd " Selbstcheck... "
Locate 2 , 1
Lcd "Ueberpr{245}fe DHTxx"
   Gosub Read_dht_sensor
Waitms 300
If Dht_error = 1 Then
   Locate 2 , 1
   Lcd "Err Sensor DHTxx"
Else
   Locate 2 , 1
   Lcd "Sensor DHTxx OK "
End If
Wait 1
Cls
Timer1_counter = 5                                          ' Damit beim Starten nicht 5 Sekunden gewartet werden muss bis Werte angezeigt werden
'_______________________________________________________________________________
'Hauptschleife #################################################################
'-------------------------------------------------------------------------------
Do

   '____________________________________________________________________________
   'Wird jede Sekunde ausgeführt ###############################################
   '----------------------------------------------------------------------------
   If Sec_flag = 1 Then
      Sec_flag = 0
      Gosub Uhrzeit
      '_________________________________________________________________________
      'Wird alle 5 Sekunden ausgeführt #########################################
      '-------------------------------------------------------------------------
      Mod_return = Timer1_counter Mod 5
      If Mod_return = 0 Then
         Gosub Read_dht_sensor
      End If
      '_________________________________________________________________________
      'ENDE Wird alle 5 Sekunden ausgeführt ####################################
      '-------------------------------------------------------------------------
      Gosub Write_lcd_data_time
   End If

   '____________________________________________________________________________
   'Error DHTxx anzeigen #######################################################
   '----------------------------------------------------------------------------
   If Dht_error = 1 Then Gosub Dht_error_handling
   '____________________________________________________________________________
   'Lcd Anzeige Aktualisieren ##################################################
   '----------------------------------------------------------------------------
   If New_lcd_data_flag = 1 Then Gosub Write_lcd_data
   '____________________________________________________________________________
   'Timer1_counter bei 60 resetten #############################################
   If Timer1_counter > 59 Then Timer1_counter = 0
Loop
End
'_______________________________________________________________________________
'ENDE Hauptschleife ############################################################
'-------------------------------------------------------------------------------

'_______________________________________________________________________________
'Errorhandling DHTxx Sensor ####################################################
'-------------------------------------------------------------------------------
Dht_error_handling:
   Dht_error = 0
   Locate 2 , 1
   Lcd "Err Sensor DHTxx"
Return

'_______________________________________________________________________________
'Uhrzeit am Display ausgeben ###################################################
'-------------------------------------------------------------------------------
Write_lcd_data_time:
   If Double_point_flash = 1 Then
       Toggle Double_point_flash
       Double_point = ":"
   Elseif Double_point_flash = 0 Then
       Toggle Double_point_flash
       Double_point = " "
   End If

   Locate 1 , 12
   Lcd Format(stunde_s , "00") ; Double_point ; Format(minute_s , "00")       '; Double_point ; Format(sekunde_s , "00")
   'Locate 1 , 1
   'Lcd Dht_error_counter
Return
'_______________________________________________________________________________
'###############################################################################
'-------------------------------------------------------------------------------
Write_lcd_data:
   New_lcd_data_flag = 0
   Locate 2 , 1
   Lcd Format(temperatures , "#.#") ; Chr(223) ; "C" ; "   "

   If Humiditys > "99.9" Then
      'Humiditys = "1" + Humiditys 'Zum testen
      Locate 2 , 10
      Lcd " " ; Format(humiditys , "#.#") ; "%"
   Else
      Locate 2 , 10
      Lcd "  " ; Format(humiditys , "#.#") ; "%"
   End If
Return
'_______________________________________________________________________________
'DHTxx Sensor auslesen #########################################################
'-------------------------------------------------------------------------------
Read_dht_sensor:
 Humidityw = 0
 Temperaturew = 0
 Humsens_chksum = 0
 Count = 1

Config Pinc.3 = Output : Portc.3 = 0                        ' request data
Waitms 20                                                   ' wait 20 ms
Config Pinc.3 = Input                                       ' wait for data, receive data

   While Count < 43 And Dht_error = 0                       'collect 42 timings / signals

      While Tcnt0 < 100
         If Tcnt0 > 95 Then
            Incr Dht_error_counter
            Dht_error = 1
            Return
         End If
         If Pinc.3 = 1 And Tcnt0 = 0 Then Start Timer0
         If Pinc.3 = 0 And Tcnt0 > 0 Then
            Stop Timer0
            Timec = Tcnt0
            Tcnt0 = 100
         End If
      Wend
      Tcnt0 = 0
      Select Case Count

         Case 3 To 18
            X = 18 - Count
            If Timec > Min_time Then Toggle Humidityw.x

         Case 19 To 34
            X = 34 - Count
            If Timec > Min_time Then Toggle Temperaturew.x

         Case 34 To 42
            X = 42 - Count
            If Timec > Min_time Then Toggle Humsens_chksum.x

      End Select
      Incr Count

  Wend

'############################################################# Calculate Checksum and compare with trasnmitted value
If Dht_error = 0 Then
   Chksum = Low(humidityw) + High(humidityw)
   Chksum = Chksum + Low(temperaturew)
   Chksum = Chksum + High(temperaturew)

   If Chksum = Humsens_chksum Then

      'reset the temperature string
      Temperatures = ""
      If Temperaturew.15 = 1 Then                              'if this bit is set, temperatur is negative
       Temperaturew.15 = 0                                     'Reset the indicator bit for later conversion
       Temperatures = "-"                                      'Add a negative sign to the temperature string
      End If

      Humidityw = Humidityw + Humidity_dht_offset
      Humiditys = Str(humidityw)

      Temperaturew = Temperaturew + Temp_dht_offset
      Temperatures = Temperatures + Str(temperaturew)
      Dht_error_counter = 0
      New_lcd_data_flag = 1                                 'Dht_error_counter zurücksetzen
   End If
End If
Return

'_______________________________________________________________________________
'Sekunden hochzählen ###########################################################
'-------------------------------------------------------------------------------
Uhrzeit:
   If Sekunde < 59 Then
      Incr Sekunde
   Elseif Minute < 59 Then
      Incr Minute
      Sekunde = 0
   Elseif Stunde < 23 Then
      Incr Stunde
      Sekunde = 0
      Minute = 0
   Else
      Sekunde = 0
      Minute = 0
      Stunde = 0
   End If
   Sekunde_s = Str(sekunde)
   Minute_s = Str(minute)
   Stunde_s = Str(stunde)
Return
'_______________________________________________________________________________
'Timer1 - Wird im Sekundentakt ausgeführt ######################################
'-------------------------------------------------------------------------------
Isr_timer1:
   Timer1 = 34286
   Set Sec_flag
   Incr Timer1_counter
Return
 

Ü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)