Pemograman Labview Dasar – Level Measurement

1.Pengenalan Pemrograman Labview.

File menu -> New VI. Untitled VI akan mempunyai dua bagian yang disebut Front Panel dan Block Diagram seperti gambar di bawah ini.

basic_labview_1 (2)

Front Panel Window adalah user interface window ketika VI dijalankan, sedangkan Block Diagram Window akan melakukan kalkulasi dan mengeksekusi algoritma. Berikut adalah cara yang nyaman untuk melihat kedua window bersamaan:

Front Panel: Window menu -> Tile Left and Right

Save file Untitled VI tadi dengan nama Level_Measurement_01.vi seperti dibawah ini.

basic_labview_1 (3)

Tampilan Tools Palette.

basic_labview_1 (4)

Klik kanan di Front Panel > Controls Pallete di Front Panel (atau View menu > Control Palette).

basic_labview_1 (5)

2. Memulai Pemrograman di Front Panel

Membuat free text (sebagain comments) di Front Panel

Tambahkan text di Front Panel: Double click, ketik teks “Level Measurement” “u = uin*R*K0” dan “y = K*(u-u0)”.

Atur font properties dari “Level Measurement”: Size:24, Style: Bold

Atur warna:

View menu -> Tools Palette -> Set Color:

basic_labview_1 (6)

Save VI tadi.

Langsung kita buat aplikasinya dengan memperhatikan gambar-gambar berikut.

Masukan Vertical Pointer Slide. Klik kanan untuk membuka Control Palette. Disana terdapat komponen-komponen yang bisa kita masukan ke Front Panel. Jika kita bingung dengan komponen yang ada, kita bisa tekan ctrl+h untuk membuka Help Window seperti pada Figure 2 window kecil sebelah kanan. Tinggal sorotkan cursor pada objek, maka keterangan akan muncul.

Komponen-komponen di front panel bisa diatur warnanya dengan bantuan Tools Palette.

basic_labview_1 (7)

Atur Propertiesnya.

basic_labview_1 (8)

Nama yang tertera pada label akan tampil di front panel jika di centang visible nya. Nama tersebut biasanya akan sama dengan nama yang ada pada block diagram. Karena pada front panel biasanya keterangan nama komponen dibuat sejelas mungkin, maka nama komponen akan terlalu panjang di block diagram. Maka dari itu, jangan centang visible di label tapi centang visible di caption. Di label beri nama singkat saja yang mana nanti akan tertera di block diagram. Sedangkan di caption silakan beri nama komponen sejelas mungkin dan akan tampil di front panel. Seperti pada gambar berikut untuk inisialisasi nama pada gain K input control.

basic_labview_1 (9)

Untuk menampilkan angka numeric dari tiap control ataupun indicator centanglah show digital display pada properties komponen.

basic_labview_1 (10)

Masukan numeric control sebagai input dan tank sebagai indicator (disini output) sebagai berikut.

basic_labview_1 (11)

Jadi tipe datanya itu ada control sebagai input, Constant juga sebagai input, dan Indicator sebagai output.

Kembali ke block diagram. Disana akan muncul icon dari masing-masing komponen yang kita tambahkan tadi.

basic_labview_1 (12)

Tambahkan while loop.

basic_labview_1 (13)

basic_labview_1 (14)

Jangan lupa untuk menambahkan stop button di front panel dan sambungkan dengan stop loop komponen seperti gambar di atas.

Menambahkan persamaan ke dalam block diagram.

basic_labview_1 (15)

Sehingga menjadi sebagai berikut.

basic_labview_1 (16)

basic_labview_1 (17)

Wiringlah komponen-komponen tersebut seperti Nampak di atas. Cursor akan berubah menjadi rol kabel maka tinggal klik kiri dan tahan sampai tersambung ke ujung yang ingin kita sambungkan. Untuk mendelete kabel yang sudah tersambung bisa double klik kable dengan cursor yang menunjukan tanda panah biasa. Untuk mendelete kabel yang rusak (bertanda silang merah dan garis putus-putus) tekan ctrl+b.

basic_labview_1 (18)

Jika kita menemukan kabel yang terhubung sembarangan, kita bisa merapikannya degan cara sebagai berikut.

basic_labview_1 (19)

basic_labview_1 (20)

Kita juga bisa memunculkan label dari komponen sebagai keterangan.

basic_labview_1 (21)

Coba masukan komponen wait until ms. Komponen ini akan mendelay proses sehingga satu cycle proses akan digenapkan sesuai waktu yang diinputkan ke komponen tersebut dalam millisecond.

basic_labview_1 (22)

Jika di block diagram window kita men-double click komponen, maka window akan berganti ke front panel dan cursor akan menyorot komponen yang bersangkutan. Begitu pula sebaliknya di front panel ke block diagram window. Coba sekarang double klik di stop button pada block diagram window.

basic_labview_1 (23)

Atau untuk mengganti window yang muncul pada layar antara front panel atau block diagram window, kita bisa menekan ctrl+e.

Aturlah pada stop button properties seperti pada gambar berikut.

basic_labview_1 (24)

Set pada keadaan “Latch when pressed”. Atur pula warna pada saat ON dan pada saat OFF sehingga Nampak seperti gambar di bawah ini.

basic_labview_1 (25)

