DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
RS_SMB100B.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "RS_SMB100B.h"
5
6namespace DynExpInstr
7{
9 {
10 auto InstrParams = DynExp::dynamic_Params_cast<RS_SMB100B>(Instance.ParamsGetter());
11 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
12
13 Instance.LockObject(InstrParams->HardwareAdapter, InstrData->HardwareAdapter);
14
16 }
17
19 {
20 ExitFuncImpl(dispatch_tag<ExitTask>(), Instance);
21
22 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
23
24 Instance.UnlockObject(InstrData->HardwareAdapter);
25 }
26
28 {
29 try
30 {
31 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
32 bool UpdateError = false;
33
34 try
35 {
36 *InstrData->HardwareAdapter << "OUTPut1:STATe?";
37 InstrData->Running = InstrData->HardwareAdapter->WaitForLine(3) == "1";
38 }
39 catch ([[maybe_unused]] const DynExp::SerialCommunicationException& e)
40 {
41 UpdateError = true;
42
43 // Swallow if just one or two subsequent updates failed.
44 if (InstrData->NumFailedStatusUpdateAttempts++ >= 3)
45 throw;
46 }
47
48 if (!UpdateError)
49 InstrData->NumFailedStatusUpdateAttempts = 0;
50 }
51 // Issued if a mutex is blocked by another operation.
52 catch (const Util::TimeoutException& e)
53 {
54 Instance.GetOwner().SetWarning(e);
55
56 return;
57 }
58 // Issued if reading data from RS_SMB100B controller failed.
60 {
61 Instance.GetOwner().SetWarning(e);
62
63 return;
64 }
65
66 UpdateFuncImpl(dispatch_tag<UpdateTask>(), Instance);
67 }
68
70 {
71 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
72
73 *InstrData->HardwareAdapter << "OUTPut1:STATe ON";
74
75 return {};
76 }
77
79 {
80 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
81
82 *InstrData->HardwareAdapter << "OUTPut1:STATe OFF";
83
84 return {};
85 }
86
88 {
89 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
90
91 *InstrData->HardwareAdapter << "SOURce1:FREQuency:MODE CW";
92 *InstrData->HardwareAdapter << "SOURce1:FREQuency:CW " + Util::ToStr(FunctionDesc.FrequencyInHz);
93 *InstrData->HardwareAdapter << "SOURce1:POWer:MODE CW";
94 *InstrData->HardwareAdapter << "SOURce1:POWer:POWer " + Util::ToStr(FunctionDesc.Amplitude);
95
96 if (Autostart)
97 InstrData->EnqueueTask(DynExp::MakeTask<RS_SMB100BTasks::StartTask>(nullptr));
98
99 return {};
100 }
101
103 {
104 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
105
108 {
109 *InstrData->HardwareAdapter << std::string("SOURce1:LFOutput1:SHAPe SINE");
110 *InstrData->HardwareAdapter << std::string("SOURce1:LFOutput1:FREQuency ")
111 + Util::ToStr(ModulationDesc.FrequencyInHz, 0) + " Hz";
112 }
115 {
116 *InstrData->HardwareAdapter << std::string("SOURce1:LFOutput1:SHAPe PULSe");
117 *InstrData->HardwareAdapter << std::string("SOURce1:LFOutput1:SHAPe:PULSe:PERiod ")
118 + Util::ToStr(1 / ModulationDesc.FrequencyInHz, 8) + " s";
119 *InstrData->HardwareAdapter << std::string("SOURce1:LFOutput1:SHAPe:PULSe:DCYCle ")
120 + Util::ToStr(ModulationDesc.PulseDutyCycle * 100, 3);
121 }
122
124 {
125 *InstrData->HardwareAdapter << std::string("SOURce1:FM1:SOURce LF1");
126 *InstrData->HardwareAdapter << std::string("SOURce1:FM1:DEViation ")
127 + Util::ToStr(ModulationDesc.Depth, 0) + " Hz";
128
129 *InstrData->HardwareAdapter << "SOURce1:AM1:STATe 0";
130 *InstrData->HardwareAdapter << "SOURce1:PM1:STATe 0";
131 *InstrData->HardwareAdapter << "SOURce1:FM1:STATe 1";
132 }
134 {
135 *InstrData->HardwareAdapter << std::string("SOURce1:AM1:SOURce LF1");
136 *InstrData->HardwareAdapter << std::string("SOURce1:AM1:DEPTh ")
137 + Util::ToStr(ModulationDesc.Depth, 0);
138
139 *InstrData->HardwareAdapter << "SOURce1:FM1:STATe 0";
140 *InstrData->HardwareAdapter << "SOURce1:PM1:STATe 0";
141 *InstrData->HardwareAdapter << "SOURce1:AM1:STATe 1";
142 }
144 {
145 *InstrData->HardwareAdapter << std::string("SOURce1:PM1:SOURce LF1");
146 *InstrData->HardwareAdapter << std::string("SOURce1:PM1:DEViation ")
147 + Util::ToStr(ModulationDesc.Depth, 0);
148
149 *InstrData->HardwareAdapter << "SOURce1:AM1:STATe 0";
150 *InstrData->HardwareAdapter << "SOURce1:FM1:STATe 0";
151 *InstrData->HardwareAdapter << "SOURce1:PM1:STATe 1";
152 }
153 else
154 {
155 *InstrData->HardwareAdapter << "SOURce1:AM1:STATe 0";
156 *InstrData->HardwareAdapter << "SOURce1:FM1:STATe 0";
157 *InstrData->HardwareAdapter << "SOURce1:PM1:STATe 0";
158 }
159
160 return {};
161 }
162
164 {
165 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
166
168 {
169 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:FREQuency:RETRace ")
170 + (SweepDesc.Retrace ? "1" : "0");
171 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:FREQuency:DWELl ")
172 + Util::ToStr(SweepDesc.TimeDiffPerSample_ms, 3) + " ms";
173 *InstrData->HardwareAdapter << std::string("SOURce1:FREQuency:STARt ")
174 + Util::ToStr(SweepDesc.Min, 0) + " Hz";
175 *InstrData->HardwareAdapter << std::string("SOURce1:FREQuency:STOP ")
176 + Util::ToStr(SweepDesc.Max, 0) + " Hz";
177 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:FREQuency:SPACing LINear");
178 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:FREQuency:SHAPe SAWTooth");
179 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:FREQuency:STEP:LINear ")
180 + Util::ToStr(SweepDesc.ValueDiffPerSample, 0) + " Hz";
181
182 *InstrData->HardwareAdapter << "SOURce1:POWer:MODE CW";
183 *InstrData->HardwareAdapter << "SOURce1:FREQuency:MODE SWEep";
184
186 }
188 {
189 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:POWer:RETRace ")
190 + (SweepDesc.Retrace ? "1" : "0");
191 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:POWer:DWELl ")
192 + Util::ToStr(SweepDesc.TimeDiffPerSample_ms, 3) + " ms";
193 *InstrData->HardwareAdapter << std::string("SOURce1:POWer:STARt ")
194 + Util::ToStr(SweepDesc.Min, 2) + " dBm";
195 *InstrData->HardwareAdapter << std::string("SOURce1:POWer:STOP ")
196 + Util::ToStr(SweepDesc.Max, 2) + " dBm";
197 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:POWer:SPACing LINear");
198 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:POWer:SHAPe SAWTooth");
199 *InstrData->HardwareAdapter << std::string("SOURce1:SWEep:POWer:STEP ")
200 + Util::ToStr(SweepDesc.ValueDiffPerSample, 2) + " dB";
201
202 *InstrData->HardwareAdapter << "SOURce1:FREQuency:MODE CW";
203 *InstrData->HardwareAdapter << "SOURce1:POWer:MODE SWEep";
204
206 }
207 else
208 {
209 *InstrData->HardwareAdapter << "SOURce1:FREQuency:MODE CW";
210 *InstrData->HardwareAdapter << "SOURce1:POWer:MODE CW";
211
213 }
214
215 return {};
216 }
217
219 {
220 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
221
222 if (InstrData->GetCurrentSweepType() == FunctionGeneratorDefs::SweepDescType::SweepType::Frequency)
223 {
224 *InstrData->HardwareAdapter << std::string("TRIGger1:FSWeep:SOURce ")
226 *InstrData->HardwareAdapter << "SOURce1:SWEep:FREQuency:MODE AUTO";
227
228 *InstrData->HardwareAdapter << "SOURce1:SWEep:FREQuency:EXECute";
229 }
230 else if (InstrData->GetCurrentSweepType() == FunctionGeneratorDefs::SweepDescType::SweepType::Amplitude)
231 {
232 *InstrData->HardwareAdapter << std::string("TRIGger1:PSWeep:SOURce ")
234 *InstrData->HardwareAdapter << "SOURce1:SWEep:POWer:MODE AUTO";
235
236 *InstrData->HardwareAdapter << "SOURce1:SWEep:POWer:EXECute";
237 }
238
239 return {};
240 }
241
243 {
244 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(Instance.InstrumentDataGetter());
245
246 if (InstrData->GetCurrentSweepType() == FunctionGeneratorDefs::SweepDescType::SweepType::Frequency)
247 {
248 *InstrData->HardwareAdapter << std::string("TRIGger1:FSWeep:SOURce ")
249 + RS_SMB100B::TriggerModeToCmdString(TriggerDesc.TriggerMode);
251 *InstrData->HardwareAdapter << "SOURce1:SWEep:FREQuency:MODE STEP";
252 else
253 *InstrData->HardwareAdapter << "SOURce1:SWEep:FREQuency:MODE AUTO";
254 }
255 else if (InstrData->GetCurrentSweepType() == FunctionGeneratorDefs::SweepDescType::SweepType::Amplitude)
256 {
257 *InstrData->HardwareAdapter << std::string("TRIGger1:PSWeep:SOURce ")
258 + RS_SMB100B::TriggerModeToCmdString(TriggerDesc.TriggerMode);
260 *InstrData->HardwareAdapter << "SOURce1:SWEep:POWer:MODE STEP";
261 else
262 *InstrData->HardwareAdapter << "SOURce1:SWEep:POWer:MODE AUTO";
263 }
264
265 *InstrData->HardwareAdapter << std::string("SOURce:INPut:TRIGger:SLOPe ") +
266 (TriggerDesc.TriggerEdge == FunctionGeneratorDefs::TriggerDescType::TriggerEdgeType::Fall ? "NEGative" : "POSitive");
267
268 return {};
269 }
270
272 {
273 NumFailedStatusUpdateAttempts = 0;
274 Running = false;
276
277 ResetImpl(dispatch_tag<RS_SMB100BData>());
278 }
279
291
292 RS_SMB100B::RS_SMB100B(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
293 : FunctionGenerator(OwnerThreadID, std::move(Params))
294 {
295 }
296
298 bool PersistParams, bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
299 {
300 if (PersistParams)
301 {
302 auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
303 InstrParams->WaveformType = FunctionGeneratorDefs::WaveformTypes::Sine;
304 InstrParams->FrequencyInHz = FunctionDesc.FrequencyInHz;
305 InstrParams->Amplitude = FunctionDesc.Amplitude;
306 InstrParams->Offset = 0;
307 InstrParams->PhaseInRad = FunctionDesc.PhaseInRad;
308 InstrParams->DutyCycle = 0;
309 InstrParams->Autostart = Autostart;
310 } // InstrParams unlocked here.
311
312 MakeAndEnqueueTask<RS_SMB100BTasks::SetSineFunctionTask>(FunctionDesc, Autostart, CallbackFunc);
313 }
314
316 bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
317 {
318 MakeAndEnqueueTask<RS_SMB100BTasks::SetModulationTask>(ModulationDesc, CallbackFunc);
319 }
320
322 bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
323 {
324 MakeAndEnqueueTask<RS_SMB100BTasks::SetSweepTask>(SweepDesc, CallbackFunc);
325 }
326
328 {
329 MakeAndEnqueueTask<RS_SMB100BTasks::ForceTriggerTask>(CallbackFunc);
330 }
331
333 {
334 auto InstrData = DynExp::dynamic_InstrumentData_cast<RS_SMB100B>(GetInstrumentData());
335
336 return InstrData->IsRunning();
337 }
338
343
345 bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
346 {
347 MakeAndEnqueueTask<RS_SMB100BTasks::SetTriggerTask>(TriggerDesc, CallbackFunc);
348 }
349}
Implementation of an instrument to control the Rohde & Schwarz SMB100B function generator.
Function generator meta instrument based on the data stream meta instrument to generate waveforms by ...
void ResetImpl(dispatch_tag< FunctionGeneratorData >) override final
void ExitFuncImpl(dispatch_tag< FunctionGeneratorTasks::ExitTask >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
void InitFuncImpl(dispatch_tag< FunctionGeneratorTasks::InitTask >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
Definition RS_SMB100B.cpp:8
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
void UpdateFuncImpl(dispatch_tag< FunctionGeneratorTasks::UpdateTask >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
virtual void SetTriggerChild(const FunctionGeneratorDefs::TriggerDescType &TriggerDesc, bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const override
SetTrigger() configures the function generator's trigger, which determines when the waveform generati...
RS_SMB100B(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
virtual Util::OptionalBool IsRunning() const override
Determines whether the underlying hardware adapter is running a data acquisition or writing data.
virtual void SetSineFunction(const FunctionGeneratorDefs::SineFunctionDescType &FunctionDesc, bool PersistParams=false, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Generates a sine function.
virtual void ForceTrigger(DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Forces the generation of the waveform ignoring the trigger.
virtual void SetSweep(const FunctionGeneratorDefs::SweepDescType &SweepDesc, bool PersistParams=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Configures the function generator to perform a sweep.
static const char * TriggerModeToCmdString(FunctionGeneratorDefs::TriggerDescType::TriggerModeType TriggerMode) noexcept
void ResetImpl(dispatch_tag< FunctionGenerator >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual void SetModulation(const FunctionGeneratorDefs::ModulationDescType &ModulationDesc, bool PersistParams=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Configures the function generator to perform a modulation.
Refer to DynExp::ParamsBase::dispatch_tag.
Refer to DynExp::ParamsBase::dispatch_tag.
InstrumentDataTypeSyncPtrType GetInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault)
Locks the mutex of the instrument data class instance InstrumentData assigned to this InstrumentBase ...
Refer to ParamsBase::dispatch_tag.
Definition Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition Instrument.h:772
const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter
Getter for instrument's data. Refer to InstrumentBase::InstrumentDataGetterType.
Definition Instrument.h:791
ParamsTypeSyncPtrType GetNonConstParams(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Allows derived Objects to edit their own parameters - even in const task functions (for instruments) ...
Definition Object.cpp:475
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT > > &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition Object.h:3524
Defines an exception caused by a serial communication operation of a hardware adapter.
std::function< void(const TaskBase &, ExceptionContainer &)> CallbackType
Type of a callback function which is invoked when a task has finished, failed or has been aborted....
Definition Instrument.h:939
Defines the return type of task functions.
Definition Instrument.h:824
Refer to DynExp::ParamsBase::dispatch_tag.
Data type which stores an optional bool value (unknown, false, true). The type evaluates to bool whil...
Definition Util.h:549
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition Exception.h:261
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition Object.h:1807
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition Util.h:625
Accumulates include statements to provide a precompiled header.
double FrequencyInHz
Frequency of the function in Hz.
Type describing modulation parameters for a waveform.
@ Pulse
Pulse (binary) modulation switching the affected quantity between two values.
@ Frequency
Modulation affecting the waveform's frequency.
@ Amplitude
Modulation affecting the waveform's amplitude.
double PhaseInRad
Phase of the function in radians.
Type describing sweep parameters for a waveform.
Type describing trigger parameters determining when the waveform is generated.
TriggerModeType
Type to determine the trigger mode. Not a strongly-typed enum to allow using the enumeration in a Dyn...
@ ExternStep
Advance by a single (sweep) sample after an external trigger signal has been detected.
@ Continuous
Run continuously disabling the trigger.
@ ExternSingle
Run once after an external trigger signal has been detected.