Jumat, 21 Desember 2012
AISI555 in action di Majalah Reload Vol.17
Majalah Reload merupakan majalah komunitas AIRSOFTGUN yang terbit dua bulan sekali. Terdapat rubrik Do IT Yourself dimana para pembaca diajak untuk membuat modifikasi atau alat khusus dari bahan-bahan yang mudah didapat. Aisi555 diberi kesempatan untuk mengisi rubrik DIY pada vol. 17 - desember 2012 . Pembahasan timer ini akan dibahas 2 bulan kedepan , jika berminat merangkai diharap membeli majalahnya saja !
Segera dapatkan Majalahnya di toko buku terdekat !
Rabu, 19 Desember 2012
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; }
SELAMAT MENCOBA !
Rabu, 12 Desember 2012
BELAJAR ACCESS SD CARD CARA SIMPLE DENGAN ATTINY2313 - Part3
ATTINY2313 TALKING MACHINE
Disclaimer : collected from various source on Google, writer read and modify for educational purpose only. Free to use !
Sebaiknya anda baca Part2 agar tidak kebingungan
sebelum lanjut, kita ingat project wav player dengan memory I2C (silahkan baca disini), kapasitasnya kecil banget dan sagat pendek, kenapa tidak kita pakai SD card saja ?
ternyata kita tidak perlu pusing2, karena jika memainkan attiny pada clock 8mhz, maka waktu access SD card dan PWM sangatlah pas sehingga cukup memainkan beberapa nilai delay saja sudah mendapatkan suara yang cukup bagus (file wav PCM 6000hz 8bit)
kita ingat dulu code untuk membuat audio via PWM - OC1A, kita hilangkan sekarang beberapa pembagian dan script jadi lebih simple
Code:
void pwm_init(void)
{
/* use OC1A pin as output */
DDRB = _BV(PB3);
/*
* clear OC1A on compare match
* set OC1A at BOTTOM, non-inverting mode
* Fast PWM, 8bit
*/
TCCR1A = _BV(COM1A1) | _BV(WGM10);
/*
* Fast PWM, 8bit
* Prescaler: clk/1 = 8MHz
* PWM frequency = 8MHz / (255 + 1) = 31.25kHz
*/
TCCR1B = _BV(WGM12) | _BV(CS10);
/* set initial duty cycle to zero */
OCR1A = 0;
}
dan kita mainkan delay pada code pembacaan SD CARD melalui USI, untuk clock 8mhz dan file format 6000hz 8bit mengggunakan delay seperti berikut
Code:
unsigned char SPI_write(unsigned char ch){
USIDR = ch;
USISR |= (1<<USIOIF);
do {
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
_delay_us(9);
} while((USISR & (1<<USIOIF)) == 0);
return USIDR;
}
THAT"S IT ....hanya itu yang dirubah, selanjutnya simpan file wav pada SD card dan dengan bantuan software winhex, kita dapat membaca sector dimana file dimulai. Jika format SD card adalah FAT16, maka jika file dicopy setelah di format ulang akan diletakkan di posisi sector 555. Karena memory attiny yang kecil, maka ga usah dibingungkan dengan pembacaan root, FAT1, FAT2 dan sebagainya. Kita baca dulu saja via winhex kemudian dimanfaatkan. Seperti pada skematik berikut, saya akan memutar audio setelah tombol dipencet...file audio saya rekam dari laptop.
(klik biar tambah gede)
audio output pada OC1A bisa menggunakan amplifier sederhana seperti diatas, atau bisa juga membuat yg lebih paten, semisal menggunakan opamp LM386 atau TDA2003 (googling aja)
Langkah selanjtunya adalah memformat SDcard dan membuat file audio yang akan diputar (bisa dipotong dari mp3 atau direkam dan jangan lupa diconvert ke WAV PCM 6000Hz 8 bit). Sebagai contoh saya mempunyai 4 file dan copykan ke SD card. Selanjutnya buka SD menggunakan winhex seperti gambar berikut :
dan tampilan snapshot SD card dan file-filenya seperti berikut:
untuk mengetahui awal dan akhir sector dari file maka kita baca FAT1 atau FAT2 yang berisikan informasi dari isi file. Tiap file yg ada pada SD card memiliki "alokasi" pada FAT ini dimana 2byte berarti 1 cluster dari file. Untung saja winhex memberitahu pada layar sebelah kiri kalau sedang klik pada alokasi file apa dan nomer sector berapa. seperti pada gambar diatas , kita hanya perlu mencari awal cluster dan akhir cluster (ditandai dengan FF FF). Kemudian kita catat seperti yang saya dapatkan.
Code:
tombol3.wav = cluster 2 - 18 silahkan.wav = cluster 19 - 43 tombol1.wav = cluster 44 - 62 tombol2.wav = cluster 63 - 82 ingat cluster = sector
sedangkan untuk physical sector, cukup dengan menambahkan 553 (bukan 555 karena sector 0-1 dianggap tidak ada oleh FAT16)
selanjutnya scriptnya kita tweak biar tambah maknyus seperti berikut , karena ada beberapa bagian dari file yang digenerate oleh wavepad editor kudu di skip biar halus.
Code:
void SD_play(unsigned long sector_start, unsigned long sector_end) { char i; int byte=0; SD_begin(sector_start); for(i=0; i<100; i++) { SPI_write(0xFF); byte++; } //biar tidak njebluk pas pencet while(1) { OCR1A=SPI_write(0xFF); byte++; if(byte>= 512 && byte<515)OCR1A=0x80; //silent if(byte >= 515) { OCR1A=0x80;//silent CS_DISABLE(); byte =0; sector_start++; if(sector_start > (sector_end -7))break; //biar halus else SD_begin(sector_start); } } }
selanjutnya semua script bisa didownload dimari
hasilnya kayak gini gan ....
SELAMAT MENCOBA !!
BELAJAR ACCESS SD CARD CARA SIMPLE DENGAN ATTINY2313 - PART2
Disclaimer : collected from various source on Google, writer read and modify for educational purpose only. Free to use !
Silahkan Baca Part1 terlebih dahulu agar tidak kebingungan
SPI via USI
SPI merupakan serial peripheral interface yang dapat mengkomunikasikan antara master dan slave. Kecepatan transfer data bergantung dari pembagian clock yang diberikan . Sedangkan USI adalah SPI mode simple, dimana clock diberikan manual secara software atau input dari luar. Pin SS (slave select ) juga tidak disediakan tapi bisa di akali dengan PIN & software
dari gambar diatas dapat dilihat mode 3 wire USCK, DO (MOSI) , DI (MISO)
USCK diberikan secara software (manual) dengan toogling register USICR pada USICLK dan USITC
ada 3 buah register yg perlu diperhatikan yaitu USIDR = Data register , USICR =Control register dan USISR = Status Register
Berikut script untuk inisialisasi dari USI sebagai SPI
Code:
//definisi port
#define SPI_DDR DDRB
#define MOSI (1<<PB6)
#define MISO (1<<PB5)
#define SCK (1<<PB7)
#define CS_DDR DDRD
#define CS (1<<PD6) // PD6 sebagai slave/chip select
#define CS_ENABLE() (PORTD &= ~CS)
#define CS_DISABLE() (PORTD |= CS)
//inisialisasi port SPI
void SPI_init() {
CS_DDR |= CS; // SD card circuit select as output
SPI_DDR |= MOSI + SCK; // MOSI and SCK as outputs
}
//Pembacaan SPI
unsigned char SPI_write(unsigned char ch) {
USIDR = ch; // data yang akan dikirim
USISR |= (1<<USIOIF); // aktifkan interrupt Overflow
do {
//Kirim USCK8 x
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
_delay_us(100);
} while((USISR & (1<<USIOIF)) == 0); // selesai jika overflow
return USIDR; // baca data reply yg masuk
}
gampang bukan ? selanjutnya kita dapat mengirim perintah ke SD card melalui port USI dan kita siap untuk membaca data dari SD CARD.
Jika bahan-bahan sudah siap dan tersusun di breadboard (jangan lupa set fusebit memakai clock 8MHZ , clk_div jangan dipake, bisa meakai xtal atau internal RC) kita akan membaca file text yang telah dicopy ke dalam SD card
Pertama kita bahas cara read (CMD 51) dari isi file SDCARD , langkahnya seperti berikut:
1. Pull CS low (select)
2. Send 0×51
3. Send 0x00000000 (Sector x 512)
4. Send 0×FF
5. Baca data yg dikirim 520 kali (sambil kirim 0xFF ke kartu)
6. Pull CD low (deselect)
kenapa 520 kali ? karena format reply per sector seperti ini :
yang garis merah diatas merupakan header awal (6 byte) yang menyatakan data ready, jadi di script nantinya kita akan mendeteksi 00 dan FE , sedangkan 2 terakhir merupakan CRC yang bisa di abaikan.
jadi kita susun script seperti berikut :
Code:
void SD_command(unsigned char cmd, unsigned long arg, unsigned char crc, unsigned char read) {
unsigned char i;
//berfungsi mengirim perintah ke SD card
CS_ENABLE();
SPI_write(cmd);
SPI_write(arg>>24); //geser byte
SPI_write(arg>>16);//karena format
SPI_write(arg>>8);//0x00000000
SPI_write(arg);//alias 4 bit argumen
SPI_write(crc);
for(i=0; i<read; i++) SPI_write(0xFF); //kirim & baca
CS_DISABLE();
}
char SD_init() {
char i;
//berfungsi inisialisasi SD card
CS_DISABLE();
for(i=0; i<10; i++) SPI_write(0xFF);
_delay_ms(500);
// langkah 1 0x40
SD_command(0x40, 0x00000000, 0x95, 8);
_delay_ms(500);
// langkah 2 0x41
SD_command(0x41, 0x00000000, 0xFF, 8);
_delay_ms(500);
// langkah 3 0x50
SD_command(0x50, 0x00000200, 0xFF, 8);
_delay_ms(500);
return 0;
}
void SD_begin(unsigned long sector) {
uint8_t i = 0;
//berfungsi untuk membaca data SD card
CS_ENABLE();
SPI_write(0x51); //perintah baca 0x51
//selanjutnya geser2 byte sector
SPI_write(sector>>15); // sector*512 >> 24
SPI_write(sector>>7); // sector*512 >> 16
SPI_write(sector<<1); // sector*512 >> 8
SPI_write(0); // sector*512
SPI_write(0xFF);
for(i=0; i<10 && SPI_write(0xFF) != 0x00; i++) {} // wait for 0
for(i=0; i<10 && SPI_write(0xFF) != 0xFE; i++) {} // wait for data start
// baca SD& kirim melalui serial
for(i=0; i<512; i++) USART_Tx(SPI_write(0xFF));
//2 kali checksum
SPI_write(0xFF);
SPI_write(0xFF);
CS_DISABLE();
}
Yah..begitulah...ga terlalu susah ....hanya masalah creativitas, ntar munculnya di layar (jika dihubungkan dengan serial via putty/hyperterminal) seperti ini :
atau jika data langsung dibaca, bisa langsung membaca text. Sesuai percobaan bahwa sector paling depan tempat file disimpan adalah sector 96,
kenapa ? karena SD CARD yang aku pake jadul , memakai system FAT12
sedangkan jika memakai Format pc terbaru maka otomatis menjadi system FAT16 dan File pertama berada di sector 555. Jadi sesuaikan dengan jenis format yang dipakai
semua source code dapat didownload dimari , untuk dapat membaca wav file dan memainkan suara kita lanjut ke post berikut disini
SELAMAT MENCOBA