Mari kita cek dengan menjalankan program yang kita buat dengan meng-klik tombol run, tanda panah ke kiri warna putih pada menu bar sehingga beruba menjadi hitam Nampak seperti gambar berikut.

basic_labview_1 (26)

Mengoreksi error pada program.

Program yang error atau salah syntax biasanya akan terindikasi pada tombol run yang berubah menjadi warna abu-abu seperti di bawah ini.

basic_labview_1 (27)

Klik pada run button abu-abu tadi maka akan muncul list error window yang akan member tahu kiat bagian mana yang error. Coba saja double klik pada error message yang ada di window tersebut. Biasanya cursor akan menuju komponen yang bersangkutan dan berkedip.

basic_labview_1 (28)

Sekaran coba tambahkan display meter seperti gambar berikut.

basic_labview_1 (29)

Dan atur propertiesnya seperti gamabar di bawah ini.

basic_labview_1 (30)

Dan pada block diagram window wiringlah seperti gambar berikut.

basic_labview_1 (31)

Sehingga hasil akhir dari front panel akan Nampak seperti berikut ini.

basic_labview_1 (32)

Dan tampilan block diagram wndow akan Nampak seperti di bawah ini.

basic_labview_1 (1)

RAM/Flash dalam Aplikasi Embedded C Programs

http://www.esacademy.com/en/library/technical-articles-and-documents/8051-programming/8051-memory-configurations-with-c-compilers.html

http://coactionos.com/embedded%20design%20tips/2013/10/18/Tips-RAM-Flash-Usage-in-Embedded-C-Programs/

http://www.leonardomiliani.com/2013/la-memoria-sram-dei-microcontrollori/?lang=en

http://playground.arduino.cc/Learning/Memory

http://mbed.org/handbook/Memory-Model

http://en.wikibooks.org/wiki/Embedded_Systems/C_Programming

Disain Gripper

Tipe Grippers

  1. Single mechanical devices-hooks and scoops
  2. Mechanical grippers-two or more fingers actuated by the robot controller
  3. Vacuum grippers-suction cups used to hold flat objects
  4. Magnetized grippers -A type of end effector that uses electromagnets or permanent magnets to pick up metallic objects.
  5. Adhesive devices-adhesive substance used to hold flexible material

Perbandingan beberapa jenis gripper

gripper_1

 

Vacuum Grippers

gripper_2

 

Pneumatic Gripper

1.Berdasarkan Gripper Action:

gripper_action

2.Berdasarkan Tipe Pneumatic Gripper yang Digunakan:

gripper_parallel

gripper_angular

 

3.Berdasarkan Jaw Configuration:

gripper_jaw

Referensi lain menyatakan bahwa secara garis besar mekanika dari sebuah gripper bisa diklasifikasikan sebagai berikut.

1.Mechanical Finger Grippers

a.Linkage Grippers

gripper1.TIF

 

b.Gear and Rack Grippers

gripper2.TIF

 

c.Cam-actuated Grippers

gripper3.TIF

 

d.Screw-driven Grippers

gripper4.TIF

 

e.Rope & Pulley Grippers

gripper5.TIF

 

2.Vacuum & Magnetic Grippers

a.Vacuum Grippers

gripper6.TIF

 

b.Magnetic Gripper

gripper7.TIF

 

3.Versatile or universal Grippers

a.Inflatable grippers used for picking up irregular and fragile objects without concentrated loading. In the initial position before gripping, the lever 1, are opened up, the bellows are in a compressed condition because the gas pressure in the bags,3, with the spheres is close, even a slight pressure of the object on a bag is sufficient enough to cause the bag wall to be deeply depressed and surround the object. When the degree of the surrounding is adequate the lever motion ceases, and pressure in the bags is reduced by bellows, diaphragm device pr vacuum pump, causing bags to harden without changing shape and hence gripping the object. To release the object operation is done in reverse.

gripper8.TIF

 

b.Soft Grippers

gripper9b.TIF

 

c.Three Fingered Grippers

gripper10.TIF

 

Beberapa acuan desain gripper:

6_011 6_010 6_009 6_008 6_007 6_006 6_005 6_005 6_004 6_002 6_002 6_003 6_003 6_004 6 6

Tambahan link katalog produk gripper:

directindustry.com/prod/fabco-air/2-jaw-angular-grippers-11741-443594.html#product-item_1303373

___________________________________________

Daftar Pustaka

grippers.com/size.htm

curriculum.vexrobotics.com/curriculum/object-manipulation/manipulators

directindustry.com/prod/fabco-air/2-jaw-angular-grippers-11741-443594.html#product-item_1303373

omega.com/prodinfo/grippers.html

sra.vjti.info/knowledgebase/posts-on-a-roll-1/gripper-mechanisms

stab-iitb.org/resources/images/d/de/Ww-gripper.pdf

Membuat AVR Programmer Lewat Koneksi Serial

AVR910 – AVR Programmer

schematic AVR910Rangkaian ini adalah AVR programmer dari koneksi serial ke ISP.

Rangkaian di atas dapat  dimodif agar terkoneksi secara USB dengan menambahkan chip USB2Serial seperti PL-2303HX. Jadi Programmer tersebut dapat terkoneksi dengan port USB PC ataupun laptop tanpa harus ada port RS232. Driver untuk chip tersebut bisa didownload di webnya.

