Translate

Kendali dan Tracking Object dengan Image Processing OPENCV dan Visual Studio

Kendali dan Tracking Object dengan Image Processing OPENCV dan Visual Studio

         Pagi ini saya akan menjelaskan bagaimana cara membuat sebuah alat yang bisa digunakan untuk mengontrol device lain untuk melakukan apa yang kita inginkan menggunakan sebuah kamera, bisa kamera wireless maupu kamera nirkabel. Pada contoh kali ini sengaja saya akan mendemokan bagaimana cara mengendalikan led menyala menggunakan posisi kamera. memang alat dan bahan untuk membuat sistem ini tidaklah mudah, yaitu software Visual Studio 2010 dan OPENCV 2.3.1, hardwarenya yaitu kamera webcam, microcontroller, 4 buah led, RS232. jadi prinsip kerjanya sangat sederhana sekali, dari posisi object yang terdeteksi kamera kemudian object tersebut memberikan posisi X dan Y, posisi tersebut akan dikirimkan ke mikrokontroller melalui jalur serial RS232, sehingga mikrokontroller akan mengeksekusi perintah yang dikirim oleh komputer. berikut penjelasan skema dan programnya.

Tutorial cara konfigurasi OpenCV dengan Visual Studio bisa didownload di link berikut :


a. Minimum System




b. Rangkaian RS232




 c. Program Bascom AVR
'=====================================================
'Programmer: Yanuar Mukhammad
'E-mail    : Yanuarm@hotmail.com
'=====================================================
$regfile = "m16def.dat"
$crystal = 12000000

Dim Perintah As String * 1

Ddrb.0 = 1
Ddrb.1 = 1
Ddrb.2 = 1
Ddrc.5 = 1

Do

Perintah = Waitkey()


  Select Case Perintah

    Case "A" :
    Portb.0 = 0
    Portb.1 = 0
    Portb.2 = 0
    Portc.5 = 1

    Case "B" :
    Portb.0 = 0
    Portb.1 = 0
    Portb.2 = 1
    Portc.5 = 0

    Case "C" :
    Portb.0 = 1
    Portb.1 = 0
    Portb.2 = 0
    Portc.5 = 0

    Case "D" :
    Portb.0 = 0
    Portb.1 = 1
    Portb.2 = 0
    Portc.5 = 0

  End Select

Loop




d. Program Visual Studio

#include <iostream>

#include<opencv/cvaux.h>
#include<opencv/highgui.h>
#include<opencv/cxcore.h>

#include <sstream>
#include <string>
#include <opencv\cv.h>

#include<stdio.h>
#include<stdlib.h>

// Need to include this for serial port communication
#include <Windows.h>

////////////////////////////////////

