Anda di halaman 1dari 103

APLIKASI PEMBACAAN SUHU LM35 DENGAN PENAMPIL LCD MENGGUNAKAN CODEVISION AVR

SUHU LM35 DENGAN PENAMPIL LCD MENGGUNAKAN CODEVISION AVR Aplikasi pembacaan suhu (monitoring suhu) in i, menggunakan

Aplikasi pembacaan suhu (monitoring suhu) ini, menggunakan sensor LM35 yang merupakan sebuah sensor suhu dengan harga yang relatif murah dan output nya sudah berupa tegangan yang sudah linear.

Menurut datasheet LM35, untuk kenaikan 1 derajat Celcius akan mengakibatkan perubahan 10mV terhadap output tegangannya. Dimana saat suhu 0° Celcius sensor ini mempunyai tegangan offset sebesar 0 V.

Disini saya akan melakukan pembacaan suhu dalam satuan derajat Celcius dengan range pengukuran 0°-100° Celcius. Sehingga tegangan output dari LM35 adalah 0-1 V.

Tegangan output tersebut sudah dapat dibaca oleh mikrokontroler melalui ADC tanpa diperlukan sebuah penguat tegangan. Aplikasi ini telah saya buat dalam bentuk real (sesungguhnya) dan juga saya simulasikan menggunakan Proteus. Schematic LM35 yang kemudian ditampilkan pada LCD dapat dilihat diatas.

Sedangkan untuk programnya menggunakan CodeVision AVR, berikut adalah listing program lengkapnya.

int SUHU; char temp[8]; float suhu_celcius;

#include <mega16.h> #include <stdlib.h> #include <lcd.h> #include <delay.h>

// Alphanumeric LCD Module functions #asm

.equ

#endasm

lcd_port=0x15 ;PORTC

#define ADC_VREF_TYPE 0x40

// Read the AD conversion result

unsigned int read_adc(unsigned char adc_input)

{

ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);

// Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

return ADCW;

}

void main(void)

{

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;

// ADC initialization // ADC Clock frequency: 750.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: None ADMUX=ADC_VREF_TYPE & 0xff;

ADCSRA=0x84;

// LCD module initialization

lcd_init(16);

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf("ElectrO cOntrOl");

lcd_gotoxy(0,1);

lcd_putsf("SENSOR SUHU LM35");

delay_ms(1000);

while (1)

{

lcd_clear( ); SUHU = read_adc(0); suhu_celcius = (float)SUHU*500/1023;//rumus untuk mengubah kedalam derajat celcius

lcd_gotoxy(0,0);

lcd_putsf("ElectrO cOntrOl"); ftoa(suhu_celcius,1,temp);//mengubah tipe data float ke tipe data array yg akan ditampilkan di LCD

lcd_gotoxy(0,1);

lcd_puts(temp);

lcd_gotoxy(5,1);

lcd_putchar(0xdf);//menampilkan karakter derajat lcd_putsf("C");

delay_ms(500);

};

}

LCD DAN KEYPAD

Pada dasarnya keypad yang ada dipasaran baik yang berukuran keypad 3×3, 3×4 atau 4×4, hanya tersusun dari beberapa push button yang dikonfigurasikan antara kolom dengan baris. Sehingga sering disebut juga keypad matriks nxm (n=kolom m=baris). Kolom dan baris ini nantinya yang digunakan untuk pendeteksian penekanan tombol. Berikut adalah konfigurasi dasar untuk keypad 4×4.

Berikut adalah konfigurasi dasar untuk keypad 4×4. B1, B2, B3 dan B4 merupakan baris ke 1

B1, B2, B3 dan B4 merupakan baris ke 1 sampai baris ke 4, sedangkan C1, C2, C3 dan C4 merupakan kolom ke 1 sampai kolom ke 4 keypad. Terlihat jelas betapa sederhananya rangkaian dasar keypad untuk ukuran keypad 4×4 yang terdiri dari 16 buah push button yang dikonfigurasikan seperti matriks. Saya sendiri membuat keypad menggunakan rangkaian diatas, dikarenakan mahalnya harga keypad. Dipasaran saja keypad 4×4 bisa seharga Rp. 50.000, sedangkan untuk membuatnya tidak sampai Rp. 10.000.

Baiklah kembali lagi kemateri keypad. Sekarang saya punya pertanyaan? Kenapa kita tidak menggunakan push button saja yang disusun seperti biasa, kenapa harus menggunakan keypad matrik. Jawabannya mudah saja, kalo menggunakan susunan seperti biasa maka akan menghabiskan 16 pin mikrokontroler untuk 16 buah tombol. Sedangkan jika dikonfigurasikan seperti diatas hanya menghabiskan 8 pin saja. Jadi lebih ringkas dan irit dalam penggunaan pin mikrokontroler.

Sekarang cara untuk mengakses keypad, tapi terlebih dahulu perhatikan gambar berikut.

Sebelumnya kita harus menentukan terlebih dahulu mana yang akan dijadikan input atau output mikrokontroler. Sebagian

Sebelumnya kita harus menentukan terlebih dahulu mana yang akan dijadikan input atau output mikrokontroler. Sebagian banyak orang membuat kolom keypad sebagai output mikrokontroler sedangkan baris keypad sebagai input mikrokontroler. Sebenarnya bisa saja kita balik penggunaannya, tetapi agar standar kita ikut saja yang sudah banyak digunakan orang. Cara kerja keypad adalah scanning yaitu mendeteksi terus menerus apakah ada penekanan tombol. Berikut adalah algoritma cara mengakses keypad:

Tentukan terlebih dahulu kolom sebagai output dari mikrokontroler sedangkan baris sebagai input kemikrokontroler. Mengacu pada gambar diatas

Langkah pertama (Scanning kolom 1 PB0) keluarkan output ke kolom 1(PB0) kemudian deteksi penekanan baris1 (PB4) kemudian deteksi penekanan baris2 (PB5) kemudian deteksi penekanan baris3 (PB6) kemudian deteksi penekanan baris4 (PB7)

Langkah kedua (Scanning kolom 2 PB1) keluarkan output ke kolom 2 (PB1) kemudian deteksi penekanan baris1 (PB4) kemudian deteksi penekanan baris2 (PB5) kemudian deteksi penekanan baris3 (PB6) kemudian deteksi penekanan baris4 (PB7)

Langkah ketiga (Scanning kolom 3 PB2) keluarkan output ke kolom 3 (PB2) kemudian deteksi penekanan baris1 (PB4) kemudian deteksi penekanan baris2 (PB5) kemudian deteksi penekanan baris3 (PB6)

kemudian deteksi penekanan baris4 (PB7)

Langkah kempat (Scanning kolom 4 PB3) keluarkan output ke kolom 4 (PB3) kemudian deteksi penekanan baris1 (PB4) kemudian deteksi penekanan baris2 (PB5) kemudian deteksi penekanan baris3 (PB6) kemudian deteksi penekanan baris4 (PB7)

Untuk realisasi programnya dapat dilihat pada listing program di akhir postingan ini.

>>>LCD 2×16<<<

Disini saya tidak akan menjelaskan tentang hardware dari LCD, tetapi akan fokus kepada instruksi intruksi yang akan digunakan dalam mengakses LCD. Jika temanteman ingin paham lebih dalam lagi mengenai hardware dan pengalamatan memory LCD, teman teman dapat mendownload datasheet LCD 2×16 disini. Dibawah ini ada beberapa instruksi yang digunakan untuk mengakses LCD pada compiler CodeVision AVR:

lcd_clear() digunakan untuk menghapus LCD dan meletakkan kembali kursor ke kolom 0 baris 0.

lcd_gotoxy(unsigned char x,unsigner char y) Untuk meletakkan kursor ke kolom x baris y. Kolom dan baris pada LCD dimulai dari 0, sehingga kolom antara 0 15 dan baris 0 1 untuk LCD 2×16. contoh:

lcd_gotoxy(10,1) maka akan meletakkan kursor di kolom 10 dan baris 1

lcd_putsf(char flash *str) menampilkan karakter karakter yang ada dimemori flash pada alamat yang ditunjuk oleh pointer str ke LCD dengan posisi kursor saat ini. contoh:

lcd_putsf(“Electro_cOntrOl”) maka akan menampilkan tulisan Electro cOntrOl