Untuk kode mikrokontroler ATTiny2313 dapat diunduh di forum sbb

elektroda.pl/rtvforum/topic2382719.html

Kalau saya lebih senang dengan file avr910_2313_ver31.asm karena maksimal baudratenya bisa sampai 115200. Untuk mendapat file hex, file asm dicompile dengan AVRStudio 4. Setelah itu downloadkan ke chip ATTiny2313 lewat bantuan ISP programmer lainnya. Dan AVR910 kita siap digunakan untuk mendownload program mikrokontroler AVR kita.

Referensi
_________________

elektroda.pl/rtvforum/topic2382719.html
kmitl.ac.th/~kswichit/avr910/avr910.htm
atmel.com/Images/doc0943.pdf

Membuat Server Video Streming Sederhana Visual C# 2012

Berdasarkan post sebelumnya http://wangready.wordpress.com/2011/10/09/akuisisi-gambar-dari-webcam-menggunakan-aforge-net-library-berbasis-bahasa-c/

saya edit dan tambahkan timer untuk menyimpan file gambar pada server xampp. Jadi instal dulu xampp.

private void timer1_Tick(object sender, EventArgs e)
        {
            Bitmap im1 = videoSourcePlayer.GetCurrentVideoFrame();
            pictureBox1.Image = im1;
            im1.Save(@"C:\xampp\htdocs\my_page\tes_buff.jpg");
            try
            {
                System.IO.FileInfo f = new System.IO.FileInfo(@"C:\xampp\htdocs\my_page\tes_buff.jpg");
                long s1 = f.Length;
                label4.Text = s1.ToString();
                if(s1>100000)
                    System.IO.File.Copy(@"C:\xampp\htdocs\my_page\tes_buff.jpg", @"C:\xampp\htdocs\my_page\tes.jpg", true);
            }
            catch (Exception a)
            {
            }
        }

file gambar saya simpan di C:\xampp\htdocs\my_page\tes.jpg . File bisa di browse lewat page html sederhana sbb.

<html>
<head>
<title>HTML in 10 Simple Steps or Less</title>
<meta http-equiv="refresh" content="0.5" >
</head>
<body>
<img src="http://10.7.21.8/my_page/tes.jpg"/>
</body>

Untuk mengganti folder file browsing saya mengedit file dari index.php di folder htdocs menjadi /my_page/

<?php
	if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
		$uri = 'https://';
	} else {
		$uri = 'http://';
	}
	$uri .= $_SERVER['HTTP_HOST'];
	header('Location: '.$uri.'/my_page/');
	exit;
?>

gambar bisa distreaming juga lewat aplikasi yang contohnya ada di example library aforge.net langsung mengakses file .jpg nya dengan alamat URL server. file project aplikasinya ada di directory \AForge.NET\Framework\Samples\Vision\MotionDetector

Map Koordinat GPS Visual C#

map

map_gui

Source static map yang digunakan adalah dari openstreetmap karena free. Bisa juga menggunakan google map Static Maps API V2 Developer akan tetapi 25 000 free static map requests per application per 24 hour period. Lebih dari itu harus mempunyai API_KEY  Google Maps API for Business.

Item yang digunakan pada contoh ini menggunakan picturebox1 untuk menampilkan map yang di browsing lewat koneksi internet, timer1 memberi jeda waktu untuk merefresh map, dan label1 untuk menampilkan parameter yang ingin dipantau (fleksible untuk memudahkan memeriksa parameter2). Karena input latitude dan longitude yang saya berikan adalah dengan format yang terdapat pada SiRF NMEA Reference Manual hardware GPS, dengan format Latitude ddmm.mmmm,N/S Indicator, Longitude dddmm.mmmm, N/S Indicator, maka saya melakukan konversi dahulu kedalam desimal.

 
Decimal Degrees = Degrees + minutes/60 + seconds/3600

 

public double conversi_degrees(double time_deg)
{
   double depan = (double)(int)time_deg;
   double belakang = time_deg - depan;
   double degrees = (double)(int)(depan/100);
   double minutes = Math.Round(time_deg - (degrees*100),6);
   double dec_degrees = degrees + Math.Round((minutes/60),6);
   return (dec_degrees);
}

 
Setelah didapat nilai dalam format desimal, maka variabel tersebut siap dimasukan ke dalam format URL dari openstreetmap untuk kemudian ditampilkan di picturebox1.
kode lengkap.
 

using System;
using System.Windows.Forms;

