Kreasi pembaca lanjutan dari tulisan
sebelumnya merupakan penggabungan dari beberapa pembahasan mengenai penulisan ke
lcd dan topik yang membahas tentang
ADC (Analog To Digital Converter). Sinyal yang diterima oleh mic condenser kemudian dikuatkan dua kali oleh op-amp LM358 kemudian output yang berupa tegangan ini akan memberikan inputan menuju ADC port pada minimum system 8535. Sebelumnya alangkah baiknya kita ketahui dulu bagaimana response tegangan dengan suara yang tidaklah linear akan tetapi logaritmik.
Microcontroller 8 bit akan mengalami kesulitan jika dipaksakan berhitung di skala logarithmic (entah micronya yg bakal error atau kepala yg bikin script akan pusing hebat). Nah untuk itu kita akan mengambil sampling data sound level dari sebuah bunyi (tone generator) , kemudian kita ukur pada dbMeter yang difungsikan sebagai kalibrator. Pada saat yang bersamaan kita catat pula level pembacaan ADC yang keluar pada layar LCD minimum system.
Karena sudah memakai minimum system maka rangkaian yg kita tampilkan hanya berupa penguat dari mic condenser.
Klik gambar untuk memperjelas gambar
*) VCC 5v tidak sebagai input, melainkan input dari supply 9-12v
Jika pembaca sudah terbiasa dengan pembahasan ADC ungkin akan sangat mudah tetapi tetap saja saya tempel scriptnya demi kemudahan bagi pembaca setia.
//Insisialisasi awal
#define F_CPU 4000000UL //frek minsys 8535 versi innovative
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
// silahkan baca pembahasan menulis di lcd
//fungsi untuk menulis angka ke ASCII LCD
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s)-1; i < j; i++, j--){
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) // record sign
n = -n; // make n positive
i = 0;
do { // generate digits in reverse order
s[i++] = n % 10 + '0'; // get next digit
} while ((n /= 10) > 0); // delete it
if (sign < 0)
s[i++] = '-';
s[i] = '\0'; // add null terminator for string
reverse(s);
}
//insisialisasi ADC
void initADC()
{
ADMUX=(1<<REFS0);// Aref=AVcc;
ADCSRA=(1<<ADEN)|(1<<ADIE)|(7<<ADPS0);
MCUCR |= _BV(SE); // Sleep Enable, jadi abis ini processor diturunkan loadnya
MCUCR |=_BV(SM0); // mode ADC NOISE REDUTION
}
//Baca ADC, pilih pin portA yg diinginkan
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
ADCSRA|=(1<<ADIF);
return(ADC);
}
int main(void)
{
uint16_t baca,decimal,pecahan;
uint8_t a;
//inisialisasi port I/O
//PORTC menuju LCD & BUzzer
//PC0=buzzer, dapat tidak digunakan
DDRC |= (1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6)|(1<<PC7);
//PC1=Rs PC2=R/W PC3= E PC4-PC7 = data lcd 4 bit
//inisialisasi LCD
lcd_init(LCD_DISP_ON);
lcd_clrscr();
initADC();
char dum; //dum = variabel sementara penyimpan angka
while(1)
{
baca=ReadADC(1); //baca tegangan output op-amp
lcd_clrscr();
lcd_gotoxy(0,0);
// baca merupakan binner 10 bit, range 0-5V
// jadi binnernya 0-1023
// berikut ini untuk buat animasi level VU
for(a=0; a< (baca/64); a++)
{
if(a<16) lcd_putc(0xFF); //tulis kotak ke LCD sesuai level
}
// yang ini penentuan level buzzer, gunakan sesuai keinginan
if(a>13) PORTC|=(1<< PC0);
else PORTC &= ~(1<< PC0);
//buzzer dapat tidak digunakan
decimal= (baca * 5)/1000 ;
pecahan= ( ((baca * 5) - (decimal * 1000) ) /10);
// tampilan tegangan ke LCD
lcd_gotoxy(0,1);
lcd_puts("teg =");
itoa(decimal,&dum);
lcd_puts(&dum);
lcd_putc(',');
if(pecahan <10) lcd_putc('0');
itoa(pecahan,&dum);
lcd_puts(&dum);
lcd_puts(" V ");
_delay_ms(100); //delay pembacaan, ubah2 sesuai keinginan, makin cepet susah dibaca tapi makin realtime
}
return 0;
}
Selanjutnya jika menginginkan perhitungan dB (desibel) dari level suara, maka kita buat tabel seperti contoh berikut :
dB P1 P2 P3 AVG BINER
45 2.09 2.22 2.12 2.14 429
50 2.12 2.25 2.19 2.19 437
47 2.15 2.27 2.21 2.21 442
48 2.18 2.31 2.22 2.24 447
49 2.25 2.32 2.23 2.27 453
51 2.28 2.34 2.24 2.29 457
52 2.32 2.35 2.26 2.31 462
53 2.36 2.37 2.27 2.33 467
55 2.41 2.39 2.29 2.36 473
56 2.47 2.42 2.31 2.40 480
58 2.53 2.44 2.33 2.43 487
59 2.56 2.46 2.34 2.45 491
61 2.57 2.48 2.35 2.47 493
62 2.59 2.49 2.37 2.48 497
65 2.60 2.53 2.41 2.51 503
67 2.62 2.54 2.43 2.53 506
68 2.63 2.56 2.44 2.54 509
70 2.66 2.58 2.47 2.57 514
Dengan perolehan data seperti diatas maka dapat dilakukan pengambilan sample level db vs voltage(rata-rata) kemudian secara mudah dapat dilakukan menggunakan lookup array ataupun paling primitif menggunakan "IF ELSE" saja seperti contoh berikut:
if( baca <= 429) lcd_puts("<45 dB");
else if( baca > 429 && baca <= 437 ) lcd_puts(" 45 dB");
else if( baca > 437 && baca <= 442 ) lcd_puts(" 50 dB");
else if( baca > 442 && baca <= 447 ) lcd_puts(" 47 dB");
else if( baca > 447 && baca <= 453 ) lcd_puts(" 48 dB");
else if( baca > 453 && baca <= 457 ) lcd_puts(" 49 dB");
else if( baca > 457 && baca <= 462 ) lcd_puts(" 51 dB");
else if( baca > 462 && baca <= 467 ) lcd_puts(" 52 dB");
else if( baca > 467 && baca <= 473 ) lcd_puts(" 53 dB");
else if( baca > 473 && baca <= 480 ) lcd_puts(" 55 dB");
else if( baca > 480 && baca <= 487 ) lcd_puts(" 56 dB");
else if( baca > 487 && baca <= 491 ) lcd_puts(" 58 dB");
else if( baca > 491 && baca <= 493 ) lcd_puts(" 59 dB");
else if( baca > 493 && baca <= 497 ) lcd_puts(" 61 dB");
else if( baca > 497 && baca <= 503 ) lcd_puts(" 62 dB");
else if( baca > 503 && baca <= 506 ) lcd_puts(" 65 dB");
else if( baca > 506 && baca <= 509 ) lcd_puts(" 67 dB");
else if( baca > 509 && baca <= 514 ) lcd_puts(" 68 dB");
else if( baca > 514 ) lcd_puts(">70 dB");
Hasilnya pada video berikut ...jangan terkejut alau kualitas video jelek dan ada suara latar yang sangat "menggetarkan hati..."
Dan seperti biasa kabar gembira muncul dari hasil bimbinganku ini, tugas akhir yang dibuat mahasiswi dari aceh ini mendapatkan nilai "A" . Duh ...senangnya.....
SELAMAT MENCOBA