background image

 

Katedra Robotyki i Mechatroniki  

 

Systemy wizyjne.  

OpenCv_Cw2 

Temat: Obsługa portu w standardzie RS-232 

Obsługa i konfiguracja portu szeregowego: Baundrate, ByteSize,Parity,StopBits,DtrControl,  

CreateFile, WriteFile 

Instrukcje Melfa: OPEN COM, INPUT, PRINT, OVRD, MOV, MVS, HOPEN, HCLOSE,DLY

 

Prowadzący: dr inż. Piotr KOHUT 

Grupa: 

 

Imię i nazwisko: 

Data: 

Uwagi: 

 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

background image

1.) Cel dwiczenia:  

Zapoznanie się z algorytmami wysyłania i odbierania danych w standardzie RS-232. 

2.) Podstawy teoretyczne 

Robot  przemysłowy  Mitsubishi  Melfa  RV  –  2AJ  jest  robotem  antropomorficznym, 

posiadającym  5  stopni  swobody.  Na  rysunku  4.1  zaprezentowano  jego  budowę 

oraz podstawowe  parametry  geometryczne.  Rysunek  4.2  przedstawia  widok  sterownika 

CR1 – 571. 

 

 

 

 

 

 

 

 

Rys. 1. Mitsubishi Melfa RV – 

2AJ . 

 

 

 

Rys. 2. Sterownik Mitsubishi CR1 – 571  

 

 

 

 

 

 

background image

W tabeli 1 zestawiono parametry użytkowe robota oraz sterownika. 

Typ robota 

Antropomorficzny, 5 DOF 

Powtarzalność 

±0,02mm 

Zasięg 

J1: 300° (-150° ÷ 150°) 
J2: 180° (-60° ÷ 120°) 
J3: 230° (-110° ÷ 120°) 
J4: - 
J5: 180° (-90° ÷ 90°) 
J6: 400° (-200° ÷ s200°) 

Prędkości 

J1: 180°/s 
J2: 90°/s 
J3: 135°/s 
J4: - 
J5: 180°/s 
J6: 210°/s 

Udźwig 

2kg 

Dopuszczalny moment obciążający złącze: 

J4: - 
J5: 2,16Nm 
J6: 1,10Nm 

Dopuszczalne momenty bezwładności dla 
złącz: 

J4: - 
J5: 3,24∙10

-2 

kg∙m

2

 

J6: 8,43∙10

-3

 kg∙m

2

 

Zasięg 

410mm 

Cyfrowe We/Wy Sterownika 

16/16 (rozszerzalne do 240/240) 

Tryb Sterowania  

Złączowe, interpolacja liniowa i kołowa, 
wielozadaniowość (do 32 zadań), 
optymalizacja parametrów ruchu 

Pobór Mocy 

0,7 kVA, 230V AC 

Język Programowania Sterownika 

Melfa Basic IV 

Tab. 1 Zestawienie parametrów użytkowych robota Mitsubishi Melfa RV – 2AJ. 

 

3.) Instrukcja wykonania dwiczenia 

a.)  Schemat blokowy postępowania w dwiczeniu 

 

 

 

 

 

 

 

Implementacja 
wymaganych 
etapów 
wysyłania 
danych po  
RS-232 

Implementacja 
zadanego 
programu w 
środowisku 
COSIROP, 
kontrola 
położeń 

Konfiguracja 
połączenia w 
programie 
COSIROP 

Uruchomienie 
programu, test 
działania 

Modyfikacja 
programu 

Uruchomienie i 
test 
zmodyfikowanego 
programu. 

background image

b.)  Zaimplementuj wymagane etapy algorytmu wysłania  danych w standardzie RS-

232.   

 

#include <windows.h> 
#include <highgui.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <iostream> 
#include <sstream> 

 

 
int main() 

//    Deklaracja zmiennych do wysyłania po RS232 

    HANDLE hCom;     

//uchwyt portu

 

    DCB dcb;         

//konfiguracja portu

 

    BOOL fSuccess;   

//flaga pomocnicza

 

    BYTE RS_buf;     

//bufor danej 

    DWORD RS_ile;    

