DHT11

Bavelt

Golden Member

Ik ben nu wat aan het oefenen met een vochtigheids-sensor. In dit geval heb ik een DHT11.

Die probeer ik uit te lezen.

Daarvoor heb ik een C-routine moeten omzetten naar Mikro Basic:

c code:



unsigned short Check_Response() {
  TMR1H = 0;                                  // Reset Timer1
  TMR1L = 0;
  TMR1ON_bit = 1;                             // Enable Timer1 module
  while(!DHT11_PIN && TMR1L < 100);           // Wait until DHT11_PIN becomes high (cheking of 80µs low time response)
  if(TMR1L > 99)                              // If response time > 99µS  ==> Response error
    return 0;                                 // Return 0 (Device has a problem with response)
  else {    TMR1H = 0;                        // Reset Timer1
    TMR1L = 0;
    while(DHT11_PIN && TMR1L < 100);          // Wait until DHT11_PIN becomes low (cheking of 80µs high time response)
    if(TMR1L > 99)                            // If response time > 99µS  ==> Response error
      return 0;                               // Return 0 (Device has a problem with response)
    else
      return 1;                               // Return 1 (response OK)
  }
}

Het werd dit:

pic basic code:


'====================================================================================================
Sub Function Check_Response() as Byte
'====================================================================================================
 TMR1H = 0                                        'Reset Timer1
 TMR1L = 0
 TMR1ON_bit = 1                                   'Enable Timer1 module
 While((Not DHT11_PIN) And (TMR1L < 100))         'Wait until DHT11_PIN becomes high (cheking of 80µs low time response)
  If(TMR1L > 99) Then                             'If response time > 99µS  ==> Response error
    Result = 0                                    'Return 0 (Device has a problem with response)
  Else
    TMR1H = 0                                     'Reset Timer1
    TMR1L = 0
    While(DHT11_PIN And (TMR1L < 100))            'Wait until DHT11_PIN becomes low (cheking of 80µs high time response)
      If(TMR1L > 99) Then                         'If response time > 99µS  ==> Response error
        Result = 0                                'Return 0 (Device has a problem with response)
      Else
        Result = 1                                'Response OK
      End If
    Wend
  End If
Wend

End Sub

Maar er komt altijd "OK" uit, of je er een sensor aan hangt of niet.

Heb ik iets niet goed 'vertaald'?

Fouten zijn het bewijs dat je het probeert..

Zijn de timer variablen etc het zelfde?

In de c code word de timer namelijk gereset en enabled etc. Wellicht beschouwd Mikro basic dit alleen als variable?

An amplifier is just a modulator for a power supply |Toffe Gebruiker
Jeroen

Moderator

In jouw code heb je de if opgenomen als onderdeel van de while loop, in de C-code staat de if voor de while loop.

Let ook op het verschil tussen return in C en het instellen van de Result variabele: een return stopt de uitvoering van de functie, bij het toekennen van een waarde aan Result gebeurt dat niet (als mijn Basic kennis niet te roestig is).

Bavelt

Golden Member

Op 31 mei 2021 12:39:39 schreef Jeroen:
In jouw code heb je de if opgenomen als onderdeel van de while loop, in de C-code staat de if voor de while loop.

Ik zie dat nog niet..
Welke if bedoel je dan?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 31 mei 2021 12:16:17 schreef Gerwin:
Zijn de timer variablen etc het zelfde?

In de c code word de timer namelijk gereset en enabled etc. Wellicht beschouwd Mikro basic dit alleen als variable?

Die zijn hetzelfde, ze verwijzen naar de Registers van de PIC16F1936 die ik gebruik.

Fouten zijn het bewijs dat je het probeert..

code:

while(!DHT11_PIN && TMR1L < 100);  

Let op de puntcomma op het eind.

Dat is de -lege- instruktie die steeds herhaald wordt.
Dus het programma wacht totdat DHT11_PIN Hoog wordt en TMR1L kleiner dan 100, en gaat dan verder naar de if op de volgende regel.

