Óåëßäá 3 áðü 3 ÐñþôïÐñþôï 123
ÅìöÜíéóç áðïôåëåóìÜôùí 21 ìÝ÷ñé 27 áðü 27

ÈÝìá: Ðñïãñáììáôéóìüò ìå object Pascal (Delphi)

  1. #21
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99

    Çëåêôñïíéêü êáôÜóôçìá åéäþí èÝñìáíóçò êáé êëéìáôéóìïý

    TCP/IP Server
    Èá õëïðïéÞóù Ýíá áðëü TCP/IP ðïëõíçìáôéêü äéáêïìéóôÞ (Server) ÷ñçóéìïðïéþíôáò ôá TServerSocket & TClientSocket components.
    (Áðáéôåßôáé íá åãêáôáóôáèåß ôï package /bin/dclsockets70.bpl)
    Óôï http://delphi.about.com/od/networking/l/aa112602a.htm èá âñåßôå ðåñéóóüôåñåò ðëçñïöïñßåò ãéá ôçí ÷ñÞóç ôùí óõãêåêñéìÝíùí components.
    Åðßóçò óôï http://www.overbyte.be/frame_index.h...ducts/ics.html èá âñåßôå ìéá äéáöïñåôéêÞ õëïðïßçóç áðü Indy êáé Delphi socket components.

    Ãéá ðåëÜôåò (clients) èá ÷ñçóéìïðïéÞóïõìå

    1. ¸íá áðëü browser ðïõ èá «÷ôõðÜåé» ìßá http äéåýèõíóç
    Êþäéêáò:
    http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
    êáé óôçí ðåñßðôùóÞ ìáò http://127.0.0.1:1024

    H ðáñáðÜíù HTTP êëÞóç åìöáíßæåôáé óôïí Server óáí ôï ðáñáêÜôù êåßìåíï
    Êþäéêáò:
    GET / HTTP/1.1
    Host: 127.0.0.1:1024
    User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20100101 Firefox/15.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en,el;q=0.8,el-gr;q=0.5,en-us;q=0.3
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: keep-alive
    Ï Server áðáíôÜ
    Êþäéêáò:
    HTTP/1.1 200 OK
    Content-Length: 11
    Hello World
    Connection: close
    [empty line]


    2. Ôï telnet óôï ïðïßï èá åðéóôñÝöåôáé üôé óôÝëíïõìå (echo).
    Start/Run Cmd
    Óôï Dos box ðëçêôñïëïãïýìå telnet 127.0.0.1 1024
    Ðëçêôñïëïãïýìå «Hello» êáé ôï áðïóôÝëëïõìå óôïí Server ìå Enter
    Êþäéêáò:
    Client  ---------- initate connection -----------> Server
    ...
    Client  <---------------command------------------- Server
    Client  ----------------response-----------------> Server
    ...
    Client  <---------------command------------------- Server
    Client  ----------------response-----------------> Server
    ÐñÝðåé íá õëïðïéçèåß ôï RFC 854, êáé äåí ìðïñåß íá óõíõðÜñîåé ìå ôï modbus Þ ôï Web server


    3. To modbus client.
    Èá ðñÝðåé íá åðéëÝîïõìå ãéá èýñá ðïõ áêïýåé ï Server ôçí 502.

    Êþäéêáò:
    |Modbus Application Protocol (MBAP) Header | Protocol Data Unit (PDU)|
    |------------------------------------------+-------------------------|
    |Transaction |Protocol  | Length  | Unit   | Function   |   Data     |
    |Identifier  |Identifier| Field   | ID     | Code       |            |
    |--------------------------------------------------------------------|
    | (2 bytes)  |(2 bytes) |(2 bytes)|(1 byte)|(1 byte)    | Ìåôáâëçôü  |
    |------------------------------------------+-------------------------|
    Õëïðïßçóá, óôïí TCP/Server, Ýíá modbus client ðïõ õðïóôçñßæåé ìüíï ôéò ðáñáêÜôù functions.

    03 (0x03) Read Holding Registers
    ÂëÝðå MODBUS Application Protocol Specification V1.1b óåëßäá 19/51
    http://www.modbus.org/docs/Modbus_Ap...ocol_V1_1b.pdf

    06 (0x06) Write Single Register
    ÂëÝðå. MODBUS Application Protocol Specification V1.1b óåëßäá



    Statefull
    ¸íáò WebServer, äçìéïõñãåß ãéá êÜèå íÝá óýíäåóç Ýíá SessionId ðïõ ôï åðéóôñÝöåé óôïí Client óáí Cookie. Ìå êëåéäß áõôü ôï SessionId, ï WebServer, óõó÷åôßæåé üëç ôá äåäïìÝíá ôïõ óõãêåêñéìÝíïõ client (user name, db connection êôë)
    Ï ßäéïò client, óôçí åðüìåíç åðéêïéíùíßá ôïõ, áðïóôÝëëåé ôï SessionId þóôå íá åðáíá÷ñçóéìïðïéÞóåé ôá äåäïìÝíá ðïõ üñéóå óå ðñïçãïýìåíç êëÞóç (statefull).

    ÐåñéãñáöÞ ôïõ ðñïãñÜììáôïò.
    Ï server áêïýåé óôçí ðüñôá 1024 êáé ãéá êÜèå íÝá óýíäåóç ðåëÜôç äçìéïõñãåß Ýíá îå÷ùñéóôü thread ðïõ èá ÷åéñßæåôáé ôçí åðéêïéíùíßá ìåôáîý ôïõò (ServerType= stThreadBlocking). Ìüëéò áðïóôáëåß ç áðÜíôçóç óôïí ðåëÜôç, ôï íÞìá ôåëåéþíåé ôçí åñãáóßá ôïõ êáé åðéóôñÝöåé óôï pool. Ç åðüìåíç êëÞóç áðü ôïí ßäéï ðåëÜôç äåí èá óõó÷åôéóèåß ìå êáìßá ðñïçãïýìåíç (stateless).
    Äçìéïõñãïýíôáé íÞìáôá (threads) êëÜóçò ðïõ êëçñïíïìåß áðü ôçí TServerClientThread êáé åðéóôñÝöïíôáé óôï Server ìÝóù ôïõ event OnGetThread.
    Êþäéêáò:
    procedure TFrmServer.ServerGetThread(Sender: TObject;  ClientSocket: TServerClientWinSocket;   var SocketThread: TServerClientThread);
    begin
     SocketThread:=TSrvThread.Create(ClientSocket, Handle);
    end;
    
    TSrvThread=class(TServerClientThread)
               private
                fHandle:THandle;
    ...
               protected
                procedure ClientExecute; override; 
               public
                constructor Create(aSocket:TServerClientWinSocket;
               aHandle:THandle);
               end;
    Óôçí procedure TSrvThread.ClientExecute; äéáâÜæïõìå ôï åéóåñ÷üìåíï TCP/IP ìÞíõìá.

    Ç ñïõôßíá RequestType ôï êáôçãïñéïðïéåß óáí rtHTTP, rtText, rtModBus Þ rtBinary êáé áðáíôÜåé áíÜëïãá.

    Óôï http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html ðåñéãñÜöåôáé üôé ç ðñþôç ãñáììÞ ïñßæåôáé óáí

    Êþäéêáò:
    Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
    ¼ðïõ Method         = "OPTIONS"                ; Section 9.2
                          | "GET"                    ; Section 9.3
                          | "HEAD"                   ; Section 9.4
                          | "POST"                   ; Section 9.5
                          | "PUT"                    ; Section 9.6
                          | "DELETE"                 ; Section 9.7
                          | "TRACE"                  ; Section 9.8
                          | "CONNECT"                ; Section 9.9
                          | extension-method
           extension-method = token
    Óôï ðñüãñáììá êáôçãïñéïðïéþ ôçí êëÞóç óáí http áí ðåñéÝ÷åé ôï HTTP/1. êáé îåêéíÜåé ìå ôéò ëÝîåéò GET Þ HEAD.

    Ï ÷åéñéóìüò ôïõ telnet, åßíáé äéáöïñåôéêüò. To socket ðáñáìÝíåé «áíïéêôü» Ýùò íá Ýñèåé êÜðïéïò control ÷áñáêôÞñáò.

    Ôï ðñüãñáììá ÷ñåéÜæåôáé åðåêôÜóåéò åÜí êÜðïéïò èÝëåé íá êÜíåé ðñáãìáôéêÞ äïõëåéÜ ìå áõôü.

    Ç ðñþôç êáé óçìáíôéêüôåñç åßíáé ç õëïðïßçóç ìéáò êëÜóçò TModbus ðïõ èá õëïðïéåß ôï modbus ðñùôüêïëëï Ýôóé þóôå ï êþäéêáò (C ìåôáöéåóìÝíç óå Pascal) íá ãßíåé óõíôçñÞóéìïò.

    Êþäéêáò:
      
      rtModBus : begin
             case pbFC^ of
               $03 : begin // mbfReadHoldingRegs = $03;
                      pa:=pword(FRequest);
                      pd:=pa;
                      inc(pa, 4); // points to Start Address
                      inc(pd, 5); // point to count
                      move(FRequest^,data[0],8);
                      cnt:=swap(pd^);
                      data[ 8]:=cnt*2;
                      pd:=pword(@data[9]);
                      for i:=0 to pred(cnt) do begin
                        w:=SendMessage(fHandle,REG_GET,swap(pa^)+i,0);
                        pd^:=swap(w);
                        inc(pd);
                       end;
                      size:=8+1+cnt*2;
                      data[5]:=2 + 1 + cnt*2;
                      ClientSocket.SendBuf(data,size);
                     end;
    Ìðïñåßôå íá êáôåâÜóåôå ôçí åöáñìïãÞ êáé ôï source áðü ôï
    http://www.filefactory.com/file/dftv...n/Server01_rar

    Êáé ðáñáöñÜæïíôáò ôïí ìáýñï ðåéñáôÞ (Áóôåñßî óôç ÊïñóéêÞ óåë. 19)
    Bugus humanum est

    Êáëü öèéíüðùñï

  2. #22
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99
    ÓùóôÞ Þ ëáíèáóìÝíç õëïðïßçóç ;

    ÌåôÜ áðü áñêåôÜ ÷ñüíéá óôçí äïõëåéÜ âëÝðù ôï ëÜèïò áðü ìáêñéÜ. Êáé áðü ìéá ðáñÜîåíç óýìðôùóç üôáí åëÝã÷ù ôçí äïõëåéÜ êÜðïéïõ Üëëïõ ó÷åäüí ðÜíôá «óêïíôÜöôù» åðÜíù ôïõ.

    Óáí íá åßíáé åêåß êáé íá ìïõ êëåßíåé ôï ìÜôé êáé íá ìïõ ëÝåé «ðñïóðÝñíá ìå».

    Óôçí õëïðïßçóç ôïõ Server Ýìðëåîá ôéò ëåéôïõñãßåò ôïõ server ìå ôïí ÷åéñéóìü ôùí ìçíõìÜôùí. Ï Server äéá÷åéñßæåôáé tcp/ip óõíäÝóåéò, êáé «ðåñíÜåé» ôá ìçíýìáôá óå êáôÜëëçëïõò ÷åéñéóôÝò (handler threads).
    Åêåß ôá ðñÜãìáôá ðñÝðåé íá åßíáé åðßóçò êáèáñÜ êáé ôçí áðïêùäéêïðïßçóç ôçò åñþôçóçò êáé ôçí êùäéêïðïßçóç ôçò áðÜíôçóçò ðñÝðåé íá ôçí êÜíåé ìéá Üëëç HTTP Þ Telnet Þ TModbus êëÜóç.

    Ç áðÜíôçóç ëïéðüí åßíáé áðëÞ. ÎáíáãñÜøôï. ÍÝá ó÷åäßáóç, õëïðïßçóç êáé ôåêìçñßùóç.

    TModbus
    Ôï modbus åßíáé Ýíá ðñùôüêïëëï áíôáëëáãÞò åñùôÞóåùí & áðáíôÞóåùí êáé ðáñÝ÷åé ìßá client/server åðéêïéíùíßá ìåôáîý óõóêåõþí óõíäåäåìÝíùí ìÝóù TCP/IP. ÊÜèå åñþôçìá ðåñéãñÜöåôáé áðü Ýíá êùäéêü (function code FC). Ôï modbus ðñùôüêïëëï áðåéêïíßæåé ôéò äéåõèýíóåéò êáé ôá äåäïìÝíá ìå ôï ðéï óçìáíôéêü byte ðñþôï (big Endian).
    Ïé 4 êýñéïé ðßíáêåò ðïõ ÷ñçóéìïðïéåß ôï Modbus åßíáé
    ÄéáêñéôÝò åßóïäïé, áðåéêïíßæïíôáé óå bits êáé ìðïñïýìå ìüíï íá ôéò äéáâÜóïõìå.
    Coils, (solid-state relay) áðåéêïíßæïíôáé óå bits êáé ìðïñïýìå íá ôéò äéáâÜóïõìå & íá ãñÜøïõìå
    Input Registers, áðåéêïíßæïíôáé óå 16-bit word, ìðïñïýìå ìüíï íá ôéò äéáâÜóïõìå.
    Holding Registers, áðåéêïíßæïíôáé óå 16-bit word, ìðïñïýìå íá ôéò äéáâÜóïõìå & íá ãñÜøïõìå
    Ïé âáóéêÝò ëåéôïõñãßåò åßíáé
    (0x01) Read Coils
    (0x02) Read Discrete Inputs
    (0x03) Read Holding Registers
    (0x04) Read Input Registers
    (0x05) Write Single Coil
    (0x06) Write Single Register

    O modbus Master ñùôÜåé Þ êáèïñßæåé ôéìÝò ãéá åéóüäïõò Þ åîüäïõò åíüò PLC. To PCL åßíáé slave êáé áðáíôÜåé óôá åñùôÞìáôá ôïõ Master.
    Óôçí äéêÞ ìáò ðåñßðôùóç õëïðïéïýìå áìöïôÝñïõò.

    Ï Master/client ÷ñçóéìïðïéåß Ýíá socket component ãéá ôçí TCP/IP óýíäåóç ìå ôïí Server/ Slave. ÊáôáóêåõÜæåé Ýíá object ôçò êëÜóçò TModbus êáé êáëåß ôéò ñïõôßíåò ðïõ õëïðïéïýí ôéò âáóéêÝò ëåéôïõñãßåò.

    Ôá áðïôåëÝóìáôá åìöáíßæïíôáé óå array properties.

    Êþäéêáò:
    Modbus:=TModbus.Create(FSocket);
    If Modbus.ReadHoldingRegisters(1,1) then
     Modbus.HoldingRegs[1]
    Ý÷åé ôçí æçôïýìåíç ôéìÞ.

    Ï Server/Slave Ý÷åé Þäç ëÜâåé ôï TCP/IP ìÞíõìá êáé ðñÝðåé íá áðïöáóßóåé ôïí ôýðï ôïõ.
    ×ñçóéìïðïéþíôáò ôïí 2ï constructor äçìéïõñãåß Ýíá object êáé åëÝã÷åé ôçí ïñèüôçôá ôïõ ìçíýìáôïò. Óå ðåñßðôùóç ëÜèïõò óôçí äïìÞ ôïõ ìçíýìáôïò, äçìéïõñãåß exception.

    Ç êëÜóç TModbus ðåñéêëåßåé (encapsulates) ôçí äïìÞ åíüò modbus ìçíýìáôïò êáé ï ðáñáêÜôù êþäéêáò (éóÜîéïò ìüíï ãéá ôïí Chuck http://blog.magicsoftware.com/2011/0...rogrammer.html )
    Êþäéêáò:
      // check for ModBus request
      if FReqSize>=12 then begin
       pwTI :=pword(p);    // 0..1 Transaction Identifier
       pwPI :=pword(p+2);  // 2..3 Protocol Identifier
       pwlf :=pword(p+4);  // 4..5 Length Field
       pbUID:=pbyte(p+6);  // 6    Unit ID
                           //      MB_IGNORE_UNITID = 255
       pbFC :=pbyte(p+7);  // 7;   Function Code
                           //      mbfReadHoldingRegs = $03;
                           //      mbfWriteOneReg = $06;
                           // 8;   Data
    
       if ((pbFC^=$06) or (pbFC^=$03)) and (pwlf^=swap($0006)) then begin
        result:=rtModBus;
        exit;
       end;
      end;
    áíôéêáèßóôáôáé ìå
    Êþäéêáò:
      try
       FModbus:=TModbus.Create(FRequest^,FReqSize);
       FModbus.OnGetData:=ModbusGetData;
       FModbus.OnSetData:=ModbusSetData;
       result:=rtModBus;
       exit;
      except
       Log('Not modbus message');
      end;
    Êáé ï åðßóçò «áíäñéêüò» êþäéêáò
    Êþäéêáò:
    rtModBus : begin
             case pbFC^ of
               $03 : begin // mbfReadHoldingRegs = $03;
                      pa:=pword(FRequest);
                      pd:=pa;
                      inc(pa, 4); // points to Start Address
                      inc(pd, 5); // point to count
                      move(FRequest^,data[0],8);
                      cnt:=swap(pd^);
                      data[ 8]:=cnt*2;
                      pd:=pword(@data[9]);
                      for i:=0 to pred(cnt) do begin
                        w:=SendMessage(fHandle,REG_GET,swap(pa^)+i,0);
                        pd^:=swap(w);
                        inc(pd);
                       end;
                      size:=8+1+cnt*2;
                      data[5]:=2 + 1 + cnt*2;
                      ClientSocket.SendBuf(data,size);
                     end;
    áíôéêáèßóôáôáé ìå
    Êþäéêáò:
           rtModBus : begin
                       FModbus.PrepareResponse;
                       FModbus.Respond(ClientSocket);
                       FreeAndNil(FModbus);
                      end
    êáé ç êëÜóç ÔModbus áêïëïõèåß.

    Êþäéêáò:
     TBytes = array of byte;
    
     TMBAP = packed record { 7 bytes }
               TrnId : word;
               ProtocolIdent: word;
               Len:word;
               UnitId:byte;
              end;
    
     TPDU  = packed record { 253 bytes }
               FC  : byte;
               Data: packed record case integer of
                      0 : (b: array[0..251] of byte);
                      1 : (w: array[0..125] of word);
                      2 : (o: packed record
                                len : byte;
                                w   : array[0..124] of word;
                                b   : byte;
                               end)
                     end;
              end;
    
     TADU  = packed record // 260 bytes
               MBAP : TMBAP;
               PDU  : TPDU;
              end;
    
    |Modbus Application Protocol (MBAP) Header | Protocol Data Unit (PDU)|
    |------------------------------------------+-------------------------|
    |Transaction |Protocol  | Length  | Unit   | Function   |   Data     |
    |Identifier  |Identifier| Field   | ID     | Code       |            |
    |--------------------------------------------------------------------|
    | (2 bytes)  |(2 bytes) |(2 bytes)|(1 byte)|(1 byte)    | Ìåôáâëçôü  |
    |------------------------------------------+-------------------------|
    
     TModbus = class
               Private
                 ...
               Public
                // Client Side
                constructor Create(aSocket:TCustomWinSocket); overload;
                // Server Side
                constructor Create(const Request; size:word); overload;  
                procedure   PrepareResponse;
                procedure   Respond(aSocket:TCustomWinSocket);
    
                function ReadCoils(StartAddress, Count:word):boolean;
                function ReadDiscreteInputs(StartAdd,Count:word):boolean; 
                function ReadHoldingRegisters(RegNo,Count:word):boolean; 
                function ReadInputRegisters(RegNo,Count:word):boolean;
                procedure WriteSingleCoil(Addr:word;value:boolean);
                procedure WriteSingleRegister(RegNo,value:word);
    
                property  DiscreteInput[idx:integer]:boolean read ...
                property  Coils[idx:integer]:boolean read ...
                property  InputRegs[idx:integer]:word read ...
                property  HoldingRegs[idx:integer]:word read ...
    
                property  FC:byte read FFC;
                property  Request:TBytes read GetRequest;
                property  Response:TBytes read GetResponse;
    
                property  OnGetData:TOnExchangeData read ...         
                property  OnSetData:TOnExchangeData read ...
    
               end;
    Íïìßæù üôé ðëÝïí ãßíåôáé öáíåñÞ ç ÷ñçóéìüôçôá ôùí objects.
    ÐåñéëáìâÜíïõí äåäïìÝíá êáé ìåèüäïõò ðïõ õëïðïéïýí ôéò õðçñåóßåò ôïõò ðñïò ôïí ÷ñÞóôç.

    ¸ðñåðå, ç êëÜóç TModbus íá áíïßãåé êáé ôçí TCP/IP óýíäåóç ?
    ÁðïöÜóéóá üôé ç êëÜóç èá ÷ñçóéìïðïéåß connected sockets êáé èá óõíäéáëÝãåôáé ìå ôçí õðüëïéðç åöáñìïãÞ ìå êáèáñü ôñüðï.

    ÅðéðëÝïí ç ìíÞìç ðïõ ãñÜöåé Þ äéáâÜæåé ï Server/Slave èá áíÞêå óôïí ßäéï, êáé ôçí äéá÷åéñßæåôáé, ôçí åìöáíßæåé Þ óôçí êëÜóç TModbus ðïõ âáóéêÜ ÷åñßæåôáé ìüíï ôïí ó÷çìáôéóìü ôùí ìçíõìÜôùí. ÅðÝëåîá ç ìíÞìç íá áíÞêåé óôïí Slave êáé íá ç TModbus êëÜóç íá åðéêïéíùíåß ìå event Handlers
    Êþäéêáò:
    TOnExchangeData = procedure(FC:byte; param1,param2:word;var value:word) of object;
    Ìðïñåßôå íá êáôåâÜóåôå ôçí åöáñìïãÞ êáé ôï source áðü ôï
    http://www.filefactory.com/file/vjru...n/Server02.rar

    ÐáñáôçñÞóåéò êáé ó÷üëéá ðÜíôá äåêôÜ.


  3. #23
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99
    ÓåéñéáêÞ åðéêïéíùíßá

    ¼ôáí ÷ñçóéìïðïéÞóáìå PSTN ãñáììÞ óõíäÝáìå ôï modem óôçí óåéñéáêÞ ôïõ õðïëïãéóôÞ êáé «âãáßíáìå» óôï internet.
    Ç óåéñéáêÞ (RS232) åðéêïéíùíßá Þôáí êõñßáñ÷ç áíÜìåóá óå óõóêåõÝò ðïõ åß÷áí íá áíôáëëÜîïõí äåäïìÝíá. ÓÞìåñá áíôéêáèßóôáôáé óôáäéáêÜ ìå ôï USB ôùí 480 kbits.
    Ïé 2 óåéñéáêÝò óõóêåõÝò áíôáëëÜóïõí óôïé÷åßá üôáí ç ìßá ôá æçôÞóåé áðü ôçí 2ç Þ üôáí ç 2ç ôá Ý÷åé Ýôïéìá êáé ôá óôÝëíåé ÷ùñßò åñþôçóç. ÓõíÞèùò ïé äéÜëïãïé åßíáé åñþôçóç – áðÜíôçóç.
    Ç óåéñéáêÞ åðéêïéíùíßá âáóßæåôáé óå Ýíá çëåêôñéêü êáé óå Ýíá ëïãéêü ðñùôüêïëëï.
    Ðáëìïß óôï êáëþäéï
    Ðþò èá êùäéêïðïéÞóïõìå ôçí ðëçñïöïñßá åíüò byte óå Ýíá êáëþäéï?. Óôçí óåéñéáêÞ åðéêïéíùíßá äçìéïõñãïýìå ìéá ðáëìïóåéñÜ óôáèåñÞò äéÜñêåéáò , ìå ðáëìïýò ãéá êÜèå bit=1 ôïõ byte. ÐñïóôÝèçêáí êáé êÜðïéïé åðéðëÝïí ðáëìïß óõã÷ñïíéóìïý êáé áíß÷íåõóçò óöÜëìáôïò åðéêïéíùíßáò êáé ìåôáäßäïíôáé óôï êáëþäéï ìå óõãêåêñéìÝíç ôá÷ýôçôá. ×ñçóéìïðïéïýìå Ýíá ïðïéïäÞðïôå UART (ð÷ 8051) ìå Ýíá êáëþäéï áðïóôïëÞò (Tx) êáé Ýíá êáëþäéï ëÞøçò.
    http://www.slideshare.net/pantechsol...municationuart
    Ðñïöáíþò, ãéá ëüãïõò óõã÷ñïíéóìïý ïé 2 Üêñåò ðñÝðåé íá ñõèìéóèïýí óôá ßäéá ÷áñáêôçñéóôéêÜ óåéñéáêÞò åðéêïéíùíßáò (ôá÷ýôçôá, parity, stop bits).

    Áíß÷íåõóç ëáèþí.
    ÊÜèå byte ðåñéÝ÷åé Üñôéï Þ ðåñéôôü áñéèìü áðü 1. ÐñïóèÝôïíôáò Ýíá áêüìá bit (ðáëìü) ìðïñåßò íá åîáóöáëßóåéò üôé ï áñéèìüò ôùí 1 óôï óõãêåêñéìÝíï byte åßíáé Üñôéïò Þ ðåñéôôüò (parity odd / even). Ç áíß÷íåõóç ëáèþí âáóßóôçêå óôï ìÝôñçìá ôùí 1 êáôÜ ôçí ëÞøç êáé ôçí åðéâåâáßùóç ôçò óõìöùíßáò åðéêïéíùíßáò (odd/even parity).
    Ôï UART ðáñÜãåé interrupts üôáí ï êáôá÷ùñçôÞò áðïóôïëÞò (transmit register) åßíáé Üäåéïò êáé ï êáôá÷ùñçôÞò ëÞøçò (receive register) ãåìÜôïò. ÁõôÜ ôá interrupts öôÜíïõí óôïí driver ôïõ óåéñéáêïý ðïõ ôá ðñïùèåß óáí events óôéò åöáñìïãÝò.
    ¸ôóé ìðïñïýìå áóýã÷ñïíá íá åíçìåñùèïýìå ãéá ôçí ëÞøç ìÝóù óåéñéáêÞò åðéêïéíùíßáò åíüò ÷áñáêôÞñá Þ íá ãñÜøïõìå óå Ýíá buffer ôï ðñïò áðïóôïëÞ ìÞíõìá êáé áöÞóïõìå íá áðïóôáëåß . ¼ëá áõôÜ åßíáé ìÝñïò ôïõ ëåéôïõñãéêïý óõóôÞìáôïò êáé áðïôåëïýí ðñüâëçìá ôùí ïäçãþí (drivers) ôùí óåéñéáêþí èõñþí.
    ÔåëéêÜ Ý÷ïõìå 2 óõóêåõÝò óõíäåäåìÝíåò ìå ôïõëÜ÷éóôïí 3 êáëþäéá (Tx, Rx, Gnd) üðïõ ôï Tx ôçò ìßáò óõóêåõÞò óõíäÝåôáé óôï Rx ôçò Üëëçò êáé Ý÷ïõí êïéíü Gnd.

    Ëïãéêü ðñùôüêïëëï.
    Áò äïýìå Ýíá ðñùôüêïëëï åðéêïéíùíßáò ãéá öïñïëïãéêïýò åêôõðùôÝò (áðü áõôïýò åêäßäïíôáé ïé áðïäåßîåéò óôá super market).
    ftp://ftp.accordgroup.ro/Pentru%20de...20PROTOCOL.pdf

    ÊÜèå ìÞíõìá îåêéíÜ ìå ôïí STX (0x02) êáé ôåëåéþíåé ìå ÅÔ× (0x03).
    Êþäéêáò:
    +-----+---------------+-----+
    | STX |      Data     | ETX |
    +-----+---------------+-----+
    ¼ëá ôá äåäïìÝíá óôá Data åßíáé ascii ÷áñáêôÞñåò áðü 0x32 Ýùò 0xFF.

    Tx data packet
    Êþäéêáò:
    <--------------------- Data -------------------><--Checksum -->
    +---------+---------+---------+------+---------+---------------+
    | Request / Field 1 / Field 2 / .... / Field N /       CC      |
    +---------+---------+---------+------+---------+---------------+
    Request 1 char

    Rx data packet
    Êþäéêáò:
    <--------------------- Data -----------------------------><-Checksum->
    +---------+--------+--------+-------+-------+------------+-----------+
    |Response /Status 1/Status 2/Field 1/Field 2/..../Field N/    CC     |
    +---------+--------+--------+-------+-------+------------+-----------+
    Response,status1, status2 2 numeric digits

    Êþäéêáò:
     BYTE CalcChecksum(BYTE *packet)                        
     {                                                      
       BYTE sum = 0;                                        
       int  checklength = strlen(packet) - 2;               
                                                            
       while(check length--) sum += (BYTE) (*packet++);     
       return (sum % 100));                                 
     }
    Ó÷åäßáóç

    1. ÊÜèå ìÞíõìá áðáíôÜôáé óýìöùíá ìå ôçí ðáñáêÜôù ñïÞ

    Sender (host) Receiver (device)
    Êþäéêáò:
    ---------------------------------------------------------
         IDLE                           IDLE
         ENQUIRE ---------------------> 
                 <--------------------- ACKNOWLEDGE
       Ôx PACKET ---------------------> 
                 <--------------------- ACKNOWLEDGE
                 <--------------------- Rx PACKET
     ACKNOWLEDGE --------------------->
            IDLE                        IDLE
    2. ¼ëá ôá ìçíýìáôá áðïóôïëÞò ìïñöïðïéïýíôáé, ðñéí áðïóôáëïýí, óå ìßá ñïõôßíá
    3. ¼ëá ôá ìçíýìáôá ëáìâÜíïíôáé áðü ìßá ñïõôßíá.
    4. ×ñçóéìïðïéþ blocking äéáäéêáóßá åðéêïéíùíßáò.

    Ç äéáäéêáóßá åðéêïéíùíßáò ðåñéãñÜöåôáé áðü ôï ðáñáêÜôù äéÜãñáììá áëëáãÞò êáôÜóôáóçò (state transition diagram).

  4. #24
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99
    êáé ôï äéÜãñáììá.



    Ç õëïðïßçóç áêïëïõèåß óå åðüìåíï post.

  5. #25
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99
    Õëïðïßçóç

    Óå üëá ôá ðñùôüêïëëá åðéêïéíùíßáò õðÜñ÷åé Ýíá ìÞíõìá áðïóôïëÞò êáé Ýíá ìÞíõìá áðÜíôçóçò êáé ðÜíôá èá õðÜñ÷ïõí ðñïâëÞìáôá åðéêïéíùíßáò. Ç õëïðïßçóç åíüò ðñùôïêüëëïõ ðñÝðåé, áðáñáßôçôá, íá ëáìâÜíåé õðüøéí ôá óöÜëìáôá (åðéêïéíùíßáò Þ ëïãéêÜ) êáé íá ÷åéñßæåôáé áíÜëïãá. Êñéíüìáóôå ðñþôá áðü ôçí ëåéôïõñãéêüôçôá êáé Ýðåéôá áðü ôçí áîéïðéóôßá êÜèå óõóôÞìáôïò. Áðü åðéêïéíùíßåò ìå óåéñéáêïýò öïñïëïãéêïýò åêôõðùôÝò Ýùò ôéò áíåìïãåííÞôñéåò.

    TPacket
    Áò îåêéíÞóïõìå ìå ôçí ðñþôç êëÜóç ðïõ õëïðïéåß ôçí ëåéôïõñãéêüôçôá ôïõ ðáêÝôïõ áðïóôïëÞò & ëÞøçò.
    Êþäéêáò:
    TPacketType = (ptTx, ptRx);
    
    TPacket = class(TObject)
    ...
     public
      constructor Create;            overload;
      constructor Create(aReq:char); overload;
      destructor  destroy; override;
      class function CalcCheckSum(const data: string): string;
      class function ChecksumValid(const data:string):boolean;
      property Fields[index:integer]:string read GetField write SetField;
      property Data:string read GetData write SetData;
      property PacketType:TPacketType read fPacketType write fPacketType;
      property RxResposeCode:integer read fRxResposeCode;
      property RxStatus1:integer  read fRxStatus1;
      property RxStatus2:integer read fRxStatus2;
     end;
    ¼ôáí èÝëïõìå íá äçìéïõñãÞóïõìå Ýíá ìÞíõìá ãéá áðïóôïëÞ ôüôå

    Êþäéêáò:
    tx:=TPacket.Create('b'); // Request = SetVatRates
    for i:=1 to 5 do // ðñïóèÝôïõìå 5 óõíôåëåóôÝò ÖÐÁ
     tx.Fields[i]:=format('%.2f/',[VatRates[i]]);
    ×ñçóéìïðïéïýìå ôï property data ðïõ ðñïóèÝôåé êáé checksum

    ¼ôáí ëáìâÜíïõìå Ýíá ìÞíõìá
    Êþäéêáò:
    rx:=TPacket.Create;
    rx.data:=msg; // ÷ùñßò STX, ETX
    ôo property RxResposeCode:integer ðåñéÝ÷åé ôçí êùäéêü åðéôõ÷ßáò/áðïôõ÷ßáò.
    Ôï array property fields ôá ðåäßá ôïõ ìçíýìáôïò.

    ×ñçóéìïðïßçóá ãéá ðñþôç öïñÜ class functions. ×ñåéáæüìïõí ìßá õðçñåóßá (èá ìðïñïýóá íá åßíáé ìéá áðëÞ âïçèçôéêÞ function) ðïõ áíÞêå óå ìßá êëÜóç êáé äåí Þèåëá íá äçìéïõñãÞóù object.

    Ç êëÜóç åßíáé Ýíá óõìâüëáéï ðïõ áðáñéèìåß êáé ðåñéãñÜöåé õðçñåóßåò.
    Ãéá íá "ðÜñïõìå" áõôÝò ôéò õðçñåóßåò äçìéïõñãïýìå objects ìÝóù ôïõ constructor êÜèå êëÜóçò. Ôá objects êáôáëáìâÜíïõí ìíÞìç ãéá ôéò åóùôåñéêÝò ìåôáâëçôÝò ôïõò êáé üëá ìïéñÜæïíôáé ôïí êþäéêá functions.

    Ç ßäéá ç êëÜóç ìðïñåß íá ìáò äþóåé õðçñåóßåò áñêåß íá ìçí ÷ñçóéìïðïéåß ìíÞìç ôïõ object. O constructor, ðïõ äçìéïõñãåß objects áðïôåëåß ÔÇÍ class function.

    TSession
    Áêïëïõèåß ç êëÜóç ôçò åðéêïéíùíßáò. Åäþ õëïðïéÞóáìå ôçí ëïãéêÞ ôïõ äéáãñÜììáôïò áëëáãÞò êáôáóôÜóåùí.
    ÌåëåôÞóôå ôï êáé êáôáëÜâåôÝ ôï. Ï êþäéêáò åßíáé ðéóôÞ áíôéãñáöÞ ôïõ.
    Êþäéêáò:
    TSession = class
    ... 
     public
      constructor Create(const params:string); // COM1,9600,N,8,1
      destructor destroy; override;
      // <0 ÓöÜëìá åðéêïéíùíßáò
      // 0  Åðéôõ÷ßá åðéêïéíùíßáò & åêôÝëåóçò ôçò åíôïëÞò
      // >0 ÓöÜëìá ðñùôïêüëëïõ
      function  Communicate(const TxPacket:TPacket; 
                            out RxPacket:TPacket):integer;
     end;


    TFiscalPrinter
    Êáé êáôáëÞãïõìå óôçí êëÜóç ðïõ ÷ñçóéìïðïéåß ç åöáñìïãÞ.
    ÁõôÞ ìå ôçí óåéñÜ ôçò ÷ñçóéìïðïéåß ôçí TSession & ôçí Tpacket ãéá ôçí åðéêïéíùíßá ìå ôïí åêôõðùôÞ.

    ÁëëÜ ïé õðçñåóßåò ðïõ ðáñÝ÷åé åßíáé õøçëïý åðéðÝäïõ, ðïõ ìðïñïýí Üìåóá íá ÷ñçóéìïðïéçèïýí áðü ìßá åöáñìïãÞ (application).

    Êþäéêáò:
    TFiscalPrinter = class
    .. .
     public
      constructor create(const COMPort:string);
      destructor destroy; override;
    
      function FiscalTime:TDateTime;
      function SerialNumber:String;
      function TicketNumber:integer;
      function ZNumber:integer;
    
      procedure OpenDay;        // Logical operation
      procedure CloseDay;       // Issue Z, read EJ
    
      procedure OpenTicket(tt:TTicketType; const Title:string ='';                 
                           const Seira:string=''; number:integer=0);
      procedure SaleItem(const code, descr, barcode:string; 
                         price, quant, amount:double; vatCat:integer);
      procedure VoidItem(const code, descr, barcode:string; 
                         price, quant, amount:double; vatCat:integer);
      procedure RefoundItem(const code, descr, barcode:string; 
                            price, quant, amount:double; vatCat:integer);
      procedure DiscountItem(const code, descr, barcode:string; 
                         amount:double; vatCat:integer);
      procedure SubTotalTicket;
      procedure SubTotalDiscount(amount:double);
    
      procedure CancelTicket;
      procedure CloseTicket;
    ...
     property capEJ:boolean read FcapEJ; // capability has Electronic Journal
     property capSlip:boolean read FcapSlip;// capability has SlipPrinter
    
     property Header[index:integer]:string read GetHeader write SetHeader;
     property Footer[index:integer]:string read GetFooter write SetFooter;
     property VatRates[index:integer]:string read GetVatRate write SetVatRate;    
     end;
    ÕÃ.
    1. Ç ìüíç ìïõ ðáñáôÞñçóç óôï óõãêåêñéìÝíï ðñùôüêïëëï Þôáí ç ëáíèáóìÝíç åðéëïãÞ ôïõ ‘/’ óáí äéá÷ùñéóôÞ ðåäßùí (field separator) äéüôé ìðïñåß íá õðÜñîåé êáé óôá äåäïìÝíá åíüò ðåäßïõ ôïõ ìçíýìáôïò.
    Èá ìðïñïýóå íá ÷ñçóéìïðïéçèåß ï ÷áñáêôÞñáò FS = 28 Þ 0x 1C

    2. ×ñçóéìïðïéþ ôï async32 component. (open source)
    http://www.general-files.com/downloa...s554ee144h32i0

    3. Ìå áõôü ôï post ôåëåßùóá ìå üóá èÝìáôá åß÷á óêåöèåß íá áíáëýóù.
    ÁíáìÝíù ðñïôÜóåéò êáé åñùôÞóåéò.

    ÐÖ

  6. #26
    ÅîÝ÷ïí ìÝëïò
    Çìåñïìçíßá åããñáöÞò
    Jun 2008
    ÈÝóç
    Glyfada, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    3,101
    Ôé íá ðù! ÌÝíù Üöùíïò!
    Ðéóôåýù üôé ôüóç áíÜðôõîç êþäéêá äåí ðñÝðåé íá õðÜñ÷åé óå Üëëï forum áêüìç êáé ôïõ åîùôåñéêïý.
    Ç äïõëåéÜ áõôÞ ÐÜíï ðñïïñßæåôáé ãéá ôïõò åðüìåíïõò áíáãíþóôåò ôïõ forum áõôïý ðïõ áöåíüò èá åßíáé åéäéêïß ãéá íá ìðïñÝóïõí íá ðáñáêïëïõèÞóïõí üëï áõôü ôï îåäßðëùìá êáé áöåôÝñïõ ðïëý åéäéêïß èá Ýëåãá!

    Åãþ äåí Ý÷ù íá ðáñáôçñÞóù ôßðïôá äéüôé äåí Ý÷ù áó÷ïëçèåß ìå modbus êáé åðéêïéíùíßåò ãåíéêþò. Áí ÷ñåéáóèåß íá áó÷ïëçèþ îÝñù áìÝóùò ðïõ èá áíáôñÝîù ìéáò êáé ôï Ý÷ù Þäç áñ÷åéïèåôÞóåé óå 23 óåëßäåò ôïõ acrobat.
    Ôï ìüíï ðïõ èá ðù åßíáé üôé áõôÞ ç êáôáðëçêôéêÞ ãëþóóá (Pascal) ðïõ ôçí ðåèÜíáíå ïé ðåèáìåíáíôæÞäåò ðÜíôá ìå óõãêéíåß!! Áêüìá êáé üôáí ôçí ãñÜöåé Üëëïò êáé ü÷é åãþ!


    Õ.Ó.
    Ìç ðåñéìÝíåéò «ëáïèÜëáóóá» íá óå ñùôÜåé êáé óõ íá áðáíôÜò. ×ôýðçóåò ìå ôçí ìßá ðïëý øçëÜ ôüóï øçëÜ ðïõ èá ðÜó÷åéò áðü «ìïíáîéÜ». ¸÷å ôï õð' üøç óïõ áõôü. Êáé ðÜëé åýãå!


    Óôßãìá ÌáóôñïêáðåôÜíéïõ

  7. #27
    ÌÝëïò
    Çìåñïìçíßá åããñáöÞò
    Mar 2012
    ÈÝóç
    Athens, , Greece.
    Éäéüôçôá:
    Áãíùóôç
    ÁðáíôÞóåéò
    99

    Çëåêôñïíéêü êáôÜóôçìá åéäþí èÝñìáíóçò êáé êëéìáôéóìïý

    ÊáðåôÜíéå,

    Áðü ôçí áñ÷Þ óêüðåõá óôïõò íÝïõò ìç÷áíéêïýò. Áõôïýò ðïõ óôï ðïëõôå÷íåßï äéäÜ÷èçêáí íá ëýíïõí ðñïâëÞìáôá. Óå áõôïýò ðïõ ôá ìáèçìáôéêÜ Þôáí åñãáëåßï êáé ü÷é áõôïóêïðüò. ÌÜèáìå êáé ìáèáßíïõíå íá ëýíïõí ðñïâëÞìáôá áíáëõôéêÜ (óðÜæïíôÜò ôá óå ìéêñüôåñá êïììÜôéá) êáé óõíäõáóôéêÜ (íá åíþíïõí ìéêñÜ êïììÜôéá ãíùóôÞò óõìðåñéöïñÜò êáé íá äçìéïõñãïýí ìåãáëýôåñá).

    ÁëëÜ ôï ëïãéóìéêü, üóï soft êáé íá åßíáé, áðáéôåß ó÷åäßáóç ðñéí ôçí õëïðïßçóç.
    Áõôü ðñïóðÜèçóá íá ôïíßóù. Êáé ðëÝïí ïé êëÜóåéò êáé ôá objects áðïôåëïýí åñãáëåßá ãéá íá ãñÜöïõìå êáëýôåñï ëïãéóìéêü.
    quote:ðïëý åéäéêïß èá Ýëåãá!
    Äåí óõìöùíþ ãéá ôï ðïëý åéäéêïß. Áí ïé ìç÷áíïëüãïé êáé ïé çëåêôñïëüãïé ðñÝðåé íá ãíùñßæïõí ôïõò ôñüðïõò ìåôÜäïóçò ôçò èåñìüôçôáò ôüôå èá ðñÝðåé íá ãíùñßæïõí íá ãñÜöïõí êáé óùóôÜ ëïãéóìéêü. Ïé ìç÷áíéêïß öôéÜ÷íïõí óõóôÞìáôá êáé ü÷é ïé ðñïãñáììáôéóôÝò. Ç ãëþóóá ðñïãñáììáôéóìïý áëëÜæåé áëëÜ üðùò åßðå êáé ï ÓùôÞñçò
    quote:Ïé ôå÷íéêåò ðáñáìåíïõí ôå÷íéêåò..
    Åóý Þóïõí Þäç Ýôïéìïò. Ç ðåñéÝñãåéÜ óïõ óå åß÷å Þäç ïäçãÞóåé óôï íá åîåñåõíÞóåéò ôïí áíôéêåéìåíïóôñåöÞ ðñïãñáììáôéóìü. ÁëëÜ íá áëëÜîåéò áõôÞ ôçí ôåñÜóôéá unit ìå ôéò âïçèçôéêÝò functions ðïõ îÝñåéò ðéá áðÝîù åßíáé äýóêïëï.

    Ðïõ îÝñåéò, ìðïñåß ôåëéêÜ êáé íá ðñïóåëêýóù íÝá ìÝëç ìüíï ãéá ôï ëïãéóìéêü. Áõôïß öõóéêÜ èá ìåôñÜíå óôïõò Çëåêôñïëüãïõò.

    Èá óõíå÷ßóù íá ãñÜöù ãéá äéÜöïñá èÝìáôá ðïõ èá åðéëÝãù ìå ôï ßäéï, ÷áëáñü, ñõèìü.

    ÄÜóêáëå, óå åõ÷áñéóôþ èåñìÜ.
    ÐÜíïò

Äéêáéþìáôá áðÜíôçóçò

  • You may not post new threads
  • ÄÅÍ Ý÷åôå ôï äéêáßùìá áðÜíôçóçò
  • You may not post attachments
  • ÄÅÍ ìðïñåßôå íá åðåîåñãáóôåéôå ôéò áðáíôçóåéò óáò
  •  
  • BB code is Áíïéêôü
  • Smilies are Áíïéêôü
  • [IMG] code is Áíïéêôü
  • [VIDEO] code is Êëåéóôü
  • HTML code is Êëåéóôü