//ilosc bitow wyslanych

 

 
    //Otwarcie portu COM1 

    hCom = CreateFile( TEXT("COM1"), 
           GENERIC_READ | GENERIC_WRITE, 
           FILE_SHARE_WRITE | FILE_SHARE_READ, 
           NULL, 

// default security attributes

 

           OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

            
    //Obsluga bledu: CreateFile failed with error 

    if (hCom == INVALID_HANDLE_VALUE) 
    { 
        printf("\nCreateFile failed with error %d.\n", GetLastError()); 
        return 1; 
    } 

 
    //Pobranie aktualnych ustawien portu     
    

fSuccess = GetCommState(hCom, &dcb); 

     
    //Obsluga bledu: GetCommState failed with error 

    if (!fSuccess) 
    { 
      printf ("\nGetCommState failed with error %d.\n", GetLastError()); 
      return 2; 
    } 

 
    //Konfiguracja portu  
    

dcb.BaudRate = CBR_9600;

   // predkosc transmisji 

    

dcb.ByteSize = 8;          

// ilosc bitow danych 

    

dcb.Parity = 2;

            // parzystosc 

    

dcb.StopBits = TWOSTOPBITS;

// bity stopu 

    dcb.fDtrControl = DTR_CONTROL_DISABLE;

 //brak kontroli DTR 

   
 fSuccess = SetCommState(hCom, &dcb); 
 

   //Obsluga bledu: SetCommState failed with error 

   if (!fSuccess) 
   { 
      printf ("\nSetCommState failed with error %d.\n", GetLastError()); 
      return 3; 
   } 
   int a,b; 

background image

   printf("Podaj wspolrzedna x: "); 
   scanf("%d",&a); 
   printf("\nPodaj wspolrzedna y: "); 
   scanf("%d",&b); 
   using namespace std; 
   ostringstream oss; 
   int i = 0;  
   string s; 
  printf(“\nWciśnij Enter aby zatwierdzic wyslanie wspolrzednych.”); 
  getchar(); 

    //////////////////    wysyłanie cx 

                      oss << ”PRN”<<a << "\r"; 
                      s = oss.str(); 
                      for (i = 0; i <= s.size()-1; i++) 
                      { 
                          RS_buf=s[i]; 
                          RS_ile=1; 
                          fSuccess = WriteFile( hCom, &RS_buf, RS_ile, &RS_ile, 0); 
                           

  //Obsluga bledu: WriteFile failed with error 

                          if (!fSuccess) 
                          { 
                             printf ("WriteFile failed with error %d.\n", GetLastError()); 
                             return 1; 
                          }; 
                      }; 
 oss.str(“”);                      

//////////////////    wysyłanie cx 

                      oss <<”PRN” <<b << "\r"; 
                      s = oss.str(); 
                      for (i = 0; i <= s.size()-1; i++) 
                      { 
                          RS_buf=s[i]; 
                          RS_ile=1; 
                          fSuccess = WriteFile( hCom, &RS_buf, RS_ile, &RS_ile, 0); 
                           

//Obsluga bledu: WriteFile failed with error 

                          if (!fSuccess) 
                          { 
                             printf ("WriteFile failed with error %d.\n", GetLastError()); 
                             return 1; 
                          }; 
                      }; 
oss.str(“”);                     
   CloseHandle(hCom); 
   system("PAUSE"); 
   return 0; 
    

 

 
 
 
 
 
 
 
 
 
 
 

background image

c.)  Zaimplementuj zamieszczony poniżej program robota Mitsubishi Melfa RV-2AJ w 

środowisku COSIROP. 

 
 

10 P1=(+283.36,-88.03,+329.19,+24.15,+160.00) 
20 OVRD 8 
30 MOV P1 
40 OPEN "COM1:" AS #1 
50 INPUT #1, X1 
60 INPUT #1, Y1 
70 OVRD 10 
80 P1.X = 220+X1 
90 P1.Y = -60+Y1 
100 MOV P1 
110 END 

 
 
 

Punkt P1 jest przykładową pozycją w przestrzeni roboczej manipulatora. Należy wybrad go z 
należytą ostrożnością, uważając na ewentualne kolizje, to samo tyczy się wartości w liniach 8 
i 9 programu.  
 

