Friday, March 2, 2018

Laporan Tugas 1 Sistem Mikroprosesor: Jam Digital Multitasking





IMPLEMENTASI JAM DIGITAL PADA SEVEN SEGMENT MENGGUNAKAN ARDUINO BESERTA KEMAMPUAN MULTITASKING SEDERHANA
Theo Gunawan (13215029)
Yoland Nababan (13215053)
EL3014-Sistem Mikroprosesor
Program Studi Teknik Elektro - Sekolah Teknik Elektro dan Informatika ITB



Abstrak


Setelah sukses mengimplementasikan jam digital sederhana pada seven segment dengan menggunakan Arduino, percobaan ini adalah mengenai kemampuan multitasking sederhana dari jam digital yang telah dibuat. Pada percobaan ini source code yang telah dibuat pada percobaan sebelumnya dimodifikasi agar dapat melakukan multitasking yang diimplementasikan menggunakan push button. Source code diunggah menuju Arduino untuk diuji keberjalanannya pada rangkaian.
Kata kunci: Implementasi jam digital, seven segment, Arduino, multitasking

1.         Pendahuluan

Arduino merupakan sebuah mikroprosesor yang banyak digunakan dalam pembuatan rangkaian tertentu. Salah satu implementasi yang dapat dilakukan dengan menggunakan Arduino adalah jam digital. Kemampuan multitasking pada jam digital ini dapat diimplementasikan dengan menggunakan push button. Pada percobaan ini dibahas mengenai implementasi jam digital dengan multitasking sederhana dengan menggunakan Arduino.

2.        Studi Pustaka
Berikut adalah beberapa referensi yang digunakan dalam membuat implementasi ini.
Deskripsi register (misal: port output) didefinisikan sebagai berikut.[1]


Gambar 4-1 Deskripsi register
Deskripsi timer/counter didefinisikan sebagai berikut.[1]


Gambar 4-2 Deskripsi timer/counter TCCR
Clock select didefinisikan sebagai berikut.[1]


Gambar 4-3 Daftar clock select dan prescaler
TCNT, OCR, TIMSK, dan TIFR didefinisikan sebagai berikut.[1]


Gambar 4-4 TCNT, OCR, TIMSK, dan TIFR

3.        Metodologi

3.1                        Komponen dan Alat
Komponen dan alat yang dipakai dalam percobaan ini adalah sebagai berikut.
  • Komputer.
  • Software Arduino.
  • Arduino Uno beserta kabel USB.
  • Breadboard.
  • Seven segment.
  • Push button.
  • Kabel jumper.
3.2                       Langkah-langkah Percobaan
Langkah-langkah yang dilakukan pada percobaan ini adalah sebagai berikut.
  • Merangkai implementasi jam digital multitasker pada breadboard menggunakan seven segment dan push button.
  • Memodifikasi source code pada percobaan sebelumnya sesuai dengan lampiran menggunakan software Arduino.
  • Memasang kabel USB pada Arduino dan pada komputer.
  • Mengunggah kode pada Arduino untuk diuji dan dilihat keberjalanannya.

4.        Hasil dan Analisis

4.1                        Hasil Percobaan
Hasil dari percobaan kali ini adalah sebuah jam digital yang dapat diimplementasikan pada seven segment dan melakukan multitasking sederhana dengan menggunakan Arduino. Berikut merupakan gambar implementasinya.

Gambar 4-1 Implementasi jam digital multitasking pada seven segment
Hasil lebih lanjut terlampir pada video.