namespace GPS_MAP
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int jum_pin = 5;
        double center_lat_val = -658.62665;
        double center_long_val = 10737.81812;
        double[] center_lat_pin = new double[5] { -658.62665, -658.62665, -658.62665, -658.62665, -658.62665 };
        double[] center_long_pin = new double[5] { 10737.81812, 10737.92722, 10738.03632, 10738.14542, 10738.25442 };
        
        string url_data;
        string pin_data;

        int count = 15;
        private void timer1_Tick(object sender, EventArgs e)
        {
            double lat_val;
            double long_val;
            lat_val = conversi_degrees(center_lat_val);
            long_val = conversi_degrees(center_long_val);
            int val_zoom = count;
            pin_data = "";
            for (int i = 0; i < jum_pin; i++)
            {
                double lat_pin = conversi_degrees(center_lat_pin[i]);
                double long_pin = conversi_degrees(center_long_pin[i]); 
                pin_data += string.Format("{0},{1},lightblue{2}|", lat_pin, long_pin,i+1);
            }
            url_data = String.Format("http://staticmap.openstreetmap.de/staticmap.php?center={0},{1}&zoom={2}&size=600x300&maptype=mapnik&markers={3}",lat_val,long_val,val_zoom,pin_data);
            pictureBox1.ImageLocation = url_data;

            label1.Text = url_data;
        }

        public double conversi_degrees(double time_deg)
        {
            double depan = (double)(int)time_deg;
            double belakang = time_deg - depan;
            double degrees = (double)(int)(depan/100);
            double minutes = Math.Round(time_deg - (degrees*100),6);
            double dec_degrees = degrees + Math.Round((minutes/60),6);
            return (dec_degrees);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        protected override void OnMouseWheel(MouseEventArgs mea)
        {
            if (mouse_stat_enter == 1)
            {
                count += mea.Delta / 120;
                if (count < 0)
                    count = 0;
                else if (count > 18)
                    count = 18;
            }
        }

        int mouse_pos_X, mouse_pos_Y;
        int prev_mouse_pos_X, prev_mouse_pos_Y;
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            pictureBox1.Cursor = Cursors.Hand;
            prev_mouse_pos_X = e.X;
            prev_mouse_pos_Y = e.Y; 
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            pictureBox1.Cursor = Cursors.Default;
            mouse_pos_X = e.X;
            mouse_pos_Y = e.Y;
            int delta_X = prev_mouse_pos_X - mouse_pos_X;
            int delta_Y = prev_mouse_pos_Y - mouse_pos_Y;
            double constanta;
            if((count >=15)&&(count<=18))
                constanta = 20;
            else if((count >=12)&&(count<15))
                constanta = 8;
            else if((count >=9)&&(count<12))
                constanta = 1;
            else if((count >=6)&&(count<9))
                constanta = 0.5;
            else if((count >=3)&&(count<6))
                constanta = 0.1;
            else
                constanta = 0.1;
            center_lat_val -= (double)delta_Y/(count*constanta);
            center_long_val += (double)delta_X/(count * constanta);
        }

        int mouse_stat_enter = 0;
        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            mouse_stat_enter = 1;
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            mouse_stat_enter = 0;
        }
    }
}

 
________________________________________
Daftar Pustaka
wiki.openstreetmap.org/wiki/Static_map_images
staticmap.openstreetmap.de/
developers.google.com/maps/documentation/staticmaps/
itouchmap.com/latlong.html
andrew.hedges.name/experiments/convert_lat_long/

Template HMI Sederhana C# VS2012

HMI_simple
FILE DOWNLOAD

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Configuration;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            //------------------------------------------------------------------
            int panjang = pictureBox1.Size.Height;
            int lebar = pictureBox1.Size.Width;
            Graphics g = this.pictureBox1.CreateGraphics();
            Pen p1 = new Pen(Color.Black, 3);
            Pen p2 = new Pen(Color.GreenYellow, 3);
            int batas_panjang = panjang * (100-level_panjang)/100;
            for (int y = 0; y < batas_panjang; y++)
            {
                g.DrawLine(p1, new Point(0, y), new Point(lebar, y));
            }
            for (int y = batas_panjang; y < panjang; y++)
            {
                g.DrawLine(p2, new Point(0, y), new Point(lebar, y));
            }
            //------------------------------------------------------------------
            //------------------------------------------------------------------
           /* label1.Text = panjang_O.ToString() + " " + lebar_O.ToString() +
                Environment.NewLine + Y.ToString() +
                Environment.NewLine + X.ToString() +
                Environment.NewLine + jarum.ToString();*/
        }
        Bitmap default_image;
        int level_panjang;
        int Stat_button1;
        private void button1_Click(object sender, EventArgs e)
        {
            if (Stat_button1 == 0)
            {
                button1.Text = "ON";
                button1.ForeColor = Color.Black;
                button1.BackColor = Color.Yellow;
                Stat_button1 = 1;
            }
            else
            {
                button1.Text = "OFF";
                button1.ForeColor = Color.White;
                button1.BackColor = Color.DarkBlue;
                Stat_button1 = 0;
            }

        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            level_panjang = trackBar1.Value;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            default_image = (Bitmap)pictureBox3.Image.Clone();
            pictureBox4.Enabled = false;

            int x_ = pictureBox3.Size.Width;
            int y_ = pictureBox3.Size.Height;
            label2.Parent = pictureBox3;
            label2.BackColor = Color.Transparent;
            label2.BringToFront();
            label2.ForeColor = Color.DarkGreen;
            label2.Location = new Point(0, (int)(y_*0.7));

            button1.Text = "OFF";
            button1.ForeColor = Color.White;
            button1.BackColor = Color.DarkBlue;
        }

        int alarm_stat;
        private void timer2_Tick(object sender, EventArgs e)
        {
            float derajat = ((float)level_panjang/100) * 360;
            label2.Text = Convert.ToString((int)derajat);
            pictureBox3.Image = RotateImage(default_image, derajat-143);

            if (level_panjang > 50)
            {
                pictureBox4.Enabled = true;
                timer3.Enabled = true;

                if (alarm_stat == 0)
                {
                    if (this.WindowState == FormWindowState.Minimized)
                        this.WindowState = FormWindowState.Normal;
                    this.Show();
                    this.Activate();
                    this.ShowInTaskbar = true;
                    this.TopMost = true;
                    this.Focus();
                    alarm_stat = 1;
                }
            }
            else
            {
                pictureBox4.Enabled = false;
                timer3.Enabled = false;
                BackColor = Color.FromName("Control");
                pictureBox3.BackColor = Color.FromName("Control");

                if (alarm_stat == 1)
                {
                    this.TopMost = false;
                    alarm_stat = 0;
                }
            }
        }

        public static Image RotateImage(Image img, float rotationAngle)
        {
            //create an empty Bitmap image
            Bitmap bmp = new Bitmap(img.Width, img.Height);

            //turn the Bitmap into a Graphics object
            Graphics gfx = Graphics.FromImage(bmp);

            //now we set the rotation point to the center of our image
            gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

            //now rotate the image
            gfx.RotateTransform(rotationAngle);

            gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

            //set the InterpolationMode to HighQualityBicubic so to ensure a high
            //quality image once it is transformed to the specified size
            gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //now draw our new image onto the graphics object
            gfx.DrawImage(img, new Point(0, 0));

            //dispose of our Graphics object
            gfx.Dispose();

            //return the image
            return bmp;
        }

        int stat;
        private void timer3_Tick(object sender, EventArgs e)
        {
            if (stat == 0)
            {
                BackColor = Color.Red;
                pictureBox3.BackColor = Color.Red;
                Console.Beep();
                stat = 1;
            }
            else
            {
                BackColor = Color.FromName("Control");
                pictureBox3.BackColor = Color.FromName("Control");
                stat = 0;
            }
        }

        private void timer4_Tick(object sender, EventArgs e)
        {
            label4.Text = DateTime.Now.ToString();
        }
    }
}

