PHP 怎么USB继电器

wen PHP项目 2

本文目录导读:

PHP 怎么USB继电器

  1. 使用 HID 库(推荐,跨平台)
  2. 使用串口通信(FTDI/CDC 类型)
  3. 使用通用 USB 通信库
  4. 通过 Shell 命令调用(最实用)
  5. 使用 Python 桥接(临时方案)
  6. 关键注意事项
  7. 建议

在 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();
}
?>

建议

  1. 首选方法:HID API(最简单,无需驱动)
  2. 最实用:通过 shell 命令调用(兼容性最好)
  3. 高性能场景:使用 libusb 绑定或 C 扩展

需要我帮你针对特定的 USB 继电器型号编写具体代码吗?请提供你的设备型号和 VID/PID。

抱歉,评论功能暂时关闭!