En zo ook bij de andere while.

PE9SMS

Special Member

Alletwee de while's zijn in de C code 1 regel lang. Er gebeurt dus niks binnen die while's, er wordt alleen net zo lang gewacht totdat er aan de voorwaarde wordt voldaan. Dus in basic is dat iets als

pic basic code:

While((Not DHT11_PIN) And (TMR1L < 100))
Wend

En dan verder met de if.
e: wat Kees al schreef dus :)

This signature is intentionally left blank.
Arco

Special Member

pic basic code:


'====================================================================================================
Sub Function Check_Response() as Byte
'====================================================================================================
 TMR1H = 0                                        'Reset Timer1
 TMR1L = 0
 TMR1ON_bit = 1                                   'Enable Timer1 module
 While((Not DHT11_PIN) And (TMR1L < 100)) Wend    'Wait until DHT11_PIN becomes high (cheking of 80µs low time response)
 If(TMR1L > 99) Then                              'If response time > 99µS  ==> Response error
   Result = 0                                     'Return 0 (Device has a problem with response)
 Else
   TMR1H = 0                                      'Reset Timer1
   TMR1L = 0
   While(DHT11_PIN And (TMR1L < 100)) Wend        'Wait until DHT11_PIN becomes low (cheking of 80µs high time response)
   If(TMR1L > 99) Then                            'If response time > 99µS  ==> Response error
     Result = 0                                   'Return 0 (Device has a problem with response)
   Else
     Result = 1                                   'Response OK
   End If
 End If
End Sub
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 31 mei 2021 13:26:33 schreef deKees:

code:

while(!DHT11_PIN && TMR1L < 100);  

Let op de puntcomma op het eind.

Dat is de -lege- instruktie die steeds herhaald wordt.
Dus het programma wacht totdat DHT11_PIN Hoog wordt en TMR1L kleiner dan 100, en gaat dan verder naar de if op de volgende regel.

En zo ook bij de andere while.

Ja, dat was het! :)

Ik dacht dat een While in C werd afgesloten met een '} maar is dit niet zo.

De code is nu:

pic basic code:

'====================================================================================================
Sub Function Check_Response() as Byte
'====================================================================================================
 TMR1H = 0                                        'Reset Timer1
 TMR1L = 0
 TMR1ON_bit = 1                                   'Enable Timer1 module
 While((Not DHT11_PIN) And (TMR1L < 100)) Wend    'Wait until DHT11_PIN becomes high (cheking of 80µs low time response)
 If(TMR1L > 99) Then                              'If response time > 99µS  ==> Response error
   Result = 0                                     'Return 0 (Device has a problem with response)
   Exit
 Else
   TMR1H = 0                                      'Reset Timer1
   TMR1L = 0
   While(DHT11_PIN And (TMR1L < 100)) Wend        'Wait until DHT11_PIN becomes low (cheking of 80µs high time response)
   If(TMR1L > 99) Then                            'If response time > 99µS  ==> Response error
     Result = 0                                   'Return 0 (Device has a problem with response)
     Exit
   Else
     Result = 1                                   'Response OK
     Exit
   End If
 End If
End Sub

Ik heb ook een exit toegevoegd nadat het rersult is gevuld, dan weet je zeker dat de routine wordt verlaten..

Update: nadat ik dit poste, zag ik dat Arco hetzelfde had geconstateerd.. :)

Vraag is dan of de result = 0 ook betekent dat de routine wordt verlaten.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik zie het al; de exit hoeft niet omdat er vanzelf uit de loop wordt gestapt...

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het kan volgens mij nog veel korter... ;)

pic basic code:


  Result = (TMR1L < 100)        
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het blijft even worstelen met dat C..

Sta me toe nog een 'conversietje'..

c code:

unsigned short Read_Data(unsigned short* dht_data) {
  short i;
  *dht_data = 0;
  for(i = 0; i < 8; i++){
    TMR1H = 0;                                // Reset Timer1
    TMR1L = 0;
    while(!DHT11_PIN)                         // Wait until DHT11_PIN becomes high
      if(TMR1L > 100) {                       // If low time > 100  ==>  Time out error (Normally it takes 50µs)
        return 1;
      }
    TMR1H = 0;                                // Reset Timer1
    TMR1L = 0;
    while(DHT11_PIN)                          // Wait until DHT11_PIN becomes low
      if(TMR1L > 100) {                       // If high time > 100  ==>  Time out error (Normally it takes 26-28µs for 0 and 70µs for 1)
        return 1;                             // Return 1 (timeout error)
      }
     if(TMR1L > 50)                           // If high time > 50  ==>  Sensor sent 1
       *dht_data |= (1 << (7 - i));           // Set bit (7 - i)
  }
  return 0;                                   // Return 0 (data read OK)
}

Daarvan maakte ik:

pic basic code:


'====================================================================================================
Sub Function Read_Data(Dim Dht_Data as byte) As Byte
'====================================================================================================
 Dim i1 As byte
 Dht_data = 0

 For i1 = 0 to 7
   TMR1H = 0                                     'Reset Timer1
   TMR1L = 0
   While(NOT DHT11_PIN)                          'Wait until DHT11_PIN becomes high
     If(TMR1L > 100) Then                        'If low time > 100  ==>  Time out error (Normally it takes 50µs)
       Result = 1
       Exit
     End If
   Wend
   TMR1H = 0                                     'Reset Timer1
   TMR1L = 0

 While(DHT11_PIN)                                'Wait until DHT11_PIN becomes low
   If(TMR1L > 100) Then                          'If high time > 100  ==>  Time out error (Normally it takes 26-28µs for 0 and 70µs for 1)
     Result = 1                                  'Return 1 (timeout error)
     Exit
   End If
   If(TMR1L > 50) Then                           'If high time > 50  ==>  Sensor sent 1
     Dht_data =  (1 << (7 - i1))
   End If
 Wend
 Result = 0                                      'Data read OK
Next i1
End Sub

Het C-statement *dht_data |= (1 << (7 - i)); // Set bit (7 - i)

snapte ik ook niet echt. Wat doet die * en de |= daar nu?

En ook hier: zit die Wend wel goed?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

c code:


       *dht_data |= (1 << (7 - i));           // Set bit (7 - i)

is

pic basic code:


  Dht_data = Dht_data Or (1<<(7-i))

Sterretje is een pointer (in MB is dat ByRef)

pic basic code:


Sub Function Read_Data(ByRef Dht_Data as byte) As Byte
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 31 mei 2021 14:41:07 schreef Arco:

pic basic code:


Sub Function Read_Data(ByRef Dht_Data as byte) As Byte

Dat pikt de compiler niet. Die wil daar Dim zien (zegt-ie)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Klopt, was weggevallen. Moet Dim ByRef zijn...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Voegt die 'Byref' dan wat toe in MB?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

ByRef is By Reference: Je geeft het adres door van een variabele i.p.v. de inhoud. De data op dat adres wordt dan gebruikt en eventueel gewijzigd.
Default is ByVal (By Value). De data wordt dan gewoon doorgegeven via een tijdelijke variabele.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Jeroen

Moderator

Op 31 mei 2021 14:22:21 schreef Bavelt:
En ook hier: zit die Wend wel goed?

Nee, de if(TMR1L > 50) staat buiten de while loop, want die while loop heeft geen accolades. Dat betekent dat alleen het eerstvolgende statement (if(TMR1L > 100)) onderdeel is van de while loop.

Het inconsistent gebruik van inspring-spaties in de C-code helpt niet echt mee met begrijpbaarheid. Overigens gebruik ik altijd accolades, ook als ik maar 1 statement binnen een if, while, for, etc. heb staan. Dat is een stuk minder verwarrend.

Bavelt

Golden Member

Nu ik toch bezig ben met dat C:

c code:

Read_Data(&RH_byte1)

Wat doet die & daar in de Read? Is dat soms 'hex'?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Heb ik gedownload als naslagwerk!

Maar voor mijn MB-programma hoef ik daar dus verder geen rekening mee te houden omdat er al de Byref staat in de function Read_Data. Toch?

De routine:

pic basic code:

'====================================================================================================
Sub Function Read_Data(Dim Byref Dht_Data as byte) As Byte
'====================================================================================================
 Dim i1 As byte
 Dht_data = 0

 For i1 = 0 to 7
   TMR1H = 0                                     'Reset Timer1
   TMR1L = 0
   While(NOT DHT11_PIN)                          'Wait until DHT11_PIN becomes high
     If(TMR1L > 100) Then                        'If low time > 100  ==>  Time out error (Normally it takes 50µs)
       Result = 1
       latb.4 = 1
       Exit
     End If
   Wend
   TMR1H = 0                                     'Reset Timer1
   TMR1L = 0

 While(DHT11_PIN)                                'Wait until DHT11_PIN becomes low
   If(TMR1L > 100) Then                          'If high time > 100  ==>  Time out error (Normally it takes 26-28µs for 0 and 70µs for 1)
     Result = 1                                  'Return 1 (timeout error)
     Exit
   End If
 Wend
   If(TMR1L > 50) Then                           'If high time > 50  ==>  Sensor sent 1
      Dht_data = Dht_data Or (1<<(7-i1))
   End If
Next i1

Result = 0                                      'Data read OK
End Sub

Ik krijg wel meteen een Timeout error (te zien aan LATB.4). Zit dus iets nog niet goed.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

ByRef is eigenlijk dat je een global gedeclareerde variabele meegeeft aan een routine. De routine kan dus rechtstreeks die variable 'bewerken'

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Ik dacht dat een While in C werd afgesloten met een '} maar is dit niet zo.

Nee, een while in C geldt in principe alleen voor een enkele statement die direct op de while volgt. Dat kan een normaal statement zijn, afgesloten met een punt-comma, of een lege statement (alleen puntcomma). Maar je kunt ook een compound statement maken door een groep statements samen te pakken in een set accolates. Een stel accolades met nix ertussen kan ook.

Wat doet die & daar in de Read? Is dat soms 'hex'?

Die '&' is de C-methode om By-reference aan te geven. Dan krijgt de procedure niet de waarde van RH_Byte1, maar het adres van de variabele zodat de waarde door de procedure kan worden gewijzigd.

Bavelt

Golden Member

Nou, het is allemaal keurig gelukt! :)

Daarom hierbij de volledige code. Wie weet heeft iemand er iets aan (er zijn immers vrij weinig publicaties met Mikro Basic).

Sensor: DHT11
Processor: PIC16F1936
Frequentie: 8 Mhz Intern
Prog. taal: Mikro Basic
Display: Oled 0,96" SPI

pic basic code:


 Program Test1936
'====================================================================================================
' Project name: Test1936
' MCU:          PIC16F1936
' Oscillator:   Internal 8 MHz
' Display: Oled SPI 0,96"
' SDO:          PORT C.5                 Pin 16
' SCK:          PORT C.3                 Pin 14
' D/C:          LAT C.0                  Pin 11
' RES:          LAT C.1                  Pin 12
' DHT11         PORTB.0                  Pin 21
'====================================================================================================

