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

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

รูปภาพของฉัน

เป็นโปรแกรมเมอร์ที่ฝันว่าจะได้นอนเกาพุงไปวัน ๆ จนพุงลดกลายเป็นเอว ได้เป็นบุคคลที่มีความสุขที่สุดในโลกจนคนอื่น ๆ อิจฉา