Rabu, 17 September 2014

Signal Generator (DDS AD9850) dan Frekuensi Meter dan Kontrol Frekuensi dari Serial Monitor

Ini adalah posting lanjutan dari Signal Signal Generator DDS A9850 dan Frekuensi Meter . Dengan Saya tambahkan bagian untuk dapat merubah frekuensi secara serial melalui serial monitor pada Arduino sehingga frekuensi dapat diatur lebih fleksibel tanpa bolak balik upload program. 

Berikut definisi variable yang perlu ditambahkan pada source code sebelumnya:

float buff_data;
String buff_string = "";
char buff_char;
 

Berikut modifikasi souce code (pengganti) yang berada pada bagian void loop(). Sedangkan yang lain masih tetap sama dengan source code sebelumnya.

void loop()
{
       
        //lcd.clear();
       
        //cek perintah serial
        while(Serial.available()) {
        buff_char = Serial.read();
        buff_string.concat(buff_char);    //menggabungkan variabel buff_char ke variable buff_string
        }
       
        //merubah tipe data string ke float (tipe data float = double)
        char buf[buff_string.length()];
        buff_string.toCharArray(buf,buff_string.length()+1);
        float buff_data=atof(buf);  //buff_data akan nol pada loop berikutnya jika tidak ada perintah

                                    //(karena buff_string dikosongkan "" diakhir loop)
       
        //cek jika ada permintaan perubahan frekuensi 
        if (buff_data>0) sendFrequency(buff_data);
      
        Serial.print(freq_cek);
        Serial.print(" ");
        Serial.println(freq_satuan);
        lcd.setCursor(0,0);   
        lcd.print("Freq DDS AD9850");
        lcd.setCursor(0,1);   
        lcd.print("Freq= ");
        lcd.print(freq_cek);
        lcd.print(" ");
        lcd.print(freq_satuan);
        //delay(500);
       
        buff_string="";
}



Berikut adalah screenshot hasil modifikasi dengan source code di atas:

Contoh Hasil pada Serial Monitor


Beberapa referensi utama:
http://www.instructables.com/id/Arduino-Timer-Interrupts/?ALLSTEPS
http://www.ad7c.com/projects/ad9850-dds-vfo/

http://letsmakerobots.com/content/how-convert-strings-double
http://stackoverflow.com/questions/5697047/convert-serial-read-into-a-useable-string-using-arduino 

Merubah tipe data String ke Float (atau Double)

Berikut adalah source code untuk merubah tipe data String ke tipe data float (atau double). Ini sangat berguna saat komunikasi serial yang biasanya perintah dikirimkan melalui tipe data string

float buff_data;
String buff_string = "123.22";

//merubah tipe data string ke float (tipe data float = double)
        char buf[buff_string.length()];
        buff_string.toCharArray(buf,buff_string.length()+1);
        float buff_data=atof(buf);


double buff_data;
String buff_string = "123.22";

//merubah tipe data string ke float (tipe data float = double)
        char buf[buff_string.length()];
        buff_string.toCharArray(buf,buff_string.length()+1);
        double buff_data=atof(buf);


Referensi:
http://letsmakerobots.com/content/how-convert-strings-double

Membaca tipe String pada komunikasi serial (Arduino - PC)

Berikut adalah source code untuk membaca string pada komunikasi serial. Hasil yang terbaca adalah semua string yang dikirim secara serial setelah ditekan enter.

String buff_string = "";
char buff_char;

while(Serial.available()) {
  buff_char = Serial.read();
  buff_string.concat(buff_char);    //menggabungkan variabel buff_char ke variable buff_string

}

Referensi:
http://stackoverflow.com/questions/5697047/convert-serial-read-into-a-useable-string-using-arduino

Signal Generator (DDS AD9850) dan Frekuensi Meter

Posting kali ini bertujuan untuk membangkitkan signal DDS menggunakan IC AD 9850. IC ini sudah tersedia dalam bentuk modul. Keluaran IC ini berupa gelombang sinus dan kotak. Karena IC ini bersifat programmable maka frekuensi akan disetting menggunakan Arduino Uno.

