Tampilkan postingan dengan label AVR. Tampilkan semua postingan
Tampilkan postingan dengan label AVR. Tampilkan semua postingan

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

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 Mikrokontroler AVR pada Aplikasi Pemisah Bola Logam dan Non Logam



Studi Kasus

Pada aplikasi kali ini akan dibuat program mikrokontroler jenis AVR untuk mengontrol proses pemisahan bola logam dengan non logam. Pada kasus ini jg akan Sy tampilkan simulasi sederhananya menggunakan ISIS.

Sensor yang diperlukan adalah sensor Gaya (berat) untuk mendeteksi apakah sdh ada bola (baik logam maupun non logam) yang akan dipisahkan. Kemudian sensor Proximity untuk mendeteksi keberadaan logam atau non logam. Sensor Proximity akan disambungkan pada PORT D4 dan sensor Gaya akan disambungkan pada PORT D5 pada mikrokontroler AVR.

Proses kontrol akan berjalan hanya apabila tombol Start/Reset ditekan. Dan akan mati otomatis (Powerdown) apabila pada saat sdh berjalan tidak terdeteksi adanya bola baik logam maupun non logam (terdeteksi dari sensor Gaya). Pada saat mati otomatis maka sistem akan di Powerdown untuk menghemat daya dan hanya bisa dihidupkan kembali dengan menekan tombol Start/Reset. Oleh karena itu tombol Start/Reset akan disambungkan pada input Interupt (PORT D0) pada mikrokontroler AVR.

Pada sisi aktuator akan dipasang LED yang mengindikasikan jenis bola apakah Logam atau NonLogam. Indikator LED ini akan dihubungkan dengan PORT A2 sebagai output serta dirangkaikan transistor PNP dan NPN sedemikian rupa sehingga bisa berfungsi untuk menyalakan LED Logam pada kondisi output LOW (0) dan menyalakan LED Non Logam pada kondisi output HIGH (1). Indikator LED ini pada kondisi real akan dihubungkan pada motor untuk mengatur posisi pada channel mana bola akan dikelompokkan (Logam atau Non Logam).

Aktuator berikutnya adalah selenoid untuk mendorong bola yang terdeteksi baik logam maupun non logam. Namun tentu saja setelah mendorong bola (selama selang waktu tertentu, misal 100ms) aktuator ini juga harus kembali ke posisi semula sehigga diperlukan sinyal untuk menarik kembali ke posisi semula (selama selang waktu tertentu, misal 100ms). Pada simulasi kali ini aktuator ini akan diperagakan oleh LED yg dirangkaikan dengan transistor PNP dan NPN sedemikian rupa sehingga apabila ada signal HIGH (1) maka aktuator akan melakukan aksi "dorong" dan bila LOW (0) akan melakukan aksi "tarik". Aktuator ini akan dihubungkan dengan mikrokontroler melalui PORT A1.

Pada saat Powerdown mikrokontroler juga akan memberikan indikator yaitu suara sirine (buzzer) sehingga memungkinkan operator untuk mengecek apakah bola sdh habis atau ada kesalahan pada sistem (atau ada bola yang macet misalnya) sehigga operator bisa segera me Start ulang sistem.

Pada sistem ini juga dilengkapi LCD 16x2 supaya lebih interaktif dan menampilkan jumlah bola Logam dan Non Logam yang sudah dipisah.

Pada saat Powerdown maka sistem tidak akan bisa menjalankan apa apa kecuali ada sinyal interupt dari tombol Start. Nah setelah di Start ulang maka sistem bisa langsung meneruskan perhitungan jumlah bola Logam dan Non Logam tanpa harus mengulang dari awal.

Berikut video simulasinya :)



Berikut screenshoot konfigurasi ISIS


Berikut screenshoot konfigurasi Codevision

Berikut Source Code yg sdh Sy buat:

/*****************************************************
Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 10.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/

#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#include <sleep.h>

// Alphanumeric LCD functions
#include <alcd.h>

#define sensor_gaya PIND.5
#define sensor_logam PIND.4

bit start = 0;
unsigned int jumlah_logam, jumlah_nonlogam, bataswaktu;
char text[16];

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
start |= 1; //untuk interlock (mengunci)
//start ^= 1; //untuk toggle (pada saat on jika ditekan maka akan jadi off, begitu pula sebaliknya)
PORTA.0 = 0;
bataswaktu = 0;
lcd_clear();
lcd_putsf("    Starting    ");
}

// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
bataswaktu++;           //setiap 1/25 detik
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTA=0x00;
DDRA=0xFF;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

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

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1250.000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0xC3;
OCR1AL=0x50;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer3 Stopped
// Mode: Normal top=0xFFFF
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x03;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;

ETIMSK=0x00;

// USART0 initialization
// USART0 disabled
UCSR0B=0x00;

// USART1 initialization
// USART1 disabled
UCSR1B=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=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")
sleep_enable();
lcd_clear();
lcd_putsf("Pemisahan Logam.");
lcd_gotoxy(0,1);
lcd_putsf("  Tekan Start!  ");

while (1)
      {
      // Place your code here
        if(sensor_logam)
            PORTA.2 = 0;
        else PORTA.2 = 1;
       
        while (start)
            {
                if(sensor_logam)
                    PORTA.2 = 0;
                else PORTA.2 = 1;
               
                if((sensor_gaya < 1) & (bataswaktu >= 25))  //sensor_gaya tidak dibuat = 0  karena meskipun tidak ditekan nilainya belum tentu sama dengan 0
                    {
                        PORTA.0 = 1;
                        lcd_clear();
                        lcd_putsf("   Power Down   ");
                        lcd_gotoxy(0,1);
                        lcd_putsf("Check & Restart!");
                        bataswaktu = 0;
                        powerdown();
                    }
               
                while (sensor_gaya)
                    {           
                       if (sensor_logam)
                       {     
                            jumlah_logam++;                          
                       }
                       else
                       {
                            jumlah_nonlogam++;                       
                       }
                      
                       PORTA.1 = 1;
                       delay_ms(100);   //untuk S1 dorong
                       PORTA.1 = 0;                  
                      
                       lcd_clear();
                      
                       sprintf(text,"Logam: %u  ", jumlah_logam);
                       lcd_gotoxy(0,0);
                       lcd_puts(text);
                      
                       sprintf(text,"Non Logam: %u  ", jumlah_nonlogam);
                       lcd_gotoxy(0,1);
                       lcd_puts(text);
                      
                       delay_ms(100);   //untuk S1 tarik
                       bataswaktu = 0;                               
                    }
            }
           
      }
}


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....