From 02012d9841ca9cc15d39f018c20987eca2726d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Sandstr=C3=B6m?= Date: Fri, 1 Mar 2024 21:06:50 +0100 Subject: [PATCH] WIP --- src/ecmcDAQDataArray.cpp | 36 +++++++++++++++++--- src/ecmcDAQDataArray.h | 11 +++--- src/ecmcDAQDataChannel.cpp | 58 +++++++++++++++++++++++++++++++ src/ecmcDAQDataChannel.h | 70 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 src/ecmcDAQDataChannel.cpp create mode 100644 src/ecmcDAQDataChannel.h diff --git a/src/ecmcDAQDataArray.cpp b/src/ecmcDAQDataArray.cpp index 4d4dee6..471a2b0 100644 --- a/src/ecmcDAQDataArray.cpp +++ b/src/ecmcDAQDataArray.cpp @@ -20,6 +20,7 @@ ecmcDAQDataArray::ecmcDAQDataArray(size_t nelm){ buffer_ = new double [nelm]; + memset(buffer_,0,sizeof(buffer_)) nelm_ = nelm; channelCounter_ = 0; } @@ -28,8 +29,8 @@ ecmcDAQDataArray::~ecmcDAQDataArray() { } -void ecmcDAQDataArray::addDataItem(char* name, int timeFormat) { - dataChannels_.push_back(new ecmcDataChannel(name, timeFormat); +void ecmcDAQDataArray::addDataItem(int type) { + dataChannels_.push_back(new ecmcDAQDataChannel(type); channelCounter_++; } @@ -38,11 +39,11 @@ void ecmcDAQDataArray::connectToDataSources() { return; } - for(std::vector::iterator pDataCh = dataChannels_.begin(); pDataCh != dataChannels_.end(); ++pDataCh) { + for(std::vector::iterator pDataCh = dataChannels_.begin(); pDataCh != dataChannels_.end(); ++pDataCh) { if(!(*pDataCh)) { throw std::runtime_error( "Channel empty.."); } - (*pDataCh)->connectToSource(); + (*pDataCh)->connectToSources(); } // Register asyn parameters @@ -51,8 +52,33 @@ void ecmcDAQDataArray::connectToDataSources() { dataSourceLinked_ = 1; } -void ecmcDAQDataArray::buildHeader(){ +// Prepare header first in array 4 elements per channel. +void ecmcDAQDataArray::buildArrayHeader(){ + size_t index = 0; + size_t dataStartOffset=channelCounter_* 4 + 1; //4 elements plus first timestamp + buffer_[index] = 0; // Timestamp, will be set in each loop in execute + index++; // Each Data channel takes 4 doubles + for(std::vector::iterator pDataCh = dataChannels_.begin(); pDataCh != dataChannels_.end(); ++pDataCh) { + if(!(*pDataCh)) { + throw std::runtime_error( "Channel empty.."); + } + // 4 elements per channel + // First element: Type + buffer_[index] = (double)(*pDataCh)->getType(); + index++; + // Second element: data start index + buffer_[index] = (double)dataStartOffset; + index++; + // Third element: data start index + buffer_[index] = (double)(*pDataCh)->getElementCount(); + // Prepare data start index for next data item + dataStartOffset = dataStartOffset + (*pDataCh)->getElementCount(); + index++; + // Forth index spare... + buffer_[index] = 0; + index++; + } } void ecmcDAQDataArray::execute() { diff --git a/src/ecmcDAQDataArray.h b/src/ecmcDAQDataArray.h index 4392921..4278eca 100644 --- a/src/ecmcDAQDataArray.h +++ b/src/ecmcDAQDataArray.h @@ -19,16 +19,15 @@ #include "ecmcDataItem.h" /* Class to store data channels */ -class ecmcDataChannel { +class ecmcDAQDataChannel { public: - ecmcDataChannel(char* name, int formatAsTime) { + ecmcDAQDataChannel(char* name, int formatAsTime) { dataItem_ = NULL; - dataItemInfo_ = NULL; name_ = name; timeFormat_ = formatAsTime; } - void connectToSource() { + void connectToSources() { // Get data item for dataItem_ = (ecmcDataItem*) getEcmcDataItem(name_.c_str()); if(!dataItem_) { @@ -49,7 +48,7 @@ class ecmcDataChannel { int timeFormat_; }; -/* Class to fromat an array of ecmcDataChannels with headers and push over asyn to epics */ +/* Class to fromat an array of ecmcDAQDataChannels with headers and push over asyn to epics */ class ecmcDAQDataArray { public: ecmcDAQDataArray(size_t nelm); @@ -60,7 +59,7 @@ class ecmcDAQDataArray { private: double *buffer_; - std::vector dataChannels_; + std::vector dataChannels_; size_t channelCounter_; }; diff --git a/src/ecmcDAQDataChannel.cpp b/src/ecmcDAQDataChannel.cpp new file mode 100644 index 0000000..fe59c1e --- /dev/null +++ b/src/ecmcDAQDataChannel.cpp @@ -0,0 +1,58 @@ +7/*************************************************************************\ +* Copyright (c) 2024 PSI +* ecmc is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +* +* ecmcDAQDataChannel.cpp +* +* Created on: March 1, 2024 +* Author: anders sandstrom +* Credits to https://github.com/sgreg/dynamic-loading +* +\*************************************************************************/ + +// Needed to get headers in ecmc right... +#define ECMC_IS_PLUGIN + +#include +#include "ecmcDAQDataChannel.h" +#include "ecmcPluginClient.h" + +ecmcDAQDataChannel::ecmcDAQDataChannel(int type){ + itemCounter_ = 0; + type_ = (double) type; +} + +ecmcDAQDataChannel::~ecmcDAQDataChannel() { + +} + +void ecmcDAQDataChannel::addDataItem(char* name, int timeFormat) { + dataItems_.push_back(new ecmcDAQChannelItem(name, timeFormat); + itemCounter_++; +} + +void ecmcDAQDataChannel::connectToDataSources() { + if( dataSourceLinked_ ) { + return; + } + + for(std::vector::iterator pDataItem = dataItems_.begin(); pDataItem != dataItems_.end(); ++pDataItem) { + if(!(*pDataItem)) { + throw std::runtime_error( "Channel empty.."); + } + (*pDataItem)->connectToSource(); + } + + // Register asyn parameters + initAsyn(); + + dataSourceLinked_ = 1; +} + +void ecmcDAQDataChannel::execute() { + +} + + + diff --git a/src/ecmcDAQDataChannel.h b/src/ecmcDAQDataChannel.h new file mode 100644 index 0000000..47b8061 --- /dev/null +++ b/src/ecmcDAQDataChannel.h @@ -0,0 +1,70 @@ +/*************************************************************************\ +* Copyright (c) 2024 PSI +* ecmc is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +* +* ecmcDAQDataChannel.h +* +* Created on: Mar 01, 2024 +* Author: anders sandstrom +* +\*************************************************************************/ +#ifndef ECMC_DAQ_DATA_ARRAY_H_ +#define ECMC_DAQ_DATA_ARRAY_H_ + +#include +#include +#include +#include "ecmcDAQDataChannel.h" +#include "ecmcDataItem.h" + +/* Class to store data channels */ +class ecmcDAQChannelItem { + public: + ecmcDAQChannelItem(char* name, int formatAsTime) { + dataItem_ = NULL; + dataItemInfo_ = NULL; + name_ = name; + timeFormat_ = formatAsTime; // micro s in int32 + } + + void connectToSource() { + // Get data item + dataItem_ = (ecmcDataItem*) getEcmcDataItem(name_.c_str()); + if(!dataItem_) { + printf("ERROR: DataItem %s NULL.\n", name_.c_str()); + throw std::runtime_error( "ERROR: DataItem NULL." ); + } + + dataItemInfo_ = dataItem_->getDataItemInfo(); + if(!dataItemInfo_) { + printf("ERROR: DataItemInfo %s NULL.\n", name_.c_str()); + throw std::runtime_error( "ERROR: DataItemInfo NULL." ); + } + } + + ecmcDataItem* dataItem_; + ecmcDataItemInfo* dataItemInfo_; + std::string name_; + int timeFormat_; +}; + +/* Class for an data channel */ +class ecmcDAQDataChannel { + public: + ecmcDAQDataChannel(int type); + ~ecmcDAQDataChannel(); + void connectToSources(); + void execute(); + void addDataItem(char* name, int timeFormat); + +private: + std::vector dataItems_; + size_t itemCounter_; + double type_; +}; + +#endif /* ECMC_DAQ_DATA_ARRAY_H_ */ + + +