using namespace cv;
//initial min and max HSV filter values.
//these will be changed using trackbars
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
//default capture width and height
const int FRAME_WIDTH = 640;
const int FRAME_HEIGHT = 480;
//max number of objects to be detected in frame
const int MAX_NUM_OBJECTS=100;
//minimum and maximum object area
const int MIN_OBJECT_AREA = 100*100;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5;
//names that will appear at the top of each window
//const string windowName = "Original Image";
//const string windowName1 = "HSV Image";
//const string windowName2 = "Thresholded Image";
//const string windowName3 = "After Morphological Operations";
const string trackbarWindowName = "Trackbars";
void on_trackbar( int, void* )
{//This function gets called whenever a
    // trackbar position is changed
}
string intToString(int number){

    std::stringstream ss;
    ss << number;
    return ss.str();
}
void createTrackbars(){
    //create window for trackbars


    namedWindow(trackbarWindowName,0);
    //create memory to store trackbar name on window
    char TrackbarName[50];
    sprintf( TrackbarName, "H_MIN", H_MIN);
    sprintf( TrackbarName, "H_MAX", H_MAX);
    sprintf( TrackbarName, "S_MIN", S_MIN);
    sprintf( TrackbarName, "S_MAX", S_MAX);
    sprintf( TrackbarName, "V_MIN", V_MIN);
    sprintf( TrackbarName, "V_MAX", V_MAX);
  
    createTrackbar( "H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar );
    createTrackbar( "H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar );
    createTrackbar( "S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar );
    createTrackbar( "S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar );
    createTrackbar( "V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar );
    createTrackbar( "V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar );

}


int main(int argc, char* argv[])
{
    // Setup serial port connection and needed variables.
    HANDLE hSerial = CreateFile(L"COM2", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (hSerial !=INVALID_HANDLE_VALUE)
    {
        printf("Port opened! \n");

        DCB dcbSerialParams;
        GetCommState(hSerial,&dcbSerialParams);

        dcbSerialParams.BaudRate = CBR_9600;
        dcbSerialParams.ByteSize = 8;
        dcbSerialParams.Parity = NOPARITY;
        dcbSerialParams.StopBits = ONESTOPBIT;

        SetCommState(hSerial, &dcbSerialParams);
    }
    else
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            printf("Serial port doesn't exist! \n");
        }

        printf("Error while setting up serial port! \n");
    }

    char outputChars[] = "c";
    DWORD btsIO;

    // Setup OpenCV variables and structures
    CvSize size640x480 = cvSize(640, 480);          

    CvCapture* p_capWebcam;                      

    IplImage* p_imgOriginal;          
    IplImage* p_imgProcessed;          
    IplImage* p_imgHSV;               
                                      

    CvMemStorage* p_strStorage;          

    CvSeq* p_seqCircles;              
                                      
   
    float* p_fltXYRadius;              
                                        // [0] => x position of detected object
                                        // [1] => y position of detected object
                                       
    int i;                              
    char charCheckForEscKey;          

    p_capWebcam = cvCaptureFromCAM(1);  

    if(p_capWebcam == NULL) {          
        printf("error: capture is NULL \n");  
        getchar();                              
        return(-1);                              
    }                                                 
    cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);      
    cvNamedWindow("Processed", CV_WINDOW_AUTOSIZE);      

    createTrackbars();
    p_imgProcessed = cvCreateImage(size640x480,          
                                  IPL_DEPTH_8U,      
                                   1);                  

    p_imgHSV = cvCreateImage(size640x480, IPL_DEPTH_8U, 3);

    // Variables for Arduino Control
    int servoPosition = 90;
    int servoOrientation = 0;
    int servoPosition1=90;
    int servoOrientation1=0;

    // Main program loop
    while(1) {                              
        p_imgOriginal = cvQueryFrame(p_capWebcam);      
      
        if(p_imgOriginal == NULL) {                  
            printf("error: frame is NULL \n");      
            getchar();
            break;
        }

        cvCvtColor(p_imgOriginal, p_imgHSV, CV_BGR2HSV);

        cvInRangeS(p_imgHSV,              
                   cvScalar(H_MIN,  S_MIN,  V_MIN),          
                   cvScalar(H_MAX, S_MAX, V_MAX),          
                   p_imgProcessed);              

        p_strStorage = cvCreateMemStorage(0);  

                                      
        cvSmooth(p_imgProcessed,      
                 p_imgProcessed,      
                 CV_GAUSSIAN,          
                 9,                      
                 9);                  

                                                  
        p_seqCircles = cvHoughCircles(p_imgProcessed,      
                                      p_strStorage,          
                                      CV_HOUGH_GRADIENT,  
                                      2,                  
                                      p_imgProcessed->height / 4,  
                                      100,                      
                                      50,                      
                                      10,     //10                  
                                      400);                      



            if (p_seqCircles->total == 1)
            {
            p_fltXYRadius = (float*)cvGetSeqElem(p_seqCircles, 1);  

            printf("ball position x = %f, y = %f, r = %f \n", p_fltXYRadius[0],      
                                                              p_fltXYRadius[1],      
                                                              p_fltXYRadius[2]);  

            // atas
            if (p_fltXYRadius[0] > 250 && p_fltXYRadius[0] < 300)
            {
                outputChars[0] = 'A';
                WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);

                servoPosition+=1;

                if (servoPosition > 180)
                    servoPosition = 180;
            }

            //kiri
            if (p_fltXYRadius[0] < 80)
            {
                outputChars[0] = 'C';
                WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);

                servoPosition-=1;

                if (servoPosition < 0)
                    servoPosition = 0;
            }


            //kanan
            if (p_fltXYRadius[0] > 500)
            {
                outputChars[0] = 'B';
                WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);

                servoPosition1+=1;

                if (servoPosition1 > 180)
                    servoPosition1 = 180;
            }

            //bawah
            if (p_fltXYRadius[0] > 300 && p_fltXYRadius[0] < 400)
            {
                outputChars[0] = 'D';
                WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);

            }

                                      
            cvCircle(p_imgOriginal,                                      
                     cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])),      
                     3,                                                  
                     CV_RGB(0,255,0),                                  
                     CV_FILLED);                                      
          
                                      
            cvCircle(p_imgOriginal,                                      
                     cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])),      
                     cvRound(p_fltXYRadius[2]),                          
                     CV_RGB(255,0,0),                                  
                     3);                                              
        }    // end for

        cvShowImage("Original", p_imgOriginal);          
        cvShowImage("Processed", p_imgProcessed);      

        cvReleaseMemStorage(&p_strStorage);              

        charCheckForEscKey = cvWaitKey(10);              
        if(charCheckForEscKey == 27) break;              
    }    // end while

    cvReleaseCapture(&p_capWebcam);                  

    cvDestroyWindow("Original");
    cvDestroyWindow("Processed");

    // This closes the Serial Port
    CloseHandle(hSerial);

    return(0);
}




 e. VIDEO HASILNYA