Kemudian dibuat pula program untuk mengecek frekuensi yang dikeluarkan oleh IC tersebut setelah diprogram sebelumnya. Aplikasi penghitung frekuensi ini juga dapat digunakan untuk menghitung frekuensi yang lain dengan cara menghubungkan sumber frekuensi ke pin T1 (timer1 sebagai counter.

Untuk menghitung frekuensi yang dikeluarkan oleh DDS AD9850 maka output signal kotak dihubungkan ke pin T1 dari Arduino Uno.

Hasil penghitungan frekuensi kemudian ditampilkan dalam LCD 16x2 dan dikirim ke PC secara serial.

Konfigurasi Pin Arduino Uno

Konfigurasi Pin Modul DDS AD9850
Konfigurasi LCD:
LiquidCrystal lcd(12,13,3,4,6,7); //Konfigurasi schematic LCD Keypad

Konfigurasi DDS AD9850:
///////////////AD9850
#define W_CLK 8   // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9   // Pin 9 - connect to freq update pin (FQ)
#define DATA 10   // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11  // Pin 11 - connect to reset pin (RST)
///////////////AD9850
Konfigurasi Counter1:
Pin output gelombang kotak dari DDS AD9850 dihubungkan ke pin T1 pada Arduino Uno.

Berikut Source Code Lengkapnya:
/*
Author: Muhammad Nurul Puji
muhammadpuji.its@gmail.com
This program have been tested on Arduino Uno R3, DDS AD9850 and LCD Keypad
2013
*/

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,13,3,4,6,7); //Konfigurasi schematic LCD Keypad

///////////////AD9850
#define W_CLK 8   // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9   // Pin 9 - connect to freq update pin (FQ)
#define DATA 10   // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11  // Pin 11 - connect to reset pin (RST)
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
String freq; // string to hold the frequency
///////////////AD9850

/////////Freq Cek
float freq_cek;
int kilo,mega, timer0;
String freq_satuan;
/////////Freq Cek

void setup()
{
       
        ///////////setting counter atau timer
        timer0;
        kilo=0;
        mega=0;
        freq_cek=0;
        freq_satuan="Hz";
       
        cli();//stop interrupts
     
        //set timer0 interrupt
        TCCR0A = 0;// set entire TCCR0A register to 0
        TCCR0B = 0;// same for TCCR0B
        TCNT0  = 0;//initialize counter value to 0
        // set compare match register for 2khz increments
        OCR0A = 249;// 250 (dimulai dari 0) - karena prescaler 64 (250KHz) maka diperlukan 1000 kali interrupt untuk 1 detik
        // turn on CTC mode
        TCCR0A |= (1 << WGM01);
        // Set CS01 and CS00 bits for 64 prescaler (250KHz)
        TCCR0B |= (1 << CS01) | (1 << CS00);  
        // enable timer compare interrupt
        TIMSK0 |= (1 << OCIE0A);
     
        //set timer1 interrupt sebagai counter sinyal frekuensi yang masuk
        TCCR1A = 0;// set entire TCCR1A register to 0
        TCCR1B = 0;// same for TCCR1B
        TCNT1  = 0;//initialize counter value to 0
        // set compare match register for 1hz increments
        OCR1A = 999;//seribu kali - mulai dari 0
        // turn on CTC mode
        TCCR1B |= (1 << WGM12);
        // Set CS10 and CS11 bits for external clock T1 falling edge
        TCCR1B |= (1 << CS12) | (1 << CS11); 
        // enable timer compare interrupt
        TIMSK1 |= (1 << OCIE1A);
     
        sei();//allow interrupts       
        //////////////setting counter atau timer
     
   
        ///////////////AD9850
        pinMode(FQ_UD, OUTPUT);
        pinMode(W_CLK, OUTPUT);
        pinMode(DATA, OUTPUT);
        pinMode(RESET, OUTPUT);
        pulseHigh(RESET);
        pulseHigh(W_CLK);
        pulseHigh(FQ_UD);  // this pulse enables serial mode on the AD9850 - Datasheet page 12.
        sendFrequency(1000000); //tes frekuensi 1MHz
        ///////////////AD9850 
 
      Serial.begin(9600);
    lcd.begin(16,2);
}

