本文目录导读:

在 PHP 中控制 USB 继电器,主要有以下几种方法,根据你的硬件类型(HID 或串口)和操作系统,选择合适的方法:
使用 HID 库(推荐,跨平台)
大多数 USB 继电器是 HID 设备,无需额外驱动。
安装依赖
composer require phpHid/hid # 或使用 hidapi
示例代码
<?php
require 'vendor/autoload.php';
use PHPDID\HIDDevice;
// 查找继电器设备
$device = HIDDevice::find(vendorId: 0x16C0, productId: 0x05DF);
if ($device) {
// 打开继电器通道1
$data = [0x00, 0x01, 0x01, 0x00]; // 根据继电器型号调整
$device->sendFeatureReport($data);
// 关闭继电器
$data = [0x00, 0x01, 0x00, 0x00];
$device->sendFeatureReport($data);
$device->close();
}
?>
使用串口通信(FTDI/CDC 类型)
如果继电器模拟的是串口设备:
<?php
class USBRelay {
private $serialPort;
public function __construct($port = '/dev/ttyUSB0') {
$this->serialPort = $port;
}
public function sendCommand($command) {
$handle = fopen($this->serialPort, 'w');
if (!$handle) {
throw new Exception("无法打开端口");
}
fwrite($handle, $command);
fclose($handle);
}
// 控制继电器(根据厂商协议修改)
public function controlRelay($channel, $state) {
// 发送 A0 0F 01 01(打开)或 A0 0F 01 00(关闭)
$cmd = sprintf("A0 0F %02X %02X", $channel-1, $state);
$this->sendCommand($cmd);
}
}
?>
使用通用 USB 通信库
通过 libusb(PHP 扩展)
<?php
// 使用 php-usb 扩展(需要编译)
$usb = new USB();
$device = $usb->openDevice(0x16C0, 0x05DF); // 根据你的设备 VID/PID
if ($device) {
// 发送控制传输
$result = $usb->controlTransfer(
0x40, // Request Type
0x01, // Request
$state, // Value
$channel, // Index
$data // Data
);
$usb->closeDevice($device);
}
?>
通过 Shell 命令调用(最实用)
如果没有现成库,可以调用系统命令:
<?php
class USBRelayCLI {
public function controlRelay($relayNumber, $state) {
// 使用 hidapi 命令行工具
$cmd = sprintf(
'hidapi -v 0x16c0 -p 0x05df --send 0x00,%02d,%02d,0x00',
$relayNumber,
$state
);
exec($cmd, $output, $returnCode);
return $returnCode === 0;
}
}
$relay = new USBRelayCLI();
$relay->controlRelay(1, 1); // 打开继电器1
?>
使用 Python 桥接(临时方案)
<?php
$relayState = 1;
exec("python3 /path/to/relay_control.py --relay 1 --state $relayState");
?>
python 脚本:
import hid
import sys
import argparse
def control_relay(relay_num, state):
device = hid.device()
device.open(0x16C0, 0x05DF) # 你的设备 VID/PID
# 根据你的继电器协议调整
data = [0x00, relay_num, state, 0x00]
device.write(data)
device.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--relay", type=int, required=True)
parser.add_argument("--state", type=int, required=True)
args = parser.parse_args()
control_relay(args.relay, args.state)
关键注意事项
获取设备信息
<?php
// 先找到你的设备 VID/PID
exec('lsusb', $output);
print_r($output); // 查看设备信息
?>
权限设置
# Linux 下创建 udev 规则
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="05df", MODE="0666"' > /etc/udev/rules.d/99-usb-relay.rules
完整示例封装
<?php
class USBRelayController {
private $vendorId;
private $productId;
private $relayCount;
public function __construct($vendorId = 0x16C0, $productId = 0x05DF) {
$this->vendorId = $vendorId;
$this->productId = $productId;
}
public function turnOn($relayNum) {
return $this->sendControl($relayNum, 'ON');
}
public function turnOff($relayNum) {
return $this->sendControl($relayNum, 'OFF');
}
private function sendControl($relayNum, $state) {
// 方法1: 使用 exec + python
$stateCode = ($state === 'ON') ? 1 : 0;
exec("python3 relay_control.py $relayNum $stateCode", $output, $code);
// 方法2: 使用 PHP 串口
// $this->writeToSerial($relayNum, $stateCode);
return $code === 0;
}
private function writeToSerial($relayNum, $state) {
$fp = fopen("/dev/ttyUSB0", "w");
if (!$fp) return false;
// 根据具体协议发送命令
$cmd = chr(255).chr(0).chr($relayNum).chr($state);
fwrite($fp, $cmd);
fclose($fp);
return true;
}
}
// 使用示例
try {
$relay = new USBRelayController();
if ($relay->turnOn(1)) {
echo "继电器1已打开";
}
sleep(2);
if ($relay->turnOff(1)) {
echo "继电器1已关闭";
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
?>
建议
- 首选方法:HID API(最简单,无需驱动)
- 最实用:通过 shell 命令调用(兼容性最好)
- 高性能场景:使用 libusb 绑定或 C 扩展
需要我帮你针对特定的 USB 继电器型号编写具体代码吗?请提供你的设备型号和 VID/PID。