4.2                       Analisis
Pada tugas kali ini, dibuat sebuah jam digital yang diimplementasikan ke dalam empat buah seven segment. Seven segment yang digunakan terdiri dari empat buah untuk mewakiliki format hh:mm. Seven segment membutuhkan sebanyak 8 pin untuk dapat dinyalakan. Karena menggunakan 4 buah seven segment, maka akan dibutuhkan pin sekitar 32 pin. Sementara pin yang tersedia pada Arduino Uno tidak sebanyak itu. Oleh karena itu, seven segment akan dinyalakan secara bergantian sehingga jumlah pin yang dibutuhkan adalah 12 buah pin. Seven segment harus berganti cukup cepat sehingga mata manusia tidak dapat mendeteksi perubahannya. Akibatnya, seven segment akan menyala seperti dinyalakan secara bersamaan. Untuk menjalankan fungsi sebagai sebuah jam digital, maka dibutuhkan pewaktuan pada jam tersebut. Hal ini dapat tercapai dengan menggunakan timer pada Arduino—dalam hal ini merupakan mikroprosesor ATMEGA 328p. Setelah itu, program ini akan menjalankan program utamanya. Program utamanya adalah sebuah prosedur yang digunakan untuk menyalakan keempat seven segment tersebut. oleh karena itu, program akan selalu berulang untuk menampilkan display tersebut. Prosedur untuk menampilkan seven segment ini berisi prosedur yang berfungsi sebagai decoder pada seven segment. Seven segment yang digunakan menggunakan seven segment dengan common cathode. Oleh karena itu, untuk menyalakan satu buah seven segment, pin katoda diberikan nilai LOW dan pin anodanya diberi nilai HIGH. Sementara untuk memadamkan satu seven segment, nilai anoda tidak perlu diubah ubah, hanya perlu mengubah nilai katoda menjadi HIGH untuk memastikan beda tegangan antara kedua kaki tidak cukup besar untuk menyalakan seven segment. Dalam prosedur tersebut, ada bagian yang berfungsi untuk melakukan fungsi ini. Oleh karena itu, untuk menyalakan seven segment, maka nilai katoda dari masing masing seven segment diubah. Ketika 1 pin bernilai LOW, maka tiga pin lainnya bernilai HIGH dan begitu seterusnya. Sementara metode yang digunakan untuk menghasilkan jam yang cukup akurat adalah dengan menggunakan interrupt dan overflow pada timer. Interrupt berfungsi untuk menjalankan suatu prosedur atau instruksi yang cukup singkat. Program utama akan dihentikan sebentar kemudian prosedur interrupt akan dijalankan. Sementara, memastikan delay yang dihasilkan adalah 1 detik dapat dilakukan dengan melakukan pengesetan terlebih dahulu pada beberapa register timer. Pertama-tama adalah dengan mengeset nilai clock yang digunakan. Selain interrupt, program ini akan berjalan menggunakan konsep overflow. Ketika suatu register counter/timer mencapai nilai maksimumnya, maka overflow akan terjadi. Oleh karena itu, untuk menghasilkan delay 1 detik, maka dilakukan dengan mengisikan suatu nilai awal pada register counter/timer. Untuk percobaan ini akan digunakan TIMER1. Timer ini memiliki nilai maksimum sebesar 65535. Oleh karena itu, untuk menghasilkan delay sebesar 1 sekon, maka dapat dilakukan dengan cara sebagai berikut.


Untuk mengatur nilai prescaler, dapat dilakukan dengan mengubah nilai register TCCR1B. Nilai prescaler yang digunakan adalah sebesar 1024. Nilai awal ini akan menghasilkan delay jika bertambah dari nilai awal tersebut sampai nilainya overflow. Overflow ini nantinya akan digunakan sebagai sinyal untuk memanggil interupsi. Oleh karena itu, pada saat mendeklarasikan prosedur interrupt (ISR), maka digunakan vector TIMER1_OVF_vect. Sedangkan untuk membuat overflow dapat dimanfaatkan maka akan digunakan sebuah register yang berujuan untuk meng-enable fitur tersebut. Caranya adalah dengan mengubah nilai register TIMSK yang merupkan register yang bertujuan untuk melakukan enable pada fungsi interrupt jika overflow terjadi. Hal inilah yang kita butuhkan untuk menghasilkan perilaku yang kita harapkan. Artinya ketika terjadi overflow pada register TCNT1, maka akan terjadi overflow yang nantinya menjadi pemicu terjadinya interrupt. Bagian prosedur ISR digunakan untuk mengupdate nilai jam, menit, dan detik. Oleh karena itu, pada program interrupt ini, nilai detik akan mengalami penambahan sebanyak 1 dan akan diubah ke dalam nilai jam dan menit. Kemudian nilai counter di-reset ke nilai awal tadi yaitu TCNT1 = 0xC2F7. Kemudian dilakukan implementasi pada program yang sudah dirancang. Dari program tersebut dapat menghasilkan delay yang akurat yaitu 1 detik.

Implementasi multitasker pada jam digital ini dilakukan dengan menggunakan tiga buah push button dan diimplementasikan dengan menggunakan external interrupt.

5.        Kesimpulan
Dari hasil percobaan ini dapat disimpulkan:
  • Jam digital dapat diimplementasikan dengan menggunakan counter/timer dan interrupt.
  • Multitasking dalam jam digital ini dapat diimplementasikan dengan menggunakan interrupt.

Daftar Pustaka
[1]            Mervin T. Hutabarat dkk., Petunjuk Praktikum Sistem Mikroprosesor, ed. 2017-2018, Laboratorium Dasar Teknik Elektro Institut Teknologi Bandung, Bandung, 2018.

Lampiran
Source code proyek
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include <avr/interrupt.h>

int val[4] = {0,0,0,0};
volatile unsigned int detik ;
char key;
// merah coklat orens kuning
// abu2  ungu biru hijo

volatile unsigned int menit;
volatile unsigned int jam;
volatile char prev_temp;
volatile unsigned int temp;