void loop()
{
       
        //lcd.clear();
        Serial.print(freq_cek);
        Serial.print(" ");
        Serial.println(freq_satuan);
        lcd.setCursor(0,0);   
        lcd.print("Freq DDS AD9850");
        lcd.setCursor(0,1);   
        lcd.print("Freq= ");
        lcd.print(freq_cek);
        lcd.print(" ");
        lcd.print(freq_satuan);
        //delay(500);
}


//////////////untuk handle interrupt counter dan timer
ISR(TIMER0_COMPA_vect){//timer0 interrupt
 
timer0++; 
if (timer0==1000) {    //setiap 1 detik dicek jumlah pulsanya
  if (mega>0){
    freq_cek=((float)mega+((float)kilo/1000) + ((float)TCNT1/1000000))*1;    //dikali 1 supaya 1 detik
    freq_satuan = "MHz  ";
  }else if (kilo>0){
    freq_cek=((float)kilo + ((float)TCNT1/1000))*1;    //dikali 1 supaya 1 detik
    freq_satuan = "KHz  ";
  }else {
    freq_cek = ((float)TCNT1) * 1;
    freq_satuan = "Hz   ";
  } 
  timer0=0;
  kilo=0;
  mega=0;
  TCNT1=0;
  TCNT0=0;
}
}

ISR(TIMER1_COMPA_vect){//counter1 interrupt
 
kilo++;
if (kilo==1000){
  mega++;
  kilo=0;
}
}
//////////////untuk handle interrupt counter dan timer


/////////////////////AD9850
// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) { 
  int32_t freq = frequency * 4294967295/125000000;  // note 125 MHz clock on 9850.  

  for (int b=0; b<4; b++, freq>>=8) {
    tfr_byte(freq & 0xFF);
  }
  tfr_byte(0x000);   // Final control byte, all 0 for 9850 chip
  pulseHigh(FQ_UD);  // Done!  Should see output
}
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data)
{
  for (int i=0; i<8; i++, data>>=1) {
    digitalWrite(DATA, data & 0x01);
    pulseHigh(W_CLK);   //after each bit sent, CLK is pulsed high
  }
}
/////////////////////AD9850

Hasil:
DDS AD9850 dapat membangkitkan gelombang sinus dan kotak. Berikut pengambilan data menggunakan ADC pada frekuensi rendah (0,5 Hz; 1 Hz; 2Hz)
 - Mungkin akan dijabarkan diposting terpisah :)

Hasil keluaran DDS AD9850 gelombang sinus dan kotak

Hasil keluaran DDS AD9850 sine 1 dan sine 2

Hasil pengukuran frekuensi oleh Arduino Uno menggunakan Counter dan Timer1:

Pengukuran Nilai Frekuensi keluaran DDS AD9850 (di tes pada 1 MHz)
Pengukuran Nilai Frekuensi keluaran DDS AD9850 (di tes pada 1 Hz)
Pengukuran Nilai Frekuensi keluaran DDS AD9850 (dites pada 2,25 MHz)


Beberapa referensi utama:
http://www.instructables.com/id/Arduino-Timer-Interrupts/?ALLSTEPS
http://www.ad7c.com/projects/ad9850-dds-vfo/

Sabtu, 12 April 2014

Pemrograman Keypad 3x4 pada AVR 128 menggunakan Code Vision

Bismillah..
Berawal dari mencoba mempraktekkan teori cara kerja (scan) pembacaan keypad, sehingga Sy bisa share hasilnya disini. :)

Salah satu perangkat yang sering dibutuhkan pada aplikasi mikrokontroler adalah kemampuan berinteraksi dengan pengguna peralatan tersebut. Salah satu cara berinteraksi dengan pengguna adalah dengan menggunakan keypad. Di sini akan kita pelajari tentang pemrograman keypad 3x4 pada mikrokontroler AVR128 dengan menggunakan Code Vision.