Jika saat menjalankan program terdapat error "tbb.dll is missing" maka lakukanlah langkah berikut.
1. Copy file "tbb.dll" di "C:\opencv\build\common\tbb\bin\ia32\vc10"
2. Kemudian paste di "C:\Users\yanuar\Documents\Visual Studio 2010\Projects"
3. Selamat berkarya





Membuat BARGRAPH Lcd 16x2 Bascom AVR

Membuat BARGRAPH Lcd 16x2 Bascom AVR

              Disini saya akan menjelaskan bagaimana cara membuat bargraph menggunakan bascom avr dengan media yang digunakan adalah LCD 16x2, Bargraph adalah sebuah grafik yang tersusun dari gambar kotak atau garis, sehingga jika kotak dan garis tersebut disusun akan membentuk seperti grafik, pada penjelasan kali ini bargraph difungsikan untuk visualisasi dari tegangan yang terukur. supaya lebih jelas dan lebih mudah dimengerti oleh orang awam maka bargraph ini bisa digunakan, baik itu untuk visualisasi tegangan maupun visualisasi yang lainnya, berikut adalah penjelasan skematik dan programnya. 


a. Skematik Minimum System



b. Potensiometer




c. Program Bascom AVR

$regfile = "m16def.dat"
$crystal = 12000000
$baud = 9600

Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2
Config Lcdpin = Pin , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Config Lcd = 16 * 2

Cursor Off Noblink
Cls

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Symbols for bargraph-------------
Deflcdchar 0 , 32 , 32 , 32 , 21 , 21 , 21 , 32 , 32        ' empty symbol
Deflcdchar 1 , 32 , 31 , 31 , 31 , 31 , 31 , 31 , 31        ' 5/5, filled symbol
Deflcdchar 2 , 32 , 16 , 16 , 21 , 21 , 21 , 16 , 16        ' replace [x] with number (0-7)
Deflcdchar 3 , 32 , 24 , 24 , 29 , 29 , 29 , 24 , 24        ' replace [x] with number (0-7)
Deflcdchar 4 , 32 , 28 , 28 , 29 , 29 , 29 , 28 , 28        ' replace [x] with number (0-7)
Deflcdchar 5 , 32 , 30 , 30 , 31 , 31 , 31 , 30 , 30        ' replace [x] with number (0-7)