lcd_puts(char *str) menampilkan karakter yang ada si memori RAM pada alamat yang ditunjuk oleh pointer str ke LCD dengan posisi kursor saat ini.

lcd_putchar(char c) digunakan untuk menampilkan karakter sesuai isi variabel c ke LCD dengan posisi kursor saat ini.

Untuk lebih jelasnya dapat temanteman lihat pada listing program. Berikut adalah schematic keypad dan LCD yang dihubungkan ke mikrokontroler.

keypad dan LCD yang dihubungkan ke mikrokontroler. #include <mega8535.h> #include <stdlib.h>

#include <mega8535.h> #include <stdlib.h> #include <delay.h> #include <lcd.h>

// Alphanumeric LCD Module functions #asm

.equ

#endasm

lcd_port=0×15 ;PORTC

void tekan_keypad_tampil_lcd() //penekanan keypad kemudian ditampilkan di LCD

{

PORTB = 0b11111110;

delay_ms(30);

if (PINB.4 == 0) {lcd_putsf(“1); delay_ms(300);} if (PINB.5 == 0) {lcd_putsf(“4); delay_ms(300);} if (PINB.6 == 0) {lcd_putsf(“7); delay_ms(300);} if (PINB.7 == 0) {lcd_putsf(“F”); delay_ms(300);} PORTB = 0b11111101;

delay_ms(30);

if (PINB.4 == 0) {lcd_putsf(“2); delay_ms(300);} if (PINB.5 == 0) {lcd_putsf(“5); delay_ms(300);} if (PINB.6 == 0) {lcd_putsf(“8); delay_ms(300);} if (PINB.7 == 0) {lcd_putsf(“0); delay_ms(300);} PORTB = 0b11111011;

delay_ms(30);

if (PINB.4 == 0) {lcd_putsf(“3); delay_ms(300);} if (PINB.5 == 0) {lcd_putsf(“6); delay_ms(300);} if (PINB.6 == 0) {lcd_putsf(“9); delay_ms(300);} if (PINB.7 == 0) {lcd_putsf(“E”); delay_ms(300);} PORTB = 0b11110111;

delay_ms(30);

if (PINB.4 == 0) {lcd_putsf(“A”); delay_ms(300);} if (PINB.5 == 0) {lcd_putsf(“B”); delay_ms(300);}

if (PINB.6 == 0) {lcd_putsf(“C”); delay_ms(300);} if (PINB.7 == 0) {lcd_putsf(“D”); delay_ms(300);}

}

void tampil_string()

{

lcd_gotoxy(0,0);

//menempatkan kursor lcd pada baris 0 kolom 0

lcd_putsf(“tampilan lcd2x16); //menampilkan tulisan tampilan lcd2x16

lcd_gotoxy(0,1); //menempatkan kursor lcd pada baris 1 kolom 0

lcd_putsf(“Elektro-cOntrOl”);

}

//menampilkan tulisan ElektrO-cOntrOl

void tampil_variabel()

{

//sebuah variabel yg akan ditampilkan kedalam LCD harus diubah dahulu kedalam tipe data

array //jika variabel bertipe data float maka diubah kedalan array dengan instruksi ftoa //jika variabel bertipe data int maka diubah kedalan array dengan instruksi itoa char temp[6]; int a=500; float b=123.45; itoa(a,temp);

lcd_gotoxy(0,0);

lcd_puts(temp); ftoa(b,2,temp); //angka 2, banyaknya digit dibelakang koma yg ditampilkan

lcd_gotoxy(0,1);

lcd_puts(temp);

}

void main(void)