Berikut adalah contoh gambar fisik keypad yang sering digunakan:

Keypad tersebut memiliki konfigurasi internal berupa skema berbentuk matrix baris (ROW) dan kolom (COL) sebagai berikut:

Pada mikrokontroler setiap COLOM keypad akan dihubungkan dengan pin "output" mikrokontroler. Sedangkan pada setiap ROW keypad akan dihubungkan dengan pin "input" mikrokontroler.

Salah satu cara untuk membaca data dari matrix keypad adalah dengan teknik scanning, dimana baris atau kolom selalu discan untuk mendeteksi tombol yang ditekan. Caranya yaitu dengan memberikan status ‘0’ (low) pada salah satu pin COL (dan yg lain kondisi HIGH) secara bergantian, lalu pin ROW dideteksi apakah ada salah satunya yang berkondisi ‘0’ (low). Berikut ilustrasi urutan scaning dan pembacaan keypad:
  1. Apabila Kolom 1 diberi logika ‘0’, kolom kedua dan kolom ketiga diberi logika ‘1’ maka program akan mengecek tombol 1, 4, 7, dan *, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
     
  2. Apabila Kolom 2 diberi logika ‘0’, kolom pertama dan kolom ketiga diberi logika ‘1’ maka program akan mengecek tombol 2, 5, 8, dan 0, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
  3. Apabila Kolom 3 diberi logika ‘0’, kolom pertama dan kolom kedua diberi logika ‘1’ maka program akan mengecek tombol 3, 6, 9, dan #, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
Cara ini dilakukan secara terus menerus sehingga setiap kali keypad ditekan maka akan langsung terdeteksi posisi tombol yang ditekan.

Kali ini Sy akan mencontohkan pemrograman keypad dan menampilkannya pada LCD 16x2 sehingga mudah mengecek tombol yang ditekan. LCD Sy hubungkan dengan PORTC sedangkan Keypad Sy hubungkan dengan PORTE, dengan konfigurasi keypad sebagai Berikut

row1 -> PINE.0 
row2 ->PINE.1
row3 ->PINE.2
row4 ->PINE.3
col1 ->PINE.6
col2 ->PINE.5
col3 ->PINE.4

Berikut skema proteusnya

Pada program kali ini Sy membuat procedure bernama keypad(), yang kemudian prosedur keypad() tersebut akan dieksekusi oleh Timer0 secara terus menerus dan akan mengupdate posisi tombol yg ditekan (bila ada). Penggunaan Timer ini cukup penting karena Timer bisa bekerja secara paralel dengan program utama pada mikrokontroler itu sendiri. (Tolong dicross cek apabila salah).

Berikut adalah coding untuk konfigurasinya:

#include <alcd.h>
#include <stdio.h>

unsigned char text[16],nilai_keypad; /*kalo ada yg tdk sesuai pada saat awal sebelum ada tombol yg ditekan maka perlu inisialisasi nilai_keypad=13 (angka diluar range angka yang benar)*/
 
// Port E initialization
// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=0 State5=0 State4=0 State3=P State2=P State1=P State0=P
PORTE=0x0F;
DDRE=0x70;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 10000.000 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x01;
TCNT0=0x00;
OCR0=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;

ETIMSK=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 2
// EN - PORTC Bit 1
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);

// Global enable interrupts
#asm("sei")
 
Program Procedure keypad()

unsigned char keypad(){
    unsigned char x,i,j;  
    bit y;
    x=0b01000000;
    for (i=0;i<3;i++) {
        PORTE =~((x>>i) & 0x70);
        for (j=0;j<4;j++) {
            y=(PINE >> j) & 0x1;
            if(y==0) return((i+1)+(3*j));  
            //rumus ini untuk menentukan posisi sesuai baris dan kolom
        }
    }
}

Scaning keypad() pada Timer0 supaya dilakukan scan terus menerus

// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// Place your code here
nilai_keypad=keypad();
}

