Skip to content
Snippets Groups Projects
Commit 7d539d53 authored by Simon Florian Koch's avatar Simon Florian Koch Committed by Elisabetta Pianori
Browse files

Add rigol dm3000 scope

parent e2f1ff8a
Branches
Tags
2 merge requests!316Merge devel into main,!315Add rigol dm3000 scope
...@@ -10,6 +10,7 @@ target_sources(Meter ...@@ -10,6 +10,7 @@ target_sources(Meter
PM6680.cpp PM6680.cpp
DMM6500.cpp DMM6500.cpp
KeysightDAQ970A.cpp KeysightDAQ970A.cpp
RigolDM30XX.cpp
) )
target_link_libraries(Meter PRIVATE Com Utils) target_link_libraries(Meter PRIVATE Com Utils)
target_include_directories(Meter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(Meter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
......
#include "RigolDM30XX.h"
#include "IMeter.h"
#include "Logger.h"
#include "MeterRegistry.h"
#include "ScopeLock.h"
#include "StringUtils.h"
REGISTER_METER(RigolDM30XX)
RigolDM30XX::RigolDM30XX(const std::string& name)
: IMeter(name, {"DM3058", "DM3058E", "DM3068"}) {}
bool RigolDM30XX::ping(unsigned /*dev*/) {
std::string result = "";
logger(logDEBUG) << "ping the multimeter.....";
result = m_com->sendreceive("*IDN?");
utils::rtrim(result);
if (result.empty()) {
throw std::runtime_error("Failed communication with the device");
} else {
logger(logDEBUG) << result;
}
return !result.empty();
}
std::string RigolDM30XX::identify() {
std::string idn = m_com->sendreceive("*IDN?");
return idn;
}
void RigolDM30XX::autowait() {
m_com->send("*OPC");
int ESRValue = 0;
while ((ESRValue & 1) == 0) {
ESRValue = std::stoi(m_com->sendreceive("*ESR?"));
std::this_thread::sleep_for(std::chrono::milliseconds(m_wait));
}
}
void RigolDM30XX::send(const std::string& cmd) {
logger(logDEBUG) << __PRETTY_FUNCTION__ << " -> Sending: " << cmd;
m_com->send("*CLS");
m_com->send(cmd);
this->autowait();
}
std::string RigolDM30XX::sendreceive(const std::string& cmd) {
m_com->send("*CLS");
std::string buf = m_com->sendreceive(cmd);
this->autowait();
logger(logDEBUG) << __PRETTY_FUNCTION__ << " -> Received: " << buf;
utils::rtrim(buf);
return buf;
}
void RigolDM30XX::reset() {
logger(logDEBUG) << __PRETTY_FUNCTION__ << " -> Initialising: ";
this->send("*RST");
}
// measure DC voltage with high precision
// take average of 10 repeatings
double RigolDM30XX::measureDCV(unsigned channel) {
ScopeLock lock(m_com);
return std::stod(this->sendreceive(":MEAS:VOLT:DC?"));
}
// measure resistance (2W or 4W)
// take average of 10 repeatings
double RigolDM30XX::measureRES(unsigned channel, bool use4w) {
std::string n_func = "RES";
if (use4w) n_func = "FRES";
ScopeLock lock(m_com);
return std::stod(this->sendreceive(":MEAS:" + n_func + "?"));
}
// measure DC current with high precision
// take average of 10 repeatings
double RigolDM30XX::measureDCI(unsigned channel) {
ScopeLock lock(m_com);
return std::stod(this->sendreceive(":MEAS:CURR:DC?"));
}
#ifndef RigolDM30XX_H
#define RigolDM30XX_H
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include "IMeter.h"
/*
RigolDM30XX single-channel multimeter
Author: Simon Koch
Date: Feb 2024
Reference 1 (User Guide, DM3068):
https://www.rigol-uk.co.uk/pdf/Rigol-DM3068-User-Guide.pdf
Reference 2 (Programmers Guide, DM3058/3058E/3068):
https://beyondmeasure.rigoltech.com/acton/attachment/1579/f-003f/0/-/-/-/-/file.pdf
Based on implementation of Keithley2000
- channel argument included only for compatibility with IMeter interface
*/
class RigolDM30XX : public IMeter {
public:
RigolDM30XX(const std::string& name);
/** ping the device
*/
virtual bool ping(unsigned dev = 0);
virtual std::string identify();
virtual void reset();
/** measure DC voltage (unit: V)
*/
virtual double measureDCV(unsigned channel = 0);
/** measure DC current (unit: A)
*/
virtual double measureDCI(unsigned channel = 0);
/* measure resistance (unit: Ohm)
*/
virtual double measureRES(unsigned channel = 0, bool use4w = false);
private:
void send(const std::string& cmd);
std::string sendreceive(const std::string& cmd);
void autowait();
std::chrono::milliseconds m_wait{10};
};
#endif
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "IMeter.h" #include "IMeter.h"
#include "Keithley2000.h" #include "Keithley2000.h"
#include "KeysightDAQ970A.h" #include "KeysightDAQ970A.h"
#include "RigolDM30XX.h"
namespace py = pybind11; namespace py = pybind11;
...@@ -152,6 +153,20 @@ void register_meter(py::module& m) { ...@@ -152,6 +153,20 @@ void register_meter(py::module& m) {
const std::vector<unsigned>&, bool)>( const std::vector<unsigned>&, bool)>(
&Keithley2000::measureRES)); &Keithley2000::measureRES));
// RigolDM30XX
py::class_<RigolDM30XX, IMeter, std::shared_ptr<RigolDM30XX>>(m,
"RigolDM30XX")
.def(py::init<const std::string&>())
.def("ping", &RigolDM30XX::ping)
.def("identify", &RigolDM30XX::identify)
.def("reset", &RigolDM30XX::reset)
.def("measureDCV", static_cast<double (RigolDM30XX::*)(unsigned)>(
&RigolDM30XX::measureDCV))
.def("measureDCI", static_cast<double (RigolDM30XX::*)(unsigned)>(
&RigolDM30XX::measureDCI))
.def("measureRES", static_cast<double (RigolDM30XX::*)(unsigned, bool)>(
&RigolDM30XX::measureRES));
// KeysightDAQ970A // KeysightDAQ970A
py::class_<KeysightDAQ970A, IMeter, std::shared_ptr<KeysightDAQ970A>> py::class_<KeysightDAQ970A, IMeter, std::shared_ptr<KeysightDAQ970A>>
daq970a(m, "KeysightDAQ970A"); daq970a(m, "KeysightDAQ970A");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment