Với cách nói "RealTime" ở đây chỉ có tính tương đối, nghĩa là đáp ứng qua Mạng Ethernet/Internet sẽ nhanh hơn tùy thuộc vào tốc độ mạng.
Vấn đề ở đây là gì?
+ Khi điều làm một ứng dụng điều khiển qua mạng, mọi người thường chú ý tới giao thức HTTP, lý do: HTTP rất phổ biến, bất kỳ máy tính nào cũng có một trình duyệt có thể liên kế tới một Server nào đó bằng giao thức HTTP. Điều khiển thông qua trình duyệt và không cần bất kỳ một phần mềm nào là xu hướng vẫn thường được xử dụng.
+ Tuy nhiên, HTTP là kết nối đóng, không liên tục, nghĩ là mỗi khi Client gởi yêu cầu tới Server, nó sẽ đáp ứng, gởi trả lại kết quả của yêu cầu cho Client, đồng thời đóng kết nối. Vậy nên kết nối giữ Client và Server là kết nối thụ động cho Server, nếu Server có sự thay đổi nào cần báo cho Client nó phải chờ đến khi Client có yêu cầu.
* Vậy làm thế nào để có thể dùng trình duyệt để điều khiển qua mạng mà vẫn có thể có kết nối mở (kết nối liên tục giữa Client và Server), bất kỳ khi nào có thay đổi trên Server đều có thể gởi sự thay đổi đó về cho Client
* Giải quyết: Hầu hết Trình duyệt (Browser) hiện nay đều tích hợp Flash Player, Flash có thể tạo kết nối TCP Socket đến Server và giữ kết nối này liên tục.
*Thực hiện:
File đính kèm bao gồm 1 file mô phỏng dùng Proteus, TCP IP Stack của MCHP, nội dung của Demo này là gì:
+ Mạch Proteus là mạch giao tiếp Ethernet bao gồm PIC24FJ128GA010 kết nối với 1 ENC28J60. Chương trình chạy trên nó là TCP IP STack, sử dụng HTTP Server trên cổng 80. HTTP Server này sẽ gởi dữ liệu của một Website có cả Flash File (.SWF), file này sẽ được tải về Client (Browser) và được Flash Player trên Browser chạy nó. Sau khi Flash Player play file .SWF nó sẽ tạo kết nối TCP Socket tới cổng 9764 của BerkeleyTCPServer trên mạch PIC
+ Trên tình duyệt sẽ hiển thị một nút nhấn, nếu như nhấn nút này sẽ gởi lệnh tắt/mở LED trên Board, đồng thời trên Board kiểm tra trạng thái của LED D4 và gởi lại trạng thái LED nếu nó thay đổi
+ Trên Board có Switch S5, khi nhấn Switch này thì LED D4 thay đổi trạng thái - nếu LED này thay đổi trạng thái thì nó lại gởi trạng thái đó về cho Client
*Các yêu cầu để bạn có thể chạy Demo này là gì?
+ Cài đặt Proteus + Wincap ->http://www.winpcap.org/
+ Bạn cần nối mạng LAN, nếu bạn cài VMWare thì bạn có 2 Virtual Network Card như phần màu vàng ở hình dưới, bạn cần chọn Network Card cho ENC là 2 hoặc 3. Nếu bạn không cài VMWare thì khi chạy demo, bạn phải sang máy khác và dùng trình duyệt của máy khác trong mạng LAN để truy cập tới HTTP Server này
+ Gõ địa chỉ IP trên LCD lên địa chỉ trình duyệt, hay http://MCHPBOARD, dùng user: admin, pass: microchip để đăng nhập
+ đợi Log view có chữ connected, click vào hình tròn và xem trạng thái LED thay đổi trên Proteus. Nhấp vào nút nhấn S5 trên Proteus để thay đổi trạng thái LED và xem sự thay đổi đó trên trình duyệt
*Sau nay là một số hình ảnh Demo và Video
Video
http://www.youtube.com/watch?v=qt-dgZkdwNg
*Tạo kết nối Socket cho Flash
+Trước tiên cần tải Adobe Flash 10 -> http://adobe.com (dùng thử)
+Trong File gởi kèm có có thư mục Web và WebFinish, các bạn modifiy trong thư mục Web và copy tất cả các file hoàn thành trừ những file khôgn cần thiết qua WebFinish
+File Flash:
Code phần Flash TCP Socket
Code phần Berkeley Server dùng MCHP TCP IPStack cho PIC24, biên dịch C30
Chú ý phần Flash Policy
http://www.adobe.com/devnet/flashpla...curity_04.html
Sau khi chạy biên dịch Flash và hoàn thành Website có thể dùng MPFS tool đi kèm TCP IP Stack của MCHP để upload như hình sau
Chú ý: Bài này không có tính chất hướng dẫn cho newbie nên các bạn chưa làm bao giờ đừng than nhé
Vấn đề ở đây là gì?
+ Khi điều làm một ứng dụng điều khiển qua mạng, mọi người thường chú ý tới giao thức HTTP, lý do: HTTP rất phổ biến, bất kỳ máy tính nào cũng có một trình duyệt có thể liên kế tới một Server nào đó bằng giao thức HTTP. Điều khiển thông qua trình duyệt và không cần bất kỳ một phần mềm nào là xu hướng vẫn thường được xử dụng.
+ Tuy nhiên, HTTP là kết nối đóng, không liên tục, nghĩ là mỗi khi Client gởi yêu cầu tới Server, nó sẽ đáp ứng, gởi trả lại kết quả của yêu cầu cho Client, đồng thời đóng kết nối. Vậy nên kết nối giữ Client và Server là kết nối thụ động cho Server, nếu Server có sự thay đổi nào cần báo cho Client nó phải chờ đến khi Client có yêu cầu.
* Vậy làm thế nào để có thể dùng trình duyệt để điều khiển qua mạng mà vẫn có thể có kết nối mở (kết nối liên tục giữa Client và Server), bất kỳ khi nào có thay đổi trên Server đều có thể gởi sự thay đổi đó về cho Client
* Giải quyết: Hầu hết Trình duyệt (Browser) hiện nay đều tích hợp Flash Player, Flash có thể tạo kết nối TCP Socket đến Server và giữ kết nối này liên tục.
*Thực hiện:
File đính kèm bao gồm 1 file mô phỏng dùng Proteus, TCP IP Stack của MCHP, nội dung của Demo này là gì:
+ Mạch Proteus là mạch giao tiếp Ethernet bao gồm PIC24FJ128GA010 kết nối với 1 ENC28J60. Chương trình chạy trên nó là TCP IP STack, sử dụng HTTP Server trên cổng 80. HTTP Server này sẽ gởi dữ liệu của một Website có cả Flash File (.SWF), file này sẽ được tải về Client (Browser) và được Flash Player trên Browser chạy nó. Sau khi Flash Player play file .SWF nó sẽ tạo kết nối TCP Socket tới cổng 9764 của BerkeleyTCPServer trên mạch PIC
+ Trên tình duyệt sẽ hiển thị một nút nhấn, nếu như nhấn nút này sẽ gởi lệnh tắt/mở LED trên Board, đồng thời trên Board kiểm tra trạng thái của LED D4 và gởi lại trạng thái LED nếu nó thay đổi
+ Trên Board có Switch S5, khi nhấn Switch này thì LED D4 thay đổi trạng thái - nếu LED này thay đổi trạng thái thì nó lại gởi trạng thái đó về cho Client
*Các yêu cầu để bạn có thể chạy Demo này là gì?
+ Cài đặt Proteus + Wincap ->http://www.winpcap.org/
+ Bạn cần nối mạng LAN, nếu bạn cài VMWare thì bạn có 2 Virtual Network Card như phần màu vàng ở hình dưới, bạn cần chọn Network Card cho ENC là 2 hoặc 3. Nếu bạn không cài VMWare thì khi chạy demo, bạn phải sang máy khác và dùng trình duyệt của máy khác trong mạng LAN để truy cập tới HTTP Server này
+ Gõ địa chỉ IP trên LCD lên địa chỉ trình duyệt, hay http://MCHPBOARD, dùng user: admin, pass: microchip để đăng nhập
+ đợi Log view có chữ connected, click vào hình tròn và xem trạng thái LED thay đổi trên Proteus. Nhấp vào nút nhấn S5 trên Proteus để thay đổi trạng thái LED và xem sự thay đổi đó trên trình duyệt
*Sau nay là một số hình ảnh Demo và Video
Video
http://www.youtube.com/watch?v=qt-dgZkdwNg
*Tạo kết nối Socket cho Flash
+Trước tiên cần tải Adobe Flash 10 -> http://adobe.com (dùng thử)
+Trong File gởi kèm có có thư mục Web và WebFinish, các bạn modifiy trong thư mục Web và copy tất cả các file hoàn thành trừ những file khôgn cần thiết qua WebFinish
+File Flash:
Code phần Flash TCP Socket
PHP Code:
import flash.errors.*;
import flash.events.*;
import flash.net.XMLSocket;
var flashVars = this.loaderInfo.parameters;
txtTrace.appendText(flashVars.IP+"\n");
var socket:XMLSocket = new XMLSocket();
socket.addEventListener(DataEvent.DATA,sOnData);
socket.addEventListener(Event.CONNECT,function(evt):void{
txtTrace.text = "Connected\n"+txtTrace.text;
});
socket.addEventListener(Event.CLOSE,function(evt):void{
txtTrace.text = "Disconnected\n"+txtTrace.text;
});
socket.addEventListener(IOErrorEvent.IO_ERROR,function(evt):void{
txtTrace.text = "Error\n"+txtTrace.text;
});
socket.connect(flashVars.IP,9764);
function sOnData(evt:DataEvent):void {
trace(evt.data);
txtTrace.text = evt.data+"\n"+txtTrace.text;
if(evt.data == "4:1") {
led4.gotoAndStop(2);
} else if(evt.data == "4:0") {
led4.gotoAndStop(1);
}
}
led4.Btn.addEventListener(MouseEvent.CLICK,function(evt:MouseEvent):void{
if(led4.currentFrame == 1) {
//led4.gotoAndStop(2);
socket.send("4:1");
trace("Led4 ON");
} else {
//led4.gotoAndStop(1);
trace("Led4 OFF");
socket.send("4:0");
}
});
Code:
char cled=0, led=0; void BerkeleyTCPServerDemo(void) { static SOCKET bsdServerSocket; static SOCKET ClientSock[MAX_CLIENT]; struct sockaddr_in addr; struct sockaddr_in addRemote; int addrlen = sizeof(struct sockaddr_in); char bfr[64]; const char RspStr[] = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\0"; int length; int i; static enum { BSD_INIT = 0, BSD_CREATE_SOCKET, BSD_BIND, BSD_LISTEN, BSD_OPERATION } BSDServerState = BSD_INIT; if(cled!=led) { bfr[0] = '4'; bfr[1] = ':'; bfr[2] = (LED1_IO?'1':'0'); bfr[3] = '\0'; for(i=0; i<MAX_CLIENT; i++) { if(ClientSock[i] == INVALID_SOCKET) continue; send(ClientSock[i], bfr, strlen(bfr)+1, 0); } led = cled; } switch(BSDServerState) { case BSD_INIT: // Initialize all client socket handles so that we don't process // them in the BSD_OPERATION state for(i = 0; i < MAX_CLIENT; i++) ClientSock[i] = INVALID_SOCKET; BSDServerState = BSD_CREATE_SOCKET; // No break needed case BSD_CREATE_SOCKET: // Create a socket for this server to listen and accept connections on bsdServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(bsdServerSocket == INVALID_SOCKET) return; BSDServerState = BSD_BIND; // No break needed case BSD_BIND: // Bind socket to a local port addr.sin_port = PORTNUM; addr.sin_addr.S_un.S_addr = IP_ADDR_ANY; if( bind( bsdServerSocket, (struct sockaddr*)&addr, addrlen ) == SOCKET_ERROR ) return; BSDServerState = BSD_LISTEN; // No break needed case BSD_LISTEN: if(listen(bsdServerSocket, MAX_CLIENT) == 0) BSDServerState = BSD_OPERATION; // No break. If listen() returns SOCKET_ERROR it could be because // MAX_CLIENT is set to too large of a backlog than can be handled // by the underlying TCP socket count (TCP_PURPOSE_BERKELEY_SERVER // type sockets in TCPIPConfig.h). However, in this case, it is // possible that some of the backlog is still handleable, in which // case we should try to accept() connections anyway and proceed // with normal operation. case BSD_OPERATION: for(i=0; i<MAX_CLIENT; i++) { // Accept any pending connection requests, assuming we have a place to store the socket descriptor if(ClientSock[i] == INVALID_SOCKET) ClientSock[i] = accept(bsdServerSocket, (struct sockaddr*)&addRemote, &addrlen); // If this socket is not connected then no need to process anything if(ClientSock[i] == INVALID_SOCKET) continue; // For all connected sockets, receive and send back the data length = recv( ClientSock[i], bfr, sizeof(bfr), 0); if( length > 0 ) { bfr[length] = '\0'; if(strcmp(bfr,"<policy-file-request/>")==0) { send(ClientSock[i], RspStr, strlen(RspStr)+1, 0); } else { if(strcmp(bfr,"4:0")==0) { LED1_IO = 0; } else { LED1_IO = 1; } bfr[0] = '4'; bfr[1] = ':'; bfr[2] = (LED1_IO?'1':'0'); bfr[4] = 0; send(ClientSock[i], bfr, strlen(bfr)+1, 0); } } else if( length < 0 ) { closesocket( ClientSock[i] ); ClientSock[i] = INVALID_SOCKET; } } break; default: return; } return; }
http://www.adobe.com/devnet/flashpla...curity_04.html
Sau khi chạy biên dịch Flash và hoàn thành Website có thể dùng MPFS tool đi kèm TCP IP Stack của MCHP để upload như hình sau
Chú ý: Bài này không có tính chất hướng dẫn cho newbie nên các bạn chưa làm bao giờ đừng than nhé
Comment