Program utama sekaligus mengecek apakah benar nilai_keypad selalu discan oleh Timer0

while (1)
    {
        // Place your code here
        lcd_gotoxy(0,0);
        lcd_putsf("* Program Utama ");
        lcd_gotoxy(0,0);
        lcd_putsf("**--Cek--**     ");
        //mengecek apakah nilai_keypad selalu update
        lcd_gotoxy(0,1);
        if(nilai_keypad<10){
            sprintf(text,"%u",nilai_keypad);
            lcd_puts(text);}
        else if(nilai_keypad==10) lcd_putsf("*");
        else if(nilai_keypad==11) lcd_putsf("0");
        else if(nilai_keypad==12) lcd_putsf("#");
      }
 

Alhamdulillah akhirnya berhasil jg menerapkan teori keypad ini.. hehe simple tapi harus teliti memang..

Catatan: Procedure keypad() bisa dieksekusi langsung di program utama tanpa menggunakan Timer. Sy hanya mengetes kinerja Timer saja..

Jumat, 04 April 2014

Pemrograman FPGA pada aplikasi Elevator 5 Lantai (Simulasi TINA)



Share tugas kuliah.. :)


BAGIAN-BAGIAN ELEVATOR

1. Panel Bagian Dalam Elevator
Panel bagian dalam elevator memiliki tombol untuk menuju ke lantai yang akan dituju dan tombol buka pintu untuk menahan pintu tetap terbuka bila diperlukan pada saat elevator dalam keadaan berhenti. Gambar 1. berikut ilustrasi panel bagian dalam elevator:
 

Gambar 1. Ilustrasi Panel Bagian Dalam Elevator Lima Lantai

2. Panel Bagian Luar Elevator pada Setiap Lantai Gedung
Panel bagian luar elevator pada setiap lantai gedung memilik tombol untuk request masuk ke elevator, sehingga penumpang bisa memanggil (request) elevator dan masuk elevator. Ilustrasi panel bagian luar pada setiap lantai dapat dilihat pada Gambar 2. berikut:

Gambar 2. Ilustrasi Panel Bagian Luar Elevator pada Setiap Lantai Gedung

3. Indikator Posisi Elevator
Elevator juga dilengkapi indikator posisi elevator (bisa berupa seven segment atau perangkat display lain), sehingga posisi elevator bisa diketahui ada pada lantai berapa dan apakah sedang naik atau turun. Gambar 3. berikut mengilustrasikan indikator posisi elevator:

 Gambar 3. Ilustrasi Indikator Posisi Elevator

STATE DIAGRAM ELEVATOR (ILUSTRASI)

Pada Gambar 4. berikut mengilustrasikan state diagram cara kerja dari elevator lima lantai. Elevator ini bergerak berdasarkan perintah atau request baik dari dalam elevator maupun dari luar elevator (pada setiap lantai). Kemudian elevator akan membandingkan posisi elevator (saat ini) dengan lantai yang akan dituju sesuai request, sehingga elevator akan bisa menentukan arah geraknya (naik atau turun).

Gambar 4. Ilustrasi State Diagram Elevator Lima Lantai

DESIGN TINA

Berikut adalah penerapan design pada simulator TINA:

Gambar 6. Simulasi Design Elevator Menggunakan Software TINA

VIDEO SIMULASI
 

SOURCE CODE

Source code dicompile dengan program Quartus. Berikut source code VHDL dari state diagram elevator lima lantai:
 
--Bismillah
--Coba Elevator
--Originally Designed by: Muhammad Nurul Puji (muhammadpuji.its@gmail.com)
--Student of University of Indonesia (UI)
library ieee;
use ieee.std_logic_1164.all;

