#include "device_ni.h" #include "core/gtl_logger.h" device_ni::device_ni(QObject *parent) : device(parent), _is_full_restarting(true), _max_amplitude(0), _name("NI device"), _is_support_iepe(false) { _device->set_name("ni"); gtl::logger::info("ni_device", "created;"); } device_ni::~device_ni() { stop(); gtl::logger::info("ni_device", "distroyed;"); } QString device_ni::type() const { return "ni"; } bool device_ni::start(QString id, qreal rate) { gtl::logger::info("ni_device", "starting device. id: " + id + "; rate: " + QString::number(rate)); emit status_changed(INIT_IN_PROGRESS); _task = 0; int err = 0; _id = id; _rate = rate; _count_ai = 0; char buffer[256]; err = DAQmxGetDevProductType(_id.toStdString().c_str(), buffer, 256); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "init device" << "DAQmxGetDevProductType error: " + get_error_message(err); return false; } _name = QString(buffer); emit name_changed(); gtl::logger::info("ni_device", "device name:" + _name + ";"); err = DAQmxGetDevAIPhysicalChans(_id.toStdString().c_str(), buffer, 256); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "init device" << "DAQmxGetDevAOPhysicalChans error: " + get_error_message(err); return false; } gtl::logger::info("ni_device", "analog input channels: " + QString(buffer) + ";"); QStringList channels = QString(buffer).split(","); int32 idata[256]; std::fill(&idata[0], &idata[256], 0); err = DAQmxGetDevAISupportedMeasTypes(_id.toStdString().c_str(), idata, 256); _is_support_iepe = std::find(&idata[0], &idata[256], 10356); gtl::logger::info("ni_device", "is iepe support: " + QString::number(_is_support_iepe) + ";"); _count_ai = channels.size(); set_ai(); QJsonArray array_config = _config.toArray(); for(int i = 0; i < qMin(array_config.size(), count_ai()); i++) { ai(i)->blockSignals(true); ai(i)->set_iepe(array_config[i].toObject().value("iepe").toBool()); ai(i)->set_coupling(array_config[i].toObject().value("ac").toBool()); ai(i)->blockSignals(false); } /* if (_is_full_restarting) { _iepe.resize(_channels); std::fill(_iepe.begin(), _iepe.end(), false); emit channels_changed(); } */ float64 range[2]; err = DAQmxGetDevAIVoltageRngs(_id.toStdString().c_str(), range, 2); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "init device" << "DAQmxGetDevAIVoltageRngs error: " + get_error_message(err); return false; } gtl::logger::info("ni_device", "voltage range: " + QString::number(range[0]) + " - " + QString::number(range[1])+ ";"); _max_amplitude = range[1]; float64 rate_max; err = DAQmxGetDevAIMaxMultiChanRate(_id.toStdString().c_str(), &rate_max); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "init device" << "DAQmxGetSampClkMaxRate error. code: " + get_error_message(err); return false; } gtl::logger::info("ni_device", "max rate: " + QString::number(rate_max) + ";"); if (rate > rate_max) _rate = rate_max; err = DAQmxCreateTask("", &_task); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxCreateTask error: " + get_error_message(err); return false; } int samples = _rate * 0.1; for (int i = 0; i < _count_ai; i++) { channels[i] = channels[i].trimmed(); if (ai(i)->is_iepe()) { err = DAQmxCreateAIAccelChan(_task, channels[i].toStdString().c_str(), "", DAQmx_Val_Cfg_Default, range[0], range[1], DAQmx_Val_AccelUnit_g, 1, DAQmx_Val_VoltsPerG, DAQmx_Val_Internal, .002, NULL); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxCreateAIVoltageChan error: " + get_error_message(err); return false; } } else { err = DAQmxCreateAIVoltageChan(_task, channels[i].toStdString().c_str(), "", DAQmx_Val_Cfg_Default, range[0], range[1], DAQmx_Val_Volts, NULL); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxCreateAIVoltageChan error: " + get_error_message(err); return false; } } err = DAQmxSetAICoupling(_task, channels[i].toStdString().c_str(), ((ai(i)->is_coupling() | ai(i)->is_iepe()) ? DAQmx_Val_AC : DAQmx_Val_DC)); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxSetAICoupling error: " + get_error_message(err); return false; } } err = DAQmxCfgSampClkTiming(_task, "", _rate, DAQmx_Val_Rising, DAQmx_Val_ContSamps, samples); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxCfgSampClkTiming error. code: " + get_error_message(err); return false; } err = DAQmxGetSampClkRate(_task, &_rate); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxGetSampClkRate error: " + get_error_message(err); return false; } qDebug() << "rate" << _rate; _buffer_read.resize(samples * _count_ai); err = DAQmxStartTask(_task); if (err != 0) { emit status_changed(INIT_FAILED); qDebug() << "start acquisition" << "DAQmxStartTask error. code: " + QString::number(err); return false; } _device->set_name(_name + "[" + id + "]"); _device->set_id(_id); _device->set_rate(_rate); QThread::start(QThread::HighestPriority); emit status_changed(OK); return true; } bool device_ni::stop() { if (_is_full_restarting) { } gtl::logger::info("ni_device", "stopping...;"); int err = DAQmxTaskControl(_task, DAQmx_Val_Task_Abort); _is_running = false; wait(); _task = 0; return true; } void device_ni::set_config(const QJsonValue &config) { gtl::hw::device::set_config(config); if(isRunning()) restart(); } void device_ni::run() { gtl::logger::info("ni_device", "started. rate: " + QString::number(_rate) + ";"); _is_running = true; int32 read = 0; do { int err = DAQmxReadAnalogF64(_task, (int)_buffer_read.size() / count_ai(), -1, DAQmx_Val_GroupByScanNumber, &_buffer_read[0], (int)_buffer_read.size(), &read, NULL); if (err != 0) { if (err != -88710 && err != -88709) { qDebug() << "start acquisition" << "DAQmxReadAnalogF64 error: " + get_error_message(err); emit status_changed(FAILED); break; } } // gtl::logger::info("ni_device", "sendign data;"); send_data(); } while (_is_running); // emit status_changed(undef); DAQmxStopTask(_task); DAQmxClearTask(_task); gtl::logger::info("ni_device", "stopped;"); } void device_ni::send_data() { _buffer_send.clear(); set_ai_data(&_buffer_read[0], (int)_buffer_read.size()); QDateTime time_current = QDateTime::currentDateTime(); _time_send = time_current; emit received_data(); } QString device_ni::get_error_message(int32 code) { char buffer[2048]; DAQmxGetErrorString(code, buffer, 2048); return QString(buffer); } void device_ni::ai_iepe_changed() { restart(); } void device_ni::ai_coupling_changed() { restart(); }