OscilloscopeBlockSegmented.cpp

/**
 * OscilloscopeBlockSegmented.cpp - for LibTiePie 0.5+
 *
 * This example performs a block mode measurement of 5 segments and writes the data to OscilloscopeBlockSegmented.csv.
 *
 * Find more information on http://www.tiepie.com/LibTiePie .
 */

#include <iostream>
#include <fstream>
#include "libtiepie++.h"
#include "PrintInfo.h"

#if defined(__linux) || defined(__unix)
  #include <cstdlib>
  #include <unistd.h>
#endif

using namespace std;
using namespace LibTiePie;

int main()
{
  int status = EXIT_SUCCESS;

  // Initialize library:
  Library::init();

  // Print library information:
  printLibraryInfo();

  // Update device list:
  DeviceList::update();

  // Try to open an oscilloscope with block measurement support:
  Oscilloscope* scp = 0;

  for(uint32_t index = 0; index < DeviceList::count(); index++)
  {
    DeviceListItem* item = DeviceList::getItemByIndex(index);

    if(item->canOpen(DEVICETYPE_OSCILLOSCOPE) && (scp = item->openOscilloscope()) && (scp->segmentCountMax() > 1))
    {
      // Check for block support:
      if(!(scp->measureModes() & MM_BLOCK))
      {
        delete scp;
        scp = 0;
      }
    }

    delete item;

    if(scp)
    {
      break;
    }
  }

  if(scp)
  {
    float*** segmentData = 0;
    uint16_t channelCount = 0;
    uint16_t segmentCount = 5;
    uint64_t samplesRead = 0;

    try
    {
      // Get the number of channels:
      channelCount = scp->channels.count();

      // Set measure mode:
      scp->setMeasureMode(MM_BLOCK);

      // Set sample frequency:
      scp->setSampleFrequency(1e6); // 1 MHz

      // Set record length:
      scp->setRecordLength(1000); // 10 kS
      const uint64_t recordlength = scp->recordLength(); // Read actual record length.

      // Set pre sample ratio:
      scp->setPreSampleRatio(0); // 0 %

      // Set segment count:
      scp->setSegmentCount(segmentCount); // 5 segments
      segmentCount = scp->segmentCount(); // read actual segment count.

      // For all channels:
      for(uint16_t ch = 0; ch < channelCount; ch++)
      {
        OscilloscopeChannel& channel = scp->channels[ch];

        // Disable channels:
        channel.setEnabled(false);

        // Set range:
        channel.setRange(8); // 8 V

        // Set coupling:
        channel.setCoupling(CK_DCV); // DC Volt
      }

      OscilloscopeChannel& channel = scp->channels[0];
      // Enable channel to measure it:
      channel.setEnabled(true);


      // Set trigger timeout:
      scp->setTriggerTimeOut(100e-3); // 100 ms

      // Disable all channel trigger sources:
      for(uint16_t ch = 0; ch < channelCount; ch++)
      {
        scp->channels[ch].trigger->setEnabled(false);
      }

      // Setup channel trigger:
      OscilloscopeChannelTrigger* chTr = scp->channels[0].trigger; // Ch 1

      // Enable trigger source:
      chTr->setEnabled(true);

      // Kind:
      chTr->setKind(TK_RISINGEDGE); // Rising edge

      // Levels:
      chTr->Levels[0] = 0.5; // 50 %

      // Hysteresis:
      chTr->Hystereses[0] = 0.05; // 5 %

      // Print oscilloscope info:
      printDeviceInfo(scp);

      // Start measurement:
      scp->start();

      // Wait for measurement to complete:
      while(!scp->isDataReady())
      {
        // 10 ms delay, to save CPU time:
#if defined(_WIN32) || defined(_WIN64)
        Sleep(10);
#elif defined(__linux) || defined(__unix)
        usleep(10000);
#endif
      }

      // Create data buffer:
      segmentData = new float**[segmentCount];
      for(uint16_t seg = 0; seg < segmentCount; seg++)
      {
        segmentData[seg] = new float*[channelCount];
        for(uint16_t ch = 0; ch < channelCount; ch++)
        {
          if(scp->channels[ch].enabled())
            segmentData[seg][ch] = new float[recordlength] ;
        }
      }

      // Get all data from the scope:
      uint16_t seg = 0;
      while(scp->isDataReady())
      {
        samplesRead = scp->getData(segmentData[seg], channelCount , 0 , recordlength);
        seg++;
      }

      // Open file with write/update permissions:
      const std::string filename("OscilloscopeBlockSegmented.csv");
      ofstream csv(filename.c_str() , std::ofstream::out);

      if(csv.is_open())
      {
        // Write csv header:
        csv << "Sample";
        for(uint16_t seg = 0; seg < segmentCount; seg++)
        {
          csv << ";Segment " << (seg + 1);
        }
        csv << endl;

        // Write the Ch1 data to csv:
        for(uint64_t i = 0; i < samplesRead; i++)
        {
          csv << i;
          for(uint16_t seg = 0; seg < segmentCount; seg++)
          {
            csv << ";" << (float)segmentData[seg][0][i];
          }
          csv << endl;
        }

        cout << "Data written to: " << filename << endl;

        // Close file:
        csv.close();
      }
      else
      {
        cerr << "Couldn't open file: " << filename;
        status = EXIT_FAILURE;
      }
    }
    catch(const exception& e)
    {
      cerr << "Exception: " << e.what() << endl;
      status = EXIT_FAILURE;
    }

    // Delete data buffer:
    if(segmentData)
      for(uint16_t seg = 0; seg < segmentCount; seg++)
      {
        for(uint16_t ch = 0; ch < channelCount; ch++)
          if(scp->channels[ch].enabled())
            delete [] segmentData[seg][ch];
        delete [] segmentData[seg];
      }
    delete [] segmentData;

    // Close oscilloscope:
    delete scp;
  }
  else
  {
    cerr << "No oscilloscope available with block measurement and segmented trigger support!" << endl;
    status = EXIT_FAILURE;
  }

  // Exit library:
  Library::exit();

  return status;
}