C++ Instrument Catalog
MFCCatalogExample.cpp
Go to the documentation of this file.
1 //
8 //
9 
10 #include <iostream>
11 #include <queue>
12 #include <fstream> // ifstream to read files
13 #include <windows.h> // GetModuleFileName
14 
15 #include "InstrumentCatalog.h"
16 #include "MFCManager.h"
17 
18 using namespace MTL;
19 
21 {
22 private:
24  CAsyncSnaphsotNotifier m_ASNotifier;
25  std::mutex m_QLock;
26  // This queue is the heart of the interchange mechanism.
27  // The catalog being "interchange-agnostic", it is up to you to
28  // select which type of communication mechanism you want to implement
29  // in your application. In this specific and simple example, we
30  // aimed for a queue.
31  std::queue< CAsyncNotification *> m_Q;
32 
33  // Instrument to connect to.
34  static std::string m_InstrToConnect;
35 
36 private:
37  void l_PushNewAsyncNotification(CAsyncNotification * pANot)
38  {
39  std::lock_guard<std::mutex> l_LG(m_QLock);
40  m_Q.push(pANot);
41  }
42  CAsyncNotification * l_GetNotification()
43  {
44  std::lock_guard<std::mutex> l_LG(m_QLock);
45  if (m_Q.empty())
46  return nullptr;
47 
48  CAsyncNotification * l_pNot = m_Q.front();
49  m_Q.pop();
50  return l_pNot;
51  }
52 
53 public:
55  : m_Cat(rCat), m_ASNotifier(&CMyApplication::l_PushNewAsyncNotification, this)
56  {
57  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59  // NOTE:
60  // You can edit this m_InstrToConnect string according to the instrument you want to connect to. This string must correspond to the UniqueID string of an instrument found in the "New Instrument List".
61  // The UniqueID string corresponds to the VISA ressource name.
62  // As example, UniqueID according to different interfaces:
63  // - USB connection (as PT2026 instrument), UniqueID looks like: "USB0::0x1BFA::0x07EA::0000001::INSTR" , with 0000001 the 7 digit instrument serial number.
64  // - Ethernet connection (as PT2026 instrument), UniqueID looks like: "TCPIP0::pt2026_00001::inst0::INSTR" .
65  // - Serial connection (as MFC3045 instrument), UniqueID looks like: "ASRL1::INSTR" , in ASRLx the x corresponds to the serial port COM number.
66  m_InstrToConnect = "USB0::0x1BFA::0x07EA::0000001::INSTR";
67  // END OF NOTE
68  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70  }
71 
72  void SyncControls()
73  {
74  // We do not need to sync anything with the catalog for this application
75  }
77  {
78  // We do not need to sync anything with the catalog for this application
79  }
80  void Subscribe()
81  {
82  // Proceed to the subscription to each variable of interrest.
83  m_Cat.oInstrumentList.Subscribe(m_ASNotifier);
84  m_Cat.oProbeArrayInformation.Subscribe(m_ASNotifier);
85  m_Cat.oSearchResult.Subscribe(m_ASNotifier);
86  m_Cat.oInstrumentStatus.Subscribe(m_ASNotifier);
87  m_Cat.oError.Subscribe(m_ASNotifier);
88  }
89 
91  {
92  std::string l_InterfaceStr = "Unknown";
93  switch (l_InstrInterface)
94  {
96  l_InterfaceStr = "Ethernet";
97  break;
99  l_InterfaceStr = "Serial";
100  break;
102  l_InterfaceStr = "USB";
103  break;
104 
105  default:
106  break;
107  }
108  return l_InterfaceStr;
109  }
110 
111  void DoJob()
112  {
113  bool l_Operate = true;
114  while (l_Operate)
115  {
116  // Get the current notification.
117  CAsyncNotification * l_pNot = l_GetNotification();
118  if (nullptr == l_pNot)
119  {
120  // No notification currently in the queue.
121  // Sleep for a while.
122  std::this_thread::sleep_for(std::chrono::milliseconds(100));
123  }
124  else
125  {
126  // Since we have a notification...
127  CObserver_untyped & rVar = l_pNot->Observer();
128  const CAsyncSnapshotNotification * l_pASNot = static_cast<CAsyncSnapshotNotification *>(l_pNot);
129 
130  // Try determining which variable spawned it.
131 
132  if (rVar.Is(m_Cat.oInstrumentList)) //New instrument list received
133  {
134  std::cout << "New Instrument List" << std::endl;
135  const CInstrumentCatalog::tInstrumentList * l_pVal = static_cast<const CInstrumentCatalog::tInstrumentList *>(l_pASNot->DataCopy());
136  for (int i = 0; i < l_pVal->size(); i++)
137  {
138  std::cout << "Instrument num " << i << " : UniqueID = " << l_pVal->at(i).UniqueID << " , Label = " << l_pVal->at(i).Label << " , Inteface = " << GetInterfaceString(l_pVal->at(i).Interface) << std::endl;
139  }
140  std::cout << std::endl;
141 
142  for (CInstrumentCatalog::tInstrumentList::const_iterator it= l_pVal->begin(); it != l_pVal->end(); it++)
143  {
144  if (m_InstrToConnect == it->UniqueID)
145  {
146  //Connect to the default instrument if found in the list
147  std::cout << "Trying to connect to default Instrument:" << " : UniqueID = " << it->UniqueID << " , Label = " << it->Label << " , Inteface = " << GetInterfaceString(it->Interface) << std::endl;
148  m_Cat.cInstrumentCurrent(*it);
149  }
150  }
151  }
152  else if (rVar.Is(m_Cat.oProbeArrayInformation)) //New ProbeArray information received
153  {
154  std::cout << "New Probe-Array Information received" << std::endl;
157  {
158  std::cout << "Probe-Array connected. Start a NMR search operation." << std::endl;
159  // Configure instrument and start a NMR Seacrh
164  l_NewState.FreqMin = l_pVal->FreqMin;
165  l_NewState.FreqMax = l_pVal->FreqMax;
166  l_NewState.NbAveragedMeasurements = 0;
167  m_Cat.cInstrumentState(l_NewState);
168  }
169  else
170  {
171  std::cout << "No Probe-Array connected." << std::endl;
172  }
173  }
174  else if (rVar.Is(m_Cat.oSearchResult)) //New NMR search result received
175  {
176  const CInstrumentCatalog::sSearchResult * l_pVal = static_cast<const CInstrumentCatalog::sSearchResult *>(l_pASNot->DataCopy());
177  std::cout << "New Search Result :" << CInstrumentCatalog::l_Dump(*l_pVal);
178  l_Operate = false;
179  }
180  else if (rVar.Is(m_Cat.oInstrumentStatus)) // New Instrument Status received
181  {
182  const CInstrumentCatalog::sInstrumentStatus * l_pVal = static_cast<const CInstrumentCatalog::sInstrumentStatus *>(l_pASNot->DataCopy());
183  std::cout << CInstrumentCatalog::l_Dump(*l_pVal);
184  }
185  else if (rVar.Is(m_Cat.oError)) // New Error received
186  {
187  const CInstrumentCatalog::sError * l_pVal = static_cast<const CInstrumentCatalog::sError *>(l_pASNot->DataCopy());
188  std::cout << CInstrumentCatalog::l_Dump(*l_pVal);
189  l_Operate = false;
190  }
191 
192  // Delete notification (and its content)
193  delete l_pNot;
194  }
195  }
196  }
197 };
198 
199 
200 std::string CMyApplication::m_InstrToConnect;
201 
202 std::string GetApplicationDir()
203 {
204 #ifdef _WIN32
205  wchar_t l_ExePath[MAX_PATH];
206  GetModuleFileName(NULL, l_ExePath, MAX_PATH); // Get executable path
207  std::wstring l_AppPath(l_ExePath);
208  std::string l_AppDir(l_AppPath.begin(), l_AppPath.end());
209  return l_AppDir.substr(0, l_AppDir.find_last_of('\\')); // Remove application name
210 #endif
211 }
212 
213 int main()
214 {
215  std::string l_AppDir = GetApplicationDir();
216 
217  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219  // NOTE:
220  //
221  // These C++ classes are provided by Metrolab and should not be edited.
222  CInstrumentCatalog l_Catalog;
223  CMFCManager l_MFCMan(l_Catalog, l_AppDir + "/../../../../InstrumentCatalog/MFC/ExternalFiles/DefaultCommandScript.scs", l_AppDir + "/../../../../InstrumentCatalog/MFC/ExternalFiles");
224  //
225  // This C++ class is the custom user application example.
226  // You should edit this class for your own application to interact with the C++ instrument catalog
227  CMyApplication l_MyApp(l_Catalog);
228  //
229  // END OF NOTE
230  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232 
233 
234  // Synchronize catalog controls
235  l_MFCMan.SyncControls();
236  l_MyApp.SyncControls();
237  // Synchronize catalog observers
238  l_MFCMan.SyncObservers();
239  l_MyApp.SyncObservers();
240  // Subscribe to variables
241  l_MFCMan.Subscribe();
242  l_MyApp.Subscribe();
243  // Operate
244  l_MFCMan.Operate();
245 
246  l_MyApp.DoJob();
247 
248  // Terminate manager operation
249  l_MFCMan.Terminate();
250 
251  return 0;
252 }
main
int main()
Definition: MFCCatalogExample.cpp:213
CMyApplication::CMyApplication
CMyApplication(CInstrumentCatalog &rCat)
Definition: MFCCatalogExample.cpp:54
MTL::CInstrumentCatalog::l_Dump
static std::string l_Dump(const tInstrumentList &rInsList)
Definition: InstrumentCatalog.h:340
MTL::CGUICatalogInterface::oProbeArrayInformation
CObserver< CInstrumentCatalog::sProbeArrayInformation > oProbeArrayInformation
Definition: InstrumentCatalog.h:570
MTL::CInstrumentCatalog::tInstrumentList
std::vector< sInstrumentConnection > tInstrumentList
Definition: InstrumentCatalog.h:54
MTL::CInstrumentCatalog::sInstrumentState::ProbeSelection
sMeasureProbeSelection ProbeSelection
Definition: InstrumentCatalog.h:215
MTL::CInstrumentCatalog::sInstrumentState::RepeatMode
eRepeatMode RepeatMode
Definition: InstrumentCatalog.h:214
MTL::InstrumentCatalogInterface::CAsyncSnapshotNotification
Definition: CatalogInterface.h:180
CMyApplication
Definition: MFCCatalogExample.cpp:20
MTL::InstrumentCatalogInterface::CAsyncSnaphsotNotifier
Definition: CatalogInterface.h:299
MTL::CInstrumentCatalog::sInstrumentStatus
Definition: InstrumentCatalog.h:229
GetApplicationDir
std::string GetApplicationDir()
Definition: MFCCatalogExample.cpp:202
MTL::CGUICatalogInterface::cInstrumentState
CControl< CInstrumentCatalog::sInstrumentState > cInstrumentState
Definition: InstrumentCatalog.h:574
MTL::CMFCManager::SyncObservers
void SyncObservers()
Definition: MFCManager.cpp:820
MTL::CInstrumentCatalog::eProbeArrayType::kUnknown
@ kUnknown
MTL::CInstrumentCatalog::sSearchResult
Definition: InstrumentCatalog.h:250
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:150
MTL::CGUICatalogInterface::oSearchResult
CObserver< CInstrumentCatalog::sSearchResult > oSearchResult
Definition: InstrumentCatalog.h:580
CMyApplication::SyncControls
void SyncControls()
Definition: MFCCatalogExample.cpp:72
CMyApplication::SyncObservers
void SyncObservers()
Definition: MFCCatalogExample.cpp:76
MTL::CInstrumentCatalog::sProbeArrayInformation::Type
eProbeArrayType Type
Definition: InstrumentCatalog.h:146
MTL::CInstrumentCatalog::eConnectionInterface::kEthernet
@ kEthernet
MTL::CMFCManager::Subscribe
void Subscribe()
Definition: MFCManager.cpp:832
MTL::CMFCManager::SyncControls
void SyncControls()
Definition: MFCManager.cpp:805
MFCManager.h
MTL::CInstrumentCatalog::sError
Definition: InstrumentCatalog.h:298
MTL::CInstrumentCatalog::sMeasureProbeSelection
Definition: InstrumentCatalog.h:197
MTL::CInstrumentCatalog::sInstrumentState
Definition: InstrumentCatalog.h:212
MTL::CGUICatalogInterface
Definition: InstrumentCatalog.h:555
MTL::CInstrumentCatalog::sInstrumentState::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:217
MTL::InstrumentCatalogInterface::CAsyncSnapshotNotification::DataCopy
const void * DataCopy() const
Definition: CatalogInterface.h:195
MTL
Definition: CPT2026PeripheralROM.h:19
MTL::CGUICatalogInterface::cInstrumentCurrent
CControl< CInstrumentCatalog::sInstrumentConnection > cInstrumentCurrent
Definition: InstrumentCatalog.h:564
MTL::InstrumentCatalogInterface::CObserver::Subscribe
void Subscribe(CObserverNotifier_untyped &rNotifier)
Definition: CatalogInterface.h:95
MTL::CInstrumentCatalog::eRepeatMode::kSingle
@ kSingle
MTL::CInstrumentCatalog::eConnectionInterface::kSerial
@ kSerial
MTL::CInstrumentCatalog::sProbeArrayInformation
Definition: InstrumentCatalog.h:145
MTL::InstrumentCatalogInterface::CObserver_untyped
Definition: CatalogInterface.h:62
MTL::CInstrumentCatalog::eConnectionInterface::kUSB
@ kUSB
MTL::CGUICatalogInterface::oError
CObserver< CInstrumentCatalog::sError > oError
Definition: InstrumentCatalog.h:586
InstrumentCatalog.h
MTL::CMFCManager::Terminate
void Terminate()
Definition: MFCManager.cpp:878
MTL::InstrumentCatalogInterface::CAsyncNotification
Definition: CatalogInterface.h:144
MTL::CGUICatalogInterface::oInstrumentStatus
CObserver< CInstrumentCatalog::sInstrumentStatus > oInstrumentStatus
Definition: InstrumentCatalog.h:575
MTL::CInstrumentCatalog::sInstrumentState::NbAveragedMeasurements
U32 NbAveragedMeasurements
Definition: InstrumentCatalog.h:218
CMyApplication::DoJob
void DoJob()
Definition: MFCCatalogExample.cpp:111
MTL::CInstrumentCatalog::sInstrumentState::OperatingMode
eOperatingMode OperatingMode
Definition: InstrumentCatalog.h:213
MTL::CMFCManager::Operate
void Operate()
Definition: MFCManager.cpp:858
MTL::CMFCManager
Definition: MFCManager.h:39
CMyApplication::GetInterfaceString
std::string GetInterfaceString(CInstrumentCatalog::eConnectionInterface l_InstrInterface)
Definition: MFCCatalogExample.cpp:90
MTL::CInstrumentCatalog::eConnectionInterface
eConnectionInterface
Definition: InstrumentCatalog.h:32
MTL::CInstrumentCatalog::eOperatingMode::kSearch
@ kSearch
MTL::CInstrumentCatalog::sInstrumentState::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:216
MTL::CInstrumentCatalog
Definition: InstrumentCatalog.h:22
MTL::InstrumentCatalogInterface::CObserver_untyped::Is
bool Is(const CObserver_untyped &rObs)
Definition: CatalogInterface.h:70
CMyApplication::Subscribe
void Subscribe()
Definition: MFCCatalogExample.cpp:80
MTL::CGUICatalogInterface::oInstrumentList
CObserver< CInstrumentCatalog::tInstrumentList > oInstrumentList
Definition: InstrumentCatalog.h:563
MTL::InstrumentCatalogInterface::CAsyncNotification::Observer
CObserver_untyped & Observer() const
Definition: CatalogInterface.h:162
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:151