d.) Ustawienia robota. 

 
W środowisku COSIROP należy wprowadzid następujące ustawienia robota:  
 
W pozycji Parameter w drzewku RV-2AJ: 

 

 

 
 
 
 
 
 
 
 
 
 

background image

W pozycji Connection w drzewku RV-2AJ: 
 

       

 

 
 
 
 
 
W przypadku parametrów niewidocznych na zdjęciu, ustawid je zgodnie z konfiguracją 
połączenia w programie. 
 

e.) Uruchamianie aplikacji. 

 
W celu uruchomienia aplikacji należy: 

 

W środowisku COSIROP przeprowadzid download programu do kontrolera robota. W 

oknie RCI Explorer rozwinąd pozycję Programs w drzewku Workplace, następnie 
kliknąd prawym klawiszem myszy na zapisany uprzednio program, wybierając 
Download. Potwierdzid przyciskiem OK. 
 

 

 
 

 

Rozwinąd zakładkę Programs w drzewku RV-2AJ, odszukad wysłany w poprzednim 

kroku program, kliknąd na jego nazwę prawym klawiszem myszy i wybrad opcję 
Start(CYC) – uruchomienia jednorazowego. Robot przemieści się do punktu P1 i 

background image

rozpocznie oczekiwanie na dane wysłane do sterownika za pośrednictwem portu 
RS232. 

 

 
 

 

Uruchomid skompilowany program wysłania danych poprzez interface RS232 w 

języku C. Podad współrzędne (niewielkie wartości na poziomie kilkunastu 
milimetrów!
) gdy pojawi się odpowiedni komunikat, następnie wcisnąd ENTER.  

 
Manipulator przemieści się do punktu w przestrzeni roboczej, którego współrzędne 
wyznaczone są przez różnice współrzędnych punktu P1 oraz wartości przesłanych do 
sterownika robota przez port RS232, zgodnie z liniami kodu: 

80 P1.X = 220+X1 
90 P1.Y = -60+Y1 
 

f.)  Modyfikacja program 

Po poprawnym uruchomieniu funkcjonowania powyższych programów należy zmodyfikowad 
program sterownika robota, aby wykorzystad go do transportu przedmiotu, przy użyciu 
danych otrzymanych poprzez port RS232. 

Przykładowe rozwiązanie tego problemu to program w wyniku którego robot odbiera z 
zadanego punktu przedmiot, następnie oczekuje na podanie współrzędnych x i y punktu 
koocowego poprzez port RS-232. Po otrzymaniu współrzędnych przenosi do niego obiekt, i 
odkłada. 

Poniżej przedstawiono przykładowy kod programu realizujący powyższe funkcje. 

Uwaga! Kod jest przykładowy, nie należy implementowad go w całości, wszelkie wartości 
punktów odbioru i koocowych, a także położenia w osi „z” należy najpierw przetestowad 
przy użyciu panelu operatorskiego. 

 

10 P1=(+283.36,-88.03,+329.19,+24.15,+160.00) 
20 P2=(+200.00,-88.00,+300.00,+25.00,+160.00) 
30 OVRD 8 

background image

40 MOV P1 
50 HOPEN 1 
60 DLY 0.5 
70 MVS P1 , +60 
80 DLY 0.5 
90 HCLOSE 1 
100 DLY 0.5 
110 MVS P1 , -60 
120 DLY 0.5 
130 OPEN "COM1:" AS #1 
140 INPUT #1, X1 
150 INPUT #1, Y1 
160 OVRD 10 
170 P2.X = X1 
180 P2.Y = Y1 
190 MOV P2 
200 DLY 0.5 
210 MVS P2 , +60 
220 DLY 0.5 
230 HOPEN 1 
240 DLY 0.5 
250 MVS P2 , -60 
260 DLY 0.5 
270 MOV P1 
280 END 

 

Przygotowany program należy wgrad do sterownika robota, zgodnie z procedurą opisaną w 
poprzednim podpunkcie, a następnie przetestowad jego działanie, z zachowaniem wszelkich 
środków ostrożności. 

Zdjęcia i print screeny obrazujące pracę programu i robota należy zawrzed w raporcie, 
ponadto należy dodad kod wszelkich zmodyfikowanych programów. 

 