Dim L As Byte , R As Byte , Cols As Byte , J As Integer , M As Byte
Dim N As Byte , O As Byte , T As Byte , I As Byte
Dim Adc_val As Word , Adc_sin As Single
Dim Adc1 As Single , Adc2 As Single , Volt As String * 5
Declare Sub Bargraph()

Do
Adc_val = Getadc(7)
Call Bargraph

Adc1 = Adc_val * 5
Adc2 = Adc1 / 1023

Volt = Fusing(adc2 , "#.##")

Upperline
Lcd "Volt = " ; Volt

Loop

'----------------Bar graph------
Sub Bargraph()
Adc_sin = Adc_val / 4
L = Adc_sin
Cols = L / 17
J = Cols - 1
T = Cols + 1
M = 255 - L
N = Cols * 17
O = L - N
Locate 2 , 1
For I = 1 To Cols
Lcd Chr(1)                                                  'filled symbol
Next I
If L > N Then
Locate 2 , T
If O > 0 And O <= 3 Then
Lcd Chr(2)                                                  '1/5
Elseif O > 3 And O <= 7 Then
Lcd Chr(3)                                                  '2/5
Elseif O > 7 And O <= 10 Then
Lcd Chr(4)                                                  '3/5
Elseif O > 10 And O <= 14 Then
Lcd Chr(5)                                                  '4/5
Elseif O > 14 And O <= 17 Then
Lcd Chr(1)                                                  '5/5
End If
End If
For I = Cols To 13
Lcd Chr(0)                                                  'empty symbol
Next I
End Sub



d. VIDEO HASILNYA







CARA MENGGUNAKAN 2 SERIAL (UART) ATMega128

CARA MENGGUNAKAN 2 SERIAL (UART) ATMega128

       
             Minggu pagi yang cerah, kali ini saya akan menjelaskan bagaimana cara menggunakan fitur ATMega128 yang tidak dimiliki oleh ATMega dibawahnya, yaitu 2 buah port serial, pada ATMega8,16,8535 dan 32 hanya memiliki 1 port serial, namun ATMega128 tidak-lah sama, ia memiliki fitur tambahan, diantaranya yatitu 2 buah port serial, ini sangatlah penting sekali karena dengan 2 port serial, mikrokontroller bisa berkomunikasi dengan 2 device sekaligus, pada contoh video ini di tampilkan dua buah device sebagai slave yaitu mikrokontroller ATMega16 dan sebuah laptop / komputer, jadi ATMega128 mengirimkan ke dua buah device secara berurutan. berikut adalah penjelasan lengkap tentang skematik dan konfigurasinya.


a. ATMega128

  

b. Minimum System ATMega16



 c. Program Master M128 Bascom AVR

$regfile = "m128def.dat"
$crystal = 16000000


Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Open "com1:" For Binary As #1
Open "Com2:" For Binary As #2


Do

Print #1 , "#coba 128 Com 1"
Print #2 , "#test 128 Com 2"


Loop



 d. Program Slave M16 Bascom AVR

$regfile = "m16def.dat"
$crystal = 12000000
$baud = 9600

Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2
Config Lcdpin = Pin , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Config Lcd = 16 * 2

Dim Data_masuk As String * 100
Dim Cmti_pos As Byte , Cmgr_pos As Byte , Index_pos As Byte , Cmd_pos As Byte
Dim Pjg_sms_index As Byte , Pjg_data As Byte
Dim Sms_index As String * 3
Dim Cmd As String * 20
Dim Cmdbin As Byte

Upperline
Lcd "SLAVE MCU"
Lowerline
Lcd "YANUAR M"
Wait 3

Ddrd.6 = 1
Ddrd.7 = 1

Cls
Cursor Off


Do

   Input Data_masuk

   Upperline
   Lcd "DATA MASUK"

   Pjg_data = Len(data_masuk)

  ' Cmti_pos = Instr(data_masuk , "#")

   Cmd_pos = Instr(data_masuk , "#")

   If Cmd_pos <> 0 Then
      Incr Cmd_pos
      Cmd = Mid(data_masuk , Cmd_pos , 20)

      Lowerline
      Lcd Cmd


   End If

Loop



e. VIDEO HASILNYA