Translate

Alarm Pintu, Harap Pintu Tutup Kembali, Jangan Buka Pintu Lama-lama versi 2



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:


Saklar geser (dip switch) S101 digunakan untuk menyetel waktu yang diinginkan. Nomor 1 dari S101 dimulai dari atas atau dari P1.0 terus ke bawah sampai P1.7. Perlu diingat karena P1.0 dan P1.1 adalah juga sebuah masukan op-amp dalam AT89C2051 dan tidak diberi resistor pull-up di dalamnya secara internal maka kita perlu menambahkan pemasangan resistor R106 dan R107 dengan nilai masing-masing 10k ohm.

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....

2 komentar:

  1. Sama-sama Bro. Smoga nanti kita bisa share karena saya sendiri masih belajar. Salam sukses slalu...

    BalasHapus