{

PORTB = 0xff; DDRB = 0x0f;//PA0-3 sebagai output, PA4-7 sebagai input

while(1) //program utama

{

//tinggal dilakukan pemanggilan fungsi saja, contoh:

tampil_string(); //pemanggilan fungsi tampil_string() };

}

MEMBUAT SINYAL PWM MENGGUNAKAN TIMER AVR

Mungkin temanteman semua sudah tau pengertian dari PWM (Pulse Width Modulation), jadi saya tidak akan membahasnya lagi. Disini saya akan menjelaskan beberapa istilah yang berhubungan dengan PWM sehingga nantinya akan mempermudah temanteman dalam pembuatan sinyal PWM menggunakan Timer pada AVR.

dalam pembuatan sinyal PWM menggunakan Timer pada AVR. Gambar diatas merupakan sinyal PWM dengan amplitudo 5

Gambar diatas merupakan sinyal PWM dengan amplitudo 5 volt. Dari gambar diatas dapat diketahui pengertian dari 1 periode gelombang, yaitu lamanya interval waktu dalam 1 panjang gelombang, gambar diatas mempunyai periode 10 ms. sedangkan duty cycle, yaitu lamanya pulsa high (on) selama 1 periode, terlihat bahwa lamanya duty cycle 7 ms. Biasanya duty cycle ditulis dalam satuan persentase (%). Jika dari gambar diatas ingin mengubah duty cycle kedalam persen yaitu:

Duty cycle = (interval pulsa high dalam 1 periode/periode gelombang)*100% Sehingga gambar diatas mempunyai duty cycle sebesar 70%.

Jika periode suatu gelombang diketahui, maka dapat dihitung berapa frekuensinya,

menggunakan:

F=1/T

F

= Frekuensi (Hz)

T

= Periode (detik)

Maka frekuensi dari gambar diatasa adalah F = 1/10 ms= 100 Hz.

Untuk menghasilkan sinyal PWM pada AVR digunakan fitur timer. AVR Atmega 8535 mempunyai 3 buah timer, tetapi disini saya akan membahas Timer0 dan Timer1 saja yang digunakan untuk membangkitkan sinyal PWM. Pada dasarnya Timer0 dan Timer1 mempunyai 4 buah mode untuk membangkitkan sinyal PWM. Untuk lebih jelasnya temanteman baca datasheet saja.

Disini saya akan membangkitkan sinyal PWM menggunakan Timer0 dan timer1 dengan menggunakan 2 buah mode saja, yaitu Phase Correct PWM dan Fast PWM. Untuk pengertian dan penjelasan masing masing mode dapat dilihat didatasheet ATmega8535.

Output pin PWM pada Atmega8535 terdapat pada 2 buah pin yaitu PD4 (OC1B) dan PD5 (OC1A).

>>>Timer0<<<

Mode Phase Correct PWM Foc0 = Fosc/(N*512)

D = (OCR0/255)*100%

Mode Fast PWM Foc0 = Fosc/(N*256)

D = (OCR0/255)*100%

Dimana:

Foc0 = Frekuensi output OC0

N

= Skala clock (mempunyai nilai 1, 8, 64, 256 dan 1024)

D

= Duty cycle

Fosc = Frekuensi clock kristal yang digunakan

>>>Timer1<<<

Mode Phase Correct PWM Foc1a = Fosc/(2*N*TOP) Foc1b = Fosc/(2*N*TOP)

D = (OCR1X/TOP)*100%

Mode Fast PWM Foc1a = Fosc/(N*(1+TOP)) Foc1b = Fosc/(N*(1+TOP))

D = (OCR1X/TOP)*100%

Dimana:

Foc1a = Frekuensi output OC1A

Foc1b = Frekuensi output OC1B

N

= Skala clock (mempunyai nilai 1, 8, 64, 256 dan 1024)

D

= Duty cycle

Fosc = Frekuensi clock kristal yang digunakan TOP = nilai maksimum counter (TCNT1), TOP mempunyai 3 buah nilai untuk kedua mode

tersebut yaitu 8 bit (FF), 9 bit (1FF) dan 10 bit (3FF)

Sekarang saya akan membuat aplikasi membangkitkan sinyal PWM dengan periode 20 ms dengan duty cycle 75%, menggunakan Timer1 10 Bit Mode Fast PWM.

Dengan menggunakan kristal 12 Mhz, N = 256 dan TOP = 10 bit = 3FF = 1023

Maka akan didapat frekuensi output (Foc1x) sebesar 45,77 Hz atau jika diubah kedalam peroide 21,8 ms 20 ms

Untuk Duty cycle:

D = (OCR1X/TOP)*100% 75% = (OCR1X/1023)*100% OCR1X = 767 = 2FF (dalam hexa)

Untuk membangkitkan periode yang benar-benar presisi pada sinyal PWM sangat sulit sekali karena kita hanya mampu memanipulasinya lewat 3 parameter saja yaitu, frekuensi kristal yang kita gunakan (tidak semua nilai frekuensi kristal ada dipasaran), skala clock atau N (hanya mempunyai nilai 1, 8, 64, 256, 1024) dan TOP (untuk kedua mode diatas mempunyai 3 buah nilai 8, 9 dan 10 bit). Dengan kombinasi ketiga variabel diatas kita harus benar-benar dapat menentukan periode output yang kita inginkan, menurut saya itu sangat sulit sekali.

Untuk aplikasi diatas berikut adalah setting untuk CodeVision CodeWizard AVR. Clock Value bernilai 46.875 berasal dari Fosc/N atau 12 MHz/256.

Value bernilai 46.875 berasal dari Fosc/N atau 12 MHz/256. Penjelasan diatas adalah untuk membangkitkan sinyal PWM

Penjelasan diatas adalah untuk membangkitkan sinyal PWM sesuai dengan output yang kita inginkan, sedikit sulit memang. Tetapi pada dasarnya banyak sekali aplikasi yang menggunakan PWM tanpa harus memperdulikan kepresisian periode output, contohnya pengaturan motor DC. Untuk aplikasi pengaturan motor DC sangat simple sekali programnya.

Baiklah sekarang saya akan mengimplementasikan aplikasi pengaturan kecepatan motor DC menggunakan input yang berasal dari potensiometer. Cara kerjanya kecepatan motor DC diatur

oleh potensio yang nilainya didapat dari pembacaan ADC. Untuk PWM nya saya gunakan hasil dari yang diatas (Timer1 10 bit mode Fast PWM). Berikut adalah setting untuk CodeWizard AVR dan schematicnya:

adalah setting untuk CodeWizard AVR dan schematicnya: Berikut adalah listing program lengkapnya (sangat

Berikut adalah listing program lengkapnya (sangat simple):

#include <mega16.h> #include <delay.h> int potensio;

#define ADC_VREF_TYPE 0×00 // Read the AD conversion result unsigned int read_adc(unsigned char adc_input)

{

ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0×40;

// Wait for the AD conversion to complete while ((ADCSRA & 0×10)==0);

ADCSRA|=0×10;

return ADCW;

}

void main(void)

{

// Port D initialization // Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T

PORTD=0×00;

DDRD=0×30;

// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 46.875 kHz // Mode: Ph. correct PWM top=03FFh // OC1A output: Non-Inv. // OC1B output: Non-Inv. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off

TCCR1A=0xA3;

TCCR1B=0×04;

TCNT1H=0×00;

TCNT1L=0×00;

ICR1H=0×00;

ICR1L=0×00;

OCR1AH=0×02;

OCR1AL=0xFF;

OCR1BH=0×00;

OCR1BL=0×00;

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// ADC initialization // ADC Clock frequency: 750.000 kHz // ADC Voltage Reference: AREF pin

// ADC Auto Trigger Source: None ADMUX=ADC_VREF_TYPE & 0xff;

ADCSRA=0×84;

while (1)

{

potensio=read_adc(0);//membaca nilai ADC potensio OCR1A=potensio;//nilai potensio diumpan ke register PWM untuk ngatur kecepatan motor };

}

MENGAKSES MOTOR SERVO

Dipasaran terdapat 2 tipe motor servo yaitu servo standard dan servo rotation (continuous). Dimana biasanya untuk tipe standar hanya dapat melakukan pergerakan sebesar 180° sedangkan untuk tipe continuous dapat melakukan rotasi atau 360°.

Pada dasarnya motor servo tersusun dari motor DC, rangkaian kontrol, gearbox dan potensiometer. Berikut gambar motor servo beserta komponen internal motor servo.

DC, rangkaian kontrol, gearbox dan potensiometer. Berikut gambar motor ser vo beserta komponen internal motor servo.
DC, rangkaian kontrol, gearbox dan potensiometer. Berikut gambar motor ser vo beserta komponen internal motor servo.

Terlihat jelas bahwa motor DC yang digunakan sangat kecil (compact) sehingga motor servo memiliki dimensi yang cukup kecil jika dibandingkan dengan motor DC pada umumnya. Rangkaian kontrol pada motor servo digunakan untuk mengontrol motor DC yang ada pada motor servo, dikarenakan untuk mengakses motor servo kita harus memberikan pulsa-pulsa kepada sinyal kontrol tersebut. Gearbox berfungsi untuk meningkatkan torsi dari motor servo, sebernarnya terdapat dua macam bahan penyusun gearbox yang digunakan untuk motor servo yaitu metal gear (biasanya untuk torsi yang sangat besar) dan nylon gear (berwarna putih seperti gambar diatas). Dan potensiometer berfungsi untuk menentukan batas sudut dari putaran servo. Sedangkan sudut dari sumbu motor servo diatur berdasarkan lebar pulsa yang dikirimkan.

Dikarenakan bentuknya yang compact motor servo sering digunakan untuk aplikasi robotik, biasa digunakan untuk penggerak kaki dan tangan robot.

Servo motor mempunyai 3 buah pin yang terdiri dari VCC, GND dan pin SIGNAL. Berikut adalah konfigurasi pin motor servo berdasarkan merk.

adalah konfigurasi pin motor servo berdasarkan merk. Sekarang saya akan menjelaskan bagaimana cara mengakses

Sekarang saya akan menjelaskan bagaimana cara mengakses motor servo. Secara umum untuk mengakses motor servo tipe standard adalah dengan cara memberikan pulsa high selama 1,5 ms dan mengulangnya setiap 20 ms, maka posisi servo akan berada ditengah atau netral (0°). Untuk pulsa 1 ms maka akan bergerak berkebalikan arah jarum jam dengan sudut 90°. Dan pulsa high selama 2 ms akan bergerak searah jarum jam sebesar 90°. Untuk lebih jelasnya perhatikan gambar berikut.

high selama 2 ms akan bergerak searah jarum jam sebesar 90°. Untuk lebih jelasnya perhatikan gambar

Sedangkan untuk servo motor tipe continuous untuk berputar (rotasi) searah jarum jam harus diberi pulsa high selama 1,3 ms. Sedangkan untuk berputar berlawanan arah jarum jam harus diberi logika high selama 1,7 ms. Jika motor servo continous diberi pulsa high selama 1,5 ms maka akan berhenti.

diberi pulsa high selama 1,5 ms maka akan berhenti. Catatan: karakteristik lamanya pulsa high yang diberikan

Catatan: karakteristik lamanya pulsa high yang diberikan untuk mengatur motor servo tergantung dari merk yang digunakan dengan mengacu kepada datasheet.

Pin SIGNAL pada motor servo dapat dikoneksikan ke pin mana saja pada mikrokontroler, lihat gambar dibawah. Disini saya akan memberikan contoh program cara mengakses motor servo menggunakan program CodeVision AVR.

Dibawah ini beberapa fungsi program untuk mengakses motor servo standard. void gerak ‐ 90derajat() {

Dibawah ini beberapa fungsi program untuk mengakses motor servo standard.

void gerak90derajat()

{

PORTD.0=1;//memberikan pulsa high delay_ms(1);//pulsa high diberikan selama 1 ms

PORTD.0=0;

delay_ms(20)

}

void gerak90derajat()

{

PORTD.0=1;//memberikan pulsa high

delay_ms(2);//pulsa high diberikan selama 2 ms

PORTD.0=0;

delay_ms(20)

}

void gerak0derajat()

{

PORTD.0=1;//memberikan pulsa high delay_ms(1.5);//pulsa high diberikan selama 1,5 ms

PORTD.0=0;

delay_ms(20)

}

Sedangkan untuk motor servo continuous tidak jauh berbeda seperti motor servo standard.

void putarsearahjarumjam()

{

PORTD.0=1;//memberikan pulsa high delay_ms(1.3);//pulsa high diberikan selama 1,3 ms

PORTD.0=0;

delay_ms(20)

}

void putarlawanjarumjam()

{

PORTD.0=1;//memberikan pulsa high

delay_ms(1.7);//pulsa high diberikan selama 1,7 ms

PORTD.0=0;

delay_ms(20)

}

void stop()

{

PORTD.0=1;//memberikan pulsa high

delay_ms(1.5);//pulsa high diberikan selama 1,5 ms

PORTD.0=0;

delay_ms(20)

}

Jika direalisasikan pada program menjadi seperti dibawah ini, disini saya akan mencontohkan motor servo standar bergerak 90°.

#include <mega16.h> #include <delay.h>

void main(void)

{

PORTD=0×00;

DDRD=0×01;//portd.0 sebagai output

// Analog Comparator initialization // Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

while (1)

{

PORTD.0=1;//memberikan pulsa high delay_ms(2);//pulsa high diberikan selama 2 ms

PORTD.0=0;

delay_ms(20)

}

};

PENGUKURAN KEMIRINGAN MENGGUNAKAN ACCELEROMETER MMA7260 DENGAN CODEVISION AVR TERKALIBRASI

Sensor accelerometer mma7260 buatan Freescale Semiconductor ini mempunyai 6 buah fungsi yaitu untuk mengukur gerakan (movement), getaran (vibration ), jatuh (fall ), kemiringan ( tilt ), posisi (positioning ) dan benturan (shock ).

tilt ), posisi ( positioning ) dan benturan ( shock ). saya akan jelaskan bagaimana cara

saya akan jelaskan bagaimana cara mengakses sensor accelerometer mma7260 untuk mengukur kemiringan (tilt measurement) yang ditampilkan pada LCD 2×16 menggunakan compiler CodeVision AVR. Berikut adalah schematic accelerometer mma7260.

) yang ditampilkan pada LCD 2×16 menggunakan compiler CodeVision AVR. Berikut adalah schematic accelerometer mma7260.

Pada PD.0 dan PD.1 terdapat 2 buah push button yang digunakan untuk melakukan kalibrasi pada accelerometer, dikarenakan output mma7260 masih berupa tegangan analog yang tidak linear. Berikut adalah output sensor mma7260:

gambar output mma7260 sumbu X, Y, Z

sensor mma7260: gambar output mma7260 sumbu X, Y, Z Pada dasarnya model matematis persamaan garis diatas

Pada dasarnya model matematis persamaan garis diatas sudah diketahui dengan mengacu pada application note AN3107 Measuring Tilt with Low g Accelerometers.pdf adalah sebagai berikut:

Vout=Voffset+((sensitivitas)*1g *sin θ)

Vout adalah tegangan output accelerometer Voffset adalah VDD/2 atau saat percepatan=0g atau 1,65 Volt dari persamaan diatas dapat dirubah menjadi:

Vout=Voffset+S*sin θ;

S=sensitivitas

Ada beberapa cara metode untuk melakukan pembacaan kemiringan, yaitu:

1. Measuring Tilt Using One Axis;

Ax=(Voutx-Voffset)/S; Ax=percepatan sumbu X(gravitasi);

θ= arcsin (Ax);

dimana θ=kemiringan (sudut)

2. Measuring Tilt Using Two Axis Solution;

menggunakan sumbu X dan Z.

Ax=(Voutx-Voffset)/S; Az=(Voutz-Voffset)/S; θ=arctan (Ax/Az);

dimana θ=kemiringan (sudut)

3. Measuring Tilt Using Three Axis Solution

Ax=(Voutx-Voffset)/S;

Az=(Voutz-Voffset)/S;

Ay=(Vouty-Voffset)/S; ρ=arctan(Ax/(Ay²+Az²)); picth Φ=arctan(Ay/(Ax²+Az²)); roll

ø=arctan((Ax²+Ay²)/Az);

yaw

Dimana:

Ax = percepatan sumbu X Ay = percepatan sumbu Y Az = percepatan sumbu Z

Pada dasarnya jika kita mengacu pada persamaan garis diatas seharusnya kita sudah dapat menghasilkan pembacaan kemiringan dalam satuan derajat yang sudah presisi. Tapi dikarenakan adanya beberapa kelemahan, yang merujuk pada application note AN3447 yaitu:

Sources of offset errors can occur device to device based on offset variations from trim errors, mechanical stresses from the package and mounting, shifts due to temperature and due to aging. These variables can all change the offset. This can be very significant for many applications. The offset error alone can affect a tilt reading on a flat surface by as much as 12 degrees. That is an unacceptable error for this application.

Untuk menghilangkan ketidaklinearan sensor dan adanya kelemahan seperti yang diatas, maka perlu dilakukan kalibrasi (auto zero) yang mengacu pada application note AN3447 Implementing Auto Zero Calibration Technique for Accelerometers.pdf . Pada AN3447 ada beberapa metode untuk melakukan kalibrasi diantaranya:

1. Manual 0g X, Y, Z Full Range Calibration

2. Simple 0g X, Y, Z Calibration

3. Freefall Calibration, dan

4. Simple 0g X, 0g Y, +1g Z Calibration

Disini saya akan menggunakan metode kedua yaitu “Simple 0g X, Y, Z Calibration” dengan alasan dapat dilakukan dengan mudah, dengan pengambilan data melalui penekanan tombol (push button). Dimana pada kalibrasi ini data setiap sumbu X, Y dan Z diambil nilai saat 0g (zero gravitation), 1g (earth gravitation atau one gravitation) dan nilai selisih antara 1g dengan 0g (1g-0g atau dengan kata lain adalah Sensitivitas (S)).

Berikut adalah cuplikan program pengukuran kemiringan (tilt measurement) mma7260 menggunakan dua buah axis X dan Z (Dual Axis XZ) dengan range pengukuran -180 sampai +180 derajat dan cara kalibrasinya, dengan rata-rata error 0.4 derajat (dalam sudut) pada setiap pengukuran.

void kalibrasiZ()

{

if (PIND.0==0 && indeks==3) // kalibrasi Z

{

g0X = VoutX; g0Y = VoutY; g1Z = VoutZ;

// paralel to earth surface //Z_axis is vertical with Z label UP

indeks=2;

lcd_clear();

lcd_putsf(“proses cal. Z”);

delay_ms(3000);

}

}

void kalibrasiX()

{

if (PIND.0==0 && indeks==2)

// kalibrasi X

{

//X_axis is vertical with X label UP

g1X = VoutX; g0Z = VoutZ;

indeks=1;

lcd_clear(); lcd_putsf(“proses cal. X”);

delay_ms(3000);

}

}

void kalibrasiY()

{

if (PIND.0==0 && indeks==1)

{

g1Y = VoutY; //Y_axis is vertical with Y label UP

indeks=3;

lcd_clear(); lcd_putsf(“proses cal. Y”);

delay_ms(3000);

}

}

//kalibrasi Y

void baca_adc() //baca adc untuk sumbu X dan Z

{

VoutX = (float)read_adc(0); //0=sumbu X, 1=sumbu Y, 2=sumbu Z VoutZ = (float)read_adc(2);

}

void hitung_accelerometer()

{

Ax = (float)(VoutX – g0X)/(g1X g0X); //persamaan menghitung percepatan X Az = (float)(VoutZ g0Z)/(g1Z g0Z);

sudut = atan2(Ax,Az); //persamaan menghitung sudut, masih dlm radian sudut = (sudut*180)/3.14; //ubah ke dlm sudut

}

void tampilkan_lcd()

{

lcd_putsf(“sudut =”);

ftoa(sudut,1,temp); //nampilin nilai sudut

lcd_gotoxy(8,0);

lcd_puts(temp);

}

PENGUKURAN NEGATIVE THEMPERATURE (MINUS) MENGGUNAKAN LM35 DENGAN CODEVISION AVR

Menurut datasheet, LM35 dapat mengukur dengan range 55° sampai 150°C dengan akurasi 0,5°C. Untuk lebih jelasnya dapat dibaca pada datasheet. Aplikasi ini pun telah saya simulasikan menggunakan software proteus, dan mempunyai hasil yang sangat presisi untuk pembacaannya. Dibawah ini adalah schematic rangkaiannya:

pembacaannya. Dibawah ini adalah schematic rangkaiannya: Sedangkan untuk listing program lengkapnya adalah

Sedangkan untuk listing program lengkapnya adalah sebagai berikut, pada akhir postingan ini saya juga menyertakan file program dalam codevision AVR serta file simulasi proteus.

#include <mega16.h> #include <lcd.h> #include <delay.h> #include <stdlib.h>

int data1, data2; float suhu_minus; char temp[8];

// Alphanumeric LCD Module functions #asm

.equ

lcd_port=0×15 ;PORTC

#endasm

#define ADC_VREF_TYPE 0×40 // Read the AD conversion result

unsigned int read_adc(unsigned char adc_input)

{

ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0×40;

// Wait for the AD conversion to complete while ((ADCSRA & 0×10)==0);

ADCSRA|=0×10;

return ADCW;

}

void ambil_dataADC()

{

data1=read_adc(0);

data2=read_adc(1);

}

void hitung_suhu_minus()

{

suhu_minus=(float)(data1-data2)/2;//rumus mencari suhu minus

}

void tampil_LDC()

{

lcd_gotoxy(0,0);

lcd_putsf(“ElectrO-cOntrOl”); ftoa(suhu_minus,1,temp);//float to array

lcd_gotoxy(0,1);

lcd_puts(temp);

lcd_gotoxy(5,1);

lcd_putchar(0xdf);//menampilkan karakter derajat lcd_putsf(“C”);

}

void main(void)

{

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// ADC initialization // ADC Clock frequency: 750.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: None ADMUX=ADC_VREF_TYPE & 0xff;

ADCSRA=0×84;

// LCD module initialization

lcd_init(16);

while (1)

{

ambil_dataADC();

hitung_suhu_minus();

tampil_LDC();

delay_ms(500);

};

}

PENGUNCI PINTU (DOOR LOCK) BERPASSWORD MENGGUNAKAN KEYPAD DAN LCD DENGAN CODEVISION AVR

Mungkin teman-teman semua sudah tahu tentang aplikasi yang bernama pengunci pintu (door lock) berpassword, pada aplikasi ini sudah saya realisasikan pada hardware yang sesungguhnya dan berhasil.

Kesulitan utama dari aplikasi ini adalah ketika seorang user memasukkan password dengan menggunakan keypad, kita harus dapat menyimpan input yang berasal dari keypad kedalam satu variabel. Misalnya user menekan 6, lalu 2, lalu 0 dan 4 berarti passwornya adalah 6204 (misalkan). Nilai tersebut harus dijadikan dalam 1 variabel yang kemudian akan dibandingkan dengan password yang sebenarnya. Jika user memasukkan password dengan benar maka akan membuka kunci, jika salah maka kunci tidak akan terbuka.

Untuk mengatasi masalah tersebut saya menggunakan array untuk mendeteksi berapa kali penekanan keypad dan angka berapa yang akan ditekan. Baiklah disini saya akan menjelaskan algoritma yang saya buat. Jika user menekan 6, lalu 2 lalu 0 dan 4 maka seperti ini logikanya:

Awalnya saya deklarasikan array sebagai berikut:

array[10], i=0;

saat terjadi penekanan angka 6 maka; i++ (saya increamentkan) jadi i=1 kemudian angka 6 saya simpan pada variabel array[i] jadi array[1]=6

kemudian saat terjadi penekanan angka 2, maka:

i++ (saya increamentkan lagi) jadi i=2 kemudian angka 2 saya simpan pada variabel array[i] jadi array[2]=2

kemudian saat terjadi penekanan angka 0, maka:

i++ (saya increamentkan lagi) jadi i=3 kemudian angka 0 saya simpan pada variabel array[i] jadi array[3]=0

kemudian saat terjadi penekanan angka 4, maka:

i++ (saya increamentkan lagi) jadi i=4 kemudian angka 4 saya simpan pada variabel array[i] jadi array[4]=4

maka didapat array[1]=6, array[2]=2, array[3]=0, array[4]=4

kalo sudah didapat seperti diatas maka kita tinggal kumpulkan dalam satu variabel (nama variabelnya misalkan nilai) caranya:

saat i bernilai 1, i=1 kita hitung dengan rumus:

nilai=array[1] //jadi nilai=6

saat i bernilai 2, i=2 kita hitung dengan rumus:

nilai=(array[1]*10)+array[2] //jadi nilai=62

saat i bernilai 3, i=3 kita hitung dengan rumus:

nilai=(array[1]*100)+(array[2]*10)+array[3] //jadi nilai=620

saat i bernilai 4, i=4 kita hitung dengan rumus:

nilai=(array[1]*1000)+(array[2]*100)+(array[3]*10)+array[4] //jadi nilai=6204

Sudah mengerti bukan, dari rumus-rumus diatas masih dapat disederhanakan, menjadi:

jika

i=1

nilai=array[i]

jika i bernilai (i>=2 dan i<=8)

nilai=(nilai*10)+array[i]

Banyaknya penekanan tombol saya batasi sampai 8 kali. Sebenarnya saya ingin membuatnya sampai 10 kali tetapi saat saya coba tidak berjalan dengan lancar saat penekanan ke 9 kali. Saya tidak tahu kenapa? Jika teman-teman bisa memecahkannya tolong beri tahu saya!

Baiklah kembali lagi ke aplikasi yang akan kita buat. Langsung saja ke cara kerjanya, gambar rangkaiannya bisa anda lihat dibawah ini. Saat pertama kali alat ini saya nyalakan maka dalam keadaan tidak terkunci (unlock), untuk menguncinya (lock) anda harus menekan tombol = (lihat gambar keypad dibawah). Setelah terkunci, jika anda ingin membukanya kembali anda harus memasukkan passwordnya (jika sudah mengetikan password tekan tombol + untuk memasukkannya). Jika benar maka akan membuka kunci, tetapi jika salah kunci tidak akan terbuka. Ketika sudah terbuka maka cara kerjanya kembali lagi ke awal. Sedangkan tombol ON/C saya gunakan untuk menghapus password jika salah dalam pengetikannya. Untuk indikator kuncinya saya menggunakan sebuah LED, jika LED menyala maka dalam keadaan tidak terkunci dan jika mati dalam keadaan terkunci.

Berikut adalah listing program lengkapnya: #include <mega16.h> #include <delay.h> #include

Berikut adalah listing program lengkapnya:

#include <mega16.h> #include <delay.h> #include <stdlib.h> #include <stdio.h>

float nilai=0, password=12345678; char temp[12], array[10], i=0, indeks=0; //variabel indeks digunakan untuk mendeteksi jika indeks=0 unlock, indeks=1 lock

// Alphanumeric LCD Module functions #asm

.equ

lcd_port=0×15 ;PORTC

#endasm

#include <lcd.h>

void lock()

{

while (indeks==0)

{

lcd_gotoxy(0,0);

lcd_putsf(“Please press =”);

lcd_gotoxy(0,1);

lcd_putsf(“to lock”);

PORTB = 0b11111011;

delay_ms(30);

if (PINB.7 == 0)

{

indeks=1;

PORTD.0=1;//terkunci

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf(“locked”);

delay_ms(1000);

lcd_clear();

}

}

}

void enter()

{

if (nilai==password)

{

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf(“unlocked”);

delay_ms(1000);

i=0; nilai=0;

PORTD.0=0;//kunci terbuka

indeks=0;

}

else

{

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf(“wrong password”);

delay_ms(2500);

i=0; nilai=0; indeks=1;//karena password salah jadi masih terkunci

}

}

void simpan_dlm_1variabel()

{

if (i==1){nilai=array[i];} if (i>=2 && i<=8)

{

nilai=(nilai*10)+array[i];

}

}

void scanning_keypad()//scanning pendeteksian penekanan keypad

{

lcd_gotoxy(0,0);

lcd_putsf(“enter u’r pass”); PORTB = 0b11111110;

delay_ms(30);

if (PINB.4 == 0) {i++; array[i]=1; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.5 == 0) {i++; array[i]=4; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.6 == 0) {i++; array[i]=7; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.7 == 0) {lcd_clear();i=0;nilai=0;delay_ms(300);} PORTB = 0b11111101;

delay_ms(30);

if (PINB.4 == 0) {i++; array[i]=2; simpan_dlm_1variabel(); delay_ms(300);}

if (PINB.5 == 0) {i++; array[i]=5; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.6 == 0) {i++; array[i]=8; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.7 == 0) {i++; array[i]=0; simpan_dlm_1variabel(); delay_ms(300);} PORTB = 0b11111011;

delay_ms(30);

if (PINB.4 == 0) {i++; array[i]=3; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.5 == 0) {i++; array[i]=6; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.6 == 0) {i++; array[i]=9; simpan_dlm_1variabel(); delay_ms(300);} if (PINB.7 == 0) {delay_ms(300);} PORTB = 0b11110111;

delay_ms(30);

if (PINB.4 == 0) {delay_ms(300);} if (PINB.5 == 0) {delay_ms(300);} if (PINB.6 == 0) {delay_ms(300);} if (PINB.7 == 0) {enter();delay_ms(300);}

}

void tampil_lcd()

{

if (nilai>0)

{

ftoa(nilai,0,temp);

lcd_gotoxy(0,1);

lcd_puts(temp);

}

}

void main(void)

{

PORTB=0xff;

DDRB=0x0f;

PORTD=0×00;//PD0 belogika low atau dlm keadaan unlock awalnya DDRD=0×01;//PD0 sebagai output

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// LCD module initialization

lcd_init(16);

lcd_putsf(“ElectrO cOntrOl”);

delay_ms(1500);

lcd_clear();

while (1)

{

lock();

scanning_keypad();

tampil_lcd();

};

}

PROGRAM MENGAKSES SENSOR JARAK PING))) PARALLAX MENGGUNAKAN CODEVISION AVR

Sensor jarak ultrasonic Parallax PING))) mampu mengukur jarak dengan teliti dan tanpa kontak antara 2 cm (0.8 inche) sampai 3 meter (3.3 yard). Sangat mudah untuk dikoneksikan dengan mikrokontroler, hanya membutuhkan satu pin I/O.

Sensor PING))) berkerja dengan mentransmisikan sebuah ultrasonic burst (diatas batas pendengaran manusia) dan menghasilkan sebuah pulsa output yang berhubungan dengan waktu yang dibutuhkan oleh echo dari burst untuk kembali ke sensor. Dengan mengukur lebar pulsa echo jarak sensor ke target dapat dihitung.

Karakteristik

* Tegangan suplai

* Konsumsi arus

* Jarak

* Input Trigger

* Echo Pulse

* Echo Hold-off

* Burst Frequency

* Burst Indicator LED shows sensor activity

* Delay before next measurement : 200 µs

* Size

: 5VDC

: 30 mA typ; 35 mA max

: 2 cm sampai 3 m (0.8 in sampai 3.3 yrd)

: positive TTL pulse, 2 uS min, 5 µs typ

: positive TTL pulse, 115 uS to 18.5 ms

: 750 µs from fall of Trigger pulse

: 40 kHz for 200 µs

: 22 mm H x 46 mm W x 16 mm D (0.84 in x 1.8 in x 0.6 in)

Berikut adalah program pembacaan jarak (cm) menggunakan sensor ultrasonik PING))) buatan Parallax. Pada program dibawah ini menggunakan frekuensi kristal 4Mhz, dan pin output dari PING))) dihubungkan ke port PB0, LCD pada PC.

//Clock frequency

//output sensor PING))) ke PB0

//LCD ke PC

: 4.000000 MHz

#include <mega8535.h> #include <lcd.h> #include <stdio.h> #include <delay.h>

// Alphanumeric LCD Module functions #asm

.equ

#endasm

lcd_port=0×15 ;PORTC

//deklarasi PIN I/O PING #define PULSE PORTB.0 #define ECHO PINB.0 #define ARAH DDRB.0 #define OUT 1 #define INP 0

unsigned int ultrasonic()

{

unsigned int count=0;

unsigned int jarak;

ARAH=OUT;//mengatur PIN I/O sebagai output PULSE=1;//memberikan tanda ke PING untuk memancarkan ultrasonic burst delay_us(5);//waktu tunggu sebelum pengukuran min. 2us biasanya 5us PULSE=0;//menberikan sinyal low ke PING ARAH=INP;//arah PIN I/O diatur sebagai input PULSE=1;//mengatur PIN I/O sebagai pill-up

while (ECHO==0) {};//menunggu sinyal ECHO high

while (ECHO==1)

{

count++; //menghitung lebar sinyal ECHO high

}

jarak=(unsigned int)(((float)count)/25);//nilai pembagi dikalibrasi sampai sesuai dengan satuan yang diinginkan return(jarak);//mengembalikan jarak ke fungsi ultrasonic dengan tipe data unsigned int

}