entity cobaelevator is
port (clk : in std_logic;        --untuk maintenance (tombol stop)
        manual_bukapintu : in std_logic;        --dari dalam (atau luar (diseri dgn luar atau diseri dengan sensor)) elevator (hanya pada saat berhenti)
        in1, in2, in3, in4, in5 : in std_logic;        --dari dalam elevator (untuk tujuan mau kelantai berapa?)
       
        in1naik, in2naik, in3naik, in4naik, in5naik : in std_logic;      --dari masing-masing lantai (diluar elevator)
        in1turun, in2turun, in3turun, in4turun, in5turun : in std_logic;        --dari masing-masing lantai (diluar elevator)
       
        a1, a2, a3, a4, a5, a6, a7: out std_logic;            --untuk menunjukkan posisi elevator melalui seven segmen
        motornaik, motorturun, tutuppintu: out std_logic;        --untuk mekanik motor dan pintu
        bukapintu: out std_logic);                            --harusnya pake buffer tapi di Tina tdk bisa (jadi untuk simulasi tetap pake out). Buffer digunakan sbg buffer supaya bisa di read and write (untuk cek apa masih terbuka)
end cobaelevator;

architecture behavior of cobaelevator is
    constant timetutuppintu: integer := 3;            --untuk tutup pintu otomatis
    constant timepintuselesaimenutup: integer :=2;    --waktu pintu untuk selesai menutup
    constant time_nx_state: integer := 4;            --waktu yg dibutuhkan untuk naik satu lantai
   
    signal permintaan : std_logic_vector (0 to 4) :="00000";
    signal arahelevator : integer range 0 to 2 :=0;
    signal signalmotornaik : std_logic :='0';
    signal signalmotorturun : std_logic :='0';
    signal signalnaikturunpenumpang : std_logic:='0';
    signal signalstatus : std_logic:='1';
   
    type status is (lantai1, lantai2, lantai3, lantai4, lantai5);        --penentuan signal dari masing-masing posisi lantai
    signal pr_state, nx_state: status;
   
