Skip to content
Snippets Groups Projects
Commit fefab74e authored by Elisabetta Pianori's avatar Elisabetta Pianori
Browse files

Merge branch 'kk_rampTo' into 'devel'

Add ramp of voltage/current to power supply.

See merge request berkeleylab/labRemote!178
parents 23051e20 ed688e7a
Branches
Tags
No related merge requests found
#include "IPowerSupply.h"
#include <chrono>
#include <iostream>
#include <stdexcept>
#include <thread>
#include "Logger.h"
IPowerSupply::IPowerSupply(const std::string& name, std::vector<std::string> models)
......@@ -75,6 +78,27 @@ bool IPowerSupply::isOn(unsigned channel)
return false;
}
void IPowerSupply::rampCurrentLevel(double curr, double rate, unsigned channel)
{
if(rate<0)
throw std::runtime_error("rampCurrentLevel: ramp rate must be positive");
// Get starting point and direction
double currentCurrent=measureCurrent(channel);
double dir=(currentCurrent<curr)?+1:-1; // Direction of ramp
// Ramp until you get as close as possible to desired current with
// discrete `ramp` steps
uint32_t nsteps=std::floor(std::fabs(curr-currentCurrent)/rate);
for(uint32_t i=1;i<nsteps;i++)
{
setCurrentLevel(currentCurrent+i*dir*rate, channel);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// Set final current. The final step size should be less than rate
setCurrentLevel(curr,channel);
}
void IPowerSupply::setCurrentProtect(double cur, unsigned channel)
{
logger(logWARNING) << "setCurrentProtect() not implemented for this PS.";
......@@ -86,6 +110,27 @@ double IPowerSupply::getCurrentProtect(unsigned channel)
return 0;
}
void IPowerSupply::rampVoltageLevel(double volt, double rate, unsigned channel)
{
if(rate<0)
throw std::runtime_error("rampVoltageLevel: ramp rate must be positive");
// Get starting point and direction
double currentVoltage=measureVoltage(channel);
double dir=(currentVoltage<volt)?+1:-1; // Direction of ramp
// Ramp until you get as close as possible to desired voltage with
// discrete `ramp` steps
uint32_t nsteps=std::floor(std::fabs(volt-currentVoltage)/rate);
for(uint32_t i=1;i<nsteps;i++)
{
setVoltageLevel(currentVoltage+i*dir*rate, channel);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// Set final voltage. The final step size should be less than rate
setVoltageLevel(volt, channel);
}
void IPowerSupply::setVoltageProtect(double volt, unsigned channel)
{
logger(logWARNING) << "setVoltageProtect() not implemented for this PS.";
......
......@@ -134,6 +134,18 @@ public:
* @{
*/
/** \brief Ramp current of PS
*
* Slowly changes the current level every second in discrete
* `rate` steps until `cur` is reached. The number of steps
* is determined by initial current measurement.
*
* @param cur current [A]
* @param rate absolute rate of current change [A/s]
* @param channel channel (if any)
*/
virtual void rampCurrentLevel(double cur, double rate, unsigned channel = 0 );
/** \brief Set current of PS
* @param cur current [A]
* @param channel channel (if any)
......@@ -168,6 +180,18 @@ public:
/** \name Voltage Control and Measurement
* @{
*/
/** \brief Ramp voltage of PS
*
* Slowly changes the voltage level every second in discrete
* `rate` steps until `volt` is reached. The number of steps
* is determined by initial voltage measurement.
*
* @param volt taget voltage [V]
* @param rate absolute rate of voltage change [V/s]
* @param channel channel (if any)
*/
virtual void rampVoltageLevel(double cur, double rate, unsigned channel = 0);
/** \brief Set voltage of PS
* @param volt voltage [V]
......
......@@ -56,6 +56,9 @@ void PowerSupplyChannel::turnOff()
bool PowerSupplyChannel::isOn()
{ return m_ps->isOn(m_channel); }
void PowerSupplyChannel::rampCurrentLevel(double cur, double rate)
{ m_ps->rampCurrentLevel(cur, rate, m_channel); }
void PowerSupplyChannel::setCurrentLevel(double cur)
{ m_ps->setCurrentLevel(cur, m_channel); }
......@@ -70,6 +73,9 @@ double PowerSupplyChannel::getCurrentProtect()
double PowerSupplyChannel::measureCurrent()
{ return m_ps->measureCurrent(m_channel); }
void PowerSupplyChannel::rampVoltageLevel(double volt, double rate)
{ m_ps->rampVoltageLevel(volt, rate, m_channel); }
void PowerSupplyChannel::setVoltageLevel(double volt)
{ m_ps->setVoltageLevel(volt, m_channel); }
......
......@@ -80,6 +80,17 @@ public:
* @{
*/
/** \brief Ramp current of PS
*
* Slowly changes the current level via every second at `rate`
* until `cur` is reached. The number of steps is determined
* by initial current measurement.
*
* @param cur current [A]
* @param rate absolute rate of current change [A/s]
*/
void rampCurrentLevel(double cur, double rate);
/** Set current of PS
* @param cur current [A]
*/
......@@ -111,6 +122,17 @@ public:
* @{
*/
/** \brief Ramp voltage of PS
*
* Slowly changes the voltage level via every second at `rate`
* until `volt` is reached. The number of steps is determined
* by initial voltage measurement.
*
* @param volt voltage [V]
* @param rate absolute rate of voltage change [V/s]
*/
void rampVoltageLevel(double volt, double rate);
/** Set voltage of PS
* @param volt voltage [V]
*/
......@@ -121,8 +143,8 @@ public:
*/
double getVoltageLevel();
/** Set current protection [optional]
* @param volt maximum current [A]
/** Set voltage protection [optional]
* @param volt maximum voltage [V]
*/
void setVoltageProtect(double volt);
......
......@@ -115,6 +115,16 @@ public:
channel
);
}
void rampCurrentLevel(double cur, double rate, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
IPowerSupply,
rampCurrentLevel,
cur,
rate,
channel
);
}
void setCurrentLevel(double cur, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
......@@ -157,6 +167,16 @@ public:
channel
);
}
void rampVoltageLevel(double volt, double rate, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
IPowerSupply,
rampVoltageLevel,
volt,
rate,
channel
);
}
void setVoltageLevel(double volt, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
......@@ -245,6 +265,16 @@ public:
channel
);
}
void rampCurrentLevel(double cur, double rate, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
IPowerSupply,
rampCurrentLevel,
cur,
rate,
channel
);
}
void setCurrentLevel(double cur, unsigned channel = 0) override {
PYBIND11_OVERLOAD(
void,
......@@ -287,6 +317,16 @@ public:
channel
);
}
void rampVoltageLevel(double volt, double rate, unsigned channel = 0) override {
PYBIND11_OVERLOAD_PURE(
void,
IPowerSupply,
rampVoltageLevel,
volt,
rate,
channel
);
}
void setVoltageLevel(double volt, unsigned channel = 0) override {
PYBIND11_OVERLOAD(
void,
......@@ -352,6 +392,8 @@ void register_ps(py::module& m){
.def("turnOffAll", &IPowerSupply::turnOffAll)
.def("isOn", &IPowerSupply::isOn,
py::arg("channel") = 0)
.def("rampCurrentLevel", &IPowerSupply::rampCurrentLevel,
py::arg("current"), py::arg("rate"), py::arg("channel") = 0)
.def("setCurrentLevel", &IPowerSupply::setCurrentLevel,
py::arg("current"), py::arg("channel") = 0)
.def("getCurrentLevel", &IPowerSupply::getCurrentLevel,
......@@ -362,6 +404,8 @@ void register_ps(py::module& m){
py::arg("channel") = 0)
.def("measureCurrent", &IPowerSupply::measureCurrent,
py::arg("channel") = 0)
.def("rampVoltageLevel", &IPowerSupply::rampVoltageLevel,
py::arg("voltage"), py::arg("rate"), py::arg("channel") = 0)
.def("setVoltageLevel", &IPowerSupply::setVoltageLevel,
py::arg("voltage"), py::arg("channel") = 0)
.def("getVoltageLevel", &IPowerSupply::getVoltageLevel,
......@@ -478,10 +522,12 @@ void register_ps(py::module& m){
.def("turnOn", &PowerSupplyChannel::turnOn)
.def("turnOff", &PowerSupplyChannel::turnOff)
.def("isOn", &PowerSupplyChannel::isOn)
.def("rampCurrentLevel", &PowerSupplyChannel::rampCurrentLevel)
.def("setCurrentLevel", &PowerSupplyChannel::setCurrentLevel)
.def("getCurrentLevel", &PowerSupplyChannel::getCurrentLevel)
.def("setCurrentProtect", &PowerSupplyChannel::setCurrentProtect)
.def("measureCurrent", &PowerSupplyChannel::measureCurrent)
.def("rampVoltageLevel", &PowerSupplyChannel::rampVoltageLevel)
.def("setVoltageLevel", &PowerSupplyChannel::setVoltageLevel)
.def("getVoltageLevel", &PowerSupplyChannel::getVoltageLevel)
.def("setVoltageProtect", &PowerSupplyChannel::setVoltageProtect)
......
......@@ -4,6 +4,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <chrono>
#include <iostream>
#include <string>
#include <vector>
......@@ -30,15 +31,17 @@ void usage(char *argv[])
{
std::cerr << "Usage: " << argv[0] << " [options] command [parameters]" << std::endl;
std::cerr << "List of possible COMMAND:" << std::endl;
std::cerr << " set-current -- I [V] Set current I [A] with maximum voltage V [V]" << std::endl;
std::cerr << " get-current Get set current level [A]" << std::endl;
std::cerr << " meas-current Get reading of current [A]" << std::endl;
std::cerr << " set-voltage -- V [I] Set voltage V [V] with maximum current I [A]" << std::endl;
std::cerr << " get-voltage Get set voltage level [V]" << std::endl;
std::cerr << " meas-voltage Get reading of voltage [V]" << std::endl;
std::cerr << " program [on] Execute the program block and optionally turn on the power supply" << std::endl;
std::cerr << " power-on [V I] Power ON PS, optionally setting voltage to V in Volts and current to I in Ampere" << std::endl;
std::cerr << " power-off Power OFF PS" << std::endl;
std::cerr << " set-current -- I [V] Set current I [A] with maximum voltage V [V]" << std::endl;
std::cerr << " ramp-current -- I rate Ramp voltage I [A] at rate [A/s]" << std::endl;
std::cerr << " get-current Get set current level [A]" << std::endl;
std::cerr << " meas-current Get reading of current [A]" << std::endl;
std::cerr << " set-voltage -- V [I] Set voltage V [V] with maximum current I [A]" << std::endl;
std::cerr << " ramp-voltage -- V rate Ramp voltage V [V] at rate [V/s]" << std::endl;
std::cerr << " get-voltage Get set voltage level [V]" << std::endl;
std::cerr << " meas-voltage Get reading of voltage [V]" << std::endl;
std::cerr << " program [on] Execute the program block and optionally turn on the power supply" << std::endl;
std::cerr << " power-on [V I] Power ON PS, optionally setting voltage to V in Volts and current to I in Ampere" << std::endl;
std::cerr << " power-off Power OFF PS" << std::endl;
std::cerr << std::endl;
std::cerr << "List of options:" << std::endl;
std::cerr << " -n, --name PS Name of the power supply from equipment list (default: " << name << ")" << std::endl;
......@@ -186,6 +189,18 @@ int main(int argc, char*argv[])
PS->setVoltageProtect(std::stod(params[1]));
}
}
else if (command == "ramp-current")
{
if (params.size() != 2)
{
logger(logERROR) << "Invalid number of parameters to ramp-current command.";
logger(logERROR) << "";
usage(argv);
return 1;
}
logger(logDEBUG) << "Ramp current to "<< params[0] << " A at rate " << params[1] << " A/s";
PS->rampCurrentLevel(std::stod(params[0]), std::stod(params[1]));
}
else if (command == "get-current")
{
if (logIt::loglevel >= logDEBUG) std::cout << "Current: ";
......@@ -217,6 +232,18 @@ int main(int argc, char*argv[])
PS->setCurrentProtect(std::stod(params[1]));
}
}
else if (command == "ramp-voltage")
{
if (params.size() != 2)
{
logger(logERROR) << "Invalid number of parameters to ramp-voltage command.";
logger(logERROR) << "";
usage(argv);
return 1;
}
logger(logDEBUG) << "Ramp voltage to "<< params[0] << " V at rate " << params[1] << " V/s";
PS->rampVoltageLevel(std::stod(params[0]), std::stod(params[1]));
}
else if (command == "get-voltage")
{
if (logIt::loglevel >= logDEBUG) std::cout << "Voltage: ";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment