Mengukur tegangan dan menampilkan hasil pengukuran pada LCD nama kerennya (DIGITAL VOLT METER) adalah hal yang mudah, apalagi dengan CodeVisionAVR , semuanya jadi lebih mudah. Sebagai contoh, kita akan membuat program yang bisa mengukur tegangan antara 0 – 5V dengan ketelitian tegangan yang dapat diukur sebesar 0.00488V atau 4.88mV. Dalam aplikasi ini kita akan menggunakan ADC internal AVR dengan resolusi maksimal 10bit dengan data mulai dari 0 – 1023 atau 2n-1 dan jumlah total data 1024. Untuk menentukan ketelitian yang akan diperoleh sangat mudah, yaitu dengan membagi nilai tegangan referensi dengan resolusi ADC. Misal tegangan referensi yang kita pakai adalah AVCC yang bernilai 5V maka akan didapatkan resolusi sebesar 0.00488V yang didapat dari 5/1024 = 0.00488V atau 4.88mV. Contoh disini diasumsikan bahwa tegangan AVCC adalah bernilai pas 5V.

Simulasi Proteus (Volt Meter)

Untuk aplikasi riil dengan kepresisian tinggi disarankan untuk melakukan trim tegangan dengan pembagi tegangan yang menggunakan multiturn VR dan buffer DC dan gunakan referensi pada Vref bukan AVCC . Akan tetapi kalau hanya sekedar ingin mengetahui nilai tegangan tanpa kepresisian tinggi, referensi pada AVCC sudah cukup. Dan bila diinginkan mengukur tegangan dengan level yang lebih tinggi, bisa digunakan pembagi tegangan seperti pada voltmeter digital dan tentu saja jangan lupa saklar bwt select range dan lagi.. jangan lupa modifikasi programnya hehe :). Wokey let’s check it out :D

#include <mega8535.h>
#include <delay.h>
#include <stdio.h>
 
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>

Seperti code diatas, tentukan dulu library yang mo dipake.. berhugung kita akan menggunakan LCD, delay dan fungsi sprintf jadi kita include librarinya masing2. Jangan lupa sesuaikan port yang akan digunakan untuk LCD.

#define ADC_VREF_TYPE 0x40 //AVCC

Yang tak kalah pentingnya adalah menentukan referensi untuk ADC. Dalam program ini ane gunakan referensi AVCC.

unsigned char buffer[16]; //Untuk buffer sprintf
float tegangan; //Untuk data perhitungan tegangan (float)
unsigned int temporary; //Untuk temporary data ADC (komparasi)

code diatas berfungsi untuk menentukan variable global yang akan digunakan.. buffer berfungsi untuk buffer sprintf. Berhubung sprintf disini akan digunakan dalam formating LCD jadi cukup dah arraynya cuman 16 char. Sedangkan untuk variabel tegangan berfungsi untuk menampung perhitungan hasil bagi dari (data ADC*(referensi/1024)/1000) tipe datanya adalah float biar presisi hasil pembacaanya :D. nah kalo variabel temporary berfungsi cuman untuk pembanding data ADC yang sebelumnya tersimpan dan data ADC terbaca (bwt update aja biar gk terus kerja LCDnya).

void sett_regs(void); //Fungsi untuk setting register di awal proses
unsigned int read_adc(unsigned char adc_input);//Fungsi baca ADC

code yang tertulis persis diatas tulisan ini adalah cuman untuk function prototype dan digunakan bila fungsi main mau diletakkan dimana saja… termasuk diatas fungsi tersebut.

// Routine baca ADC
unsigned int read_adc(unsigned char adc_input){
ADMUX=adc_input | (ADC_VREF_TYPE &amp; 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 &amp; 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

Fungsi diatas digunakan untuk pengambilan data ADC. Bila dipanggil akan mengembalikan nilai berupa data ADC terbaru dengan tipe unsigned int.

// Function for setting register
void sett_regs(void){
// Port a initialization
PORTA=0x00;DDRA=0x00;
// Port b initialization
PORTB=0x00;DDRB=0x00;
// Port c initialization
PORTC=0x00;DDRC=0x00;
// Port D initialization
PORTD=0x00;DDRD=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: Free Running
ADMUX=ADC_VREF_TYPE &amp; 0xff;
ADCSRA=0xA2;
SFIOR&amp;=0x1F;
 
// LCD module initialization
lcd_init(16);
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
 
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
}

Fungsi diatas untuk inisialisasi register port maupun SFR. Silahkan baca sendiri ada keterangannya disamping atau diatas baris code.

// Main function
void main(void){
//--------------- Setting IO and peripheral at startup!
sett_regs();
_lcd_ready();
//--------------- Time for going CRAZY (looping forever)..
for(;;){ //mainloop looping forever until ERROR/POWER SHUTDOWN/RST/WDT ACTIVE
    #asm("wdr") //kick your DOG before timeout! hwahwa... :D
    if (temporary != read_adc(0)){
        tegangan = (read_adc(0)*4.8828125)/1000;
        lcd_gotoxy(0,0);
        lcd_putsf("WWW.NUBIELAB.COM");//Don't forget to visit :)
        lcd_gotoxy(0,1);
        sprintf(buffer,"TEGANGAN: %0.2fV",tegangan);
        lcd_puts(buffer);
        temporary = read_adc(0);
        delay_ms(100);
        }
    #asm("nop")
    };
}

Fungsi yang paling penting dalam C yaitu main() dalam fungsi ini terdapat kode yang berfungsi untuk pengolahan data ADC sampai dengan formatting character untuk ditampilkan di LCD. Pengambilan dan penulisan data tegangan tidak dilakukan secara terus menerus.. tapi menunggu perubahan nilai dulu. Kasihan kalo LCDnya dipenetrasi terus – menerus haha.. OK, berikut adalah listing program komplitnya:

/*__ ___        __  __ ___  ___ ___  ___ _  _
|_ _|     ___ |  /  |_ _|/ __| _ / _  | | - eMBEDDED Design &amp;
 | || |) ||___|| |/| || |  (__|   / (_)| .` | - System Development
|___|___/      |_|  |_|___|___|_|_\___/_|_|______________________+
 
;Homepage   : http://www.nubielab.com
;Email      : herlambang@nubielab.com
;Code by    : Herlambang Aribowo.
------------
input tegangan dihubungkan ke PINA.0 atau ADC 0
dalam aplikasi real, mungkin diperlukan buffer dan bisa dibuat dari
opamp single supply misal LM358. Jangan lupa kalo mo dibuat beneran, PIN AVCC
dan VREF ADC dihubungkan ke tegangan 5V yg stabil.
Atmega16 X-tall 4Mhz
;*/
#include
#include
#include
 
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include
 
//#define ADC_VREF_TYPE 0xC0 //Internal
//#define ADC_VREF_TYPE 0x00 //AREF
#define ADC_VREF_TYPE 0x40 //AVCC
 
unsigned char buffer[16]; //Untuk buffer sprintf
float tegangan; //Untuk data perhitungan tegangan (float)
unsigned int temporary; //Untuk temporary data ADC (komparasi)
 
void sett_regs(void); //Fungsi untuk setting register di awal proses
unsigned int read_adc(unsigned char adc_input);//Fungsi baca ADC
 
// Main function
void main(void){
//--------------- Setting IO and peripheral at startup!
sett_regs();
_lcd_ready();
//--------------- Time for going CRAZY (looping forever)..
for(;;){ //mainloop looping forever until ERROR/POWER SHUTDOWN/RST/WDT ACTIVE
    #asm("wdr") //kick your DOG before timeout! hwahwa... :D
    if (temporary != read_adc(0)){
        tegangan = (read_adc(0)*4.8828125)/1000;
        lcd_gotoxy(0,0);
        lcd_putsf("WWW.NUBIELAB.COM");//Don't forget to visit :)
        lcd_gotoxy(0,1);
        sprintf(buffer,"TEGANGAN: %0.2fV",tegangan);
        lcd_puts(buffer);
        temporary = read_adc(0);
        delay_ms(100);
        }
    #asm("nop")
    };
}
 
// Function for setting register
void sett_regs(void){
// Port a initialization
PORTA=0x00;DDRA=0x00;
// Port b initialization
PORTB=0x00;DDRB=0x00;
// Port c initialization
PORTC=0x00;DDRC=0x00;
// Port D initialization
PORTD=0x00;DDRD=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: Free Running
ADMUX=ADC_VREF_TYPE &amp; 0xff;
ADCSRA=0xA2;
SFIOR&amp;=0x1F;
 
// LCD module initialization
lcd_init(16);
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
 
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
}
 
// Routine baca ADC
unsigned int read_adc(unsigned char adc_input){
ADMUX=adc_input | (ADC_VREF_TYPE &amp; 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 &amp; 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

Oke let’s check it outnya sudah selesai.. haha kalo bingung ato mungkin ada pertanyaan silahkan posting di kolom komentar.. tengkiyu.
Ditunggu komengnya, awas kalo gk komeng :(
Download program komplit pake telor sama simulasi proteusnya disini

Sudah ane update bro.. silahkan didownload :D. O iya, schematics dalam simulasi proteus tidak mewakili konfigurasi schematics asli bila ingin dibuat secara real. Proteus ane gunakan sebagai sarana simulasi aja.. santai, tinggal modif dikit ja :D

Herlambang Aribowo

Tagged with:  

33 Responses to AVR Digital Voltmeter (LCD Display & CodeVisionAVR)

  1. Fariz says:

    Brother ne gw “komeng”, eh komen
    bisa minta link desain peoteus, pwm, rpm.

  2. Herlambang says:

    udeh ane update bro.. silahkan didownload :D
    untuk program PWM dan RPM ane posting lain waktu hehe..

  3. tanto says:

    mas mau nanya dong . . . kalo funsi watcdog buat apa ya. . trus saya jg gk ngerti penggunaan “pragma”

    thks

    • Herlambang says:

      Watchdog adalah timer yang berjalan terpisah dari sistem clock CPU. Dalam aplikasi komersial, watchdog berperan sangat penting untuk recovery bila terjadi hang dalam program dan apabila terjadi error. Nah, bila watchdog diaktifkan dan terjadi overflow pada timer watchdog, mikrokontroler bisa mencatat error tersebut pada nonvolatile register dan selanjutnya mereset mikrokontroler. Untuk aplikasi sederhana, kita bisa menggunakan watchdog dengan cara mereset counter sebelum overflow, dan saat terjadi hang atau pada salah satu fungsi, watchdog akan mereset mikrokontroler secara otomatis.

      Pragma diatas fungsinya hanya untuk ngilangin warning saja pada saat compiler melakukan optimasi program, syntax yang ditengah antara #pragma used – dan #pragma used +

  4. ArdianAlim says:

    Postingannya sangat membantu,,
    apalagi ditambah dengan adminnya yang baik, mau ngajarin step by step,,,
    thanks for mas herlambang ,,,,

  5. agus says:

    mas mau tanya donk saya menggunakan atmega16 dan sensor gas untuk mengetahui adanya kebocoran gas dengan melalui tampilan LCD 16×2 dan alarm itu bagaiman cara koneksi dan programnya terima kasih

  6. MF says:

    Mas mau tanya donk, saya kan buat secara real tetapi pada displaynya muncul angka tidak beraturan ketika belum terhubung dengan input dan ketika terhubung dengan input pada LCD malah running trus tidak mau berhenti angka pada tampilannya.

    Mohon pencerahannya

  7. fery says:

    kalau utnuk pengukuran sampai range 500vac/vdc, apa saja komponennya?
    mohon bantuannya.

  8. Yogi says:

    Wah, makasih bang atas tutorialnya.. :)
    tp mw tanya, saya udah buat simulasi ini di aslinya, tp kenapa tampilan angka di LCD nya ga jelas ya, terutama di digit2 awal.. ga jelas gt angkanya berapa.. trus saya jg buat yg untuk 2 masukan di ADC internal AVR nya dan ditampilkan ke LCD jg, nah kedua data ADC itu saling mempengaruhi.. padahal yg saya ubah cm satu doank, tp satunya lg ngikut jg berubah.. gmn solusinya ya bang??
    terima kasih..

    • Herlambang says:

      coba cek power supply-nya dah low ripple belon, dan Vref mikon di bypass capsitor 100nf.
      cek juga kontras LCDnya gan

      seharusnya tidak saling berpengaruh antar channel ADC gan :iloveindonesias

  9. ihsan says:

    sprintf(buffer,”TEGANGAN: %0.2fV”,tegangan);
    lcd_puts(buffer);
    fungsi coding d atas ap y?
    masih ga ngerti nih
    replay k email y

  10. adetrya says:

    mas, mau tanya. kenapa kok pembacaan pada adc tidak stabil.??
    kadang naik kadang turun dan rangenya besar.
    mohon bantuannya,.
    .
    btw nice info ne,.

    • Herlambang says:

      petamax… periksa tegangan AVCC stabil gak? kalau gak stabil, kasih regulator untuk mengisolasi teganan dari pin VCC.

      kalo pake referensi tegangan internal, sudah di kasih bypass capsitor belon? kalo belon kasih 100nf ke gnd.

      :ngacir:

  11. saputra says:

    sewaktu di download ke Hardwarenya g ad penunjukan dan hanya menampilkan TEGANGAN: 2fV

  12. saputra says:

    mas q mau naikin v max pengukuranya menjadi 6,3V programnya gimana y mas?
    mhon pencerahannya.

    • Herlambang says:

      Pertamax.. yang harus dipahami adalah ADC mikrokontroler AVR hanya bisa menerima input maksimal 5VDC.. jadi bila agan ingin mengukur input maksimal sebesar 6,3VDC agan harus jadiin 0 – 6,3VDC ke 0 – 5VDC. terus nanti di scalling data ADCnya gan…

      :D

  13. djundy says:

    mas,bgmn programnya jika kita sudah mengukur tegangannya kemudian kita ingin mengkonversi ke satuan lainnya?misalnya kita ingin mengukur kelembaban tanah.

    • Pake point to point gan,, jadi ukur tegangan sumber berapa terus tegangan terukur di titik lain yang dihubungkan lewat tanah berapa,, jarak dari titik sumber ke titik pengukuran juga harus jelas nanti dari tegangan terukur di titik ukur bisa ditentukan resistansi tanah pada jarak X.. nah dari resistansi dan jarak antar titik tsb bisa ditentukan kualitas kelembaban tanah.

      • djundy says:

        ada rangkainnya saya buat pake IC LM 2907,outputnya adalah tegangan.yg mjd masalah saya adalah bgmn menggunakan nilai tegangan ini.mohon bimbngannya bang,soalnya saya baru banget belajar mikrokontroller

  14. m jazuli says:

    gan itu simulasinya pake multisim kah

  15. Abdul nalik says:

    makasih kang Her gak sengaja ku bisa masuk ke blog kang her ku tertarik dan pingin mencobanya,kirim ding skema pdfnya atau bantu saya pahami program pcb maker. tanks wassalaaaaamm

  16. Bang,bisa dijelasin void main nya?
    saya bru belajar,jadi belum terlalu paham.mohon bimbingannya

    • Herlambang says:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      
      void main(void){
      //didalam fungsi sett_regs() terdapat perintah program untuk mengatur input output mikro
      sett_regs();
      //fungsi _lcd_ready() digunakan untuk menunggu sampai LCD siap sebelum ditulisi
      _lcd_ready();
      for(;;){ //mainloop /superloop
          #asm("wdr") //fungsi untuk reset counter watchdog sebelum overflow
          if (temporary != read_adc(0)){ //bila pembacaan ADC tidak sama dengan pembacaa
                                                     //sebelumnya,, update data (display
              //perintah dibawah adalah konversi dari nilai ADC kedalam nilai tegangan terukur
              //4.8828125 = resolusi ADC 10bit dengan Vref 5V
              //read_adc(0) = membaca ADC pada channel 0
              tegangan = (read_adc(0)*4.8828125)/1000;
              //kode dibawah berfungsi untuk display temperatur terkini
              lcd_gotoxy(0,0);
              lcd_putsf("WWW.NUBIELAB.COM");//Don't forget to visit :)
              lcd_gotoxy(0,1);
              //dibawah adalah formating dengan fungsi sprintf sebelum di display ke LCD
              sprintf(buffer,"TEGANGAN: %0.2fV",tegangan);
              //display ke LCD
              lcd_puts(buffer);
              //baca dan simpan nilai ADC terkini
              temporary = read_adc(0);
              delay_ms(100);
              }
          #asm("nop")  //wait 1 clock cycle
          };
      }
    • Milly says:

      That’s an expert answer to an intsneetirg question

    • http://www./ says:

      Prezados,sou cientista político e fui convidado para dar aula em um curso de especialização. A faculdade em questão só paga por cnpj. Estou buscando na internet informações sobre como proceder para criar o meu cnpj, mas não estou encontrando. Vocês poderiam me ajudar?obrigado,Rafael

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

[+] kaskus emoticons