406 lines
9.6 KiB
PHP
406 lines
9.6 KiB
PHP
<?php
|
|
|
|
require_once(dirname(__FILE__) . "/../test_framework.php");
|
|
|
|
class PsuLabps3005d {
|
|
private $__componentName = "PsuLabps3005d";
|
|
private $__requestDelayUs = 80000; // We need some delay after every request because else the PSU will choke
|
|
private $name = "psu_Labps3005d";
|
|
private $debug = false;
|
|
private $__fd = null;
|
|
|
|
/* Hardware capability */
|
|
private $__capabilities = array(
|
|
"channels" => 1,
|
|
"v_min" => 0.00,
|
|
"v_max" => 30.00,
|
|
"i_min" => 0.00,
|
|
"i_max" => 5.00
|
|
);
|
|
|
|
private $__info = array (
|
|
"host" => "",
|
|
"port" => "",
|
|
"name" => "",
|
|
"model" => "",
|
|
"serial" => "",
|
|
"version" => ""
|
|
);
|
|
|
|
private $__channelsInfo = array (
|
|
array(
|
|
"id" => 1, // Channel ID
|
|
"enabled" => false, // Output enabled
|
|
"v" => 0.0, // Voltage
|
|
"v_inc" => 0.0, // Voltage increment step
|
|
"v_umin" => 0.0, // Voltage min (user limit)
|
|
"v_umax" => 0.0, // Current max (user limit)
|
|
"i" => 0.0, // Current
|
|
"i_inc" => 0.0, // Current increment step
|
|
"i_umin" => 0.0, // Current min (user limit)
|
|
"i_umax" => 0.0, // Current max (user limit)
|
|
),
|
|
array(
|
|
"id" => 2, // Channel ID
|
|
"enabled" => false, // Output enabled
|
|
"v" => 0.0, // Voltage
|
|
"v_inc" => 0.0, // Voltage increment step
|
|
"v_umin" => 0.0, // Voltage min (user limit)
|
|
"v_umax" => 0.0, // Voltage max (user limit)
|
|
"i" => 0.0, // Current
|
|
"i_max" => 0.0, // Current max
|
|
"i_inc" => 0.0, // Current increment step
|
|
"i_umin" => 0.0, // Current min (user limit)
|
|
"i_umax" => 0.0, // Current max (user limit)
|
|
)
|
|
);
|
|
|
|
private function debug($msg) {
|
|
if ($this->debug) {
|
|
$msg = str_replace("\r", '\r', $msg);
|
|
$msg = str_replace("\n", '\n', $msg);
|
|
DiTestMsg::dbg(trim($msg), $this->__componentName);
|
|
}
|
|
}
|
|
|
|
private function err($msg) {
|
|
DiTestMsg::err(trim($msg), $this->__componentName);
|
|
}
|
|
|
|
private function warn($msg) {
|
|
DiTestMsg::warn(trim($msg), $this->__componentName);
|
|
}
|
|
|
|
private function fail($msg) {
|
|
DiTestMsg::fail(trim($msg), $this->__componentName);
|
|
}
|
|
|
|
private function pass($msg) {
|
|
DiTestMsg::pass(trim($msg), $this->__componentName);
|
|
}
|
|
|
|
function __construct($port = "/dev/ttyACM0", $baud = 9600, $debug = false) {
|
|
$this->debug = $debug;
|
|
$this->__fd = dio_open($port, O_RDWR);
|
|
if ($this->__fd === FALSE) {
|
|
$this->fail("Error opening port");
|
|
} else {
|
|
dio_tcsetattr($this->__fd, ['baud' => $baud, 'bits' => 8, 'stop' => 1, 'parity' => 0]);
|
|
$this->setInfo("host", $port);
|
|
$this->setInfo("port", $baud);
|
|
|
|
$this->requestInfo();
|
|
|
|
$this->outputsOff();
|
|
$this->reset();
|
|
$this->resetLimits();
|
|
}
|
|
}
|
|
|
|
function __destruct() {
|
|
if ($this->__fd) {
|
|
$this->resetLimits();
|
|
$this->outputsOff();
|
|
$this->reset();
|
|
dio_close($this->__fd);
|
|
$this->__fd = null;
|
|
}
|
|
}
|
|
|
|
function setInfo($key, $value) {
|
|
$this->__info[$key] = $value;
|
|
}
|
|
|
|
function getInfo($key) {
|
|
return $this->__info[$key];
|
|
}
|
|
|
|
function getCapability($id) {
|
|
return $this->__capabilities[$id];
|
|
}
|
|
|
|
function setChannelInfo($channel, $key, $value) {
|
|
$channel = (int)$channel - 1;
|
|
$this->__channelsInfo[$channel][$key] = $value;
|
|
$this->debug("[setChannelInfo] channel: $channel, \"$key\" => \"$value\"");
|
|
}
|
|
|
|
function getChannelInfo($channel, $key) {
|
|
$channel = (int)$channel - 1;
|
|
$value = $this->__channelsInfo[(int)$channel][$key];
|
|
|
|
if ($key == "enabled") {
|
|
if ($value == true)
|
|
$value = "ON";
|
|
else
|
|
$value = "OFF";
|
|
}
|
|
|
|
$this->debug("[getChannelInfo] channel: $channel, \"$key\" => \"$value\"");
|
|
|
|
return $value;
|
|
}
|
|
|
|
private function reply() {
|
|
if ($this->__fd) {
|
|
$reply = dio_read($this->__fd, 1024);
|
|
$this->debug("[reply] \"$reply\"");
|
|
return $reply;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private function request($cmd) {
|
|
if ($this->__fd) {
|
|
$this->debug("[request] cmd: \"$cmd\"");
|
|
dio_write($this->__fd, "$cmd");
|
|
usleep(50 * 1000); // Wait a little here
|
|
}
|
|
}
|
|
|
|
private function requestInfo() {
|
|
$this->request("*IDN?");
|
|
$r = $this->reply();
|
|
$this->setInfo("serial", trim($r));
|
|
}
|
|
|
|
private function isValidChannel($channel) {
|
|
if ($channel > 0 && $channel <= 2)
|
|
return true;
|
|
|
|
$this->fail("Invalid channel $channel selected");
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Verify if requested channel voltage is within user and hardware limits
|
|
*/
|
|
private function isValidVoltage($channel, $voltage) {
|
|
// Check channel number
|
|
if (!($this->isValidChannel($channel)))
|
|
return false;
|
|
|
|
// User limit
|
|
$min = $this->getChannelInfo($channel, "v_umin");
|
|
$max = $this->getChannelInfo($channel, "v_umax");
|
|
|
|
if ($voltage >= $min && $voltage <= $max) {
|
|
$this->debug("valid voltage for channel: $channel, $voltage");
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
// Hardware limit
|
|
$min = $this->getCapability('v_min');
|
|
$max = $this->getCapability('v_max');
|
|
|
|
if($voltage >= $min && $voltage <= $max) {
|
|
$this->debug("invalid voltage for channel: $channel, $voltage");
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
$this->err("Voltage requested is invalid: $voltage >= $min (min), <= $max (max)");
|
|
return false;
|
|
}
|
|
|
|
/* @return true when OK, false otherwise */
|
|
public function setVoltage($channel, $value, $retries = 5, $timeout_ms = 100) {
|
|
$channel = (int)$channel;
|
|
$value = (float)$value;
|
|
if ($channel != 1)
|
|
return false;
|
|
|
|
if (!($this->isValidVoltage($channel, $value)))
|
|
return false;
|
|
|
|
$v = 0.00;
|
|
$this->request("VSET1:$value");
|
|
usleep($this->__requestDelayUs);
|
|
for ($i = 0; $i < $retries; $i++) {
|
|
$v = $this->getVoltage($channel);
|
|
if ($v == $value) {
|
|
$this->debug("[setVoltage] Requested voltage correctly set: \"$v\"");
|
|
return true;
|
|
}
|
|
|
|
$this->debug("[setVoltage] Verify try $i, volt: \"$v\"");
|
|
usleep(1000 * $timeout_ms);
|
|
}
|
|
|
|
$this->fail("[setVoltage] Requested voltage not correctly set to \"$value\": \"$v\"");
|
|
return false;
|
|
}
|
|
|
|
/* Set current for all outputs */
|
|
public function setVoltageAll($value) {
|
|
for ($i = 1; $i < 3; $i++) {
|
|
$this->setVoltage($i, $value);
|
|
}
|
|
}
|
|
|
|
public function getVoltage($channel) {
|
|
(int)$channel = $channel;
|
|
// TODO check channel
|
|
$this->request("VSET1?");
|
|
$v = $this->reply();
|
|
if (!empty($v)) {
|
|
$v = (float)$v;
|
|
$this->debug("[getVoltage] (channel: " . $channel . "): " . $v);
|
|
$this->setChannelInfo($channel, "v", $v);
|
|
return $v;
|
|
}
|
|
$this->fail("[getVoltage] Unexpected reply \"$v\"");
|
|
return 0;
|
|
}
|
|
|
|
public function incVoltage($channel, $verify = false) {
|
|
$channel = (int)$channel;
|
|
|
|
if (!($this->isValidChannel($channel)))
|
|
return;
|
|
|
|
// TODO check PSU voltage after increment...
|
|
|
|
if (!$verify)
|
|
$this->request("INCV".$channel);
|
|
else
|
|
$this->request("INCV".$channel."V");
|
|
|
|
usleep($this->__requestDelayUs);
|
|
$this->getVoltage($channel);
|
|
}
|
|
|
|
public function setMinVoltage($channel, $value) {
|
|
$this->setChannelInfo($channel, "v_umin", $value);
|
|
}
|
|
|
|
public function setMaxVoltage($channel, $value) {
|
|
$this->setChannelInfo($channel, "v_umax", $value);
|
|
}
|
|
|
|
public function getMinVoltage($channel) {
|
|
return $this->getChannelInfo($channel, "v_umin");
|
|
}
|
|
|
|
public function getMaxVoltage($channel) {
|
|
return $this->getChannelInfo($channel, "v_umax");
|
|
}
|
|
|
|
public function setCurrent($channel, $value) {
|
|
$channel = (int)$channel;
|
|
$value = (float)$value;
|
|
if ($channel == 1) {
|
|
$this->request("ISET1:$value");
|
|
$this->getCurrent($channel);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* Set current for all outputs */
|
|
public function setCurrentAll($value) {
|
|
for ($i = 1; $i < 3; $i++) {
|
|
$this->setCurrent($i, $value);
|
|
}
|
|
}
|
|
|
|
public function getCurrent($channel) {
|
|
(int)$channel = $channel;
|
|
if ($channel != 1)
|
|
return 0;
|
|
|
|
$this->request("ISET1?");
|
|
$c = $this->reply();
|
|
$this->debug("[getCurrent] reply: " . $c);
|
|
if (!empty($c)) {
|
|
$c = (float)$c;
|
|
$this->debug("[getCurrent] (channel: " . $channel . "):" . $c);
|
|
$this->setChannelInfo($channel, "i", $c);
|
|
return $c;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public function setMinCurrent($channel, $value) {
|
|
$this->setChannelInfo($channel, "i_umin", $value);
|
|
}
|
|
|
|
public function setMaxCurrent($channel, $value) {
|
|
$this->setChannelInfo($channel, "i_umax", $value);
|
|
}
|
|
|
|
public function getMinCurrent($channel) {
|
|
return $this->getChannelInfo($channel, "i_umin");
|
|
}
|
|
|
|
public function getMaxCurrent($channel) {
|
|
return $this->getChannelInfo($channel, "i_umax");
|
|
}
|
|
|
|
public function outputOn($channel) {
|
|
$channel = (int)$channel;
|
|
if ($channel == 1) {
|
|
$this->request("OUT1");
|
|
$this->setChannelInfo($channel, "enabled", true);
|
|
}
|
|
}
|
|
|
|
public function outputOff($channel) {
|
|
$channel = (int)$channel;
|
|
|
|
if ($channel == 1) {
|
|
$this->request("OUT0");
|
|
$this->setChannelInfo($channel, "enabled", false);
|
|
}
|
|
}
|
|
|
|
/* Enable all outputs */
|
|
public function outputsOn() {
|
|
$this->outputOn(1);
|
|
}
|
|
|
|
/* Disable all outputs */
|
|
public function outputsOff() {
|
|
$this->outputOff(1);
|
|
}
|
|
|
|
/** Disable all outputs, set all voltage and current to zero */
|
|
public function reset() {
|
|
$this->outputsOff();
|
|
$this->resetLimits();
|
|
|
|
for ($i = 1; $i < 3; $i++) {
|
|
$this->setVoltage($i, 0.00);
|
|
$this->setCurrent($i, 0.00);
|
|
}
|
|
}
|
|
|
|
public function resetLimits() {
|
|
for ($i = 1; $i < 3; $i++) {
|
|
$this->setMinVoltage($i, $this->getCapability("v_min"));
|
|
$this->setMaxVoltage($i, $this->getCapability("v_max"));
|
|
$this->setMinCurrent($i, $this->getCapability("i_min"));
|
|
$this->setMaxCurrent($i, $this->getCapability("i_max"));
|
|
}
|
|
}
|
|
|
|
public function info() {
|
|
$info = sprintf(
|
|
"===
|
|
PSU Labps3005d Status
|
|
> Device: %s Baud: %d
|
|
> Serial: %s Version: %s
|
|
> Channel 1: [%s] %.02f V %.02f I
|
|
===\n",
|
|
$this->getInfo("host"), $this->getInfo("port"),
|
|
$this->getInfo("serial"), $this->getInfo("version"),
|
|
$this->getChannelInfo(1, "enabled"),
|
|
$this->getChannelInfo(1, "v"), $this->getChannelInfo(1, "i")
|
|
);
|
|
return $info;
|
|
}
|
|
}
|