Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat dengan menggunakan sensor suhu dan kelembaban DHT22 kemudian dilengkapi dengan RTC DS1307 untuk menampilkan waktunya. program yang digunakan adalah Bascom AVR, mikrokontroller yang dipakai adalah ATMega16 dengan interface pada lcd 16x2. jadi alat ini hanya mendeteksi suhu dan kelembaban serta menampilkan waktunya secara real time, saat suhu tertentu maka relay 1 akan on begitu pula dengan kelembaban, saat kelembaban tertentu maka akan menghidupkan relay 2. untuk lebih jelasnya berikut adalah skema dan programnya.
a. Minimum System ATMega
b. Sensor DHT22 Suhu dan Kelembaban
c. RTC DS1307
d. LCD 16x2
e. Program Bascom AVR DHT22 + RTC DS1307 + Relay
$regfile = "m32def.dat"
$crystal = 8000000
Config Lcdpin = Pin , Rs = Porta.7 , E = Porta.6 , Db4 = Portc.2
Config Lcdpin = Pin , Db5 = Portc.4 , Db6 = Portc.5 , Db7 = Portc.6
Config Lcd = 16 * 2
Declare Sub Get_th(t As Word , H As Word)
Config Serialin = Buffered , Size = 128
Config Serialout = Buffered , Size = 128
'czujnik podlaczony do PortD.6
Dht_put Alias Portd.6
Dht_get Alias Pind.6
Dht_io_set Alias Ddrd.6
Cls
Cursor Off
Dim Crc As Byte 'zmienna do przechowywania bajtów parzystosci
Dim Mybyte As Byte 'zmienna do obliczania bitu parzystosci
Dim Sensor_data As String * 40 'tutaj beda zapisywac sie dane z czujnika
Dim Count As Byte
Dim T As Word 'zmienna do przechowywania temperatury
Dim H As Word 'zmienna do przechowywania wilgotnosci
Dim S16 As String * 16 'zmienna do obliczania odebranych bitów
Dim Ti As Byte 'zmienna do przechowywania dziesietnej temperatury
Dim Hi As Byte 'zmienna do przechowywania dziesietnej wilgotnosci
Enable Interrupts
Config Sda = Portc.1
Config Scl = Portc.0
Const Ds1307w = &HD0
Const Ds1307r = &HD1
Dim Oke As Integer
Dim Mark As Byte
Dim _sec As Byte
Dim _min As Byte
Dim _hour As Byte
Dim _day As Byte
Dim _month As Byte
Dim _year As Byte
Dim _weekday As Byte
Dim Sa(3) As String * 2
Dim Sb(3) As String * 2
Declare Sub Getdatetime
Declare Sub Settime
Declare Sub Getsec
Declare Sub Disptime
Declare Sub Dispdate
Declare Sub Format_00
Declare Sub Setdate
Declare Sub Subset
Dim I As Byte
Dim Flagset As Bit '0 = Waktu, 1 = Tanggal
Dim Flagreset As Bit
Dim Line1 As String * 1
Dim Weekday As Byte
Dim Jam_puluhan As Integer
Dim Jam_satuan As Integer
Dim Min_puluhan As Integer
Dim Min_satuan As Integer
Dim Sec_puluhan As Integer
Dim Sec_satuan As Integer
'_sec = 00
'_hour = 14
'_min = 59
'Settime
'_day = 28
'_month = 11
'_year = 15
'Setdate
I = 13
Line1 = Chr(13)
Ddrb.0 = 1 'kipas
Ddrb.1 = 1 'air
Do
Getdatetime
Upperline
Disptime
Dht_io_set = 1
Dht_put = 1
Wait 5
Call Get_th(t , H)
Cls
Locate 2 , 1
Lcd "T:" ; T ; "c"
Locate 2 , 10
Lcd "H:" ; H ; "%"
If H <= 60 Then
Portb.1 = 0
Elseif H > 60 Then
Portb.1 = 1
End If
If T >= 35 Then
Portb.0 = 0
Elseif T < 35 Then
Portb.0 = 1
End If
Loop
Sub Get_th(t As Word , H As Word)
Count = 0
Sensor_data = ""
Dht_io_set = 1 'robimy wyjscie z PD.6
Dht_put = 0 'ustawic magistrale w stan LOW
Waitms 1 'odczekac co najmniej 18ms
Dht_put = 1 'zwolnic magistrale
Waitus 20
Dht_io_set = 0 'robimy wejscie z PD.6
Waitus 40 'odczekaj 40 ms
If Dht_get = 1 Then 'jesli jest jeszcze jeden, ???? ?? ??? ?? ???????? 1
H = 1 'oznacza ze czujnik nie odpowiedzial
Exit Sub 'konczymy podprogram
End If
'jesli czujnik odpowiedzial i wyciagnal magistrale do ziemi kontynuujemy prace
Waitus 80 'czekamy jeszcze 80ms
If Dht_get = 0 Then 'jesli na linii jest nadal 0
H = 2 'oznacza czujnik zwariowal
Exit Sub 'konczymy podprogram
End If
'jesli wszystko pójdzie dobrze i czujnik zareagowal prawidlowo, mozemy kontynuowac
While Dht_get = 1 : Wend 'czekamy, az magistrala pokazuje 1
Do 'zaczynamy przyjmowac 40-bitowe dane
While Dht_get = 0 : Wend 'czekamy na ustawienie magistrali w stan 0
Waitus 30 'po wystapieniu stamu 0 czekac 30 ms
If Dht_get = 1 Then 'jesli na szynie 1
Sensor_data = Sensor_data + "1" 'zapisujemy do zmiennej ta ?????????? ? ?????????? ??? ???????
While Dht_get = 1 : Wend 'i czekamy az nadajnik wysle kolejny bit
Else 'w przeciwnym razie, jesli tam jest 0
Sensor_data = Sensor_data + "0" 'zapisujem je do zmiennej
End If
Incr Count 'zwiekszamy licznik
Loop Until Count = 40 'Powtarzaj te czynnosc dopóki licznik osiagnie liczbe 40
Dht_io_set = 1
Dht_put = 1
'zaczynamy rozkladac otrzymane dane
S16 = Left(sensor_data , 16)
H = Binval(s16)
H = H / 10
Hi = H Mod 10
S16 = Mid(sensor_data , 17 , 16)
T = Binval(s16)
T = T / 10
Ti = T Mod 10
S16 = Right(sensor_data , 8)
Crc = Binval(s16)
'test sumy kontrolnej
Mybyte = T + H 'dodajemy wartosci temperatury i wilgotnosci
If Mybyte <> Crc Then 'jesli suma kontrolna sie nie zgadza
Lcd "error" 'Oznacza to, ze dane nie sa poprawne
End If
End Sub
Sub Getdatetime:
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' start address in 1307
I2cstart ' Generate start code
I2cwbyte Ds1307r ' send address
I2crbyte _sec , Ack
I2crbyte _min , Ack ' MINUTES
I2crbyte _hour , Ack ' Hours
I2crbyte _weekday , Ack ' Day of Week
I2crbyte _day , Ack ' Day of Month
I2crbyte _month , Ack ' Month of Year
I2crbyte _year , Nack ' Year
I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
_day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
End Sub
Sub Settime:
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' starting address in 1307
I2cwbyte _sec ' Send Data to SECONDS
I2cwbyte _min ' MINUTES
I2cwbyte _hour ' Hours
I2cstop
End Sub
Sub Setdate
_day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 4 ' starting address in 1307
I2cwbyte _day ' Send Data to SECONDS
I2cwbyte _month ' MINUTES
I2cwbyte _year ' Hours
I2cstop
End Sub
Sub Dispdate
Sa(1) = Str(_day)
Sa(2) = Str(_month)
Sa(3) = Str(_year)
Format_00
Lcd "Date: " ; Sb(1) ; "-" ; Sb(2) ; "-" ; Sb(3)
End Sub
Sub Disptime
Sa(1) = Str(_hour)
Sa(2) = Str(_min)
Sa(3) = Str(_sec)
Format_00
Lcd "Time: " ; Sb(1) ; ":" ; Sb(2) ; ":" ; Sb(3)
End Sub
Sub Format_00
For I = 1 To 3 Step 1
Sb(i) = Format(sa(i) , "00")
Next I
End Sub
$crystal = 8000000
Config Lcdpin = Pin , Rs = Porta.7 , E = Porta.6 , Db4 = Portc.2
Config Lcdpin = Pin , Db5 = Portc.4 , Db6 = Portc.5 , Db7 = Portc.6
Config Lcd = 16 * 2
Declare Sub Get_th(t As Word , H As Word)
Config Serialin = Buffered , Size = 128
Config Serialout = Buffered , Size = 128
'czujnik podlaczony do PortD.6
Dht_put Alias Portd.6
Dht_get Alias Pind.6
Dht_io_set Alias Ddrd.6
Cls
Cursor Off
Dim Crc As Byte 'zmienna do przechowywania bajtów parzystosci
Dim Mybyte As Byte 'zmienna do obliczania bitu parzystosci
Dim Sensor_data As String * 40 'tutaj beda zapisywac sie dane z czujnika
Dim Count As Byte
Dim T As Word 'zmienna do przechowywania temperatury
Dim H As Word 'zmienna do przechowywania wilgotnosci
Dim S16 As String * 16 'zmienna do obliczania odebranych bitów
Dim Ti As Byte 'zmienna do przechowywania dziesietnej temperatury
Dim Hi As Byte 'zmienna do przechowywania dziesietnej wilgotnosci
Enable Interrupts
Config Sda = Portc.1
Config Scl = Portc.0
Const Ds1307w = &HD0
Const Ds1307r = &HD1
Dim Oke As Integer
Dim Mark As Byte
Dim _sec As Byte
Dim _min As Byte
Dim _hour As Byte
Dim _day As Byte
Dim _month As Byte
Dim _year As Byte
Dim _weekday As Byte
Dim Sa(3) As String * 2
Dim Sb(3) As String * 2
Declare Sub Getdatetime
Declare Sub Settime
Declare Sub Getsec
Declare Sub Disptime
Declare Sub Dispdate
Declare Sub Format_00
Declare Sub Setdate
Declare Sub Subset
Dim I As Byte
Dim Flagset As Bit '0 = Waktu, 1 = Tanggal
Dim Flagreset As Bit
Dim Line1 As String * 1
Dim Weekday As Byte
Dim Jam_puluhan As Integer
Dim Jam_satuan As Integer
Dim Min_puluhan As Integer
Dim Min_satuan As Integer
Dim Sec_puluhan As Integer
Dim Sec_satuan As Integer
'_sec = 00
'_hour = 14
'_min = 59
'Settime
'_day = 28
'_month = 11
'_year = 15
'Setdate
I = 13
Line1 = Chr(13)
Ddrb.0 = 1 'kipas
Ddrb.1 = 1 'air
Do
Getdatetime
Upperline
Disptime
Dht_io_set = 1
Dht_put = 1
Wait 5
Call Get_th(t , H)
Cls
Locate 2 , 1
Lcd "T:" ; T ; "c"
Locate 2 , 10
Lcd "H:" ; H ; "%"
If H <= 60 Then
Portb.1 = 0
Elseif H > 60 Then
Portb.1 = 1
End If
If T >= 35 Then
Portb.0 = 0
Elseif T < 35 Then
Portb.0 = 1
End If
Loop
Sub Get_th(t As Word , H As Word)
Count = 0
Sensor_data = ""
Dht_io_set = 1 'robimy wyjscie z PD.6
Dht_put = 0 'ustawic magistrale w stan LOW
Waitms 1 'odczekac co najmniej 18ms
Dht_put = 1 'zwolnic magistrale
Waitus 20
Dht_io_set = 0 'robimy wejscie z PD.6
Waitus 40 'odczekaj 40 ms
If Dht_get = 1 Then 'jesli jest jeszcze jeden, ???? ?? ??? ?? ???????? 1
H = 1 'oznacza ze czujnik nie odpowiedzial
Exit Sub 'konczymy podprogram
End If
'jesli czujnik odpowiedzial i wyciagnal magistrale do ziemi kontynuujemy prace
Waitus 80 'czekamy jeszcze 80ms
If Dht_get = 0 Then 'jesli na linii jest nadal 0
H = 2 'oznacza czujnik zwariowal
Exit Sub 'konczymy podprogram
End If
'jesli wszystko pójdzie dobrze i czujnik zareagowal prawidlowo, mozemy kontynuowac
While Dht_get = 1 : Wend 'czekamy, az magistrala pokazuje 1
Do 'zaczynamy przyjmowac 40-bitowe dane
While Dht_get = 0 : Wend 'czekamy na ustawienie magistrali w stan 0
Waitus 30 'po wystapieniu stamu 0 czekac 30 ms
If Dht_get = 1 Then 'jesli na szynie 1
Sensor_data = Sensor_data + "1" 'zapisujemy do zmiennej ta ?????????? ? ?????????? ??? ???????
While Dht_get = 1 : Wend 'i czekamy az nadajnik wysle kolejny bit
Else 'w przeciwnym razie, jesli tam jest 0
Sensor_data = Sensor_data + "0" 'zapisujem je do zmiennej
End If
Incr Count 'zwiekszamy licznik
Loop Until Count = 40 'Powtarzaj te czynnosc dopóki licznik osiagnie liczbe 40
Dht_io_set = 1
Dht_put = 1
'zaczynamy rozkladac otrzymane dane
S16 = Left(sensor_data , 16)
H = Binval(s16)
H = H / 10
Hi = H Mod 10
S16 = Mid(sensor_data , 17 , 16)
T = Binval(s16)
T = T / 10
Ti = T Mod 10
S16 = Right(sensor_data , 8)
Crc = Binval(s16)
'test sumy kontrolnej
Mybyte = T + H 'dodajemy wartosci temperatury i wilgotnosci
If Mybyte <> Crc Then 'jesli suma kontrolna sie nie zgadza
Lcd "error" 'Oznacza to, ze dane nie sa poprawne
End If
End Sub
Sub Getdatetime:
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' start address in 1307
I2cstart ' Generate start code
I2cwbyte Ds1307r ' send address
I2crbyte _sec , Ack
I2crbyte _min , Ack ' MINUTES
I2crbyte _hour , Ack ' Hours
I2crbyte _weekday , Ack ' Day of Week
I2crbyte _day , Ack ' Day of Month
I2crbyte _month , Ack ' Month of Year
I2crbyte _year , Nack ' Year
I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
_day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
End Sub
Sub Settime:
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' starting address in 1307
I2cwbyte _sec ' Send Data to SECONDS
I2cwbyte _min ' MINUTES
I2cwbyte _hour ' Hours
I2cstop
End Sub
Sub Setdate
_day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 4 ' starting address in 1307
I2cwbyte _day ' Send Data to SECONDS
I2cwbyte _month ' MINUTES
I2cwbyte _year ' Hours
I2cstop
End Sub
Sub Dispdate
Sa(1) = Str(_day)
Sa(2) = Str(_month)
Sa(3) = Str(_year)
Format_00
Lcd "Date: " ; Sb(1) ; "-" ; Sb(2) ; "-" ; Sb(3)
End Sub
Sub Disptime
Sa(1) = Str(_hour)
Sa(2) = Str(_min)
Sa(3) = Str(_sec)
Format_00
Lcd "Time: " ; Sb(1) ; ":" ; Sb(2) ; ":" ; Sb(3)
End Sub
Sub Format_00
For I = 1 To 3 Step 1
Sb(i) = Format(sa(i) , "00")
Next I
End Sub
f. VIDEO HASILNYA
No comments:
Post a Comment