Mem-Plot Data Serial Pada Matlab

serial_plot_matlab

Gambar di atas didapat dengan simulasi mikrokontroler dengan proteus -> virtual serial port emulator ->Matlab

Bagaimana memplot data yang di akuisisi oleh mikrokontroler lalu ditampilkan di Matlab?

Missal data yang dikirim dari mikro adalah sebagai berikut.

while (1)
      {
      // Place your code here    
       for(i=0;i<360;i+=60) 
       {        
            sin_wave = 100*sin(i * 0.0174532925);
            printf("data %d %f 100 \n\r",i,sin_wave);
       }   
      }

Kode di matlab untuk menampilkan grafik seperti gambar di atas.

clc
clear all
close all

%*******************inisialisasi serialport*****************************
delete(instrfindall); 
S1 = serial ('COM3', 'Baudrate', 9600, 'DataBits', 8, 'Parity','none'); 
fopen(S1);
figure,
time_t = 1;
for zz=1:1000
    clf; % clear current figure (refresh the polt)
    t = [];
    buffer_data = [];
    ii=0;
    while(ii<10)
        linedata = fgetl(S1);
        data_dec = textscan(linedata,'data %d %f %d');
        dat_A  = data_dec{1};
        dat_B  = data_dec{2};
        dat_C  = data_dec{3};
        t = time_t:time_t + 9;
        buffer_data = [buffer_data; dat_A dat_B dat_C]; 
        ukur = size(buffer_data);
        ii = ukur(1);
    end
    plot(t, buffer_data(:,1),'r-');hold on
    plot(t, buffer_data(:,2),'g-');hold on
    plot(t, buffer_data(:,3),'b-');hold off
    axis([time_t,time_t + 9,-120,360]);    
    time_t = time_t + 10;
    drawnow;
end

Line Follower Robot Berbasis Sensor Kamera

Robot dirancang mempunyai sensor kamera, yaitu webcam. Data citra diakuisisi menggunakan komputer lewat software MATLAB. Di komputerlah semua algoritma utama dibuat. Komputer menghasilkan output data PWM yang kemudian dikirim ke mikrokontroler lewat koneksi USB2Serial. Mikrokontroler akan menerjemahkan data yang diterima dari komputer menjadi sinyal PWM. Sinyal ini masuk ke motor driver baru kemudian masuk ke motor dengan tegangan maksimal tegangan baterai, yaitu 11,1V. Robot juga dirancang untuk dapat mengenali posisi dengan mengenali landmark yang terdapat pada beberapa posisi pada garis. Dengan menambahkan data peta garis ke dalam sistem pengolahan data, robot dapat bergerak otomatis ke posisi yang diinginkan atau disebut posisi target.

Robot mendeteksi garis dengan menggunakan metode filter warna. Metode filter warna juga digunakan untuk mendeteksi keberadaan landmark. Sebelum landmark dapat diproses untuk dikenali, citra landmark yang sudah dicrop dirotate dengan berdasarkan data kemiringan yang terdeteksi oleh Transformasi Hough. Dengan demikian input untuk proses pengenalan landmark menjadi sesuai dengan kriteria. Algoritma pengenalannya menggunakan metode PCA (Principle Component Analysis) yang terlebih dahulu membuat data latih.

Berikut skematik sistem mikrokontrolernya.

