新增 pELoad 电子负载(IT6000C)控制程序:以太网 Raw Socket SCPI 直连设备,100ms 周期功率控制(订阅 MOOS 功率消息按 P/U 折算电流,CC/CV 双环路优先 + FUNC:MODE FIX 防护),网页人机交互(步骤引导/防误触确认),sqlite3 存储(100ms 高采样 V/I/P 测量表 meas_log + CSV 导出分析),并接入 scripts/build-board.sh 板卡部署与 systemd 服务、missions/h100.moos 配置

This commit is contained in:
zjk
2026-09-03 12:26:02 +08:00
parent 38c489caec
commit 2a34b79461
21 changed files with 3601 additions and 5 deletions
+121
View File
@@ -0,0 +1,121 @@
#include "IT6000C.h"
#include <cstdio>
#include <cstdlib>
namespace eload {
//============================================================================
// 基础
//============================================================================
bool IT6000C::identify(std::string& idn) {
return m_scpi.query("*IDN?", idn, 300);
}
bool IT6000C::remote() {
// 连接建立后必须先进入远控,否则设置命令被面板本地态拒绝
return m_scpi.cmd("SYST:REM");
}
bool IT6000C::local() {
return m_scpi.cmd("SYST:LOC");
}
bool IT6000C::reset() {
return m_scpi.cmd("*RST");
}
bool IT6000C::clearStatus() {
return m_scpi.cmd("*CLS");
}
bool IT6000C::opComplete() {
std::string r;
return m_scpi.query("*OPC?", r, 300);
}
bool IT6000C::nextError(std::string& err) {
return m_scpi.query("SYST:ERR?", err, 200);
}
//============================================================================
// 输出
//============================================================================
bool IT6000C::output(bool on) {
return m_scpi.cmd(on ? "OUTP 1" : "OUTP 0");
}
bool IT6000C::queryOutput(bool& on) {
std::string r;
if (!m_scpi.query("OUTP?", r, 200)) return false;
on = (r.find("1") != std::string::npos);
return true;
}
bool IT6000C::clearProtection() {
return m_scpi.cmd("OUTP:PROT:CLE");
}
//============================================================================
// 工作模式
//============================================================================
bool IT6000C::setFunctionCC() {
return m_scpi.cmd("FUNC CURR");
}
bool IT6000C::setFunctionCV() {
return m_scpi.cmd("FUNC VOLT");
}
bool IT6000C::queryFunction(std::string& func) {
return m_scpi.query("FUNC?", func, 200);
}
bool IT6000C::setFunctionModeFixed() {
return m_scpi.cmd("FUNC:MODE FIX");
}
bool IT6000C::queryFunctionMode(std::string& mode) {
return m_scpi.query("FUNC:MODE?", mode, 200);
}
//============================================================================
// 设定值
//============================================================================
bool IT6000C::setDouble(const char* scpi, double v) {
char buf[64];
std::snprintf(buf, sizeof(buf), "%s %.6f", scpi, v);
return m_scpi.cmd(buf);
}
bool IT6000C::setCurrent(double amp) { return setDouble("CURR", amp); }
bool IT6000C::setVoltage(double volt) { return setDouble("VOLT", volt); }
bool IT6000C::setVoltageLimit(double volt){ return setDouble("VOLT:LIM", volt); }
bool IT6000C::setCurrentLimitPos(double amp) { return setDouble("CURR:LIM", amp); }
bool IT6000C::setCurrentLimitNeg(double amp) { return setDouble("CURR:LIM:NEG", amp); }
bool IT6000C::setPowerLimitPos(double watt) { return setDouble("POW:LIM", watt); }
bool IT6000C::setPowerLimitNeg(double watt) { return setDouble("POW:LIM:NEG", watt); }
//============================================================================
// 测量
//============================================================================
bool IT6000C::queryDouble(const char* scpi, double& v) {
std::string r;
if (!m_scpi.query(scpi, r, 150)) return false;
if (r.empty()) return false;
char* end = nullptr;
double d = std::strtod(r.c_str(), &end);
if (end == r.c_str()) return false;
v = d;
return true;
}
bool IT6000C::measureVoltage(double& v) { return queryDouble("MEAS:VOLT?", v); }
bool IT6000C::measureCurrent(double& i) { return queryDouble("MEAS:CURR?", i); }
bool IT6000C::measurePower(double& p) { return queryDouble("MEAS:POW?", p); }
} // namespace eload