Kalo sobat pernah jalan-jalan ke sebuah kantor dan lihat di pintu ada tulisan: HARAP PINTU TUTUP KEMBALI atau MOHON PINTU TUTUP KEMBALI atau sejenisnya, itu maksudnya supaya siapa saja yang membuka dan lewat pintu tersebut harus segera menutup kembali dan jangan dibuka terus kalau tidak dipakai. Berarti kita harus tahu bahwa jangan membuka pintu tersebut terlalu lama. Tapi sayangnya, masih ada lho yang tambeng atau cuek, alhasil, ada yang membiarkan pintu terbuka padahal enggak ada yang mau lewat.
Nah kebetulan aku pernah dapat pesanan untuk membuat semacam alarm yang akan dipasang dipintu. Prinsip kerjanya sederhana, yaitu alarm akan aktif kalau ada yang nekat buka pintu terlalu lama sampai batas yang ditentukan. Pelanggan aku tuh minta supaya lamanya waktu pintu boleh dibuka bisa disetel antara 1 menit sampai 15 menit. Ya udah, job nih, aku buatlah rangkaian untuk alat yang dimaksud.
Alarm pintu yang dipaparkan disini adalah versi kedua yang aku buat. Sebelumnya sudah lama sekali aku juga pernah buat versi pertamanya. Perbedaan dengan versi pertama dulu, maka pada versi kedua ini aku buat dengan mikrokontroler AT89C2051 dari Atmel. Masukan sensornya masih menggunakan magnetic contact atau MC dan keluarannya memakai buzzer.
Prinsip kerjanya
sederhana, mikrokontroler mendeteksi kondisi sensor. Jika pintu
tertutup maka hal tersebut adalah normal. Sewaktu ada yang membuka
pintu dan sensor MC terdeteksi membuka, aplikasi yang dijalankan oleh
mikrokontroler langsung mulai menghitung lama waktu pintu terbuka.
Kalau sampai batas waktu yang disetel ternyata pintu masih saja dalam
keadaan terbuka maka mikrokontroler langsung mengaktifkan buzzer
untuk menghasilkan suara berisik. Selama pintu terus dibuka, maka
buzzer akan terus bunyi sampai ada yang keberisikan dan menutup pintu
baru buzzernya berhenti bernyanyi.
Nah, kesimpulannya,
saat pintu ditutup mikrokontroler akan menunggu dan mengawasi sampai
pintu terbuka lalu menjalankan aplikasi pewaktu. Jika sebelum batas
waktu atau sudah lewat sekalipun kemudian pintu ditutup, maka
mikrokontroler segera me-reset aplikasi pewaktu. Pokoknya setiap baru
buka pintu pewaktu start lagi dari nol sampai batas yang ditetapkan.
Begitu seterusnya ....
Setelah aku
ceritakan cara kerja seperti di atas, pelangganku tersebut tertarik
dan pesan sampai beberapa puluh. Wah lumayan nih job tambahan di luar
jam kerja. Apalagi Bos aku saat itu mendukung banget asal enggak
ganggu jam kerja, apalagi pelanggan itu termasuk pelanggan kantor
juga makanya harus serius dilaksanakan.
Sekarang aku mau
jelasin rangkaian alarm pintu yang aku buat....
AT89C2051 memiliki
gerbang atau port sebanyak 15 bit yang bisa difungsikan sebagai
masukan atau keluaran. Gerbang itu terdiri dari Port 1 sebanyak 8 bit
dan Port 3 sebanyak 7 bit. Selanjutnya tinggal kita konfigurasikan
saja gerbang masa saja yang akan dipakai.
Pertama, kita butuh
sebuah gerbang yang berfungsi sebagai masukan sensor dan menggunakan
port 3 bit 2 atau biar gampang ditulis P3.2. Kedua, kita juga butuh
sebuah gerbang yang berfungsi sebagai keluaran untuk penggerak buzzer
menggunakan P3.3. Ketiga, kita juga butuh beberapa pin masukan untuk
menyetel lamanya waktu tundaan dan untuk itu menggunakan semua bit
dari gerbang P1.
Biar tampilan alat
yang dibuat agak keren sedikit maka aku tambahkan 2 gerbang yang
berfungsi sebagai indikator dan untuk indikator LED merah adalah P3.4
dan LED hijau adalah P3.5. LED hijau berfungsi sebagai indikator
bahwa pintu dalam keadaan normal atau sensor tertutup. LED merah
berfungsi sebagai indikator bahwa pintu terbuka, saat pewaktu aktif
LED merah akan berkedip dalam periode per-detik dan akan melotot bila
buzzer hidup.
Akhirnya rangkaian
lengkap dari alarm pintu jadi seperti gambar di bawah ini:
Gerbang P1.7
digunakan untuk menentukan setingan waktu dalam hitungan menit atau
detik. Jika S101
nomor 8 di-ON-kan sehingga masukan P1.7 dibumikan atau berlogika 0
maka setingan waktu akan berjalan dalam hitungan detik. Sebaliknya
jika S101
nomor 8 di-OFF-kan sehingga masukan P1.7 mengambang atau berlogika 1
maka setingan waktu berjalan dalam satuan menit.
Selanjutnya masukan
gerbang lainnya difungsikan sebagai jumlah waktu yang ditetapkan
dalam bentuk bilangan biner. Jika semua saklar geser dari nomor 1
sampai 7 di-ON-kan maka masukan P1.6 sampai P1.7 bernilai 00H (biner
000 0000B). Sebaliknya jika semua saklar OFF maka masukan gerbang
bernilai 7FH atau 111 1111B setara dengan desimal 128. Bisa saja kita
batasi hanya sampai 60, tapi karena hal itu tidak kritis maka biarkan
saja masukan diterima apa adanya yaitu dari 0 sampai 128 detik atau
menit.
Jika ingin
menetapkan lama waktu 1 menit dapat dilakukan dengan 2 setingan. Set
P1.7 ke logika 1 atau OFF untuk hitungan menit dan set P1.0 ke logika
1 hingga bernilai 01H (0000001B) cara lainnya adalah set P1.7 ke 0
untuk hitungan detik dan atur P1.6 – P1.0 hingga bernilai 3CH atau
011 1100B atau 60 detik. Untuk setingan waktu lainnya dapat dilakukan
dengan mengkonversikan nilai desimal ke biner. Aku sih waktu itu
sudah buatkan tabel untuk setingannya dari satuan desimal dan posisi
saklar dalam biner.
Rangkaian di atas
adalah perangkat keras atau hardware. Sebelum dilakukan pemrograman
pada mikrokontrolernya AT89C2051 maka alat tidak akan berfungsi sama
sekali. Maka kita perlu melakukan pemrograman terlebih dahulu.
Untuk membuat
program aplikasi atau istilah kerennya firmware yang dioperasikan dan
diprogramkan ke AT89C2051, aku menggunakan bahasa mesin atau bahasa
asembli yang berbasis MCS-51. Untuk menulisnya gampang cuma
menggunakan aplikasi Notepad.
Yuk sekarang kita
lihat program yang akan diisikan ke AT89C2051 kita....
$mod51
Sensor_Input bit p3.2
Buzzer_Output bit p3.3
LED_Hijau bit p3.4
LED_Merah bit p3.5
Pada baris pertama dari
program kita harus menulis $mod51 karena kita menggunakan mikrokontroler
AT89C2051 yang berbasis MCS51. Selanjutnya kita perlu menetapkan parameter dari
gerbang yang akan digunakan untuk mempermudah kita dalam menganalisa
perintah-perintah asembli yang akan ditulis. Di sini ditulis menurut keinginan
sesuai dengan fungsi gerbang yang digunakan di mana sudah ditetapkan P3.2 untuk
masukan sensor, P3.3 untuk keluaran buzzer serta P3.4 dan P3.5 untuk indikator
LED.
org 0h
ajmp Inisialiasasi
Program selanjutnya adalah
awal dari perintah yang dijalankan oleh mikrokontroler. Penulisan org 0h
merupakan alamat awal dari program yang berisi ajmp inisialisasi. Jadi di sini alamat
awal program kita pada 0000H berisi perintah untuk melompat ke alamat
inisialisasi. Namun sebelum membahas isi perintah pada alamat Inisialisasi kita
bahas dulu subrutin pada alamat 000BH sebagai berikut:
org 0bh
djnz r7, Pewaktu_Selesai
mov r7, #2048
djnz r6, Pewaktu_Indikator
mov r6, #2
jnb Sensor_Input, Indikator_Hijau
clr LED_Merah
djnz r5, Pewaktu_Selesai
djnz r4, Pewaktu_Menit
reti
Baris pertama adalah
perintah untuk mencacah turun register pada alamat 07H atau R7 dengan DJNZ R7
(decrement and jump if not zero). Jika register R7 dicacah turun dan belum
mencapai nol maka perintah akan melompat ke alamat Pewaktu_Selesai tetapi jika
habis atau bernilai 0 akan melanjutkan baris berikutnya mov r7, 2048 yaitu
mengisi ulang register R7 dengan nilai 2048 karena register ini tidak auto
reload seperti hal register TL0.
Selanjutnya kembali
perintah untuk mencacah turun register pada alamat 06H atau R6. Jika register
R6 belum nol maka perintah akan melompat ke alamat Pewaktu_Indikator. Tetapi
jika sudah habis maka selanjutnya menjalankan perintah mengisi ulang register
R6 dengan 2 kemudian memeriksa status bit Sensor_Input atau gerbang P3.2 jika
gerbang ini berlogika 0 di mana berarti nasukan normal karena pintu tertutup
maka akan melompat ke alamat Indikator_Hijau. Jika pintu terbuka maka gerbang
P3.2 akan bernilai 1 dan aplikasi akan menjalan perintah CLR LED_Merah untuk
menyalakan indikator LED warna merah.
Dari perintah-perintah di
atas jika gerbang P3.2 atau masukan sensor normal maka akan memberikan indikasi
dengan kedipan pada LED hijau
Perintah-perintah
selanjutnya adalah mencacah turun register R5, jika register ini belum nol maka
akan melompat ke alamat Pewaktu_Selesai, sebaliknya melanjutkan dengan mencacah
turun register R4. Jika register R4 ini belum kosong maka akan melompat ke
Pewaktu_Menit atau sebaliknya jika kosong akan mengakhiri sub rutin dengan
perintah RETI (return from interrupt).
Pewaktu_Indikator:
setb LED_Hijau
setb LED_Merah
reti
Baris alamat Pewaktu_Indikator
adalah alamat tujuan dari perintah pencacah turun DJNZ register R6 yang berisi
perintah-perintah untuk mematikan semua indikator baik merah maupun hijau
dengan perintah SETB dan diakhiri dengan keluar dari sub rutin interupsi RETI.
Pewaktu_Menit:
mov r5, #60
reti
Baris alamat Pewaktu_Menit
adalah alamat tujuan dari perintah pencacah turun DJNZ register R4 yang berisi
perintah untuk mengisi ulang register R5 dengan nilai 60 sebelum akhir keluar
dari sub rutin.
Indikator_Hijau:
clr LED_Hijau
Pewaktu_Selesai:
Reti
Baris alamat
Indikator_Hijau adalah alamat tujuan dari perintah JNB untuk memeriksa status
masukan gerbang P3.2 yang terdeteksi normal atau berlogika 0. Isi perintahnya
adalah menyalakan indikator LED hijau dengan perintah CLR LED_Hijau atau CLR
P3.2. Perintah ini berurutan dengan baris alamat Pewaktu_Selesai yang berisi
perintah keluar dari sub rutin interupsi dengan RETI.
Kita kembali ke baris
selanjutnya yang ditandai dengan nama Inisialisasi.
Inisialiasasi:
mov tmod, #02h
mov th0, #255-225
mov tl0, #255-225
mov r7, #2048
mov r6, #2
mov ie, #82h
mov tcon, #10h
Pada inisialisasi, kita
menetapkan parameter register TMOD (timer/counter mode control register) dengan
isian 02H. AT89C2051 memiliki 2 buah timer yaitu Timer/Counter 1 dan Timer/Counter
0. Pada aplikasi yang kita buat akan menggunakan salah satunya yaitu Timer/Counter
0, maka pada nible LSB TMOD kita isi 02H atau dalam biner 0010. Merujuk pada
fungsi register TMOD maka sesuai penulisan isi register di atas dimulai dari
bit TMOD.3, atau GATE ditetapkan 0 di mana kita ingin Timer 0 diaktifkan
melalui kendali perangkat lunak (software control). Bit selanjutnya adalah TMOD.2
atau C/T Selector ditetapkan dengan logika 0 di mana kita akan memilih Timer 0.
Dan gabungan 2 bit terakhir adalah TMOD.1 dan TMOD.0 atau MODE (M1 dan M0) yang
berisi biner 10 atau 2H di mana di sini mode yang digunakan adalah MODE 2 yaitu
8 bit auto-load. Mode 2 dengan 8 bit auto-load berkaitan dengan register timer
TH0 dan TL0. TL0 adalah timer yang mencacah secara naik. Ketika isi register
TL0 dicacah naik mencapai FF maka ketika reset akan langsung diisi oleh nilai
sesuai dengan isi pada register TH0.
Pada langkah inisialisasi
baik register TH0 (timer high 0 register) maupun TL0 (timer low 0 register) kita
isi dengan 1EH di mana nilai ini jika didesimalkan adalah 30. Karena nilai
maksimum dari register 8 bit adalah FFH atau 255 maka untuk mendapatkan angka
30 adalah pengurangan dari 255-225. Sengaja ditulis seperti ini untuk
memudahkan kita dalam melakukan perhitungan karena aplikasi kompiler MCS51 yang
digunakan mampu menerjemahkan perhitungan sesuai seperti yang ditulis di atas.
Kenapa kita menetapkan
angka 30 untuk register timer?
Begini perhitungannya....
Seperti kita ketahui, alat
kita menggunakan kristal filter yang menghasilkan frekuensi 11.059.200 hertz.
Secara internal AT89C2051 akan membagi frekuensi ini dengan cacahan 12 sehingga
didapat cacahan yang berjalan secara internal adalah 921.600. Agar nantinya
bisa dibagi utuh dalam detik maka kita perlu membagi dengan nilai 225 sehingga
diperoleh sisa hasil akhir cacahan timer dari register TL0 adalah sebesar 4.096.
Dengan nilai ini tentu lebih mudah untuk membaginya. Register 7 (R7) berisi separuh
saja dari nilai tersebut yaitu 2.048 yang bertujuan untuk memberikan kedipan
indikator dengan perioda 0,5 detik atau 2 hertz. Register 6 (R6) berisi 2. Jadi
sekarang kita sudah mendapatkan hasil akhir dari total cacahan dengan durasi 1
detik.
Selanjutnya kita akan
mengisi register IE (interrupt enable register) dengan nilai 82H atau 10000010.
Penjelasan dimulai dari register IE.7 atau bit EA (enable all) berisi 1 yang
akan mengaktifkan seluruh bit interupsi. Bit IE.6 dan IE.5 diabaikan dan
masing-masing diisi dengan logika 0. Bit IE.4 atau ES juga diisi 0 karena bit
ini untuk mengaktifkan gerbang serial. Bit IE.3 atau ET1 dan IE.2 atau EX1 kita
non aktifkan karena berkaitan dengan timer 1 dan masukan eksternal INT1 atau
gerbang P3.3. Bit IE.1 atau ET0 (enable timer 0) ditetapkan dengan logika 1
untuk mengaktifkan interupsi overflow dari timer 0. Dan terakhir adalah bit
IE.0 atau EX0 diset 0 untuk mengabaikan masukan interupsi INT0 pada gerbang
P3.2. Pengaturan register IE ini berkaitan dengan rutin pelayanan interupsi
(interrupt service routine) di mana penetapan bit ET0 akan memeriksa status bit
bendera dari timer flag 0 atau TF0. Jika terdeteksi bit TF0 menjadi 1 atau
terdeteksi overflow maka program akan menjalankan rutin yang ada pada vektor
alamat 000BH.
Baris berikutnya adalah
mengisi register TCON (timer/counter control register) dengan 10H atau
00010000. Kita hanya perlu mengeset bit TCON.4 atau TR0 menjadi 1 saja yang
lain diabaikan atau dibiarkan 0. Bit TR0 adalah timer 0 run control bit yang
berfungsi mengaktifkan atau mematikan kerja register pencacah timer 0. Kita
bisa saja mengganti baris ini dengan perintah setb tr0 tapi sekedar untuk
memastikan bit yang lain berisi 0 maka ditulis mov tcon, #10H.
Nah, dari
perintah-perintah yang ada pada inisialisasi sudah jelas timer 0 atau register
TL0 akan mencacah naik karena diaktifkan oleh bit TR0. Jika dijumpai register
TL0 menjadi overflow maka program yang sedang berjalan akan menyebabkan
perintah akan melompat ke vektor alamat 000BH.
Setelah inisialisasi,
program akan menjalankan perintah memulai aplikasi.
App_Mulai:
jnb Sensor_Input, $
mov a, p1
anl a, #80h
jz Setup_Detik
mov r5, #60
mov a, p1
anl a, #01111111b
mov r4, a
ajmp Hitung_Mundur
Perintah pertama adalah
memeriksa masukan sensor, jika masukan bernilai 0 atau rendah maka perintah
akan melompat untuk mengulangi perintah yang sama dengan menuliskan $. Perintah
ini akan terus berulang sampai mendeteksi masukan menjadi tinggi dan
melanjutkan perintah pada bars berikutnya.
Perintah berikutnya adalah
mengisi register akumulator (ACC) dengan nilai dari gerbang P1. Kemudian
dilakukan perintah ANL untuk membandingkan isi register akumulator dengan nilai
80H atau 1000000 secara logika AND. Karena logika AND memiliki persamaan Y=A.B
maka dari nilai tersebut hanya bit ACC.7 saja yang akan diperiksa sementara
lainnya dinolkan. Karena bit ACC.7 adalah gerbang P1.7 yaitu untuk menentukan
satuan waktu menit atau detik.
Jika register ACC berisi
00H berarti P1.7 rendah, dengan perintah JZ akan menyebabkan program melompat
ke baris alamat Setup_Detik. Tetapi jika register ACC berisi 80H atau P1.7
tinggi, program menjalan perintah selanjutnya yaitu mengisi register R5 dengan
nilai 60 atau sepadan dengan 1 menit atau 60 detik. Di sini register R5
berfungsi sebagai pencacah detik.
Program selanjutnya
kembali menyalin isi register P1 ke akumulator dan kembali dilakukan
pemeriksaan dengan logika AND tetapi dengan 7FH atau 01111111. Perintah ini
akan mengabaikan bit ACC.7 dan memaksanya menjadi rendah. Bit sisanya dari
ACC.6 sampai ACC.0 setelah perintah logika AND maka hasilnya di simpan di
register R4. Di sini register R4 berfungsi sebagai pencacah menit. Program
diakhiri dengan menjalankan perintah AJMP untuk menuju alamat Hitung_Mundur.
Pewaktu dari alat kita
ditetapkan dengan satuan menit. Ini ditetapkan dengan mengisikan register R4
dengan nilai yang terdapat dari gerbang P1.
Setup_Detik:
mov a, p1
anl a, #01111111b
mov r5, a
mov r4, #1
Jika P1.7 adalah rendah
maka perintah pada alamat Setup_Detik akan dijalankan. Di sini perintah pertama
menyalin akumulator dengan isi gerbang P1. Selanjutnya isi akumulator
di-AND-kan dengan 8FH untuk mengambil nilai waktu dalam detik yang kemudian
disimpan ke register R5 yang berfungsi sebagai pencacah detik. Sementara untuk
register R4 tetap diisi dengan nilai 01H setara dengan nilai 1 desimal.
Hitung_Mundur:
jnb Sensor_Input, App_Mulai
mov a, r4
jnz Hitung_Mundur
clr Buzzer_Output
Perintah pada alamat awal
Hitung_Mundur pertama adalah memeriksa status masukan sensor. Jika kembali
normal maka perintah akan melompat kembali ke App_Mulai. Jika sensor terbuka
dan berlogika tinggi maka perintah selanjutnya adalah menyalin nilai register
R4 ke akumulator. Kemudian nilai akumulator tersebut diperiksa dengan perintah
JNZ (jump if not zero). Selama nilai register R4 belum kosong maka perintah
akan kembali mengulang ke alamat Hitung_Mundur. Jika register R4 kosong
perintah selanjutnya adalah mengaktifkan alarm dengan perintah CLR.
Alarm_Aktif:
clr LED_Merah
jb Sensor_Input, Alarm_Aktif
setb Buzzer_Output
setb LED_Merah
ajmp App_Mulai
end
Baris alamat awal
Alarm_Aktif berisi perintah pertama menyalakan indikator LED merah. Kemudian
selanjutnya kembali memeriksa masukan sensor, jika masih tinggi akan mengulang
ke alamat awal Alarm_Aktif. Perintah akan terus berulang sampai sensor kembali
normal berarti buzzer akan terus hidup dan indikator akan dipaksa melotot
merah.
Jika masukan sensor
kembali rendah maka perintah selanjutnya adalah mematikan buzzer dan indikator
merah, masing-masing dengan perintah SETB. Kemudian program ini diakhiri dengan
perintah AJMP untuk melompat kembali ke alamat App_Mulai.
Sesuai prosedur maka
penulisan program diakhiri dengan END.
Nah, sebagai catatan....
Setelah program di atas
ditulis dan disimpan dalam file dengan ekstensi .ASM maka segera dapat kita kompilasi
untuk mendapatkan file yang berekstensi .HEX untuk diisikan ke mikrokontroler.
Untuk mengisinya dapat menggunakan Atmel Programmer.
Jika sobat menggunakan
Atmel ISP Programmer maka gantilah mikrokontroler AT89C2051 dengan jenis
AT89S2051 yang mendukung ISP.
Udah ya, makasih udah baca
postingan aku. Semoga bisa bermanfaat, sukur-sukur bisa diterapkan oleh sobat
semua.
Salam....
Terima Kasih Ilmunya
BalasHapusSama-sama Bro. Smoga nanti kita bisa share karena saya sendiri masih belajar. Salam sukses slalu...
BalasHapus