sch_con
_________________________________________________
DAFTAR PUSTAKA
[1] Armbrust , C. Braun , T. Föhst, T. Proetzsch, M. Renner, A. Schäfer, B.H., Berns K. The Robust Autonomous Vehicle for Off-road Navigation. Technische Universität Kaiserslautern.
[2] Bräunl, Thomas. EMBEDDED ROBOTICS: Mobile Robot Design and Applicationswith Embedded Systems. Springer-Verlag Berlin Heidelberg 2003, 2006. Germany.
[3] Datasheet mikrokontroler ATmega32.
[4] Datasheet IC H-Bridge L298.
[5] Francois Dupuis, Jean. Parizeau, Marc. Evolving a Vision-Based LineFollowing Robot Controller. Departement de genie electrique et de genie informatique. Universite Laval, Quebec. Canada.
[6] Kim, Kyungnam.Face Recognition using Principle Component Analysis. Department of Computer Science. University of Maryland, College Park MD 20742, USA.
[7] Pitowarno, Endra.2006.”ROBOTIKA: Desain, Kontrol, dan Kecerdasan Buatan”. Percetakan Andi Offset. Yogyakarta. Indonesia.
[8] Pranata Kusuma, Andri. 2013. Analysis Of Hough Transform Algorithm For Circle And Ellipse Detection Based On Digital Image Processing. Tugas Akhir Program Sarjana. Institut Teknologi Telkom.
[9] Rusdinar, Angga. Kim, Jungmin. Lee, Junha. Kim, Sungshin. 2011. Implementation Of Real-Time Positioning System Using Extended Kalman Filter And Artificial Landmark On Ceiling. School of Electrical Engineering, Pusan National University, Busan, 609-735, Korea.
[10] Schworer, Ian. 2005.Navigation and Control of an Autonomous Vehicle. Virginia Polytechnic Institute and State University. Blacksburg,Virginia.
[11] Sigit, Riyanto. 2007. Robotikaa, Sensor, dan Aktuator. Yogyakarta : Graha Ilmu.
[12] W. Wall, Richard. Bennett, Jerry. Eis, Greg. Lichy, Kevin. Owings, Elizabeth. Creating A Low-Cost Autonomous Vehicle. University of Idaho Moscow.

Membuat Virtual Joystik C#

Project kali ini adalah membuat sebuah aplikasi pada PC yang berperan menjembatani sebuah controller game yang mempunyai interface serial dengan game di PC. Controller game yang dimaksud adalah sebuah accelerometer (post sebelumnya).  Library yang digunakan adalah vjoy atau Virtual joystick. Library-nya bisa di download di link berikut.

vjoystick.sourceforge.net/site/index.php/dev

Compiler menggunakan Visual C# Express 2010.

Pada post sebelumnya saya merancang program GUI dengan chart untuk mengecek data yang diterima. Berikut tampilannya.

vjoy1

berikut kode nya.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Configuration;