void main(void)

{

unsigned char kata[16];

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// LCD module initialization

lcd_init(16);

while (1)

{

sprintf(kata, “J=%3d cm”, ultrasonic());//menyusun karakter ke dalam satu baris dengan menggunakan fungsi sprintf lcd_clear();

lcd_gotoxy(0,0);

lcd_puts(kata);//mengirim data ke LCD

delay_ms(300);

}

}

PROGRAM MENGAKSES SENSOR JARAK SHARP GP2D12 MENGGUNAKAN CODEVISION AVR

Pada postingan ini saya akan menjelaskan bagaimana cara mengkalibrasi sensor GP2D12 dan programnya menggunakan CodeVision AVR. Akhirnya saya dapat menyelesaikan kalibrasi sensor Sharp GP2D12, dimana saya sebelumnya hanya mencoba program yang berasal dari beberapa blog.

nya hanya mencoba program yang berasal dari beberapa blog. Dari blog tersebut saya mendapatkan persamaan jarak

Dari blog tersebut saya mendapatkan persamaan jarak untuk sensor GP2D12 adalah sebagai berikut.

jarak = (1611/data_adc)-3;

(tidak saya rekomendasikan untuk range 10-80 cm)

Ternyata setelah saya coba hasilnya lumayan baik, tetapi hanya pada range 10-40 cm saja. Dikarenakan saya membutuhkan pembacaan yang presisi dan mempunyai range yang cukup lebar yaitu full range (10-80 cm), maka saya mencoba melakukan kalibrasi sendiri dengan menggunakan metode Trendline (fitur dari MS. Excel). Baiklah dibawah ini beberapa penjelasan singkat tentang sensor Sharp GP2D12.

GP2D12 adalah sensor pengukur jarak yang diproduksi oleh Sharp. Sensor ini mengeluarkan sinyal analog dan mampu mengukur jarak pada rentang 10 – 80 cm.

Prinsip kerja sensor inframerah ini dalam mengukur jarak berbeda dengan sensor ultrasonik yang menggunakan waktu pantul gelombang bunyi karena waktu pantul cahaya jelas terlalu singkat untuk dapat diukur. Cahaya inframerah dengan frekuensi 40 kHz dipancarkan dan hasil pantulannya diterima oleh susunan detektor inframerah. Sudut pantulan sinar inframerah akan berubah sesuai jarak sensor dan obyek.

Antarmuka sensor GP2D12 dengan AVR sangatlah mudah, namun sayangnya output analog sensor ini sangatlah tidak linier.

Untuk mengatasi masalah ketidaklinearan sensor tersebut disini saya melakukan kalibrasi menggunakan metode Trendline dengan menggunakan MS. Exel.

Dari hasil kalibrasi yang saya lakukan dengan menggunakan ADC 8 bit, didapat persamaan jarak untuk sensor GP2D12 adalah:

8 bit, didapat persamaan jarak untuk sensor GP2D12 adalah: atau jika direalisasikan ke dala m program

atau jika direalisasikan ke dalam program CodeVision AVR, menjadi:

jarak=(float)((1/((0.04*Vout)-0.006)-0.42));

Nilai dari variabel Vout pada persamaan diatas masih merupakan tegangan keluaran (Volt) sensor GP2D12, sehingga perlu pengubahan dari nilai biner ADC 8 bit ke dalam bentuk tegangan keluaran sensor (Vout) tersebut, caranya:

Vout=read_adc(0);

Vout=Vout/51;

Berdasarkan datasheet GP2D12 perbandingn tegangan keluaran sensor dengan jarak adalah sebagai berikut:

Terlihat jelas dari grafik diatas bahwa hubungan antara tegangan keluaran sensor dengan jarak sangat tidak

Terlihat jelas dari grafik diatas bahwa hubungan antara tegangan keluaran sensor dengan jarak sangat tidak linear.

Tetapi menurut application note sensor GP2D12 mempunyai hubungan yang cukup linear antara tegangan keluaran sensor (Vout) dengan 1/(distance+K), K bernilai 0,42 untuk tipe GP2D12. Berukut adalah grafik hubungannya:

sensor (Vout) dengan 1/(distance+K), K bernilai 0,42 untuk tipe GP2D12. Berukut adalah grafik hubungannya:

Sumbu X merupakan output sensor sedangkan sumbu Y adalah 1/(distance+K). Berdasarkan grafik diatas kita sudah dapat menggunakan persamaan metode Trendline yang ada pada MS. Exel. Baiklah berikut adalah beberapa langkah panduan melakukan kalibrasi sensor GP2D12:

LANGKAH PERTAMA Teman-teman harus melakukan pengukuran dari 10-80 cm setiap kelipatan 5. Kemudian me- Record setiap tegangan keluarannya. Kemudian berikan nilai untuk X=Vout dan untuk Y=1/(distance+K), K=0,42. Teman-teman dapat menggunakan Voltmeter untuk me-Record tegangan keluaran sensor.

Atau jika temanteman malas menggunakan Voltmeter temanteman dapat melihat tegangan keluarannya menggunakan sebuah program yang difungsikan untuk menghitung tegangan keluran sensor yang kemudian ditampilkan pada LCD menggunakan mikrokontroler. Berikut adalah hasil yang saya dapatkan:

j arak X=Vout (Volt)

K=0.42

Y=1/(distance+k)

10

2.4

0.09596929

15

1.8

0.064850843

20

1.4

0.048971596

25

1.1

0.039339103

30

1

0.03287311

35

0.86

0.028232637

40

0.78

0.024740228

45

0.7

0.022016733

50

0.63

0.019833399

55

0.6

0.018044027

60

0.55

0.016550811

65

0.5

0.015285845

75

0.43

0.013259082

80 0.41

0.012434718

LANGKAH KEDUA Setelah mendapatkan nilai X dan Y untuk tabel diatas, plot tabel tersebut kedalam grafik pada MS. Exel dengan type grafik XY scatter. Maka akan muncul grafik seperti GAMBAR 2 seperti diatas.

Kemudian klik pada grafik dan pilih menu trendline di MS. Exel, caranya LAYOUT ANALYSIS TRENDLINE MORE TRENDLINE OPTIONS sesuaikan dengan gambar berikut. Kemudian CLOSE.

→ sesuaikan dengan gambar berikut. Kemudian CLOSE. Maka akan muncul trendline persamaan seperti gambar

Maka akan muncul trendline persamaan seperti gambar dibawah ini:

Akhirnya sekarang kita dapat persamaan trendline nya yaitu Y=0.04X-0.006 LANGKAH KETIGA (TERAKHIR) Langkah terakhir ini

Akhirnya sekarang kita dapat persamaan trendline nya yaitu Y=0.04X-0.006

LANGKAH KETIGA (TERAKHIR) Langkah terakhir ini digunakan untuk mendapatkan persamaan akhir yang akan dipakai pada program untuk menghitung jarak dari sensor Sharp GP2D12.

Caranya:

X=Vout Y=1/(distance+K) K=0.42

Disubtitusikan ke persamaan trendline yaitu:

Y=0.04X-0.006

Menjadi:

1/(distance+0.42)=(0.04*Vout)-0.006

Sehingga:

distance=((1/((0.04*Vout)-0.006)-0.42))

Atau dalam program menggunakan CodeVision menjadi:

jarak=(float)((1/((0.04*Vout)-0.006)-0.42));

Nilai dari Vout masih merupakan tegangan keluaran sensor GP2D12, sehingga perlu pengubahan dari nilai biner ADC 8 bit ke dalam bentuk tegangan keluaran sensor (Vout) tersebut, caranya:

Vout=read_adc(0);

Vout=Vout/51;

Berikut adalah listing program lengkap GP2D12, dengan output sensor GP2D12 masuk ke PA0:

//output sensor ke PA0

#include <mega16.h> #include <lcd.h> #include <stdlib.h> #include <delay.h>

int baca_adc; float jarak, vo; char temp[6];

// Alphanumeric LCD Module functions #asm

.equ

#endasm

lcd_port=0×15 ;PORTC

#define ADC_VREF_TYPE 0×60 // Read the 8 most significant bits // of the AD conversion result

unsigned char read_adc(unsigned char adc_input)

{

ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0×40;

// Wait for the AD conversion to complete while ((ADCSRA & 0×10)==0);

ADCSRA|=0×10;

return ADCH;

}

void baca_sensor()

{

baca_adc=read_adc(0);

vo= (float)baca_adc/51;

}

void gp2d12()

{

jarak=(float)((1/((0.04*vo)-0.006)-0.42));

}

void tampil_lcd()//menampilkan jarak ke LCD

{

lcd_clear(); lcd_putsf(“ElectO-cOntrOl”); ftoa(jarak,1,temp);//menampilkan nilai jarak yg sesungguhnya

lcd_gotoxy(0,1);

lcd_puts(temp);

lcd_gotoxy(4,1);

lcd_putsf(“cm”); ftoa(vo,2,temp); //menampilkan nilai dari Vout (tegangan keluaran sensor)

lcd_gotoxy(9,1);

lcd_puts(temp);

delay_ms(2000);

}

void main(void)

{

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// ADC initialization // ADC Clock frequency: 750.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: None // Only the 8 most significant bits of // the AD conversion result are used ADMUX=ADC_VREF_TYPE & 0xff;

ADCSRA=0×84;

// LCD module initialization

lcd_init(16);

while (1)

{

baca_sensor();

gp2d12();

tampil_lcd();

}

};

CATATAN: sebenarnya temanteman sudah bisa langsung menggunakan program diatas, tetapi dikarenakan karakteristik setiap sensor dengan tipe yang sama bisa saja berbeda, maka saya merekomendasikan untuk melakukan kalibrasi terlebih dahulu.

SCIENTIFIC CALCULATOR MENGGUNAKAN CODEVISION AVR

Saya menemukan aplikasi scientific calculator ini di situs www.avrprojects.info, aplikasi ini merupakan sebuah kalkulator dengan menggunakan keypad dan ditampilkan pada LCD. Cukup menarik, dan ternyata sudah disimulasikan menggunakan software Proteus dan berhasil, algoritma programnya pun cukup baik dan efisien. Berikut adalah schematic rangkaiannya sedangkan untuk listing program lengkap dapat didownload diakhir artikel ini.

program lengkap dapat didownload diakhir artikel ini. /* To download other free projects visit

/*

To download other free projects visit www.electrocontrol.wordpress.com

*/

#include <mega16.h>

#include <delay.h>

#include <lcd.h>

#include <stdlib.h>

#include <math.h>

#asm

.equ

#endasm

lcd_port=0x18

//#############################################

int key(void);

float _Main(void);

void Mohandes(void);

void Mohasebe(void);

void Alamat(int,int);

float Emoji(int);

//#############################################

float a = 0 , b = 0 , c = 0 , q , t;

int i ;

char y=0 , lcd[25] , z ;

//#############################################

void main(void){

DDRB=0x0F;

DDRC=0x07;

DDRD=0x0F;

lcd_init(16);

while (1){

_Main();

}

}

//#############################################################

float _Main(void){

int Loop = 1 ;

y = key();

if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}

if( y < 10 ){

a = (a*10)+y ;

itoa(y , lcd);

lcd_puts(lcd);

delay_ms(50);

}

if( y > 9 && y < 16 ){

if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}

z = y ;

Alamat(y,1);

while(Loop){

y = key();

if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}

if( y < 10 ){

b = (b*10)+y ;

itoa(y , lcd);

lcd_puts(lcd);

delay_ms(50);

}else if(y == 14){

lcd_putchar('=');

Mohasebe();

}

y = 0 ;

Loop = 0 ;

}

}

if( y > 15 ){

lcd_clear();

a= 0 ; b = 0 ; c = 0;

Alamat(y , 2);

z = y ;

Loop = 1 ;

while(Loop){

y = key();

if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}

if(y < 10){

a = (a*10) + y ;

itoa(y , lcd);

lcd_puts(lcd);

delay_ms(50);

}else if ( y == 14){

lcd_putchar('=');

Mohandes();

}

Loop = 1 ;

}

}

return 0;

}

//##########################################################

void Mohasebe(void){

if(z == 10)c = a / b ;

if(z == 11)c = a * b ;

if(z == 12)c = a b ;

if(z == 13)c = a + b ;

ftoa(c , 3 , lcd);

lcd_puts(lcd);

delay_ms(100);

}

//#########################################################

float Emoji(int rr){

q=1;

for(i=0;i<rr;i++)q = q * 2.71728 ;

return q;

}

//#########################################################

