Forum: Mikrocontroller und Digitale Elektronik Suche DHT22 Simulator


von Ruti (Gast)


Lesenswert?

Hallo Leute,

Um vorhandene Schaltungen auf ihre Funktion zu testen würde ich einen 
"DHT22" Simulator benötigen. Dieser sollte am digitalen Interface immer 
50% Feuchte und 30°C ausgeben. Inklusive CRC.

Hat jemand so ein Projekt schon in Angriff genommen?

von Ruti (Gast)


Lesenswert?

Sodala. Hab mir mal das Datenblatt durchgelsen.
Kann mir die folgende Vorgangsweise bestätigt werden?

Achtung: Pullup !!! 5,1K von SDA auf VCC

Die Kommunikation ist wie folgt (Vom Sensor aus gesehen):
Startsignal
Sensor antwortet
Sensor sendet
Sensor Übertragungsende

Startsignal:
uC zieht SDA auf LOW   min.800µs max.20ms typ. 1ms
uC lässt SDA auf HIGH  min.20µs max. 200µs typ. 30µs

Sensor antwortet:
Sensor zieht SDA auf LOW   min.75µs max.85µs typ. 80µs
Sensor lässt SDA auf HIGH  min.75µs max.85µs typ. 80µs

Sensor sendet:
Es wird SDA für jedes Bit zuerst auf low gezogen,
danach wird eine 1 oder 0 auf SDA gelegt.
Ob High oder Low entscheidet die Zeit.

Low ziehen vor jedem Bit:
min.48µs max.55µs typ. 50µs

Danach sofort High Bit:
min.68µs max.75µs typ. 70µs

Danach sofort Low Bit:
min.22µs max.30µs typ. 26µs

Aufbau der Bytes:
High humidity, Low humidity, High temp, Low temp, Parity byte

Das Parity byte ist eine AND Verknüfung zwischen den folgenden Bytes:
High humidity, Low humidity, High temp, Low temp

Für unsere Testübertragung werden folgende Werte angenommen:
High humidity  = &b0000 0010
Low humidity  = &b1001 0010
High temp    = &b0000 0001
Low temp    = &b0000 1101
Parity byte    = &b1010 0010
Das entspricht: 65.8%RH 26.9°C

Sensor Übertragungsende:
Sensor lässt SDA wieder auf High
min.45µs max.50µs typ. 55µs

von Ruti (Gast)


Lesenswert?

Nun habe ich folgenden Code:
Stimmt das Ende der Transmission, oder muss ich SDA nochmals auf low 
setzen?

program MyProject

sub Procedure InitHW
    CMCON = 0x07    'Set the comparators
    GPIO = 0        'Set all Pins to LOW Level
    TRISIO = 255    'Set all Pins to Input
    WPU = 0         'Disabel all Pullups
end sub

sub function Wait_For_Start as boolean
    dim TimeKeeper as integer     'This is the timeout counter
    Timekeeper = 0                'Set Timeout to zero
    TRISIO.2 = 1                  'Set SDA as Input
    if GPIO.2 = 1 then            'SDA is high. No Start
       Wait_For_Start = 0         'Timeout
       return
    end if
    while GPIO.2 = 0              'Wait until SDA Get High
      Delay_us(20)                'Wait
      inc(Timekeeper)             'Increment the timeoutcounter
      if timekeeper >= 1000 then  'Timeout
         Wait_For_Start = 0       'Timeout
         Return
      end if
      clrwdt                      'Clear Watchdog
    wend
    delay_us(20)                  'Security delay
    Wait_For_Start = 1
end sub

sub Procedure Response_To_Master
    GPIO.2 = 0                  'Set SDA State to low
    TRISIO.2 = 0                'Set SDA as Output
    delay_us(80)
    TRISIO.2 = 1                'Set SDA as Input
    delay_us(80)
end sub

sub Procedure Send_Bit (dim SDA_State as boolean)
    GPIO.2 = 0              'Set SDA State
    TRISIO.2 = 0            'Set SDA as Output
    delay_us(50)
    TRISIO.2 = 1            'Set SDA as Input
    if SDA_State = 1 then
       delay_us(70)         'Set time for High
    else
        delay_us(26)        'Set time for Low
    end if
end sub

sub Procedure Send_Byte (dim Byte_To_Send as byte)
    dim i as byte            'Helper for Loop
    for i = 7 to 0 step -1
        Send_Bit (Byte_to_send.i)
    next i
end sub

sub Procedure End_Of_Transmission
    'GPIO.2 = 0              'Set SDA State ????????????????????
    'TRISIO.2 = 0            'Set SDA as Output ????????????????
    delay_us(50)             'Let SDA high
    TRISIO.2 = 1             'Set SDA State
end sub

main:
     'The following values are set statical: 65.8%RH 26.9°C
     InitHW
     while TRUE                           'Endless loop
           if Wait_for_Start = 1 then     'Start detected
              Response_To_Master          'Response to master
              Send_Byte(%00000010)        'High Humidity
              Send_Byte(%10010010)        'Low Humidity
              Send_Byte(%00000001)        'High Temp
              Send_Byte(%00001101)        'Low Temp
              Send_Byte(%10100010)        'Parity
              End_Of_Transmission         'Set End of Transmission
           end if
           clrwdt                         'Clear Watchdog
     wend
end.

von Herzl (Gast)


Lesenswert?

Da wird sich kein Schwanz dafür interresieren.
Versuch es, ob der Code funktioniert oder lass es bleiben.
Basic ist ohnehin keine Programmiersprache.
Und so blöd leserlich aufgebaut.
Das kann man in ein paar Zeilen lösen.
Und nicht 1000ende Subs aufrufen.

von Supps (Gast)


Lesenswert?

Würde auch einen STM32 dafür benutzen. PIC nimmt doch keiner.

von Borislav B. (boris_b)


Lesenswert?

Herzl schrieb:
> Basic ist ohnehin keine Programmiersprache.

Wollen wir wetten?

von Fred R. (seek51)


Lesenswert?

Schaut eigentlich recht passabel aus.
Sicher kann man das "in einer Wurst" schreiben.
Aber so ist es doch übersichtlicher.
Und wenn man was am Timing ändern muss macht man das an einer Stelle.
Und nicht an 20 oder mehr.

Das mit dem End_Of_Tranmission kann ich leider auch nicht beantworten.
Must du probieren.

Ich würde eigentlich SDA auf Eingang umschalten, damit, falls der Master 
etwas falsch interpretiert und den SDA Bus aktiv auf LOW oder High setzt 
kein Kurzschluss entsteht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.