begin
   
    utama: process (clk, manual_bukapintu, in1, in2, in3, in4, in5, in1naik, in2naik, in3naik, in4naik, in5naik, in1turun, in2turun, in3turun, in4turun, in5turun)
        variable digit1 : std_logic_vector (6 downto 0);                ----------untuk Seven Segment------
        variable count: integer range 0 to (time_nx_state + timetutuppintu + timepintuselesaimenutup);
        variable bufferbukapintu: std_logic;        --harusnya menggunakan buffer untuk bukapintu, tapi di Tina tdk bisa. Jadi menggunakan variable ini
       
        ------------Variable ini untuk Arah Elevator---------------------
        variable posisi : integer range 0 to 4;
        variable tempnaik, tempturun : integer range -4 to 4 :=0;        --karena ada kemungkinan bernilai negatif (tetapi yg dipake cuma positif)
        variable temp : integer range 1 to 2 :=1;
        ------------End Variable Arah Elevator---------------------------   

    begin
        if (clk'event and clk='1') then    
            ------------------Cek Permintaan----------------
            permintaan(0)<= permintaan(0) or in1 or in1naik or in1turun;
            permintaan(1)<= permintaan(1) or in2 or in2naik or in2turun;
            permintaan(2)<= permintaan(2) or in3 or in3naik or in3turun;
            permintaan(3)<= permintaan(3) or in4 or in4naik or in4turun;
            permintaan(4)<= permintaan(4) or in5 or in5naik or in5turun;
                   
            ------------Begin Arah Elevator-----------------------
            case pr_state is
                when lantai1 => posisi :=0;
                when lantai2 => posisi :=1;
                when lantai3 => posisi :=2;
                when lantai4 => posisi :=3;
                when lantai5 => posisi :=4;
            end case;
           
            for i in 1 to 4 loop                        -- i harus dalam range konstanta
                if permintaan(i)= '1' then
                    tempnaik:=i-posisi;
                else null;
                end if;
            end loop;       
            for i in 3 downto 0 loop                -- i harus dalam range konstanta
                if permintaan(i)= '1' then
                    tempturun:=posisi-i;
                else null;
                end if;
            end loop;
                   
            if tempnaik=0 and tempturun=0 then        --saat posisi lantai sama dengan permintaan
                arahelevator<=0;
            elsif temp=1 then
                arahelevator <= 1;        --naik
                if tempnaik < 1 then
                    temp :=2 ;
                else null;
                end if;
            elsif temp= 2 then            --turun
                arahelevator <= 2;
                if tempturun <1 then
                    temp:=1;
                else null;
                end if;
            else null;
            end if;
            --------------End Arah Elevator------------------------------
               
            -----------------Bagian Utama------------------------------
            count:=count + 1;           
            if (manual_bukapintu='1' and signalmotornaik = '0' and signalmotorturun = '0') then        --untuk menahan pintu tetap terbuka saat elevator berhenti
                bukapintu<='1';
                bufferbukapintu:='1';
                tutuppintu <= '0';
                count:=0;
            elsif (signalnaikturunpenumpang='1') then
                if (count < timetutuppintu) then
                    motornaik<=signalmotornaik;
                    motorturun<=signalmotorturun;
                    bukapintu <= '1';
                    bufferbukapintu:='1';
                    tutuppintu <= '0';
                elsif (count < (timetutuppintu + timepintuselesaimenutup) ) then
                    bukapintu<='0';
                    bufferbukapintu:='0';
                    tutuppintu<='1';
                else
                    tutuppintu <='0';
                    pr_state<=nx_state;
                    if signalstatus='1' then
                        signalstatus<='0';
                    else
                        signalstatus<='1';
                    end if;
                    count:=0;
                end if;
            else                        --jika tidak ada naik turun penumpang maka lift tdk berhenti
                if (count < timepintuselesaimenutup) then        --untuk mengatasi kondisi setelah manual_bukapintu. karena akan lari ke sini, sehingga harus ditutup pintunya
                    if (bufferbukapintu = '1') then
                        bukapintu <= '0';
                        bufferbukapintu:='0';
                        tutuppintu <= '1';
                    else
                        count:=timepintuselesaimenutup;
                    end if;
                elsif (count < timepintuselesaimenutup + time_nx_state) then
                    tutuppintu <= '0';
                    motornaik<=signalmotornaik;
                    motorturun<=signalmotorturun;
                else
                    pr_state<=nx_state;
                    if signalstatus='1' then
                        signalstatus<='0';
                    else
                        signalstatus<='1';
                    end if;
                    count:=0;
                end if;               
            end if;   

            -------------Begin Display Seven Segment--------------
            case pr_state is
                when lantai1 =>
                    digit1 := "1111001";   
                    if permintaan(0)='1' then                ----------bila lantai sdh sama dengan yang diminta maka permintaan pada lantai tsb di nol kan
                        permintaan(0)<='0';
                    else null;
                    end if;
                when lantai2 =>
                    digit1 := "0100100";    
                    if permintaan(1)='1' then
                        permintaan(1)<='0';
                    else null;
                    end if;
                when lantai3 =>
                    digit1 := "0110000";       
                    if permintaan(2)='1' then
                        permintaan(2)<='0';
                    else null;
                    end if;
                when lantai4 =>
                    digit1 := "0011001";       
                    if permintaan(3)='1' then
                        permintaan(3)<='0';
                    else null;
                    end if;
                when lantai5 =>
                    digit1 := "0010010";        
                    if permintaan(4)='1' then
                        permintaan(4)<='0';
                    else null;
                    end if;
                when others => null;
            end case;
            a1<=digit1(0);
            a2<=digit1(1);
            a3<=digit1(2);
            a4<=digit1(3);
            a5<=digit1(4);
            a6<=digit1(5);
            a7<=digit1(6);
            -------------------End Display Seven Segment------------------       
        end if;
    end process utama;

    step: process (pr_state, signalstatus)
    begin
            --------------Begin Penentuan Perubahan State----------------
            case pr_state is
                when lantai1 =>               
                    if (permintaan(0)='1') then     --berhenti dan buka pintu hanya apabila ada permintaan pada lantai tsb
                        nx_state <= pr_state;
                        signalmotornaik <= '0';
                        signalmotorturun <= '0';
                        signalnaikturunpenumpang<='1';
                    else
                        signalnaikturunpenumpang<='0';
                        if arahelevator=1 then            --1 berarti naik
                            nx_state<=lantai2;
                            signalmotornaik <= '1';
                            signalmotorturun <= '0';
                        else
                            nx_state<=pr_state;            --lantai 1 hanya bisa naik atau diam
                            signalmotornaik <= '0';
                            signalmotorturun <= '0';
                        end if;
                    end if;
                when lantai2 =>               
                    if (permintaan(1)='1') then
                        nx_state <= pr_state;
                        signalmotornaik <= '0';
                        signalmotorturun <= '0';
                        signalnaikturunpenumpang<='1';
                    else
                        signalnaikturunpenumpang<='0';
                        if arahelevator=1 then            --1 berarti naik
                            nx_state<=lantai3;
                            signalmotornaik <= '1';
                            signalmotorturun <= '0';
                        elsif arahelevator=2 then        --2 berarti turun
                            nx_state<=lantai1;
                            signalmotornaik <= '0';
                            signalmotorturun <= '1';
                        else
                            nx_state<=pr_state;
                            signalmotornaik <= '0';
                            signalmotorturun <= '0';
                        end if;
                    end if;
                when lantai3 =>               
                    if (permintaan(2)='1') then     --berhenti dan buka pintu hanya apabila ada permintaan pada lantai tsb
                        nx_state <= pr_state;
                        signalmotornaik <= '0';
                        signalmotorturun <= '0';
                        signalnaikturunpenumpang<='1';
                    else
                        signalnaikturunpenumpang<='0';
                        if arahelevator=1 then            --1 berarti naik
                            nx_state<=lantai4;
                            signalmotornaik <= '1';
                            signalmotorturun <= '0';
                        elsif arahelevator=2 then        --2 berarti turun
                            nx_state<=lantai2;
                            signalmotornaik <= '0';
                            signalmotorturun <= '1';
                        else
                            nx_state<=pr_state;
                            signalmotornaik <= '0';
                            signalmotorturun <= '0';
                        end if;
                    end if;
                when lantai4 =>               
                    if (permintaan(3)='1') then     --berhenti dan buka pintu hanya apabila ada permintaan pada lantai tsb
                        nx_state <= pr_state;
                        signalmotornaik <= '0';
                        signalmotorturun <= '0';
                        signalnaikturunpenumpang<='1';
                    else
                        signalnaikturunpenumpang<='0';
                        if arahelevator=1 then            --1 berarti naik
                            nx_state<=lantai5;
                            signalmotornaik <= '1';
                            signalmotorturun <= '0';
                        elsif arahelevator=2 then        --2 berarti turun
                            nx_state<=lantai3;                       
                            signalmotornaik <= '0';
                            signalmotorturun <= '1';
                        else
                            nx_state<=pr_state;
                            signalmotornaik <= '0';
                            signalmotorturun <= '0';
                        end if;
                    end if;
                when lantai5 =>               
                    if (permintaan(4)='1') then     --berhenti dan buka pintu hanya apabila ada permintaan pada lantai tsb
                        nx_state <= pr_state;
                        signalmotornaik <= '0';
                        signalmotorturun <= '0';
                        signalnaikturunpenumpang<='1';
                    else
                        signalnaikturunpenumpang<='0';
                        if arahelevator=2 then        --2 berarti turun
                            nx_state<=lantai4;                       
                            signalmotornaik <= '0';
                            signalmotorturun <= '1';
                        else
                            nx_state<=pr_state;
                            signalmotornaik <= '0';
                            signalmotorturun <= '0';
                        end if;
                    end if;
            end case;
            --------------------------End Penentuan Perubahan State-----------------------
    end process step;
           
end behavior;

--Alhamdulillah :)

Cara mengetahui ip address raspberry atau perangkat lain yg terhubung pada wifi yg sama

1. Install nmap [jika belum ada]: sudo apt install nmap 2. Cek ip address komputer (yg akses ke wifi yang sama): ip addr misal hasilnya 192....