PHP操作串列埠 --- 操作傳送簡訊mod應用(真實專案)
<span style="font-size:12px;"><strong>首先來一個模組應用的文件截圖:</strong></span>
<img src="https://img-blog.csdn.net/20140822184417003?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2Via28=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
<?php header('Content-type:text/html;charset=UTF-8'); /** * PHP向串列埠傳送資料,操作簡訊model * * ===============簡訊 model 通訊協議說明======== * * 傳送資料協議格式:SMS13821987654#簡訊內容區 * 其中: * SMS: 固定指令 * 13821987654: 為接收簡訊的手機號碼 * #: 表示簡訊內容中文。可選值":",表示簡訊內容英文。本用例統一使用#,相容中英文。 * 簡訊內容區: 需要傳送的簡訊內容 * 如果簡訊內容為中文的指令編碼規則: * 第一部分:SMS13821987654#---分別取各個字元的ASCII碼,然後轉換成對應的16進製表示值。每個字元佔1個位元組。如:53 4D 53 31 33 38 32 31 39 38 37 36 34 35 23 * 第二部分:簡訊內容區-------分別取各個字元的UNICODE編碼的16進製表示值,每個字元佔2個位元組。如:77 ed 4f e1 51 85 5b b9 53 3a * (注:字串"簡訊內容"的Unicode編碼為:\u77ed\u4fe1\u5185\u5bb9\u533a) */ $tel = '13323332222'; // 接收簡訊的電話號碼 $sms = '《PHP也能幹大事之PHP與串列埠通訊》,@小蠻子&晚點,QQ:467166260'; // 簡訊內容 send($tel, $sms); // 傳送簡訊 function send($tel, $sms){ //include "php_serial.class.php"; // 載入php操作串列埠的類 $serial = new phpSerial; $serial->deviceSet("COM3"); // 這個硬體裝置在COM3上 if( $serial->deviceOpen() ){ $code = format_tel('SMS'.$tel.'#').' '.format_sms($sms); // 格式:SMS13821987654#簡訊內容區 $order = pack_arg($code); return $serial->sendMessage($order); } else return false; } /** * 將形如“53 4D 53 31 33 39 35 30 30 36 35 30 30 30 23 4F 60 59 7D”的資料裝入一個二進位制字串進行組包,以待通訊 */ function pack_arg($str){ $args = explode(' ', $str); $php = 'return pack("c*",'; for($i=0; $i<count($args); $i++){ $php = "{$php}0x{$args[$i]},"; } $php = rtrim($php, ','); $php .= ');'; return eval($php); } //======================= 兩個自定義工具函式 ===================== /** * 將字串轉換成ACSII碼所對應的十六進位制,每個字元佔1個位元組。例:13518250288=>31 33 35 31 38 32 35 30 32 38 38 */ function format_tel($str){ $rt = ''; for($i=0; $i<strlen($str); $i++) { $rt = $rt.' '.dechex(ord($str{$i})); } return trim($rt); } /** * 取字串的unicode編碼的十六進位制表示方法,以2個位元組來表示一個字元。例:你好=>4F 60 59 7D Aa=>00 65 00 97 */ function format_sms($str){ $rt = ''; for($i=0; $i < mb_strlen($str, 'UTF-8'); $i++){ $c = mb_substr($str, $i, 1, 'UTF-8'); $ord = ord($c); if($ord > 127) { //中文 $tmp = strtolower(trim(json_encode($c), '"')); //形如:\U0E74 $rt = $rt.' '.substr($tmp, 2, 2).' '.substr($tmp, 4, 2); } else { $rt .= ' 00 '.dechex($ord); } } return trim($rt); }
其中用到了一個類:php_serial.class.php
<?php
define ("SERIAL_DEVICE_NOTSET", 0);
define ("SERIAL_DEVICE_SET", 1);
define ("SERIAL_DEVICE_OPENED", 2);
/**
* Serial port control class
*
* THIS PROGRAM COMES WITH ABSOLUTELY NO WARANTIES !
* USE IT AT YOUR OWN RISKS !
*
* @author R閙y Sanchez <[email protected] >
* @thanks Aur閘ien Derouineau for finding how to open serial ports with windows
* @thanks Alec Avedisyan for help and testing with reading
* @copyright under GPL 2 licence
*/
class phpSerial
{
var $_device = null;
var $_windevice = null;
var $_dHandle = null;
var $_dState = SERIAL_DEVICE_NOTSET;
var $_buffer = "";
var $_os = "";
/**
* This var says if buffer should be flushed by sendMessage (true) or manualy (false)
*
* @var bool
*/
var $autoflush = true;
/**
* Constructor. Perform some checks about the OS and setserial
*
* @return phpSerial
*/
function phpSerial ()
{
setlocale(LC_ALL, "en_US");
$sysname = php_uname();
if (substr($sysname, 0, 5) === "Linux")
{
$this->_os = "linux";
if($this->_exec("stty --version") === 0)
{
register_shutdown_function(array($this, "deviceClose"));
}
else
{
trigger_error("No stty availible, unable to run.", E_USER_ERROR);
}
}
elseif(substr($sysname, 0, 7) === "Windows")
{
$this->_os = "windows";
register_shutdown_function(array($this, "deviceClose"));
}
else
{
trigger_error("Host OS is neither linux nor windows, unable tu run.", E_USER_ERROR);
exit();
}
}
//
// OPEN/CLOSE DEVICE SECTION -- {START}
//
/**
* Device set function : used to set the device name/address.
* -> linux : use the device address, like /dev/ttyS0
* -> windows : use the COMxx device name, like COM1 (can also be used
* with linux)
*
* @param string $device the name of the device to be used
* @return bool
*/
function deviceSet ($device)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
if ($this->_os === "linux")
{
if (preg_match("@^COM(\d+): [email protected]", $device, $matches))
{
$device = "/dev/ttyS" . ($matches[1] - 1);
}
if ($this->_exec("stty -F " . $device) === 0)
{
$this->_device = $device;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
elseif ($this->_os === "windows")
{
if (preg_match("@^COM(\d+):[email protected]", $device, $matches) and $this->_exec(exec("mode " . $device)) === 0)
{
$this->_windevice = "COM" . $matches[1];
$this->_device = "\\.\com" . $matches[1];
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
trigger_error("Specified serial port is not valid", E_USER_WARNING);
return false;
}
else
{
trigger_error("You must close your device before to set an other one", E_USER_WARNING);
return false;
}
}
/**
* Opens the device for reading and/or writing.
*
* @param string $mode Opening mode : same parameter as fopen()
* @return bool
*/
function deviceOpen ($mode = "r+b")
{
if ($this->_dState === SERIAL_DEVICE_OPENED)
{
trigger_error("The device is already opened", E_USER_NOTICE);
return true;
}
if ($this->_dState === SERIAL_DEVICE_NOTSET)
{
trigger_error("The device must be set before to be open", E_USER_WARNING);
return false;
}
if (!preg_match("@^[raw]\[email protected]", $mode))
{
trigger_error("Invalid opening mode : ".$mode.". Use fopen() modes.", E_USER_WARNING);
return false;
}
$this->_dHandle = @fopen($this->_device, $mode);
if ($this->_dHandle !== false)
{
stream_set_blocking($this->_dHandle, 0);
$this->_dState = SERIAL_DEVICE_OPENED;
return true;
}
$this->_dHandle = null;
trigger_error("Unable to open the device", E_USER_WARNING);
return false;
}
/**
* Closes the device
*
* @return bool
*/
function deviceClose ()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
return true;
}
if (fclose($this->_dHandle))
{
$this->_dHandle = null;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
trigger_error("Unable to close the device", E_USER_ERROR);
return false;
}
//
// OPEN/CLOSE DEVICE SECTION -- {STOP}
//
//
// CONFIGURE SECTION -- {START}
//
/**
* Configure the Baud Rate
* Possible rates : 110, 150, 300, 600, 1200, 2400, 4800, 9600, 38400,
* 57600 and 115200.
*
* @param int $rate the rate to set the port in
* @return bool
*/
function confBaudRate ($rate)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set the baud rate : the device is either not set or opened", E_USER_WARNING);
return false;
}
$validBauds = array (
110 => 11,
150 => 15,
300 => 30,
600 => 60,
1200 => 12,
2400 => 24,
4800 => 48,
9600 => 96,
19200 => 19,
38400 => 38400,
57600 => 57600,
115200 => 115200
);
if (isset($validBauds[$rate]))
{
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . (int) $rate, $out);
}
elseif ($this->_os === "windows")
{
$ret = $this->_exec("mode " . $this->_windevice . " BAUD=" . $validBauds[$rate], $out);
}
else return false;
if ($ret !== 0)
{
trigger_error ("Unable to set baud rate: " . $out[1], E_USER_WARNING);
return false;
}
}
}
/**
* Configure parity.
* Modes : odd, even, none
*
* @param string $parity one of the modes
* @return bool
*/
function confParity ($parity)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set parity : the device is either not set or opened", E_USER_WARNING);
return false;
}
$args = array(
"none" => "-parenb",
"odd" => "parenb parodd",
"even" => "parenb -parodd",
);
if (!isset($args[$parity]))
{
trigger_error("Parity mode not supported", E_USER_WARNING);
return false;
}
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . $args[$parity], $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " PARITY=" . $parity{0}, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set parity : " . $out[1], E_USER_WARNING);
return false;
}
/**
* Sets the length of a character.
*
* @param int $int length of a character (5 <= length <= 8)
* @return bool
*/
function confCharacterLength ($int)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set length of a character : the device is either not set or opened", E_USER_WARNING);
return false;
}
$int = (int) $int;
if ($int < 5) $int = 5;
elseif ($int > 8) $int = 8;
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " cs" . $int, $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " DATA=" . $int, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set character length : " .$out[1], E_USER_WARNING);
return false;
}
/**
* Sets the length of stop bits.
*
* @param float $length the length of a stop bit. It must be either 1,
* 1.5 or 2. 1.5 is not supported under linux and on some computers.
* @return bool
*/
function confStopBits ($length)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set the length of a stop bit : the device is either not set or opened", E_USER_WARNING);
return false;
}
if ($length != 1 and $length != 2 and $length != 1.5 and !($length == 1.5 and $this->_os === "linux"))
{
trigger_error("Specified stop bit length is invalid", E_USER_WARNING);
return false;
}
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . (($length == 1) ? "-" : "") . "cstopb", $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " STOP=" . $length, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set stop bit length : " . $out[1], E_USER_WARNING);
return false;
}
/**
* Configures the flow control
*
* @param string $mode Set the flow control mode. Availible modes :
* -> "none" : no flow control
* -> "rts/cts" : use RTS/CTS handshaking
* -> "xon/xoff" : use XON/XOFF protocol
* @return bool
*/
function confFlowControl ($mode)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set flow control mode : the device is either not set or opened", E_USER_WARNING);
return false;
}
$linuxModes = array(
"none" => "clocal -crtscts -ixon -ixoff",
"rts/cts" => "-clocal crtscts -ixon -ixoff",
"xon/xoff" => "-clocal -crtscts ixon ixoff"
);
$windowsModes = array(
"none" => "xon=off octs=off rts=on",
"rts/cts" => "xon=off octs=on rts=hs",
"xon/xoff" => "xon=on octs=off rts=on",
);
if ($mode !== "none" and $mode !== "rts/cts" and $mode !== "xon/xoff") {
trigger_error("Invalid flow control mode specified", E_USER_ERROR);
return false;
}
if ($this->_os === "linux")
$ret = $this->_exec("stty -F " . $this->_device . " " . $linuxModes[$mode], $out);
else
$ret = $this->_exec("mode " . $this->_windevice . " " . $windowsModes[$mode], $out);
if ($ret === 0) return true;
else {
trigger_error("Unable to set flow control : " . $out[1], E_USER_ERROR);
return false;
}
}
/**
* Sets a setserial parameter (cf man setserial)
* NO MORE USEFUL !
* -> No longer supported
* -> Only use it if you need it
*
* @param string $param parameter name
* @param string $arg parameter value
* @return bool
*/
function setSetserialFlag ($param, $arg = "")
{
if (!$this->_ckOpened()) return false;
$return = exec ("setserial " . $this->_device . " " . $param . " " . $arg . " 2>&1");
if ($return{0} === "I")
{
trigger_error("setserial: Invalid flag", E_USER_WARNING);
return false;
}
elseif ($return{0} === "/")
{
trigger_error("setserial: Error with device file", E_USER_WARNING);
return false;
}
else
{
return true;
}
}
//
// CONFIGURE SECTION -- {STOP}
//
//
// I/O SECTION -- {START}
//
/**
* Sends a string to the device
*
* @param string $str string to be sent to the device
* @param float $waitForReply time to wait for the reply (in seconds)
*/
function sendMessage ($str, $waitForReply = 0.1)
{
$this->_buffer .= $str;
if ($this->autoflush === true) $this->flush();
usleep((int) ($waitForReply * 1000000));
}
/**
* Reads the port until no new datas are availible, then return the content.
*
* @pararm int $count number of characters to be read (will stop before
* if less characters are in the buffer)
* @return string
*/
function readPort ($count = 0)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
trigger_error("Device must be opened to read it", E_USER_WARNING);
return false;
}
if ($this->_os === "linux")
{
$content = ""; $i = 0;
if ($count !== 0)
{
do {
if ($i > $count) $content .= fread($this->_dHandle, ($count - $i));
else $content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
else
{
do {
$content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
return $content;
}
elseif ($this->_os === "windows")
{
/* Do nohting : not implented yet */
}
trigger_error("Reading serial port is not implemented for Windows", E_USER_WARNING);
return false;
}
/**
* Flushes the output buffer
*
* @return bool
*/
function flush ()
{
if (!$this->_ckOpened()) return false;
if (fwrite($this->_dHandle, $this->_buffer) !== false)
{
$this->_buffer = "";
return true;
}
else
{
$this->_buffer = "";
trigger_error("Error while sending message", E_USER_WARNING);
return false;
}
}
//
// I/O SECTION -- {STOP}
//
//
// INTERNAL TOOLKIT -- {START}
//
function _ckOpened()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
trigger_error("Device must be opened", E_USER_WARNING);
return false;
}
return true;
}
function _ckClosed()
{
if ($this->_dState !== SERIAL_DEVICE_CLOSED)
{
trigger_error("Device must be closed", E_USER_WARNING);
return false;
}
return true;
}
function _exec($cmd, &$out = null)
{
$desc = array(
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$proc = proc_open($cmd, $desc, $pipes);
$ret = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$retVal = proc_close($proc);
if (func_num_args() == 2) $out = array($ret, $err);
return $retVal;
}
//
// INTERNAL TOOLKIT -- {STOP}
//
}
?>
相關推薦
PHP操作串列埠 --- 操作傳送簡訊mod應用(真實專案)
<span style="font-size:12px;"><strong>首先來一個模組應用的文件截圖:</strong></span> <img src="https://img-blog.csdn.net/2014
如何在windows系統下用串列埠通訊完爆raspberry pi(樹莓派)
相關文章 在沒有網路,沒用鍵盤,沒有顯示器的情況下,控制樹莓派就成了一個問題。 通過串列埠通訊果斷的試用了一次發現效果不錯,下面就和大家一起分享一下。 所需裝置: 1.raspberry pi 板子一塊 2.一張SD卡(至少2G我們採用8G) 3.一根
stm32-串列埠接受不定長資料方法(3種)
方法1:串列埠接受資料,定時器來判斷超時是否接受資料完成。 方法2:DMA接受+IDLE中斷 實現思路:採用STM32F103的串列埠1,並配置成空閒中斷IDLE模式且使能DMA接收,並同時設定接收緩衝區和初始化DMA。那麼初始化完成之後,當外部給單片機發送資料的時候,
【串列埠通訊】--執行緒應用(1)
一、前言: 關於串列埠通訊中的執行緒問題,本來是早就想總結一下的。但是在這兩個星期的學習過程中,發現自己原來的理解還是有很多的不全面的地方。通過兩個月的學習,自己對這塊的認識還是有了很大的提升,今
使用python在openwrt下操作串列埠傳送十六進位制資料
#!/usr/bin/python import serial from time import sleep ser = serial.Serial('/dev/ttyS0', 9600, timeout=0.5) print ser.port print ser.baudrate if
轉:Python通過pyserial控制串列埠操作
https://blog.csdn.net/lovelyaiq/article/details/48101487 你想通過串列埠讀寫資料,典型場景就是和一些硬體裝置打交道(比如一個機器人或感測器)。儘管你可以通過使用Python內建的I/O模組來完成這個任務,但對於序列通訊最好的選擇是使用 py
轉:神奇的python(六)之python的串列埠操作(pyserial)
https://blog.csdn.net/qq_14997473/article/details/80875722:Python學習筆記——串列埠配置以及傳送資料 https://blog.csdn.net/ubuntu14/article/details/75335106:python實現串列埠
轉: python 操作串列埠
https://www.cnblogs.com/zhengweizhao/p/8426826.html import serial匯入模組 然後就可以用了 ser = serial.Serial(0) 是開啟第一個串列埠 print ser.portstr 能看到第一個串列埠的標識,window
c++串列埠操作
0. 前言 做串列埠方面的程式,使用CreateFile開啟串列埠通訊埠。在對串列埠操作之前,需要首先開啟串列埠。使用C++進行串列埠程式設計,如果採用VS開發,則可以直接藉助於串列埠通訊控制元件來操作,其次,直接呼叫Windows的底層API函式來控制串列埠通訊。 在Window 32
MFC操作串列埠,詳細 複製程式碼(ActiveX控制元件和Windows API函式)
/******************************************************************* *******函式功能:開啟串列埠裝置連結 *******函式名稱:OpenComm *******輸入引數:無 *******輸出引數:無 ***
python3操作串列埠
通過引用serial模組包,來操作串列埠。 1、檢視串列埠名稱 在Linux和Windows中,串列埠的名字規則不太一樣。需要事先檢視。 Linux下的檢視串列埠命令 [email protected]:~# ls -l /dev/ttyS* crw-rw---- 1 root dialou
樹莓派3B Wiring Pi 串列埠操作
Wiring Pi是為樹莓派提供的GPIO的介面庫,我目前只使用了串列埠的介面,下面也只介紹一下串列埠的使用。 串列埠操作提供了開啟串列埠、讀取資料、傳送資料、關閉串列埠介面。 int fd; if(wiringPiSetup() < 0)
C# 串列埠操作系列(1) -- 入門篇,一個標準的,簡陋的串列埠例子。
我假設讀者已經瞭解了c#的語法,本文是針對剛打算解除串列埠程式設計的朋友閱讀的,作為串列埠程式設計的入門範例,也是我這個系列的基礎。 我們的開發環境假定為vs2005(雖然我在用vs2010,但避免有些網友用2005,不支援lambda,避免不相容,就用2005來做例子)
C#控制檯操作串列埠例項例程
本文介紹一個C#控制檯下操作串列埠的範例程式,基於多執行緒的一個接收,一個傳送,可以用來作為參考,實測VS2010編譯使用通過。 using System; using System.Collections.Generic; using System.Linq; using
C# 串列埠操作系列(1) -- 入門篇,一個標準的,簡陋的串列埠例子
我假設讀者已經瞭解了c#的語法,本文是針對剛打算解除串列埠程式設計的朋友閱讀的,作為串列埠程式設計的入門範例,也是我這個系列的基礎。 我們的開發環境假定為vs2005(雖然我在用vs2010,但避免有些網友用2005,不支援lambda,避免不相容,就用2005來做例子
linux使用者層串列埠操作
/* After the UART speed has been changed, the IOCTL is * is called to set the line discipline to N_HW_BFG */ ldisc = N_HW_BFG; /* 選擇線路規程 */ i
Android串列埠操作,簡化android-serialport-api的demo
感謝分享:http://lpcjrflsa.iteye.com/blog/2097280最近在做android串列埠的開發,找到一個開源的串列埠類android-serialport-api。其主頁在這裡http://code.google.com/p/android-ser
C# 串列埠操作系列(5)--通訊庫雛形
串列埠是很簡單的,編寫基於串列埠的程式也很容易。新手們除了要面對一堆的生僻概念,以及跨執行緒訪問的細節,還有一個需要跨越的難題,就是協議解析,上一篇已經說明了: 一個二進位制格式的協議一般包含: 協議頭 + 資料段長度 + 資料 + 校驗 一個Ascii格式的文字協議,一般
silverlight 操作串列埠資料的程式碼
串列埠PINVOKE程式碼,需要對超時時間進行設定,如果全為0,則是無限等待。而不是獲取不到退出。 public class SerialWrapper : IDisposable { #region Enum public enum
【C#】串列埠操作實用類
publicclass PortData { publicevent PortDataReceivedEventHandle Received; publicevent SerialErrorReceivedEventHandler Error; public