int main (void) {
  int mode; // untuk pengesetan mode alat
  detik = 0;
  jam = 0;
  menit = 0;
  temp = 0;
  sevseg_init();
  TIMSK1 |= (1 << TOIE1); //enable overflow interrupt
  sei();// start global interrupt
 
  // inisialisasi interrupt eksternal
  EIMSK |= (1<<INT0);
  MCUCR |= (1<<ISC01);
  EIFR |= (1<<INTF0);
  DDRD |= (0<<PD0);

//  inisialisasi input pullup
  DDRE|= (0<<PE4)|(0<<PE5);
  PORTE|= (1<<PE4)|(1<<PE5);
 
  timer1_init();// timer 1 initialization
  while (1){
    TIMSK1 |= (1 << TOIE1);
    cetakSemua();
      while (temp){
        TIMSK1 =0x00;
        val[3] = 0;
        val[2] = 0;
        val[1] = 0;
        val[0] = 0;
        detik = 0;
        while (temp){
        cetakSemua();
//        val[2] = 1;
        if (!(PORTE&&(1<<PE5))){
            _delay_ms(100);
            if (!(PORTE&&(1<<PE5))){
              jam ++;
              val[3] = jam/10;
              val[2] = jam%10;
              }
          }
        if (!(PORTE&&(1<<PE4))){
          _delay_ms(100);
          if (!(PORTE&&(1<<PE4))){
            menit ++;
            val[1] = menit/10;
            val[0] = menit%10;
            }
          }
        } 
        }
  }
}
ISR(INT0_vect){
     _delay_ms(100);
     if (!(PORTD&&(1<<PD0))){
      temp = !temp;
      }
  }

ISR(TIMER1_OVF_vect){
  detik = detik + 60;
  TCNT1 = 0xC2F7;
  if (detik%60 == 0){
    val[3] = ((detik/60)/60)/10;
    val[2] = ((detik/60)/60)%10;
    val[1] = ((detik/60)%60)/10;
    val[0] = ((detik/60)%60)%10; 
  }
}

void timer1_init(){
    // initialize counter
    TCNT1 = 0xC2F7;   
    //1024 prescaler
    TCCR1B |= ((1 << CS10) | (1 << CS12)); 
}

void cetakSemua(){
    reset();
    PORTB = 0b00001110;
    decoder(val[0]);
  
    reset();
    PORTB = 0b00001101;
    decoder(val[1]);
  
    reset();
    PORTB = 0b00001011;
    decoder(val[2]);

    reset();
    PORTB = 0b00000111;
    decoder(val[3]);
}

void decoder(unsigned char A){
  if(A == 0)
  {
    PORTC = 0b11101101; //edctbagf
  }
  if(A == 1)
  {
    PORTC = 0b00101000;
  }
  if(A == 2)
  {
    PORTC = 0b11001110;
  }
  if(A == 3)
  {
    PORTC = 0b01101110;
  }
  if(A == 4)
  {
    PORTC = 0b00101011;
  }
  if(A == 5)
  {
    PORTC = 0b01100111;
  }
  if(A == 6)
  {
    PORTC = 0b11100111;
  }
  if(A == 7)
  {
    PORTC = 0b00101100;
  }
  if(A == 8)
  {
    PORTC = 0b11101111;

  }
  if(A == 9)
  {
    PORTC = 0b01101111;
  }
}

void reset(){
  PORTC = 0x00;
  PORTB |= (1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);
}

void sevseg_init(){
  DDRB = 0x0F; // port B jadi output
  DDRC = 0xFF; // port C jadi output 
  }
 
void keypad_init(){
  DDRA = 0x0F;
  PORTA = 0xFF; 
  key = 'x';
  }

void input_key(){
    PORTA =0b11111110;
    if((PINA&(1<<PA4)) == 0) {key = 'D';}
    if((PINA&(1<<PA5)) == 0) {key = 'C';}
    if((PINA&(1<<PA6)) == 0) {key = 'B';}
    if((PINA&(1<<PA7)) == 0) {key = 'A';}

    PORTA =0b11111101;
    if((PINA&(1<<PA4)) == 0) {key = '#';}
    if((PINA&(1<<PA5)) == 0) {key = '9';}
    if((PINA&(1<<PA6)) == 0) {key = '6';}
    if((PINA&(1<<PA7)) == 0) {key = '3';}
   
    PORTA =0b11111011;
    if((PINA&(1<<PA4)) == 0) {key = '0';}
    if((PINA&(1<<PA5)) == 0) {key = '8';}
    if((PINA&(1<<PA6)) == 0) {key = '5';}
    if((PINA&(1<<PA7)) == 0) {key = '2';}
   
    PORTA =0b11110111;
    if((PINA&(1<<PA4)) == 0) {key = '*';}
    if((PINA&(1<<PA5)) == 0) {key = '7';}
    if((PINA&(1<<PA6)) == 0) {key = '4';}
    if((PINA&(1<<PA7)) == 0) {key = '1';}
  }

No comments:

Post a Comment