void Mohandes(void){

t = (3.1415926535897932384626433832795/180)*a ;

if(z == 16)c = sin(t) ;

if(z == 17)c = cos(t) ;

if(z == 18)c = tan(t) ;

if(z == 19)c = 1/tan(t) ;

if(z == 20)c = asin(t) ;

if(z == 21)c = acos(t) ;

if(z == 22)c = log(a) ;

if(z == 23)c = sqrt(a) ;

if(z == 24)c = Emoji(a) ;

ftoa(c , 3 , lcd);

lcd_puts(lcd);

delay_ms(100);

}

//#########################################################

void Alamat(int Moji,int Halat){

if(Halat == 1){

if(Moji == 10)lcd_putchar('/') ;

if(Moji == 11)lcd_putchar('*') ;

if(Moji == 12)lcd_putchar(' ') ;

if(Moji == 13)lcd_putchar('+') ;

delay_ms(100);

}

if(Halat == 2){

if(Moji == 16)lcd_putsf("Sin ") ;

if(Moji == 17)lcd_putsf("Cos ") ;

if(Moji == 18)lcd_putsf("Tan ") ;

if(Moji == 19)lcd_putsf("Cot ") ;

if(Moji == 20)lcd_putsf("aSin") ;

if(Moji == 21)lcd_putsf("aCos") ;

if(Moji == 22)lcd_putsf("Log ") ;

if(Moji == 23)lcd_putsf("Sqrt ") ;

if(Moji == 24)lcd_putsf("exp ") ;

delay_ms(100);

}

}

//#########################################################

int key(void){

char KEY = 1 ;

while(KEY){

PORTD.0 = 1 ;

PORTD.1 = 0 ;

PORTD.2 = 0 ;

PORTD.3 = 0 ;

if(PIND.4 == 1){return 7 ; KEY = 0;delay_ms(50);}

if(PIND.5 == 1){return 8 ; KEY = 0;delay_ms(50);}

if(PIND.6 == 1){return 9 ; KEY = 0;delay_ms(50);}

if(PIND.7 == 1){return 10; KEY = 0;delay_ms(50);}

//==========================================

PORTD.0 = 0 ;

PORTD.1 = 1 ;

PORTD.2 = 0 ;

PORTD.3 = 0 ;

if(PIND.4 == 1){return 4 ; KEY = 0;}

if(PIND.5 == 1){return 5 ; KEY = 0;}

if(PIND.6 == 1){return 6 ; KEY = 0;}

if(PIND.7 == 1){return 11; KEY = 0;}

//==========================================

PORTD.0 = 0 ;

PORTD.1 = 0 ;

PORTD.2 = 1 ;

PORTD.3 = 0 ;

if(PIND.4 == 1){return 1 ; KEY = 0;}

if(PIND.5 == 1){return 2 ; KEY = 0;}

if(PIND.6 == 1){return 3 ; KEY = 0;}

if(PIND.7 == 1){return 12; KEY = 0;}

//==========================================

PORTD.0 = 0 ;

PORTD.1 = 0 ;

PORTD.2 = 0 ;

PORTD.3 = 1 ;

if(PIND.4 == 1){return 15; KEY = 0;}

if(PIND.5 == 1){return 0 ; KEY = 0;}

if(PIND.6 == 1){return 14; KEY = 0;}

if(PIND.7 == 1){return 13; KEY = 0;}

//=============================================================================

PORTC.0 = 1 ;

PORTC.1 = 0 ;

PORTC.2 = 0 ;

if(PINC.5 == 1){return 16 ; KEY=0;}

if(PINC.6 == 1){return 17; KEY=0;}

if(PINC.7 == 1){return 18 ; KEY=0;}

//=====================================================

PORTC.0 = 0 ;

PORTC.1 = 1 ;

PORTC.2 = 0 ;

if(PINC.5 == 1){return 19 ; KEY=0;}

if(PINC.6 == 1){return 20 ; KEY=0;}

if(PINC.7 == 1){return 21 ; KEY=0;}

//=====================================================

PORTC.0 = 0 ;

PORTC.1 = 0 ;

PORTC.2 = 1 ;

if(PINC.5 == 1){return 22 ; KEY=0;}

if(PINC.6 == 1){return 23 ; KEY=0;}

if(PINC.7 == 1){return 24 ; KEY=0;}

KEY = 1 ;

}

}

//############################################################

SIMPLE STOPWATCH MENGGUNAKAN MIKROKONTROLER DENGAN CODEVISION AVR

Aplikasi ini merupakan sebuah stopwatch sederhana yang dapat menghitung sampai satuan waktu terkecil yaitu 1/100 detik atau 10 ms. Untuk membangkitkan timer 10 ms saya menggunakan fitur timer0 mikrokontroler AVR. Untuk lebih jelas mengenai fitur timer AVR silakan baca postingan saya mengenai tutorial Timer dan Counter AVR.

Pada aplikasi ini terdapat 3 buah tombol (push button) yang terdiri dari tombol START, STOP dan RESET. Tombol START digunakan untuk memulai stopwatch, STOP digunakan untuk memberhentikan stowatch dan tombol RESET untuk mereset (menset ulang kembali nilai stopwatch).

Saya juga menyertakan program dalam file CodeVision AVR dan file simulasi proteus pada akhir artikel ini. Berikut adalah schematik rangkaiannya.

file CodeVision AVR dan file simulasi proteus pada akhir artikel ini. Berikut adalah schematik rangkaiannya.
file CodeVision AVR dan file simulasi proteus pada akhir artikel ini. Berikut adalah schematik rangkaiannya.

unsigned char count, temp[16], indeks=0, detik=0, menit=0, jam=0;

#include <mega16.h> #include <stdio.h> #include <stdlib.h>

// Alphanumeric LCD Module functions #asm

.equ

lcd_port=0×15 ;PORTC

#endasm #include <lcd.h>

// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{

// Reinitialize Timer 0 value

TCNT0=0x8A;

count++;

}

void hitung_waktu()

{

if (count>=100)

{

lcd_clear();

detik++;

count=0;

}

if (detik>=60)

{

menit++;

detik=0;

}

if (menit>=60)

{

jam++;

menit=0;

}

}

void detek_tombol()

{

if (PINA.0==0 && (indeks==0 || indeks==2))//start timer

{

indeks=1;

TIMSK=0×01;//memulai timer lcd_clear();

}

if (PINA.1==0 && indeks==1)//stop timer

{

indeks=2;

TIMSK=0×00;//menstop timer lcd_clear();

}

if (PINA.2==0 && indeks==2)//reset timer

{

indeks=0;//semua data direset

count=0;

detik=0;

menit=0;

jam=0;

lcd_clear();

}

}

void tampil_lcd()

{

lcd_gotoxy(0,0);

sprintf(temp,”Timer %d:%d:%d:%d”,jam,menit,detik,count); lcd_puts(temp);//tampilkan waktu di LCD baris pertama if (indeks==0)

{

lcd_gotoxy(0,1);

lcd_putsf(“START”);

}

if (indeks==1)

{

lcd_gotoxy(0,1);

lcd_putsf(“STOP”);

}

if (indeks==2)

{

lcd_gotoxy(0,1);

lcd_putsf(“START

}

}

void main(void)

{

PORTA=0x0f;

DDRA=0×00;

RESET”);

// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 11.719 kHz // Mode: Normal top=FFh // OC0 output: Disconnected

TCCR0=0×05;

TCNT0=0x8A;

OCR0=0×00;

// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0×80;

SFIOR=0×00;

// LCD module initialization

lcd_init(16);

// Global enable interrupts #asm(“sei”)

while (1)

{

detek_tombol();

hitung_waktu();

tampil_lcd();

};

}

MENGAKSES MODUL SENSOR GYROSCOPE LISY300 TERKALIBRASI MENGGUNAKAN CODEVISION AVR

[OVERVIEW] Sensor gyroscope yang saya gunakan ini adalah sebuah modul yang terdiri dari sensor Gyroscope LISY300AL dan ADC serial ADC101S021 yang dikeluarkan oleh PARALLAX Inc. Pada modul ini pun telah dilengkapi dengan regulator tegangan 3.3 V sebagai supply nya. Modul Sensor Gyroscope LISY300AL dapat mendeteksi kecepatan sudut (angular rate) satu axis, yaitu sumbu Z (yaw). Dan mampu membaca sampai ± 300°/s full scale.

Z (yaw). Dan mampu membaca sampai ± 300°/s full scale. [PROTOKOL KOMUNIKASI] Pada dasarnya output dari