Skip to content

Commit

Permalink
Merge pull request #19 from UniStuttgart-VISUS/rtx
Browse files Browse the repository at this point in the history
Sensor based on RTA/RTB oscilloscopes
  • Loading branch information
crowbar27 authored Jul 21, 2023
2 parents 6bf59e7 + 3c6166c commit cf2452b
Show file tree
Hide file tree
Showing 55 changed files with 7,045 additions and 3,957 deletions.
8 changes: 4 additions & 4 deletions podump/podump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
int _tmain(const int argc, const TCHAR **argv) {
#if (defined(DEBUG) || defined(_DEBUG))
::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//::_CrtSetBreakAlloc(327);
//::_CrtSetBreakAlloc(420);
#endif /* (defined(DEBUG) || defined(_DEBUG)) */

#if false
Expand Down Expand Up @@ -114,15 +114,15 @@ int _tmain(const int argc, const TCHAR **argv) {

// Rohde & Schwarz sensors
#if true
#if false
#if true
::query_hmc8015();
#endif

#if true
#if false
::query_rtx_instrument();
#endif

#if true
#if false
::query_rtx();
#endif
#endif
Expand Down
300 changes: 223 additions & 77 deletions podump/rohde_und_schwarz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,52 +64,62 @@ void query_hmc8015(void) {
* ::query_rtx
*/
void query_rtx(void) {
//using namespace visus::power_overwhelming;

//try {
// std::vector<oscilloscope_sensor_definition> definitions;
// std::vector<rtx_sensor> sensors;
// sensors.resize(rtx_sensor::for_all(nullptr, 0));
// rtx_sensor::for_all(sensors.data(), sensors.size());

// definitions.push_back(oscilloscope_sensor_definition(L"Test1",
// 1, 10.0f, 2, 10.0f));

// // TODO: this is incomplete.

// for (auto& s : sensors) {
// s.reset();
// s.synchronise_clock();
// s.reference_position(oscilloscope_reference_point::middle);
// s.time_range(oscilloscope_quantity(500, "ms"));

// s.configure(definitions.data(), definitions.size());

// s.configure(oscilloscope_channel(1)
// .label(oscilloscope_label("PwrOwg"))
// .state(true)
// .gain(oscilloscope_quantity(10, "V"))
// .range(oscilloscope_quantity(7, L"V")));

// s.configure(oscilloscope_single_acquisition()
// .points(50000)
// .count(1));

// s.trigger_position(42.42f, "ms");
// s.trigger(oscilloscope_edge_trigger("CH1")
// .level(1, oscilloscope_quantity(2000.0f, "mV"))
// .slope(oscilloscope_trigger_slope::both)
// .mode(oscilloscope_trigger_mode::normal));

// auto data = s.data(1);

// //s.expression(1, "CH1*CH2", "W");
// std::wcout << s.name() << L":" << std::endl;
// }
//
//} catch (std::exception& ex) {
// std::cerr << ex.what() << std::endl;
//}
using namespace visus::power_overwhelming;

try {
std::vector<rtx_sensor_definition> definitions;
definitions.resize(rtx_sensor::get_definitions(nullptr, 0));
definitions.resize(rtx_sensor::get_definitions(definitions.data(), definitions.size()));

std::cout << "Sensor definitions found:" << std::endl;
for (auto& d : definitions) {
std::wcout << d.description() << std::endl;
}

std::vector<rtx_sensor> sensors(definitions.size());
for (std::size_t i = 0; i < definitions.size(); ++i) {
sensors[i] = rtx_sensor(definitions[i]);
std::wcout << L"Created " << sensors[i].name() << std::endl;
}
} catch (std::exception& ex) {
std::cerr << ex.what() << std::endl;
}

try {
std::vector<rtx_sensor> sensors;
sensors.resize(rtx_sensor::for_all(nullptr, 0));
rtx_sensor::for_all(sensors.data(), sensors.size());

for (auto& s : sensors) {
std::wcout << L"Enumerated " << s.name() << std::endl;
}

for (auto& s : sensors) {
auto waveform = s.acquire(timestamp_resolution::hundred_nanoseconds);
std::wcout << L"Acquired " << waveform.size()
<< " samples from " << waveform.sensor()
<< std::endl;

for (std::size_t i = 0; (i < 8) && (i < waveform.size()); ++i) {
auto& s = waveform.sample(i);
std::wcout << s.timestamp() << L": "
<< s.voltage() << L"V, "
<< s.current() << L"A, "
<< s.power() << L"W"
<< std::endl;
}

auto sample = s.sample(timestamp_resolution::hundred_nanoseconds);
std::wcout << sample.sensor() << L"@"
<< sample.timestamp() << L": "
<< sample.voltage() << L"V, "
<< sample.current() << L"A, "
<< sample.power() << L"W"
<< std::endl;
}
} catch (std::exception& ex) {
std::cerr << ex.what() << std::endl;
}
}


Expand All @@ -125,60 +135,196 @@ void query_rtx_instrument(void) {
for (auto d = devices.as<wchar_t>();
(d != nullptr) && (*d != 0);
d += ::wcslen(d) + 1) {
rtx_instrument i(d);

i.clear();
i.clear_status();
i.reset();
i.synchronise_clock();
i.timeout(5000);

i.reference_position(oscilloscope_reference_point::middle);
i.time_range(oscilloscope_quantity(500, "ms"));
auto is_new = false;
rtx_instrument i(is_new, d);

if (is_new) {
std::wcout << L"Connected to new instrument." << std::endl;
} else {
std::wcout << L"Reused existing connection." << std::endl;
}

visa_instrument::foreach_instance([](visa_instrument& i, void *) {
blob name(i.identify(nullptr, 0) * sizeof(wchar_t));
i.identify(name.as<wchar_t>(), name.size() / sizeof(wchar_t));
std::wcout << L"\"" << name.as<wchar_t>() << L"\""
<< L" is an active VISA instrument."
<< std::endl;
return true;
});

i.reset(true, true)
.enable_system_checks()
.timeout(20000);
i.synchronise_clock()
.service_request_status(visa_status_byte::master_status)
.operation_complete();

std::wcout << L"The device has " << i.channels() << L" channels."
<< std::endl;
std::wcout << L"The device has currently " << i.history_segments()
<< L" history segments in memory." << std::endl;
std::wcout << L"The horizontal time range is "
<< i.time_range().value() << L"s." << std::endl;
std::wcout << L"The horizontal time scale is "
<< i.time_scale().value() << L"s." << std::endl;
std::wcout << L"Acquisition state is "
<< int(i.acquisition()) << std::endl;

for (std::uint16_t c = 1; c <= i.channels(); ++c){
auto channel = i.channel(c);
std::wcout << L"Channel " << c << L" attenuation: "
<< channel.attenuation().value() << std::endl;
std::wcout << L"Channel " << c << L" bandwidth: "
<< int(channel.bandwidth()) << std::endl;
std::wcout << L"Channel " << c << L" channel: "
<< channel.channel() << std::endl;
std::wcout << L"Channel " << c << L" coupling: "
<< int(channel.coupling()) << std::endl;
std::wcout << L"Channel " << c << L" decimation_mode: "
<< int(channel.decimation_mode()) << std::endl;
std::wcout << L"Channel " << c << L" label: "
<< channel.label().text() << L", visible: "
<< channel.label().visible() << std::endl;
std::wcout << L"Channel " << c << L" offset: "
<< channel.offset().value() << std::endl;
std::wcout << L"Channel " << c << L" polarity: "
<< int(channel.polarity()) << std::endl;
std::wcout << L"Channel " << c << L" range: "
<< channel.range().value() << std::endl;
std::wcout << L"Channel " << c << L" skew: "
<< channel.skew().value() << std::endl;
std::wcout << L"Channel " << c << L" state: "
<< channel.state() << std::endl;
std::wcout << L"Channel " << c << L" zero_offset: "
<< channel.zero_offset().value() << std::endl;

std::vector<wchar_t> u(i.unit(nullptr, 0, c));
i.unit(u.data(), u.size(), c);
std::wcout << L"Probe " << c << L" measures "
<< u.data() << std::endl;
i.beep(c);
}

{
auto a = i.single_acquisition();
std::wcout << L"Automatic points enabled: "
<< a.automatic_points() << std::endl;
std::wcout << L"Number of segments: "
<< a.count() << std::endl;
std::wcout << L"Number of points: "
<< a.points() << std::endl;
std::wcout << L"Fast segmentation: "
<< a.segmented() << std::endl;
}

{
auto t = i.edge_trigger();
std::wcout << L"Trigger coupling: "
<< int(t.coupling()) << std::endl;
std::wcout << L"Trigger hold-off: "
<< convert_string<wchar_t>(t.hold_off()) << std::endl;
std::wcout << L"Trigger hysteresis: "
<< int(t.hysteresis()) << std::endl;
std::wcout << L"Trigger input: "
<< t.input() << std::endl;
std::wcout << L"Trigger level: "
<< t.level().value() << std::endl;
std::wcout << L"Trigger mode: "
<< int(t.mode()) << std::endl;
std::wcout << L"Trigger slope: "
<< int(t.slope()) << std::endl;
std::wcout << L"Trigger slope: "
<< convert_string<wchar_t>(t.source()) << std::endl;
std::wcout << L"Trigger type: "
<< convert_string<wchar_t>(t.type()) << std::endl;
}

i.reference_position(oscilloscope_reference_point::left);
i.time_scale(oscilloscope_quantity(10, "ms"));

i.channel(oscilloscope_channel(1)
.label(oscilloscope_label("podump#1"))
.state(true)
.attenuation(oscilloscope_quantity(10, "V"))
.range(oscilloscope_quantity(7)));
//i.expression(1, "CH1 * 2");

i.acquisition(oscilloscope_single_acquisition()
.points(50000)
.count(2)
.segmented(true));

i.trigger_position(oscilloscope_quantity(42.42f, "ms"));
i.trigger(oscilloscope_edge_trigger("CH1")
.level(1, oscilloscope_quantity(2000.0f, "mV"))
//i.channel(oscilloscope_channel(2)
// .label(oscilloscope_label("podump#2"))
// .state(true)
// .attenuation(oscilloscope_quantity(1, "V"))
// .range(oscilloscope_quantity(5)));

std::cout << "Main " << std::this_thread::get_id() << std::endl;
i.on_operation_complete([](visa_instrument& i, void *) {
std::cout << "bla " << std::this_thread::get_id() << std::endl;
});
i.operation_complete_async();

i.trigger_position(oscilloscope_quantity(0.0f, "ms"));
i.trigger(oscilloscope_edge_trigger("EXT")
.level(5, oscilloscope_quantity(2000.0f, "mV"))
.slope(oscilloscope_trigger_slope::rising)
.mode(oscilloscope_trigger_mode::automatic));
.mode(oscilloscope_trigger_mode::normal));
i.throw_on_system_error();

std::cout << "RTX interface type: "
<< i.interface_type()
<< std::endl
<< "RTX status before acquire: "
<< i.status()
<< static_cast<int>(i.status())
<< std::endl
<< "SRE before acquire: "
<< static_cast<int>(i.service_request_status())
<< std::endl
<< "ESE before acquire: "
<< static_cast<int>(i.event_status())
<< std::endl;

i.acquisition(oscilloscope_acquisition_state::run);
i.acquisition(oscilloscope_single_acquisition()
.points(100000)
.count(1)
.segmented(false))
.operation_complete();
i.throw_on_system_error();

//i.save_state_to_instrument(L"_PODUMP.SET").operation_complete();
//i.reset(true, true);
//i.load_state_from_instrument(L"_PODUMP.SET").operation_complete();

i.trigger();
i.trigger();
i.wait();
//i.query("*TRG; *OPC?\n");
//auto ascii_data = i.ascii_data(1);
//auto binary_data = i.binary_data(1);
i.acquisition(oscilloscope_acquisition_state::single)
.operation_complete();
//i.operation_complete();

auto segment0 = i.data(1);
i.trigger();
i.operation_complete();
i.throw_on_system_error();

i.history_segment(-1);
auto b = std::chrono::high_resolution_clock::now();
std::cout << "Segment "
<< i.history_segment()
<< " of "
<< i.history_segments()
<< std::endl;
auto segment1 = i.data(1);
auto segment0 = i.data(1, oscilloscope_waveform_points::maximum);
auto e = std::chrono::high_resolution_clock::now();
std::cout << "Download took "
<< std::chrono::duration_cast<std::chrono::milliseconds>(e - b).count()
<< " ms" << std::endl;

std::cout << "Record length: "
<< segment0.record_length() << std::endl
<< "Buffer size: "
<< segment0.end() - segment0.begin() << std::endl;

//i.history_segment(-1);
//std::cout << "Segment "
// << i.history_segment()
// << " of "
// << i.history_segments()
// << std::endl;
//auto segment1 = i.data(1);
int x = 1234;
}

} catch (std::exception& ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cstdint>
#include <cinttypes>

#include "power_overwhelming/blob.h"
#include "power_overwhelming/sensor.h"
#include "power_overwhelming/visa_instrument.h"

Expand Down Expand Up @@ -58,7 +59,7 @@ namespace power_overwhelming {
/// <summary>
/// Initialises a new instance.
/// </summary>
inline hmc8015_sensor(void) : _name(nullptr) { }
inline hmc8015_sensor(void) = default;

/// <summary>
/// Initialises a new instance.
Expand Down Expand Up @@ -393,7 +394,7 @@ namespace power_overwhelming {
_In_ const float value);

visa_instrument _instrument;
wchar_t *_name;
blob _name;
};

} /* namespace power_overwhelming */
Expand Down
Loading

0 comments on commit cf2452b

Please sign in to comment.