namespace serial
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //—menset event handler untuk DataReceived event—
            serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceived);
            //—menampilkan nama serialport yang tersedia pada
            // komputer—
            string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
            for (int i = 0; i <= portNames.Length - 1; i++)
            {
                cbbCOMPorts.Items.Add(portNames[i]);
            }
            btnDisconnect.Enabled = false;
            horison = pictureBox1.Image;

            chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 0.0;
            chart1.ChartAreas["ChartArea1"].AxisX.Maximum = 200.0;
            chart1.ChartAreas["ChartArea1"].AxisY.Minimum = -60.0;
            chart1.ChartAreas["ChartArea1"].AxisY.Maximum = 60.0;

            chart1.Series["Series1"].Color = Color.Cyan;
            chart1.Series["Series2"].Color = Color.Red;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            //—menutup akses serialport apabila akses serialport terbuka—
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
            try
            {
                //—mengatur beberapa parameter untuk koneksi serial
                // port—
                serialPort.PortName = cbbCOMPorts.Text;
                serialPort.BaudRate = 9600;
                serialPort.Parity = System.IO.Ports.Parity.None;
                serialPort.DataBits = 8;
                serialPort.StopBits = System.IO.Ports.StopBits.One;
                //—buka serial port—
                serialPort.Open();
                //—menampilkan status dari serial port dan
                // enable/disable -kan tombol—
                lblMessage.Text = cbbCOMPorts.Text + " connected.";
                btnConnect.Enabled = false;
                btnDisconnect.Enabled = true;
                timer1.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            try
            {
                //—tutup serial port—
                serialPort.Close();
                //—menampilkan status dari serial port dan
                // enable/disable -kan tombol—
                lblMessage.Text = serialPort.PortName +" disconnected.";
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
                timer1.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                //—menulis tipe data string pada serial port—
                serialPort.Write(txtDataToSend.Text + Environment.NewLine);
                //—menambahkan string yang telah dikirim pada TextBox control—
                txtDataReceived.AppendText(">" + txtDataToSend.Text +  Environment.NewLine);
                txtDataReceived.ScrollToCaret();
                //—bersihkanTextBox control—
                txtDataToSend.Text = string.Empty;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        string kata;
        string[] buff_kata = new string[8];
        //—Event handler untuk DataReceived event—
        private void DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                kata = serialPort.ReadLine();
                buff_kata = SplitWords(kata);
                if (kata != string.Empty)
                {
                    //txtDataReceived.Text = kata;
                    txtDataReceived.BeginInvoke(new myDelegate(updateTextBox));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        static string[] SplitWords(string s)
        {
            //
            // Split on all non-word characters.
            // ... Returns an array of all the words.
            //
            return Regex.Split(s, " ");
            // @      special verbatim string syntax
            // \W+    one or more non-word characters together
        }

        //—Delegate and subroutine untuk ditampilkan pada TextBox control—
        public delegate void myDelegate();

        double  Kk,
                Xk_topi,
                Pk,
                R = 0.1,
                Q = 0.002,
                Xk_topi_prev = 0,
                Pk_prev = 1,
                Pk_update,
                Xk_topi_update;
        int kalman_filter_ku(double Zk)
        {
            //Time Update
            Xk_topi_update = Xk_topi_prev;
            Pk_update = Pk_prev + Q;
            //Measurement Update
            Kk = Pk_update / (Pk_update + R);
            Xk_topi = Xk_topi_update + (Kk * (Zk - Xk_topi_update));
            Pk = (1 - Kk) * Pk_update;
            Xk_topi_prev = Xk_topi;
            Pk_prev = Pk;
            return ((int)Xk_topi);
        }

        Image horison;
        int data_y,
            kalman_y;
        public void updateTextBox()
        {
            try
            {
                data_y = Convert.ToInt32(buff_kata[2]);
            }
            catch (Exception a)
            {

            }
            kalman_y = kalman_filter_ku((double)data_y);
            txtDataReceived.Text = "ACC:"+data_y.ToString()+" Kalman:"+kalman_y.ToString();
        }

        public static Image RotateImage(Image img, float rotationAngle)
        {
            //create an empty Bitmap image
            Bitmap bmp = new Bitmap(img.Width, img.Height);

            //turn the Bitmap into a Graphics object
            Graphics gfx = Graphics.FromImage(bmp);

            //now we set the rotation point to the center of our image
            gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

            //now rotate the image
            gfx.RotateTransform(rotationAngle);

            gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

            //set the InterpolationMode to HighQualityBicubic so to ensure a high
            //quality image once it is transformed to the specified size
            gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //now draw our new image onto the graphics object
            gfx.DrawImage(img, new Point(0, 0));

            //dispose of our Graphics object
            gfx.Dispose();

            //return the image
            return bmp;
        }

        int time,
            time_prev,
            amp,
            amp_offset = 0,
            amp_prev = 220,
            volt_div = 1,
            end_scope = 200,
            amp_kalman,
            amp_prev_kalman;
        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Image = RotateImage(horison, data_y);
            pictureBox2.Image = RotateImage(horison, kalman_y);
            time++;
            time_prev = time - 1;

            amp = (data_y * volt_div) + amp_offset;
            chart1.Series["Series1"].Points.AddXY(time, amp);
            amp_kalman = (kalman_y * volt_div) + amp_offset;
            chart1.Series["Series2"].Points.AddXY(time, amp_kalman);

            amp_prev = amp;
            amp_prev_kalman = amp_kalman;

            if (time > end_scope)
            {
                chart1.Series["Series1"].Points.Clear();
                chart1.Series["Series2"].Points.Clear();
                time = 0;
            }
        }
    }
}