4.)  Funkcje i ich składnia: 

 
Open and Close Port  

 

 

 

Opening a port is actually getting the descriptor of the serial port. Due to API it can be done 
by using CreateFile function. This function results in the creation of a file with a reserved 
name.It is important when getting access to the corresponding port or device.After the 
descriptor has been obtained the work with the port is carried out the same way it is with 
files.  

Let's examine CreateFile function. Its parameters are listed below. 

Function syntax: 
HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, 
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD 
dwFlagsAndAttributes, HANDLE hTemplateFile);  

Parameters specifications:  

background image

lpFileName - pointer to a null-terminated string which defines the object name (in our case it 
is "COMx", where x is the system port number, or "\\\\.\\COM1" - if there's a need to open 
the port with its number above 9);  

dwDesiredAccess - defines the type of the access to the object. The application can get 
'read'-access, 'write'-access, 'read/write'-access or device request access. This parameter can 
use any combination of the following values:  

 

0 - specifies that the device request refers to an object. The application can make a 
request of the device attributes without referring to the device. 

GENERIC_READ - specifies the 'read' access from the object. The data can be read from the 
file and the file pointer can be relocated.  

GENERIC_WRITE - specifies the 'write' access to the object. The data can be written to the 
file and the pointer can be relocated.  

 

Combination of GENERIC_WRITE and GENERIC_READ grants 'read/write' access to 
the object. 

dwShareMode - a set of bit flags which specifies shared access to the object. If 
dwShareMode - 0, then access to the object cannot be shared. Further object opening 
operations will be rejected until the descriptor is closed. To use the object in the shared 
mode use the combination of the following values:  

 

FILE_SHARE_DELETE - Windows NT only: Subsequent open operations on the object 
will succeed only if delete access is requested. 

 

FILE_SHARE_READ - Subsequent open operations on the object will succeed only if 
read access is requested. 

 

FILE_SHARE_WRITE - Subsequent open operations on the object will succeed only if 
write access is requested. Add _READ to allow read-write access. 

lpSecurityAttributes - pointer to the SECURITY_ATTRIBUTES structure which specifies if the 
descriptor returned can be inherited by the child procedures. If lpSecurityAttributes is NULL, 
the descriptor cannot be inherited.  

Windows NT: lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure defines 
the protection descriptor for the object. If lpSecurityAttributes is NULL the object gets the 
default protection descriptor. The system of the end file must support the protection on files 
and folders for this parameter to apply this effect to the files.  

Windows 95: lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure is 
ignored.  

DwCreationDistribution - defines the ways of opening existing files and the actions taken if 
the file doesn't exist. This parameter must contain one of the following values:  

 

CREATE_NEW - creates a new file. The function fails if the specified file already exists. 

background image

 

CREATE_ALWAYS - creates a new file. If the file already exists the function replaces it 
with a new one. 

 

OPEN_EXISTING - opens a file. Fails if the file doesn't exist. 

 

OPEN_ALWAYS - opens the file if it exists. If the file doesn't exist the function creates 
a file just like CREATE_NEW. 

 

TRUNCATE_EXISTING - opens the file. After the file is opened it is reduced until it's of 
zero size. The request process must open the file with at least GENERIC_WRITE 
access. Fails if the file doesn't exist. 

dwFlagsAndAttributes - defines the file attributes and flags. Any combination of the 
following attributes except the FILE_ATTRIBUTE_NORMAL attribute is possible:  

 

FILE_ATTRIBUTE_ARCHIVE - the file must be archived. The applications use this 
attribute to mark the file for reserve copying or deletion. 

 

FILE_ATTRIBUTE_COMPRESSED - file or catalogue is compressed . If it's a file, it 
means that all data in the file are compressed. If it's a catalogue it means that 
compression is the default value for recently created files and subdirectories. 

 

FILE_ATTRIBUTE_HIDDEN - the file is hidden. It shouldn't be included into the usual 
directory list. 

 

FILE_ATTRIBUTE_NORMAL - the file has no attributes. 

 

FILE_ATTRIBUTE_OFFLINE - the data of the file are not available at the moment. It 
shows that the data of the file have been moved to an off-line archive. 

 