Const Char6x8 As Byte[570] = (       'Character table
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  ' sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,  ' !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,  ' "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,  ' #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,  ' $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,  ' %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,  ' &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,  ' '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,  ' (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,  ' )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,  ' *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,  ' +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,  ' ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,  ' -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,  ' .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,  ' /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,  ' 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,  ' 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,  ' 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,  ' 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,  ' 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,  ' 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,  ' 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,  ' 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,  ' 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,  ' 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,  ' :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,  ' ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,  ' <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,  ' =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,  ' >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,  ' ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,  ' @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,  ' A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,  ' B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,  ' C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,  ' D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,  ' E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,  ' F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,  ' G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,  ' H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,  ' I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,  ' J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,  ' K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,  ' L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,  ' M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,  ' N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,  ' O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,  ' P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,  ' Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,  ' R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,  ' S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,  ' T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,  ' U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,  ' V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,  ' W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,  ' X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,  ' Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,  ' Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,  ' [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,  ' \
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,  ' ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,  ' ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,  ' _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,  ' '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,  ' a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,  ' b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,  ' c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,  ' d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,  ' e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,  ' f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,  ' g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,  ' h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,  ' i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,  ' j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,  ' k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,  ' l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,  ' m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,  ' n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,  ' o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,  ' p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,  ' q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,  ' r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,  ' s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,  ' t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,  ' u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,  ' v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,  ' w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,  ' x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,  ' y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,  ' z
0x00, 0x10, 0x6C, 0x82, 0x00, 0x00,  ' {
0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,  ' |
0x00, 0x00, 0x00, 0x82, 0x6C, 0x10,  ' }
0x14, 0x14, 0x14, 0x14, 0x14, 0x14)  ' horiz lines

Dim D_C         As sBit at LATC.0                 'Data/Command    Pin 11
    ClockPin    As sbit at PORTC.3                'Clock           Pin 14
    Datapin     As sbit at PORTC.5                'SDO             Pin 16
    RES         As sbit at LATC.1                 'RESET           Pin 12
    DHT11_PIN   As sbit at PORTB.0                'DHT11 Sensor    Pin 21
    DHT11_PIN_Direction as sbit at TRISB0_bit

    T_byte1     As Byte
    T_byte2     As Byte
    RH_byte1    As Byte
    RH_byte2    As Byte
    CheckSum    As Byte
    
    Temperature As String[20]
    Humidity    As String[20]

'====================================================================================================
Sub Procedure Lcd_WrCmd(Dim pCmd As Byte)         'Write Command to display
'====================================================================================================
  D_C = 0
  Spi1_Write(pCmd)
End Sub

'====================================================================================================
Sub Procedure Lcd_WrDat(Dim pDat As Byte)         'Write Data to display
'====================================================================================================
  Dim lCnt As Byte
  D_C = 1
  Spi1_Write(pDat)
End Sub

'====================================================================================================
Sub Procedure Lcd_SetPos(Dim px, py as Byte)      'Set write position on display
'====================================================================================================
  Delay_us(1)
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd((px  >> 4) Or 0x10)
  Lcd_WrCmd((px And 0x0F))
  delay_us(1)
End Sub

'====================================================================================================
Sub Procedure Lcd_Fill(Dim pFill As Byte)         'Fill display with character pFill
'====================================================================================================
  Dim lx, ly As Byte
  For ly = 0 To 7
    Lcd_WrCmd(0xB0+ly)
    Lcd_WrCmd(0x00)
    Lcd_WrCmd(0x10)
    For lx = 0 to 127
      Lcd_WrDat(pFill)
    Next lx
  Next ly
End Sub

'====================================================================================================
Sub Procedure Lcd_Char_6x8(Dim px, py, pchar As Byte)           'Write one character
'====================================================================================================
  Dim lIndex As Word
  Lcd_SetPos(px, py)
  lIndex = pChar - 0x20
  lIndex = (lIndex << 2) + (lIndex << 1)                        'Multiply lIndex by 6
  Lcd_WrDat(Char6x8[lIndex+0])
  Lcd_WrDat(Char6x8[lIndex+1])
  Lcd_WrDat(Char6x8[lIndex+2])
  Lcd_WrDat(Char6x8[lIndex+3])
  Lcd_WrDat(Char6x8[lIndex+4])
  Lcd_WrDat(Char6x8[lIndex+5])
End Sub

'====================================================================================================
Sub Procedure Lcd_String_6x8(Dim px, py As Byte, Dim ByRef pDisp As String)
'====================================================================================================
  Dim lLen, lCnt As Byte
  lLen = Length(pDisp)
  For lCnt = 0 To (lLen-1)
    If px > 127 Then px = 0 py = py+1 End If
    Lcd_Char_6x8(px, py, pDisp[lCnt])
    px = px + 6
  Next lCnt