Sedangkan untuk pengaplikasian controler game-nya saya disain lebih sederhana dengan tampilan sebagai berikut.
vjoy2
berikut kode nya.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using vJoyInterfaceWrap;
namespace serial
{
    public partial class Form1 : Form
    {
        // Declaring one joystick (Device id 1) and a position structure.
        static public vJoy joystick;
        static public vJoy.JoystickState iReport;
        static public uint id = 1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //—menset event handler untuk DataReceived event—
            serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceived);
            //—menampilkan nama serialport yang tersedia pada
            // komputer—
            string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
            for (int i = 0; i <= portNames.Length - 1; i++)
            {
                cbbCOMPorts.Items.Add(portNames[i]);
            }
            btnDisconnect.Enabled = false;
            joystick = new vJoy();
            if (!joystick.AcquireVJD(id))
            {
                txtDataReceived.Text = "gagal";
            }
            else
            {
                txtDataReceived.Text = "berhasil";
                joystick.SetAxis(16384, id, HID_USAGES.HID_USAGE_X);   //min 16 center 16384 max 32767
                joystick.SetAxis(16384, id, HID_USAGES.HID_USAGE_Y);   //min 16 center 16384 max 32767
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            //—menutup akses serialport apabila akses serialport terbuka—
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
            try
            {
                //—mengatur beberapa parameter untuk koneksi serial
                // port—
                serialPort.PortName = cbbCOMPorts.Text;
                serialPort.BaudRate = 9600;
                serialPort.Parity = System.IO.Ports.Parity.None;
                serialPort.DataBits = 8;
                serialPort.StopBits = System.IO.Ports.StopBits.One;
                //—buka serial port—
                serialPort.Open();
                //—menampilkan status dari serial port dan
                // enable/disable -kan tombol—
                lblMessage.Text = cbbCOMPorts.Text + " connected.";
                btnConnect.Enabled = false;
                btnDisconnect.Enabled = true;
                timer2.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            try
            {
                //—tutup serial port—
                serialPort.Close();
                //—menampilkan status dari serial port dan
                // enable/disable -kan tombol—
                lblMessage.Text = serialPort.PortName +" disconnected.";
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
                timer2.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                //—menulis tipe data string pada serial port—
                serialPort.Write(txtDataToSend.Text + Environment.NewLine);
                //—menambahkan string yang telah dikirim pada TextBox control—
                txtDataReceived.AppendText(">" + txtDataToSend.Text +  Environment.NewLine);
                txtDataReceived.ScrollToCaret();
                //—bersihkanTextBox control—
                txtDataToSend.Text = string.Empty;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        string kata;
        string[] buff_kata = new string[8];
        //—Event handler untuk DataReceived event—
        private void DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                kata = serialPort.ReadLine();
                buff_kata = SplitWords(kata);
                if (kata != string.Empty)
                {
                    //txtDataReceived.Text = kata;
                    txtDataReceived.BeginInvoke(new myDelegate(updateTextBox));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        static string[] SplitWords(string s)
        {
            //
            // Split on all non-word characters.
            // ... Returns an array of all the words.
            //
            return Regex.Split(s, " ");
            // @      special verbatim string syntax
            // \W+    one or more non-word characters together
        }

        //—Delegate and subroutine untuk ditampilkan pada TextBox control—
        public delegate void myDelegate();

        public void updateTextBox()
        {
            //data_y = Convert.ToInt32(buff_kata[2]);
            //kalman_y = kalman_filter_ku((double)data_y);
            //txtDataReceived.Text = "ACC:"+data_y.ToString()+" Kalman:"+kalman_y.ToString();
            //txtDataReceived.Text = "x:"+buff_kata[1] + " y:"+buff_kata[2]+" ori"+kata;
        }
        double  Kk_x,
                Xk_topi_x,
                Pk_x,
                R_x = 0.1,
                Q_x = 0.0002,
                Xk_topi_prev_x = 0,
                Pk_prev_x = 1,
                Pk_update_x,
                Xk_topi_update_x;
        int kalman_filter_ku_x(double Zk_x)
        {
            //Time Update
            Xk_topi_update_x = Xk_topi_prev_x;
            Pk_update_x = Pk_prev_x + Q_x;
            //Measurement Update
            Kk_x = Pk_update_x / (Pk_update_x + R_x);
            Xk_topi_x = Xk_topi_update_x + (Kk_x * (Zk_x - Xk_topi_update_x));
            Pk_x = (1 - Kk_x) * Pk_update_x;
            Xk_topi_prev_x = Xk_topi_x;
            Pk_prev_x = Pk_x;
            return ((int)Xk_topi_x);
        }

        double  Kk_y,
                Xk_topi_y,
                Pk_y,
                R_y = 0.1,
                Q_y = 0.0002,
                Xk_topi_prev_y = 0,
                Pk_prev_y = 1,
                Pk_update_y,
                Xk_topi_update_y;
        int kalman_filter_ku_y(double Zk_y)
        {
            //Time Update
            Xk_topi_update_y = Xk_topi_prev_y;
            Pk_update_y = Pk_prev_y + Q_y;
            //Measurement Update
            Kk_y = Pk_update_y / (Pk_update_y + R_y);
            Xk_topi_y = Xk_topi_update_y + (Kk_y * (Zk_y - Xk_topi_update_y));
            Pk_y = (1 - Kk_y) * Pk_update_y;
            Xk_topi_prev_y = Xk_topi_y;
            Pk_prev_y = Pk_y;
            return ((int)Xk_topi_y);
        }

        int val_z_prev;
        private void timer2_Tick(object sender, EventArgs e)
        {
            int val_x,
                val_y,
                kalman_x,
                kalman_y,
                buff_val_x =0,
                buff_val_y =0,
                val_z =0;
            try
            {
                buff_val_y = Convert.ToInt32(buff_kata[1]);
                buff_val_x = Convert.ToInt32(buff_kata[2]);
                val_z = Convert.ToInt32(buff_kata[3]);
                //txtDataReceived.Text = buff_val_x.ToString() + " " + buff_val_y.ToString();
            }
            catch (Exception a)
            {

            }

            val_x = (buff_val_x * 410) + 16384;
            val_y = (buff_val_y * 410) + 16384;

            kalman_x = kalman_filter_ku_x((double)val_x);
            kalman_y = kalman_filter_ku_y((double)val_y);

            if      ((val_z_prev > 80) && (val_z < -30))//kotak
            {
                //txtDataReceived.AppendText("===============kotak"+Environment.NewLine);
                joystick.SetBtn(true, id, 1);
            }
            else if ((val_z_prev < -30) && (val_z > 80))//eek
            {
                //txtDataReceived.AppendText("++++++++++++++++eek" + Environment.NewLine);
                joystick.SetBtn(true, id, 2);
            }
            else
            {
                //txtDataReceived.AppendText("none" + Environment.NewLine);
                joystick.SetBtn(false, id, 1);
                joystick.SetBtn(false, id, 2);
            }

            joystick.SetAxis(kalman_x, id, HID_USAGES.HID_USAGE_X);   //min 16 center 16384 max 32767
            joystick.SetAxis(kalman_y, id, HID_USAGES.HID_USAGE_Y);   //min 16 center 16384 max 32767
            val_z_prev = val_z;
        }
    }
}

Jangan lupa untuk memasukan library vjoynya.

vjoy3
Berikut hasilnya.

Berikut file project yang bisa di download.

Follow

Get every new post delivered to your Inbox.