Skip to main content

nanonis_rs/client/lockin/
mod.rs

1mod types;
2pub use types::*;
3
4use super::NanonisClient;
5use crate::error::NanonisError;
6use crate::types::NanonisValue;
7
8impl NanonisClient {
9    // ==================== Modulator Methods ====================
10
11    /// Turn the specified Lock-In modulator on or off.
12    ///
13    /// # Arguments
14    /// * `modulator_num` - Modulator number (1-8)
15    /// * `on` - `true` to turn on, `false` to turn off
16    ///
17    /// # Errors
18    /// Returns `NanonisError` if communication fails.
19    ///
20    /// # Examples
21    /// ```no_run
22    /// use nanonis_rs::NanonisClient;
23    ///
24    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
25    /// client.lockin_mod_on_off_set(1, true)?; // Turn on modulator 1
26    /// # Ok::<(), Box<dyn std::error::Error>>(())
27    /// ```
28    pub fn lockin_mod_on_off_set(
29        &mut self,
30        modulator_num: i32,
31        on: bool,
32    ) -> Result<(), NanonisError> {
33        let on_flag = if on { 1u32 } else { 0u32 };
34        self.quick_send(
35            "LockIn.ModOnOffSet",
36            vec![NanonisValue::I32(modulator_num), NanonisValue::U32(on_flag)],
37            vec!["i", "I"],
38            vec![],
39        )?;
40        Ok(())
41    }
42
43    /// Get the on/off status of the specified Lock-In modulator.
44    ///
45    /// # Arguments
46    /// * `modulator_num` - Modulator number (1-8)
47    ///
48    /// # Returns
49    /// `true` if modulator is on, `false` if off.
50    ///
51    /// # Errors
52    /// Returns `NanonisError` if communication fails.
53    ///
54    /// # Examples
55    /// ```no_run
56    /// use nanonis_rs::NanonisClient;
57    ///
58    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
59    /// let is_on = client.lockin_mod_on_off_get(1)?;
60    /// println!("Modulator 1 is {}", if is_on { "on" } else { "off" });
61    /// # Ok::<(), Box<dyn std::error::Error>>(())
62    /// ```
63    pub fn lockin_mod_on_off_get(&mut self, modulator_num: i32) -> Result<bool, NanonisError> {
64        let result = self.quick_send(
65            "LockIn.ModOnOffGet",
66            vec![NanonisValue::I32(modulator_num)],
67            vec!["i"],
68            vec!["I"],
69        )?;
70        if let Some(val) = result.first() {
71            Ok(val.as_u32()? != 0)
72        } else {
73            Err(NanonisError::Protocol("Invalid response".to_string()))
74        }
75    }
76
77    /// Set the modulated signal of the specified Lock-In modulator.
78    ///
79    /// # Arguments
80    /// * `modulator_num` - Modulator number (1-8)
81    /// * `signal_index` - Signal index (0-127)
82    ///
83    /// # Errors
84    /// Returns `NanonisError` if communication fails.
85    ///
86    /// # Examples
87    /// ```no_run
88    /// use nanonis_rs::NanonisClient;
89    ///
90    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
91    /// client.lockin_mod_signal_set(1, 14)?; // Set modulator 1 to signal 14
92    /// # Ok::<(), Box<dyn std::error::Error>>(())
93    /// ```
94    pub fn lockin_mod_signal_set(
95        &mut self,
96        modulator_num: i32,
97        signal_index: i32,
98    ) -> Result<(), NanonisError> {
99        self.quick_send(
100            "LockIn.ModSignalSet",
101            vec![
102                NanonisValue::I32(modulator_num),
103                NanonisValue::I32(signal_index),
104            ],
105            vec!["i", "i"],
106            vec![],
107        )?;
108        Ok(())
109    }
110
111    /// Get the modulated signal index of the specified Lock-In modulator.
112    ///
113    /// # Arguments
114    /// * `modulator_num` - Modulator number (1-8)
115    ///
116    /// # Returns
117    /// Signal index (0-127).
118    ///
119    /// # Errors
120    /// Returns `NanonisError` if communication fails.
121    pub fn lockin_mod_signal_get(&mut self, modulator_num: i32) -> Result<i32, NanonisError> {
122        let result = self.quick_send(
123            "LockIn.ModSignalGet",
124            vec![NanonisValue::I32(modulator_num)],
125            vec!["i"],
126            vec!["i"],
127        )?;
128        if let Some(val) = result.first() {
129            Ok(val.as_i32()?)
130        } else {
131            Err(NanonisError::Protocol("Invalid response".to_string()))
132        }
133    }
134
135    /// Set the phase register index of the specified Lock-In modulator.
136    ///
137    /// # Arguments
138    /// * `modulator_num` - Modulator number (1-8)
139    /// * `phase_register_index` - Phase register index (1-8)
140    ///
141    /// # Errors
142    /// Returns `NanonisError` if communication fails.
143    ///
144    /// # Examples
145    /// ```no_run
146    /// use nanonis_rs::NanonisClient;
147    ///
148    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
149    /// client.lockin_mod_phas_reg_set(1, 1)?; // Assign modulator 1 to phase register 1
150    /// # Ok::<(), Box<dyn std::error::Error>>(())
151    /// ```
152    pub fn lockin_mod_phas_reg_set(
153        &mut self,
154        modulator_num: i32,
155        phase_register_index: i32,
156    ) -> Result<(), NanonisError> {
157        self.quick_send(
158            "LockIn.ModPhasRegSet",
159            vec![
160                NanonisValue::I32(modulator_num),
161                NanonisValue::I32(phase_register_index),
162            ],
163            vec!["i", "i"],
164            vec![],
165        )?;
166        Ok(())
167    }
168
169    /// Get the phase register index of the specified Lock-In modulator.
170    ///
171    /// # Arguments
172    /// * `modulator_num` - Modulator number (1-8)
173    ///
174    /// # Returns
175    /// Phase register index (1-8).
176    pub fn lockin_mod_phas_reg_get(&mut self, modulator_num: i32) -> Result<i32, NanonisError> {
177        let result = self.quick_send(
178            "LockIn.ModPhasRegGet",
179            vec![NanonisValue::I32(modulator_num)],
180            vec!["i"],
181            vec!["i"],
182        )?;
183        if let Some(val) = result.first() {
184            Ok(val.as_i32()?)
185        } else {
186            Err(NanonisError::Protocol("Invalid response".to_string()))
187        }
188    }
189
190    /// Set the harmonic of the specified Lock-In modulator.
191    ///
192    /// # Arguments
193    /// * `modulator_num` - Modulator number (1-8)
194    /// * `harmonic` - Harmonic number (1 = base frequency)
195    ///
196    /// # Errors
197    /// Returns `NanonisError` if communication fails.
198    pub fn lockin_mod_harmonic_set(
199        &mut self,
200        modulator_num: i32,
201        harmonic: i32,
202    ) -> Result<(), NanonisError> {
203        self.quick_send(
204            "LockIn.ModHarmonicSet",
205            vec![
206                NanonisValue::I32(modulator_num),
207                NanonisValue::I32(harmonic),
208            ],
209            vec!["i", "i"],
210            vec![],
211        )?;
212        Ok(())
213    }
214
215    /// Get the harmonic of the specified Lock-In modulator.
216    ///
217    /// # Arguments
218    /// * `modulator_num` - Modulator number (1-8)
219    ///
220    /// # Returns
221    /// Harmonic number (1 = base frequency).
222    pub fn lockin_mod_harmonic_get(&mut self, modulator_num: i32) -> Result<i32, NanonisError> {
223        let result = self.quick_send(
224            "LockIn.ModHarmonicGet",
225            vec![NanonisValue::I32(modulator_num)],
226            vec!["i"],
227            vec!["i"],
228        )?;
229        if let Some(val) = result.first() {
230            Ok(val.as_i32()?)
231        } else {
232            Err(NanonisError::Protocol("Invalid response".to_string()))
233        }
234    }
235
236    /// Set the modulation phase offset of the specified Lock-In modulator.
237    ///
238    /// # Arguments
239    /// * `modulator_num` - Modulator number (1-8)
240    /// * `phase_deg` - Phase offset in degrees
241    ///
242    /// # Errors
243    /// Returns `NanonisError` if communication fails.
244    pub fn lockin_mod_phas_set(
245        &mut self,
246        modulator_num: i32,
247        phase_deg: f32,
248    ) -> Result<(), NanonisError> {
249        self.quick_send(
250            "LockIn.ModPhasSet",
251            vec![
252                NanonisValue::I32(modulator_num),
253                NanonisValue::F32(phase_deg),
254            ],
255            vec!["i", "f"],
256            vec![],
257        )?;
258        Ok(())
259    }
260
261    /// Get the modulation phase offset of the specified Lock-In modulator.
262    ///
263    /// # Arguments
264    /// * `modulator_num` - Modulator number (1-8)
265    ///
266    /// # Returns
267    /// Phase offset in degrees.
268    pub fn lockin_mod_phas_get(&mut self, modulator_num: i32) -> Result<f32, NanonisError> {
269        let result = self.quick_send(
270            "LockIn.ModPhasGet",
271            vec![NanonisValue::I32(modulator_num)],
272            vec!["i"],
273            vec!["f"],
274        )?;
275        if let Some(val) = result.first() {
276            Ok(val.as_f32()?)
277        } else {
278            Err(NanonisError::Protocol("Invalid response".to_string()))
279        }
280    }
281
282    /// Set the modulation amplitude of the specified Lock-In modulator.
283    ///
284    /// # Arguments
285    /// * `modulator_num` - Modulator number (1-8)
286    /// * `amplitude` - Modulation amplitude
287    ///
288    /// # Errors
289    /// Returns `NanonisError` if communication fails.
290    pub fn lockin_mod_amp_set(
291        &mut self,
292        modulator_num: i32,
293        amplitude: f32,
294    ) -> Result<(), NanonisError> {
295        self.quick_send(
296            "LockIn.ModAmpSet",
297            vec![
298                NanonisValue::I32(modulator_num),
299                NanonisValue::F32(amplitude),
300            ],
301            vec!["i", "f"],
302            vec![],
303        )?;
304        Ok(())
305    }
306
307    /// Get the modulation amplitude of the specified Lock-In modulator.
308    ///
309    /// # Arguments
310    /// * `modulator_num` - Modulator number (1-8)
311    ///
312    /// # Returns
313    /// Modulation amplitude.
314    pub fn lockin_mod_amp_get(&mut self, modulator_num: i32) -> Result<f32, NanonisError> {
315        let result = self.quick_send(
316            "LockIn.ModAmpGet",
317            vec![NanonisValue::I32(modulator_num)],
318            vec!["i"],
319            vec!["f"],
320        )?;
321        if let Some(val) = result.first() {
322            Ok(val.as_f32()?)
323        } else {
324            Err(NanonisError::Protocol("Invalid response".to_string()))
325        }
326    }
327
328    /// Set the frequency of the specified Lock-In phase register/modulator.
329    ///
330    /// # Arguments
331    /// * `modulator_num` - Phase register/modulator number (1-8)
332    /// * `frequency_hz` - Frequency in Hz
333    ///
334    /// # Errors
335    /// Returns `NanonisError` if communication fails.
336    ///
337    /// # Examples
338    /// ```no_run
339    /// use nanonis_rs::NanonisClient;
340    ///
341    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
342    /// client.lockin_mod_phas_freq_set(1, 1000.0)?; // Set 1kHz
343    /// # Ok::<(), Box<dyn std::error::Error>>(())
344    /// ```
345    pub fn lockin_mod_phas_freq_set(
346        &mut self,
347        modulator_num: i32,
348        frequency_hz: f64,
349    ) -> Result<(), NanonisError> {
350        self.quick_send(
351            "LockIn.ModPhasFreqSet",
352            vec![
353                NanonisValue::I32(modulator_num),
354                NanonisValue::F64(frequency_hz),
355            ],
356            vec!["i", "d"],
357            vec![],
358        )?;
359        Ok(())
360    }
361
362    /// Get the frequency of the specified Lock-In phase register/modulator.
363    ///
364    /// # Arguments
365    /// * `modulator_num` - Phase register/modulator number (1-8)
366    ///
367    /// # Returns
368    /// Frequency in Hz.
369    pub fn lockin_mod_phas_freq_get(&mut self, modulator_num: i32) -> Result<f64, NanonisError> {
370        let result = self.quick_send(
371            "LockIn.ModPhasFreqGet",
372            vec![NanonisValue::I32(modulator_num)],
373            vec!["i"],
374            vec!["d"],
375        )?;
376        if let Some(val) = result.first() {
377            Ok(val.as_f64()?)
378        } else {
379            Err(NanonisError::Protocol("Invalid response".to_string()))
380        }
381    }
382
383    // ==================== Demodulator Methods ====================
384
385    /// Set the demodulated signal of the specified Lock-In demodulator.
386    ///
387    /// # Arguments
388    /// * `demodulator_num` - Demodulator number (1-8)
389    /// * `signal_index` - Signal index (0-127)
390    ///
391    /// # Errors
392    /// Returns `NanonisError` if communication fails.
393    pub fn lockin_demod_signal_set(
394        &mut self,
395        demodulator_num: i32,
396        signal_index: i32,
397    ) -> Result<(), NanonisError> {
398        self.quick_send(
399            "LockIn.DemodSignalSet",
400            vec![
401                NanonisValue::I32(demodulator_num),
402                NanonisValue::I32(signal_index),
403            ],
404            vec!["i", "i"],
405            vec![],
406        )?;
407        Ok(())
408    }
409
410    /// Get the demodulated signal index of the specified Lock-In demodulator.
411    ///
412    /// # Arguments
413    /// * `demodulator_num` - Demodulator number (1-8)
414    ///
415    /// # Returns
416    /// Signal index (0-127).
417    pub fn lockin_demod_signal_get(&mut self, demodulator_num: i32) -> Result<i32, NanonisError> {
418        let result = self.quick_send(
419            "LockIn.DemodSignalGet",
420            vec![NanonisValue::I32(demodulator_num)],
421            vec!["i"],
422            vec!["i"],
423        )?;
424        if let Some(val) = result.first() {
425            Ok(val.as_i32()?)
426        } else {
427            Err(NanonisError::Protocol("Invalid response".to_string()))
428        }
429    }
430
431    /// Set the harmonic of the specified Lock-In demodulator.
432    ///
433    /// # Arguments
434    /// * `demodulator_num` - Demodulator number (1-8)
435    /// * `harmonic` - Harmonic number (1 = base frequency)
436    pub fn lockin_demod_harmonic_set(
437        &mut self,
438        demodulator_num: i32,
439        harmonic: i32,
440    ) -> Result<(), NanonisError> {
441        self.quick_send(
442            "LockIn.DemodHarmonicSet",
443            vec![
444                NanonisValue::I32(demodulator_num),
445                NanonisValue::I32(harmonic),
446            ],
447            vec!["i", "i"],
448            vec![],
449        )?;
450        Ok(())
451    }
452
453    /// Get the harmonic of the specified Lock-In demodulator.
454    ///
455    /// # Arguments
456    /// * `demodulator_num` - Demodulator number (1-8)
457    ///
458    /// # Returns
459    /// Harmonic number (1 = base frequency).
460    pub fn lockin_demod_harmonic_get(&mut self, demodulator_num: i32) -> Result<i32, NanonisError> {
461        let result = self.quick_send(
462            "LockIn.DemodHarmonicGet",
463            vec![NanonisValue::I32(demodulator_num)],
464            vec!["i"],
465            vec!["i"],
466        )?;
467        if let Some(val) = result.first() {
468            Ok(val.as_i32()?)
469        } else {
470            Err(NanonisError::Protocol("Invalid response".to_string()))
471        }
472    }
473
474    /// Set the high-pass filter properties for the specified demodulator.
475    ///
476    /// # Arguments
477    /// * `demodulator_num` - Demodulator number (1-8)
478    /// * `filter_order` - Filter order (-1=no change, 0=off, 1-8=active)
479    /// * `cutoff_hz` - Cutoff frequency in Hz (0=no change)
480    pub fn lockin_demod_hp_filter_set(
481        &mut self,
482        demodulator_num: i32,
483        filter_order: i32,
484        cutoff_hz: f32,
485    ) -> Result<(), NanonisError> {
486        self.quick_send(
487            "LockIn.DemodHPFilterSet",
488            vec![
489                NanonisValue::I32(demodulator_num),
490                NanonisValue::I32(filter_order),
491                NanonisValue::F32(cutoff_hz),
492            ],
493            vec!["i", "i", "f"],
494            vec![],
495        )?;
496        Ok(())
497    }
498
499    /// Get the high-pass filter properties for the specified demodulator.
500    ///
501    /// # Arguments
502    /// * `demodulator_num` - Demodulator number (1-8)
503    ///
504    /// # Returns
505    /// A [`FilterConfig`] with order and cutoff frequency.
506    pub fn lockin_demod_hp_filter_get(
507        &mut self,
508        demodulator_num: i32,
509    ) -> Result<FilterConfig, NanonisError> {
510        let result = self.quick_send(
511            "LockIn.DemodHPFilterGet",
512            vec![NanonisValue::I32(demodulator_num)],
513            vec!["i"],
514            vec!["i", "f"],
515        )?;
516        if result.len() >= 2 {
517            Ok(FilterConfig {
518                order: result[0].as_i32()?,
519                cutoff_hz: result[1].as_f32()?,
520            })
521        } else {
522            Err(NanonisError::Protocol("Invalid response".to_string()))
523        }
524    }
525
526    /// Set the low-pass filter properties for the specified demodulator.
527    ///
528    /// # Arguments
529    /// * `demodulator_num` - Demodulator number (1-8)
530    /// * `filter_order` - Filter order (-1=no change, 0=off, 1-8=active)
531    /// * `cutoff_hz` - Cutoff frequency in Hz (0=no change)
532    pub fn lockin_demod_lp_filter_set(
533        &mut self,
534        demodulator_num: i32,
535        filter_order: i32,
536        cutoff_hz: f32,
537    ) -> Result<(), NanonisError> {
538        self.quick_send(
539            "LockIn.DemodLPFilterSet",
540            vec![
541                NanonisValue::I32(demodulator_num),
542                NanonisValue::I32(filter_order),
543                NanonisValue::F32(cutoff_hz),
544            ],
545            vec!["i", "i", "f"],
546            vec![],
547        )?;
548        Ok(())
549    }
550
551    /// Get the low-pass filter properties for the specified demodulator.
552    ///
553    /// # Arguments
554    /// * `demodulator_num` - Demodulator number (1-8)
555    ///
556    /// # Returns
557    /// A [`FilterConfig`] with order and cutoff frequency.
558    pub fn lockin_demod_lp_filter_get(
559        &mut self,
560        demodulator_num: i32,
561    ) -> Result<FilterConfig, NanonisError> {
562        let result = self.quick_send(
563            "LockIn.DemodLPFilterGet",
564            vec![NanonisValue::I32(demodulator_num)],
565            vec!["i"],
566            vec!["i", "f"],
567        )?;
568        if result.len() >= 2 {
569            Ok(FilterConfig {
570                order: result[0].as_i32()?,
571                cutoff_hz: result[1].as_f32()?,
572            })
573        } else {
574            Err(NanonisError::Protocol("Invalid response".to_string()))
575        }
576    }
577
578    /// Set the phase register index of the specified Lock-In demodulator.
579    ///
580    /// # Arguments
581    /// * `demodulator_num` - Demodulator number (1-8)
582    /// * `phase_register_index` - Phase register index (1-8)
583    pub fn lockin_demod_phas_reg_set(
584        &mut self,
585        demodulator_num: i32,
586        phase_register_index: i32,
587    ) -> Result<(), NanonisError> {
588        self.quick_send(
589            "LockIn.DemodPhasRegSet",
590            vec![
591                NanonisValue::I32(demodulator_num),
592                NanonisValue::I32(phase_register_index),
593            ],
594            vec!["i", "i"],
595            vec![],
596        )?;
597        Ok(())
598    }
599
600    /// Get the phase register index of the specified Lock-In demodulator.
601    ///
602    /// # Arguments
603    /// * `demodulator_num` - Demodulator number (1-8)
604    ///
605    /// # Returns
606    /// Phase register index (1-8).
607    pub fn lockin_demod_phas_reg_get(
608        &mut self,
609        demodulator_num: i32,
610    ) -> Result<i32, NanonisError> {
611        let result = self.quick_send(
612            "LockIn.DemodPhasRegGet",
613            vec![NanonisValue::I32(demodulator_num)],
614            vec!["i"],
615            vec!["i"],
616        )?;
617        if let Some(val) = result.first() {
618            Ok(val.as_i32()?)
619        } else {
620            Err(NanonisError::Protocol("Invalid response".to_string()))
621        }
622    }
623
624    /// Set the reference phase of the specified Lock-In demodulator.
625    ///
626    /// # Arguments
627    /// * `demodulator_num` - Demodulator number (1-8)
628    /// * `phase_deg` - Reference phase in degrees
629    pub fn lockin_demod_phas_set(
630        &mut self,
631        demodulator_num: i32,
632        phase_deg: f32,
633    ) -> Result<(), NanonisError> {
634        self.quick_send(
635            "LockIn.DemodPhasSet",
636            vec![
637                NanonisValue::I32(demodulator_num),
638                NanonisValue::F32(phase_deg),
639            ],
640            vec!["i", "f"],
641            vec![],
642        )?;
643        Ok(())
644    }
645
646    /// Get the reference phase of the specified Lock-In demodulator.
647    ///
648    /// # Arguments
649    /// * `demodulator_num` - Demodulator number (1-8)
650    ///
651    /// # Returns
652    /// Reference phase in degrees.
653    pub fn lockin_demod_phas_get(&mut self, demodulator_num: i32) -> Result<f32, NanonisError> {
654        let result = self.quick_send(
655            "LockIn.DemodPhasGet",
656            vec![NanonisValue::I32(demodulator_num)],
657            vec!["i"],
658            vec!["f"],
659        )?;
660        if let Some(val) = result.first() {
661            Ok(val.as_f32()?)
662        } else {
663            Err(NanonisError::Protocol("Invalid response".to_string()))
664        }
665    }
666
667    /// Set the sync filter on/off for the specified demodulator.
668    ///
669    /// The synchronous filter suppresses harmonic components very well
670    /// but only updates after each period of the demodulation frequency.
671    ///
672    /// # Arguments
673    /// * `demodulator_num` - Demodulator number (1-8)
674    /// * `on` - `true` to enable sync filter, `false` to disable
675    pub fn lockin_demod_sync_filter_set(
676        &mut self,
677        demodulator_num: i32,
678        on: bool,
679    ) -> Result<(), NanonisError> {
680        let on_flag = if on { 1u32 } else { 0u32 };
681        self.quick_send(
682            "LockIn.DemodSyncFilterSet",
683            vec![
684                NanonisValue::I32(demodulator_num),
685                NanonisValue::U32(on_flag),
686            ],
687            vec!["i", "I"],
688            vec![],
689        )?;
690        Ok(())
691    }
692
693    /// Get the sync filter status for the specified demodulator.
694    ///
695    /// # Arguments
696    /// * `demodulator_num` - Demodulator number (1-8)
697    ///
698    /// # Returns
699    /// `true` if sync filter is on.
700    pub fn lockin_demod_sync_filter_get(
701        &mut self,
702        demodulator_num: i32,
703    ) -> Result<bool, NanonisError> {
704        let result = self.quick_send(
705            "LockIn.DemodSyncFilterGet",
706            vec![NanonisValue::I32(demodulator_num)],
707            vec!["i"],
708            vec!["I"],
709        )?;
710        if let Some(val) = result.first() {
711            Ok(val.as_u32()? != 0)
712        } else {
713            Err(NanonisError::Protocol("Invalid response".to_string()))
714        }
715    }
716
717    /// Set the RT signals mode for the specified demodulator.
718    ///
719    /// # Arguments
720    /// * `demodulator_num` - Demodulator number (1-8)
721    /// * `mode` - [`RTSignalMode::XY`] or [`RTSignalMode::RPhi`]
722    pub fn lockin_demod_rt_signals_set(
723        &mut self,
724        demodulator_num: i32,
725        mode: RTSignalMode,
726    ) -> Result<(), NanonisError> {
727        self.quick_send(
728            "LockIn.DemodRTSignalsSet",
729            vec![
730                NanonisValue::I32(demodulator_num),
731                NanonisValue::U32(mode.into()),
732            ],
733            vec!["i", "I"],
734            vec![],
735        )?;
736        Ok(())
737    }
738
739    /// Get the RT signals mode for the specified demodulator.
740    ///
741    /// # Arguments
742    /// * `demodulator_num` - Demodulator number (1-8)
743    ///
744    /// # Returns
745    /// The [`RTSignalMode`] (X/Y or R/phi).
746    pub fn lockin_demod_rt_signals_get(
747        &mut self,
748        demodulator_num: i32,
749    ) -> Result<RTSignalMode, NanonisError> {
750        let result = self.quick_send(
751            "LockIn.DemodRTSignalsGet",
752            vec![NanonisValue::I32(demodulator_num)],
753            vec!["i"],
754            vec!["I"],
755        )?;
756        if let Some(val) = result.first() {
757            RTSignalMode::try_from(val.as_u32()?)
758        } else {
759            Err(NanonisError::Protocol("Invalid response".to_string()))
760        }
761    }
762}