End Sub

'====================================================================================================
Sub Procedure Display_Init()
'====================================================================================================
  Lcd_WrCmd(0xAF)                                 'Turn OLED panel off
  Lcd_WrCmd(0xA8)                                 'Multiplex ratio set to
  Lcd_WrCmd(0x3F)                                 '63
  Lcd_WrCmd(0xD3)                                 'Display offset RAM counter
  Lcd_WrCmd(0x00)                                 'none
  Lcd_WrCmd(0x40)                                 'Start line address
  Lcd_WrCmd(0xA1)                                 'Set segment remap rotation to left
  Lcd_WrCmd(0xC8)                                 'Common output scan direction
  Lcd_WrCmd(0xDA)                                 'Common signals pad
  Lcd_WrCmd(0x12)                                 'value
  Lcd_WrCmd(0x81)                                 'Contrast control
  Lcd_WrCmd(0xFF)                                 'value
  Lcd_WrCmd(0xA4)
  Lcd_WrCmd(0xA6)                                 'Normal display
  Lcd_WrCmd(0xD5)                                 'Clock ratio:oscillator frequency
  Lcd_WrCmd(0x80)                                 'oooo:rrrr
  Lcd_WrCmd(0x8D)
  Lcd_WrCmd(0x14)
  Lcd_WrCmd(0x00)                                 'Set lower column address
  Lcd_WrCmd(0x10)                                 'Set higher column address
  Lcd_WrCmd(0xD9)                                 '15 clocks, discharge 1 clock
  Lcd_WrCmd(0xF1)                                 'dddd:pppp
  Lcd_WrCmd(0xDB)                                 'Common output voltage
  Lcd_WrCmd(0x40)                                 'level
  Lcd_WrCmd(0x20)                                 'Addressing mode
  Lcd_WrCmd(0x02)                                 'value
  Lcd_WrCmd(0xAE)                                 'Turn OLED panel off
End Sub

'====================================================================================================
 Sub Procedure Blink (Dim Dnum as Integer)        'Test purpose - Led Blink
'====================================================================================================
 Dim k1 As byte
 For k1 = 1 to Dnum
    LATB.4 = 1
    Delay_Ms(500)
     LATB.4 = 0
    Delay_Ms(500)
 Next k1
 End Sub

'====================================================================================================
Sub Procedure Start_Signal()
'====================================================================================================
 DHT11_PIN_Direction = 0                          'Configure connection pin as output
 DHT11_PIN = 0                                    'Connection pin output low
 Delay_ms(25)                                     'Wait 25 ms
 DHT11_PIN = 1                                    'Connection pin output high
 Delay_us(25)                                     'Wait 25 us
 DHT11_PIN_Direction = 1                          'Configure connection pin as input
End Sub

'====================================================================================================
Sub Function Check_Response() as Byte
'====================================================================================================
 TMR1H = 0                                        'Reset Timer1
 TMR1L = 0
 TMR1ON_bit = 1                                   'Enable Timer1 module
 While((Not DHT11_PIN) And (TMR1L < 100)) Wend    'Wait until DHT11_PIN becomes high (cheking of 80µs low time response)
 If(TMR1L > 99) Then                              'If response time > 99µS  ==> Response error
   Result = 0                                     'Return 0 (Device has a problem with response)
 Else
   TMR1H = 0                                      'Reset Timer1
   TMR1L = 0
   While(DHT11_PIN And (TMR1L < 100)) Wend        'Wait until DHT11_PIN becomes low (cheking of 80µs high time response)
   If(TMR1L > 99) Then                            'If response time > 99µS  ==> Response error
     Result = 0                                   'Return 0 (Device has a problem with response)
   Else
     Result = 1                                   'Response OK
   End If
 End If
End Sub

