PALANG PINTU KERETA API OTOMATIS DENGAN ATTINY2313
Palang pintu kereta api yg kita bahas kali ini pernah saya buat
kira-kira setahun yang lalu dalam rangka membantu teman yang kesusahan
mengerjakan tugas. Dia mewanti-wanti saya agar tidak menyebarkannya di
blog sampai saatnya dia lulus kuliah. Dan saatnya kini kita bahas karena
teman saya itu sudah lulus akhirnya.
Bahan utama yang kita perlukan adalah motor stepper. Dipasaran komponen
elektronika, motor stepper dijual umumnya memiliki kumparan berjenis
BIPOLAR, dimana nantinya diperlukan sebuah driver H-bridge untuk merubah
polaritas kumparannya. Sedangkan jika beruntung (cari di loakan) atau
punya duit berlebih, maka motor stepper UNIPOLAR tentunya menjadi
pilihan yang lebih simple.
Cara mudah membedakan jenis motor steep adalah jumlah kabel, untuk
bipolar biasanya memiliki kabel 4 , sedangkan unipolar memiliki kabel 5
dimana 1 kabel sebagai common (supply)
cara menggerakkan motor stepper (courtesy wikipedia)
Prinsip sensor yang digunakan untuk mendeteksi kereta datang dan pergi
maka diletakkan sensor "cahaya terhalang" menggunakan pasangan LED
INFRARED & PHOTODIODA yang biasanya digunakan sebagai transmiter
& receiver untuk remote TV. Kedua led ini diposisikan
berhadap-hadapan (sebaiknya diberi casing/ penghalang cahaya dari
samping) sehingga ketika tanpa halangan, dengan rangkaian tambahan
resistor pull down dan anoda ke 5v , photodioda akan memberikan logika 1
(seperti tehubung langsung ke 5v). Kondisi ketika sinar infre merah
terhalang maka photo dioda akan memutus hubungan dari 5V dan rangkaian
menjadi logika 0 karena terhubung melalui resistor 10k ohm menuju ground
(0v).
Untuk mendeteksi kedatangan kereta api, maka sensor "kedatangan" akan
mendeteksi perubahan dari 1 ke 0 (falling edge) sehingga dalam script
ditunjukkan dengan INTERUPT 0 yang diinisialisasikan sebagai falling
edge. Sedangkan sensor untuk "kereta sudah lewat" menggunakan logika
interupt rising edge (0 ke 1), dimana ketika kereta masih berada di
perlintasan akan menghalangi sinar led infra (kondisi logika 0). Setelah
semua rangkaian lewat maka sinar akan kembali mengaktifkan logika 1
pada photodioda.
MCUCR |= (1<<ISC01) | (0<<ISC00) |(1<<ISC11) | (1<<ISC10);
Sensor yang ketiga merupakan sensor posisi awal dari palang pintu,
diletakkan pada posisi palang pintu terbuka penuh (90 derajat) ,
sehingga ketika alat dihidupkan atau direset maka motor stepper akan
bergerak ke kiri sampai posisi palang pintu menghalangi sinar led menuju
photodioda ke 3.
Kereta api kan bolong-bolong, ada jeda antar gerbong ...nah looo...error
dah....pintunya kebuka baru 1 gerbong lewat?? Tenang saja, ini hanya
simulasi..kita anggap bahwa kereta api itu benda yang full kontinyu
tanpa lubang jeda antar gerbong. Jika ingin menerapkan ke dunia nyata
dimana ada jarak antar gerbong, maka diperlukan suatu timer yang akan
mendeteksi waktu berapa milli second sinar infra yang dilewatkan lubang
tersebut. Jika gerbong terakhir yang lewat tentunya waktunya lebih lama
ketimbang sinar melalui celah - celah rangkaian kereta api, nah inilah
pembedanya.
Trus pertanyaan lainnya, bagaimana jika yang diinginkan adalah palang
pintu keretanya 2 arah ? Sekali lagi kita sebaiknya menggunakan metode
timer saja, jadi kita perkirakan jika cahaya tidak terhalang selama
selang waktu (misal 5 detik) maka pintu akan terbuka.
Skematik dari palang pintu otomatis seperti berikut :
(klik untuk memperbesar)
Harap diperhatikan jenis motor yang digunakan dan sesuaikan driver motor yang tepat.
FULL SCRIPT METODE INTERUPT 1 ARAH:
/* Pintu Kereta Api Otomatis Dengan motor stepper by: ahocool@gmail.com SURABAYA - 2012 1 arah saja */ #define F_CPU 100000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define SPEED _delay_ms(10) // ubah nilai delay sesuai kecepatan yang diinginkan //stepper FULL STEP, bisa dirubah sesuai keinginan void puter_kanan(void) { PORTB |=_BV(PB0); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB1); PORTB &= ~_BV(PB0) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB0) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB3); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB0); SPEED; PORTB |=_BV(PB0) | _BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB3) ; } void puter_kiri(void) { PORTB |=_BV(PB3); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB0) ; SPEED; PORTB |=_BV(PB2); PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB1); PORTB &= ~_BV(PB2) & ~_BV(PB0) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB0); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB0) | _BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB3) ; } SIGNAL (SIG_INT0) { int a; //ubah nilai max looping berikut sampai posisi berhenti yg pas for(a=0;a<3;a++) puter_kanan(); } SIGNAL (SIG_INT1) { int a; //ubah nilai max looping berikut sampai posisi berhenti yg pas for(a=0;a<3;a++) puter_kiri(); } int main(void) { PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) ; //OUTPUT Stepper pin A,B,C,D PORTD &= ~_BV(PD4); //sensor posisi awal //aktifkan interupt MCUCR |= (1<<ISC01) | (0<<ISC00) |(1<<ISC11) | (1<<ISC10); // interupt 0 (datang) falling edge, interupt 1 (pergi) rising edge GIMSK |= (1<<INT0) |(1<<INT1); sei(); //inisialisasi awal saat dihidupkan , pintu membuka sampai sensor posisi OFF while (bit_is_set(PIND, PIND4) ) { puter_kiri(); //steper naik sampe sensor awal terhalang } while(1) { } return 0; }
FULL SCRIPT METODE TIMER - 2 ARAH :
/* Pintu Kereta Api Otomatis Dengan motor stepper by: ahocool@gmail.com SURABAYA - 2012 versi timer -- 2 arah */ #define F_CPU 100000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define SPEED _delay_ms(10) // ubah nilai delay sesuai kecepatan yang diinginkan #define TIMER 5 // timer dari gerbong terakhir menlewati sensor dan membuka palang pintu int detik, posisi, depan; void init_timer(void) { TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode TIMSK |= (1 << OCIE1A); // Enable CTC interrupt OCR1A = 7812; //compare the CTC A TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64 TCNT1 = 0; detik=0; sei(); } void init_sensor_fall(void) { cli(); //aktifkan interupt MCUCR |= (1<<ISC01) | (0<<ISC00) |(1<<ISC11) | (0<<ISC10); // interupt 0 & 1 falling edge , untuk deteksi 2 arah GIMSK |= (1<<INT0) |(1<<INT1); sei(); posisi = 0 ; // sebagai penanda kalo posisi pintu terbuka } void init_sensor_rise(void) { cli(); //aktifkan interupt MCUCR |= (1<<ISC01) | (1<<ISC00) |(1<<ISC11) | (1<<ISC10); // interupt 0 & 1 rising edge , untuk deteksi akhir gerbong GIMSK |= (1<<INT0) |(1<<INT1); sei(); posisi = 1 ; // sebagai penanda kalo posisi pintu tertutup } void puter_kanan(void) { PORTB |=_BV(PB0); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB1); PORTB &= ~_BV(PB0) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB0) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB3); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB0); SPEED; PORTB |=_BV(PB0) | _BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB3) ; } void puter_kiri(void) { PORTB |=_BV(PB3); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB0) ; SPEED; PORTB |=_BV(PB2); PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB1); PORTB &= ~_BV(PB2) & ~_BV(PB0) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB0); PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) ; SPEED; PORTB |=_BV(PB0) | _BV(PB2); PORTB &= ~_BV(PB1) & ~_BV(PB3) ; } SIGNAL (SIG_INT0) { int a; //jika pintu terbuka dan kereta lewat if( posisi == 0) { depan = 1; //berarti sensor 1 jadi yg didepan init_sensor_rise(); //mode interupt berubah //ubah nilai max looping berikut sampai posisi berhenti yg pas for(a=0;a<3;a++) puter_kanan(); } else { //jika ada kondisi celah gerbong (0 -> 1) maka reset timer if(depan == 1)init_timer(); } } SIGNAL (SIG_INT1) { int a; //jika pintu terbuka dan kereta lewat if( posisi == 0) { depan = 2; //berarti sensor 2 jadi yg didepan init_sensor_rise();//mode interupt berubah //ubah nilai max looping berikut sampai posisi berhenti yg pas for(a=0;a<3;a++) puter_kanan(); } else { //jika ada kondisi celah gerbong (0 -> 1) maka reset timer if(depan == 2)init_timer(); } } ISR(TIMER1_COMPA_vect) // interupt timer detik { int a; detik++; if(detik >= TIMER ) // jika lebih dari timer yg ditentukan maka pintu terbuka { init_sensor_fall(); //kembalikan sensor sebagai interupt fall edge TIMSK=0; //matikan timer //ubah nilai max looping berikut sampai posisi berhenti yg pas for(a=0;a<3;a++) puter_kiri(); } } int main(void) { PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) ; //OUTPUT Stepper pin A,B,C,D PORTD &= ~_BV(PD2) & ~_BV(PD3) & ~_BV(PD4); //sensor sebagai input init_sensor_fall(); //awal sebagai interupt fall //inisialisasi awal saat dihidupkan , pintu membuka sampai sensor posisi OFF while (bit_is_set(PIND, PIND4) ) { puter_kiri(); //steper naik sampe sensor awal terhalang } while(1) { } return 0; }
Tidak ada komentar:
Posting Komentar