FILE_ATTRIBUTE_READONLY - the file is read-only. The applications can read the file 
but cannot write or delete the data. 

 

FILE_ATTRIBUTE_SYSTEM - a part of the file is used by the operation system only. 

 

FILE_ATTRIBUTE_TEMPORARY - the file is used for temporary data storing. File 
systems try to keep all data in memory for quicker access rather than flushing the 
data back to mass archive. A temporary file should be deleted by the application as 
soon as it is no longer needed. 

Also possible is any combination of the following flags: 

 

FILE_FLAG_WRITE_THROUGH 

 

FILE_FLAG_OVERLAPPED 

 

FILE_FLAG_NO_BUFFERING 

 

FILE_FLAG_RANDOM_ACCESS 

 

FILE_FLAG_SEQUENTIAL_SCAN 

 

FILE_FLAG_DELETE_ON_CLOSE 

 

FILE_FLAG_BACKUP_SEMANTICS 

 

FILE_FLAG_POSIX_SEMANTICS 

hTemplateFile - specifies that the descriptor with GENERIC_READ refers to a temporary file. 
The temporary file supports the file attributes and enhanced attributes for the created file.  

To open the communication ports the CreateFile function can create a descriptor for the 
port like COM1serial port. For the ports dwCreationDistribution parameter should be 
OPEN_EXISTING, hTemplate parameter should be NULL. Read access, write access or 
read/write access can be specified; the descriptor should also be open for overlapped I/O.  

background image

If the port was opened successfully the function returns the handle descriptor to work with 
further on. If the port wasn't opened successfully the function wil return 
INVALID_HANDLE_VALUE.  

CloseHandle function is used to close the port. 

Function syntax: 
BOOL CloseHandle(HANDLE hFile}; 

Parameters specifications:  
hFile  the descriptor of the open file of communication port 

Example of getting a descriptor of the serial port COM1:  

HANDLE hCOM=CreateFile("\\\\.\\COM1",GENERIC_WRITE,0,NULL,OPEN_EXISTING, 

FILE_FLAG_OVERLAPPED,NULL);  

if (hCOM!=INVALID_HANDLE_VALUE)  

{  

...  

CloseHandle(hCOM);  

}  

else cout << "Error Open" << endl;  
 
Read and Write Port 

 

 

 

 

 

As work with the ports in Windows is carried out in the same way as work with files, reading 
from and writing into the port are carried out with the help of ReadFile and WriteFile 
functions correspondingly.  

ReadFile function is used to read the information from the port  

Function syntax: 
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD 
lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);  

BOOL WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD 
nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED 
lpOverlapped);  

Parameters specifications:  

background image

hFile  descriptor of the open communication port file;  

lpBuffer buffer address. In case of Write operation the data from this buffer will be 
transmitted to the port. In case of Read operation the data received from the line will be 
placed into this buffer;  

nNumOfBytesToRead, nNumOfBytesToWrite  number of bytes to be received or or intended 
for transmission;  

nNumOfBytesRead, nNumOfBytesWritten number of actually received or transmitted bytes. 
If the number of received or transmitted bytes is lower than requested it's an error for a disc 
file but not necessarily for a communication port. The cause is to be found in timeouts.  

LpOverlapped  the address of OVERLAPPED structure used for asynchronous operations.  

In case of abnormal temination the functions return NULL, in case of normal termination - 
any other value.  

Example of read-write operation:  

DWORD numbytes, numbytes_ok, temp;  

COMSTAT ComState;  

OVERLAPPED Overlap;  

char buf_in[6] = "Hello!";  

numbytes = 6;  

ClearCommError(handle, &temp, &ComState); // if temp is not null, the port is in the error 
state  

if (!temp) WriteFile(handle, buf_in, numbytes, &numbytes_ok, &Overlap);  

ClearCommError(handle, &temp, &ComState);  

if(!temp) ReadFile(handle, buf_in, numbytes, &numbytes_ok, &Overlap); // the 
numbytes_ok variable contains the actual number of I/O bytes  

Note 
This example uses two structures COMSTAT and OVERLAPPED which we haven't yet 
discussed, and also ClearCommError function. In case of three wires connection we needn't 
consider OVERLAPPED structure (just use it as shown in the example).