'====================================================================================================
Sub Function Read_Data(Dim Byref Dht_Data as byte) As Byte
'====================================================================================================
 Dim i1 As byte
 Dht_data = 0

 For i1 = 0 to 7
   TMR1H = 0                                      'Reset Timer1
   TMR1L = 0
   While(NOT DHT11_PIN)                           'Wait until DHT11_PIN becomes high
     If(TMR1L > 100) Then                         'If low time > 100  ==>  Time out error
       Result = 1                                 'Normally takes 50µs
       Exit
     End If
   Wend
   TMR1H = 0                                      'Reset Timer1
   TMR1L = 0

 While(DHT11_PIN)                                 'Wait until DHT11_PIN becomes low
   If(TMR1L > 100) Then                           'If high time > 100  ==>  Time out error (Normally it takes 26-28µs for 0 and 70µs for 1)
     Result = 1                                   'Return 1 (timeout error)
     Exit
   End If
 Wend
   If(TMR1L > 50) Then                            'If high time > 50  ==>  Sensor sent 1
      Dht_data = Dht_data Or (1<<(7-i1))
   End If
Next i1

Result = 0                                        'Data read OK
End Sub

'====================================================================================================
Main:                                             'Main program
'====================================================================================================
  TRISB =   %00000001                             'PORTB.0 Input (DHT11 Sensor)
  TRISC =   %00101000                             'PORT C.3 and C.5 Input (SPI)
  OSCCON =  %01110000                             '8Mhz internal

  ANSELB = 0                                      'Configure all PORTB pins as digital
  T1CON = %00010000                               'Set Timer1 clock source to internal with 1:2 prescaler (Timer1 clock = 1MHz)
  TMR1H = 0                                       'Reset Timer1
  TMR1L = 0

  RES = 0                                         'Reset and Init Display
  Delay_ms(10)
  RES = 1

  SPI1_Init()
  Delay_ms(100)
  Display_Init()
  Delay_ms(100)

  Lcd_WrCmd(0xAF)                                 'Turn OLED panel on
  LCD_Setpos(0,0)                                 'Set start Position
  LCD_Fill(0x00)                                  'Blank Screen

  While True

  Start_Signal()                                  'Send start signal to the sensor

  If(Check_Response()) Then                       'Check response from sensor (If OK start reding Humidity and Temperature data)
    If(Read_Data(RH_byte1) Or Read_Data(RH_byte2) Or   'Read data from the DHT11 sensor
       Read_Data(T_byte1)  Or  Read_Data(T_byte2) Or   'and check time out errors
       Read_Data(Checksum)) Then
       Lcd_String_6x8(0,0,"Time Out!           ")
    Else
      If(CheckSum = ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) And 0xFF)) Then
        Temperature = "Temp:    ,          "
        Humidity    = "Humi:    ,          "
        Temperature[7]  = T_Byte1/10  + 48
        Temperature[8]  = T_Byte1 Mod 10  + 48
        Temperature[10] = T_Byte2/10  + 48
        Humidity[7]     = RH_Byte1/10 + 48
        Humidity[8]     = RH_Byte1 Mod 10 + 48
        Humidity[10]    = RH_Byte2/10 + 48
        Lcd_String_6x8(0,2, Temperature)
        Rtrim(Humidity)
        Lcd_String_6x8(0,6, Humidity + "%")
      Else
        Lcd_String_6x8(0,0, "Checksum Error      ")     'Checksum error
      End If
    End If
 Else
     Lcd_String_6x8(0,0, "No Response")           'No Response from Sensor
 End If

 TMR1ON_bit = 0                                   'Disable Timer1 module
 Delay_ms(1500)                                   'Wait 1,5 second
 Wend
End.
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik had toevallig die DHT11. Zijn er wellicht nog andere gangbare typen
die vochtigheid en temperatuur leveren?

Ik zag al wel de DHT22, lijkt me een beetje hetzelfde (iets duurder).

Fouten zijn het bewijs dat je het probeert..