22 ตุลาคม 2550

การเขียน PHP เพื่อติดต่อกับ COM Port (Communication Port)

ช่วงนี้ผมได้หันมาจับงานทางด้าน Hardware แทนที่จะทำเฉพาะส่วนของ Software อย่างเดียว ซึ่งมันอาจจะเป็นหนทางในการผ่าทางตันที่ผมประสบอยู่ งานที่ต้องทำคือการเชื่อมต่อ PC เพื่อควบคุมอุปกรณ์ Hardware ซึ่งสามารถติดต่อได้หลายทาง ซึ่งอันที่มีทุกยี่ห้อทุกแบบมาแต่โบราณ คือ ติดต่อผ่านพอร์ตอนุกรม (RS232, Serial Port หรือ Communication Port) ซึ่งวิธีการเชื่อมต่อก็แสนง่ายดาย แค่รู้คำสั่ง และตัวแปรที่เกี่ยวข้องก็สามารถใช้งานได้แล้ว

ในการเชื่อมต่อ ผมได้ใช้ PHP ในการทำงาน เพราะผมได้พัฒนาเน้นให้ใช้ผ่านเครือข่าย Internet และ Web browser ได้ โดยใช้ชุดคำสั่งที่อยู่ใน package PEAR ในการเชื่อมต่อ Direct IO Functions ซึ่งการใช้งานจะคล้ายกลุ่มคำสั่ง Filesystem Functions แต่สามารถกำหนดการทำงานได้ในระดับที่ต่ำกว่า เรียกว่าใกล้กับ Hardware ที่สุด

การใช้งานก็มีให้ดูในคู่มือ PHP โดยหลักๆ จะใช้คำสั่ง dio_open, dio_read, dio_write, dio_close เนื่องจากพัฒนาใน Windows ในการจัดการเรื่องความเร็วและค่าของ COM Port ผ่านคำสั่ง mode ใน command line แทน


<?php
error_reporting
(E_ALL);
$set_mode "MODE COM3: BAUD=9600 PARITY=N DATA=8 STOP=1 TO=ON XON=OFF ODSR=ON OCTS=ON DTR=ON RTS=ON IDSR=ON";
$output = array();
exec($set_mode$output$result);
$stdout fopen('CON''w');
fwrite($stdout"Set COM3 Output:\n");
print_r($output);

//check exit status from MODE command
switch ($result) {
    case 
:
        
fwrite($stdout"COM3 parameters set successfully.\n");
        break;
    default :
        
fwrite($stdout"Error while trying to set COM3 parameters - exiting.\n");
        exit;
}


echo 
"Modem Query...\n";
$aCmd = array(
    
'ATQ0V1E0',
    
'AT+GMM',
    
'AT+FCLASS=?',
    
'AT#CLS=?',
    
'AT+GCI?',
    
'AT+GCI=?',
    
'ATI1',
    
'ATI2',
    
'ATI3',
    
'ATI4',
    
'ATI5',
    
'ATI6',
    
'ATI7',
    
'ATQ0V1E0',
    
'AT+GMM',
    
'AT+FCLASS=?',
    
'AT#CLS=?',
    
'AT+GCI?',
    
'AT+GCI=?',
    
'ATI1',
    
'ATI2',
    
'ATI3',
    
'ATI4',
    
'ATI5',
    
'ATI6',
    
'ATI7',
);
foreach(
$aCmd as $out) {
    
$fd dio_open('COM3:'O_RDWR);
    echo 
$out ': ';
    
dio_write($fd"$out\x0D\x0A");
    
$tt '';
    while(
$p dio_read($fd1)) {
        echo 
$p;
        
$tt .= $p;
        if(
strpos($tt,"OK\x0D\x0A")!==FALSE) break;
        if(
strpos($tt,"ERROR\x0D\x0A")!==FALSE) break;
    }
    
dio_close($fd);
    echo 
"\n==========================================================\n";
}

echo 
"\n\n[END]\n\n";
?>

ในโปรแกรมตัวอย่างที่เขียนขึ้น จะทำการทดสอบ Modem ที่ติดตั้งอยู่ที่ COM3: โดยจะใช้คำสั่งเดียวกับที่ Query Modem ใน Control Panel ซึ่งผลที่ได้ยังไม่ถูกต้องนัก เนื่องจากยังต้องมีส่วนของการจัดการเรื่อง buffer และการตั้งการส่งข้อมูลเพิ่มเติม ซึ่งหากจะใช้งานกับอุปกรณ์ Hardware ทั่วๆไปอย่าง PLC แค่นี้ก็เพียงพอสำหรับการอ่านค่าที่ได้จาก PLC ขนาดไม่กี่ byte

8 ความคิดเห็น:

ไม่ระบุชื่อ กล่าวว่า...

ขอบคุณมั๊ก ๆ ครับ

Unknown กล่าวว่า...

สวัสดีครับ คุณCharin Nawaritloha ผมรบกวนข้อคำแนะนำหน่อยสิครับว่าจะเขียนโปรแกรมติดต่อกลับเครื่อง RFID ทาง RS232 ด้วยให้รับค่าเข้ามาเก็บไว้แล้วค่อยนำไปใช้ในระบบล็อกอินต่อนะครับพึงเริ่ม php เรยไม่มีพื้่่นฐานแต่ต้องทำส่ง project นะครับยังไงถ้ามี code หรือคำแนะนำช่วยชี้แนะหน่อยครับ ขอบคุณครับ

