/**
* OscilloscopeGeneratorTrigger.cpp
*
* This example sets up the generator to generate a 1 kHz triangle waveform, 4 Vpp.
* It also sets up the oscilloscope to perform a block mode measurement, triggered on "Generator new period".
* A measurement is performed and the data is written to OscilloscopeGeneratorTrigger.csv.
*
* Find more information on http://www.tiepie.com/LibTiePie .
*/
#include "PrintInfo.hpp"
#include <fstream>
#include <iostream>
#include <thread>
#if defined(__linux) || defined(__unix)
# include <cstdlib>
# include <unistd.h>
#endif
int main()
{
int status = EXIT_SUCCESS;
// Initialize library:
TiePie::Hardware::Library::init();
// Print library information:
printLibraryInfo();
// Enable network search:
TiePie::Hardware::Network::setAutoDetectEnabled(true);
// Update device list:
TiePie::Hardware::DeviceList::update();
// Try to open an oscilloscope with block measurement support and a generator in the same device:
std::unique_ptr<TiePie::Hardware::Oscilloscope> scp;
std::unique_ptr<TiePie::Hardware::Generator> gen;
for(uint32_t i = 0; !(scp && gen) && i < TiePie::Hardware::DeviceList::count(); i++)
{
const auto item = TiePie::Hardware::DeviceList::getItemByIndex(i);
if(item->canOpen(TIEPIE_HW_DEVICETYPE_OSCILLOSCOPE) && item->canOpen(TIEPIE_HW_DEVICETYPE_GENERATOR))
{
scp = item->openOscilloscope();
// Check for valid pointer and block measurement support:
if(scp && scp->measureModes() & TIEPIE_HW_MM_BLOCK)
gen = item->openGenerator();
else
scp = nullptr;
}
}
if(scp && gen)
{
uint16_t channelCount = 0;
try
{
// Oscilloscope settings:
// Get the number of channels:
channelCount = scp->channels.count();
// Set measure mode:
scp->setMeasureMode(TIEPIE_HW_MM_BLOCK);
// Set sample rate:
scp->setSampleRate(1e6); // 1 MHz
// Set record length:
const uint64_t recordlength = scp->setRecordLength(10000); // 10 kS
// Set pre sample ratio:
scp->setPreSampleRatio(0); // 0 %
// For all channels:
for(const auto& channel : scp->channels)
{
// Enable channel to measure it:
channel->setEnabled(true);
// Set range:
channel->setRange(8); // 8 V
// Set coupling:
channel->setCoupling(TIEPIE_HW_CK_DCV); // DC Volt
}
// Set trigger timeout:
scp->trigger->setTimeout(1); // 1 s
// Disable all channel trigger sources:
for(const auto& channel : scp->channels)
channel->trigger->setEnabled(false);
// Locate trigger input:
const auto& triggerInput = scp->triggerInputs.getById(TIEPIE_HW_TIID_GENERATOR_NEW_PERIOD); // or (TIEPIE_HW_TIID_GENERATOR_START || (TIEPIE_HW_TIID_GENERATOR_STOP
if(!triggerInput)
throw std::runtime_error("Unknown trigger input!");
// Enable trigger input:
triggerInput->setEnabled(true);
// Generator settings:
// Set signal type:
gen->setSignalType(TIEPIE_HW_ST_TRIANGLE);
// Set frequency:
gen->setFrequency(1e3); // 1 kHz
// Set amplitude:
gen->setAmplitude(2); // 2 V
// Set offset:
gen->setOffset(0); // 0 V
// Enable output:
gen->setOutputEnable(true);
// Print oscilloscope info:
printDeviceInfo(*scp);
// Print generator info:
printDeviceInfo(*gen);
// Start measurement:
scp->start();
// Start signal generation:
gen->start();
// Wait for measurement to complete:
while(!scp->isDataReady())
{
// 10 ms delay, to save CPU time:
using namespace std::chrono_literals;
std::this_thread::sleep_for(10ms);
}
// Stop generator:
gen->stop();
// Disable output:
gen->setOutputEnable(false);
// Create data buffer:
std::vector<std::vector<float>> channelData(channelCount, std::vector<float>(recordlength));
std::vector<float*> channelDataPointers(channelCount);
for(size_t i = 0; i < channelCount; i++)
channelDataPointers[i] = channelData[i].data();
// Get the data from the scope:
uint64_t samplesRead = scp->getData(channelDataPointers.data(), channelCount, 0, recordlength);
// Open file with write/update permissions:
const std::string filename("OscilloscopeGeneratorTrigger.csv");
std::ofstream csv(filename.c_str(), std::ofstream::out);
if(csv.is_open())
{
// Write csv header:
csv << "Sample";
for(uint16_t ch = 0; ch < channelCount; ch++)
csv << ";Ch" << (ch + 1);
csv << '\n';
// Write the data to csv:
for(uint64_t i = 0; i < samplesRead; i++)
{
csv << i;
for(uint16_t ch = 0; ch < channelCount; ch++)
csv << ";" << channelData[ch][i];
csv << '\n';
}
std::cout << "Data written to: " << filename << '\n';
// Close file:
csv.close();
}
else
{
std::cerr << "Couldn't open file: " << filename << '\n';
status = EXIT_FAILURE;
}
}
catch(const std::exception& e)
{
std::cerr << "Exception: " << e.what() << '\n';
status = EXIT_FAILURE;
}
// Close oscilloscope:
scp = nullptr;
// Close generator:
gen = nullptr;
}
else
{
std::cerr << "No oscilloscope available with block measurement support or generator available in the same unit!\n";
status = EXIT_FAILURE;
}
// Finalize library:
TiePie::Hardware::Library::fini();
return status;
}