Charin Nawaritloha กล่าวว่า...

Chai Pamornpongamporn แนะนำว่าศึกษาพื้นฐาน PHP ก่อนนะครับ ส่วนเรื่องนำข้อมูลจาก RFID มาทำระบบ login ในส่วนของคำสั่งที่ใช้ติดต่อกับเครื่อง RFID ปกติในคู่มือเขาจะมีคำสั่งมาให้ว่า TX RX อะไรทำงานอะไร ประมาณนั้น ส่วนเรื่อง login ใน PHP มันมีหลายแบบครับ ลองเอาพวก open source มาลองศึกษาดู พวก session_id ประมาณนี้ แต่สุดท้ายถ้าพื้น PHP ไม่แข็งแรงต่อยอดยากครับ

Unknown กล่าวว่า...

ครับผมไม่น่าเรยผมกำลังศึกษาไปด้วย(พื้นฐาน)แต่ PJ จะต้องส่งในต้นเดือนก่อนปิดเรียน summer นะครับ(ทำคนเดียวด้วยบ้าจริง)
เรื่องคู่มือใช่ในส่วนนี้รึป่าวครับ
Tx_232 TXD (RS-232)
Rx_232 RXD (RS-232)
Tx_TTL UART TXD (TTL levels only)
Rx_TTL UART RXD (TTL levels only)
THEORY OF READ OPERATION
There are two options for the read operation according to the modulation and the method used in the tag.
1. Manchester Modulation
BM1250 supports Manchester RF/64 and Manchester RF/32 modulations. The Manchester RF/64 is the most used
modulation type in 125 KHz systems and is recommended to be used for new designs. Manchester RF/32 is used in some
tags (e.g.TK5552) but the read performance is lower than the Manchester RF/64 and not recommended for new designs.
For Manchester RF/64, signal representing 1 or 0 is in 512 us width for 125 KHz. For Manchester RF/32, signal
representing 1 or 0 is in 256 us width for 125 KHz. EM4102 tags use Manchester RF/64 modulation and EM method and
the configuration of these read-only tags is fixed and can’t be altered.
คุณ Charin Nawaritloha พอจะมีเวลาสอนแบบจุดนี้มัํยครับแค่ให้สามารถติดต่อนำข้อมูลที่ได้จากบัตรเข้ามาเก็บไว้ในตัวแปรเพื่อส่งต่อให้ใช้งานครับผมยินดีจะเข้าไปหาพี่ๆ รบกวนหน่อยครับๆๆๆ

Charin Nawaritloha กล่าวว่า...

ตอบคุณ Chai Pamornpongamporn สำหรับคำสั่งที่ใช้สื่อสารกับ Hardware น่าจะอยู่ในส่วนของ Communication Protocol / UART COMMANDS ในคู่มือนะครับ ส่วนเรื่องสอน ผมไม่รับสอนส่วนตัวครับ

Unknown กล่าวว่า...

ตัวอย่างโปรแกรมด้านบนสามารถนำไปใช้ได้เรยรึป่าวครับหรือต้องแก้ไขตรงไหนบ้างเพื่อให้เข้ากับส่วนงานของแต่ละงานครับ

Warning: fopen(CON) [function.fopen]: failed to open stream: Bad file descriptor in C:\AppServ\www\start1.php on line 6

Warning: fwrite(): supplied argument is not a valid stream resource in C:\AppServ\www\start1.php on line 7
Array ( [0] => [1] => Status for device COM3: [2] => ----------------------- [3] => Baud: 9600 [4] => Parity: None [5] => Data Bits: 8 [6] => Stop Bits: 1 [7] => Timeout: ON [8] => XON/XOFF: OFF [9] => CTS handshaking: ON [10] => DSR handshaking: ON [11] => DSR sensitivity: ON [12] => DTR circuit: ON [13] => RTS circuit: ON [14] => )
Warning: fwrite(): supplied argument is not a valid stream resource in C:\AppServ\www\start1.php on line 13
Modem Query...
Fatal error: Call to undefined function dio_open() in C:\AppServ\www\start1.php on line 51


ผมนำโค้ดพี่ไปรันแล้วยังมีหลายส่วนช่วยอธิบายหน่อยครับรบกวนหน่อยครับพี่

Charin Nawaritloha กล่าวว่า...
ความคิดเห็นนี้ถูกผู้เขียนลบ
Charin Nawaritloha กล่าวว่า...

ตอบคุณ Chai Pamornpongamporn โปรแกรมนี้ต้องสั่งให้ทำงานผ่าน command line ครับ ถ้าจะให้ทำงานผ่าน เบราเซอร์ให้ตัดบรรทัดที่ 6 7 ออก ส่วนคำสั่ง dio_open สามารถใช้กับ PHP 5 <= 5.0.5 ครับ

เนื่องจากโปรแกรมนี้เขียนมาตั้งแต่ปี พ.ศ.2550 ผ่านไป 5 ปี PHP รุ่นใหม่มันต้องใช้คำสังอื่นแทนครับ แต่หลักการจะประมาณตัวอย่างโปรแกรม ดังนั้น ถ้าไม่เข้าใจเลยว่า code แต่ละบรรทัดทำงานอย่างไร แนะนำว่าให้ไปใช้ SDK ของเครื่อง RFID จะดีกว่าครับ

แสดงความคิดเห็น

เกี่ยวกับเจ้าของบล๊อก