Skip to main content

nanonis_rs/client/oscilloscope/
osci_1t.rs

1use super::super::NanonisClient;
2use crate::error::NanonisError;
3use crate::types::NanonisValue;
4
5impl NanonisClient {
6    /// Set the channel to display in the Oscilloscope 1-Channel
7    /// channel_index: 0-23, corresponds to signals assigned to the 24 slots in the Signals Manager
8    pub fn osci1t_ch_set(&mut self, channel_index: i32) -> Result<(), NanonisError> {
9        self.quick_send(
10            "Osci1T.ChSet",
11            vec![NanonisValue::I32(channel_index)],
12            vec!["i"],
13            vec![],
14        )?;
15        Ok(())
16    }
17
18    /// Get the channel displayed in the Oscilloscope 1-Channel
19    /// Returns: channel index (0-23)
20    pub fn osci1t_ch_get(&mut self) -> Result<i32, NanonisError> {
21        let result = self.quick_send("Osci1T.ChGet", vec![], vec![], vec!["i"])?;
22        match result.first() {
23            Some(value) => Ok(value.as_i32()?),
24            None => Err(NanonisError::Protocol(
25                "No channel index returned".to_string(),
26            )),
27        }
28    }
29
30    /// Set the timebase in the Oscilloscope 1-Channel
31    /// Use osci1t_timebase_get() first to obtain available timebases, then use the index
32    pub fn osci1t_timebase_set(&mut self, timebase_index: i32) -> Result<(), NanonisError> {
33        self.quick_send(
34            "Osci1T.TimebaseSet",
35            vec![NanonisValue::I32(timebase_index)],
36            vec!["i"],
37            vec![],
38        )?;
39        Ok(())
40    }
41
42    /// Get the timebase in the Oscilloscope 1-Channel
43    /// Returns: (timebase_index, timebases_array)
44    pub fn osci1t_timebase_get(&mut self) -> Result<(i32, Vec<f32>), NanonisError> {
45        let result = self.quick_send("Osci1T.TimebaseGet", vec![], vec![], vec!["i", "i", "*f"])?;
46        if result.len() >= 3 {
47            let timebase_index = result[0].as_i32()?;
48            let timebases = result[2].as_f32_array()?.to_vec();
49            Ok((timebase_index, timebases))
50        } else {
51            Err(NanonisError::Protocol(
52                "Invalid timebase response".to_string(),
53            ))
54        }
55    }
56
57    /// Set the trigger configuration in the Oscilloscope 1-Channel.
58    ///
59    /// Prefer [`osci1t_trig_set_typed`](Self::osci1t_trig_set_typed) for a
60    /// type-safe interface using `OsciTriggerMode` and `TriggerSlope` enums.
61    pub fn osci1t_trig_set(
62        &mut self,
63        trigger_mode: u16,
64        trigger_slope: u16,
65        trigger_level: f64,
66        trigger_hysteresis: f64,
67    ) -> Result<(), NanonisError> {
68        self.quick_send(
69            "Osci1T.TrigSet",
70            vec![
71                NanonisValue::U16(trigger_mode),
72                NanonisValue::U16(trigger_slope),
73                NanonisValue::F64(trigger_level),
74                NanonisValue::F64(trigger_hysteresis),
75            ],
76            vec!["H", "H", "d", "d"],
77            vec![],
78        )?;
79        Ok(())
80    }
81
82    /// Get the trigger configuration in the Oscilloscope 1-Channel (raw u16).
83    ///
84    /// Returns raw protocol values. Prefer
85    /// [`osci1t_trig_get_typed`](Self::osci1t_trig_get_typed) for type-safe
86    /// `OsciTriggerMode` and `TriggerSlope` values.
87    pub fn osci1t_trig_get(&mut self) -> Result<(u16, u16, f64, f64), NanonisError> {
88        let result = self.quick_send("Osci1T.TrigGet", vec![], vec![], vec!["H", "H", "d", "d"])?;
89        if result.len() >= 4 {
90            let trigger_mode = result[0].as_u16()?;
91            let trigger_slope = result[1].as_u16()?;
92            let trigger_level = result[2].as_f64()?;
93            let trigger_hysteresis = result[3].as_f64()?;
94            Ok((
95                trigger_mode,
96                trigger_slope,
97                trigger_level,
98                trigger_hysteresis,
99            ))
100        } else {
101            Err(NanonisError::Protocol(
102                "Invalid trigger configuration response".to_string(),
103            ))
104        }
105    }
106
107    /// Set the trigger configuration using typed enums.
108    ///
109    /// # Examples
110    /// ```no_run
111    /// use nanonis_rs::NanonisClient;
112    /// use nanonis_rs::oscilloscope::{OsciTriggerMode, TriggerSlope};
113    ///
114    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
115    /// client.osci1t_trig_set_typed(
116    ///     OsciTriggerMode::Level,
117    ///     TriggerSlope::Rising,
118    ///     0.5,   // trigger level
119    ///     0.1,   // hysteresis
120    /// )?;
121    /// # Ok::<(), Box<dyn std::error::Error>>(())
122    /// ```
123    pub fn osci1t_trig_set_typed(
124        &mut self,
125        mode: super::types::OsciTriggerMode,
126        slope: super::types::TriggerSlope,
127        level: f64,
128        hysteresis: f64,
129    ) -> Result<(), NanonisError> {
130        self.osci1t_trig_set(u16::from(mode), u16::from(slope), level, hysteresis)
131    }
132
133    /// Get the trigger configuration as typed enums.
134    ///
135    /// # Examples
136    /// ```no_run
137    /// use nanonis_rs::NanonisClient;
138    ///
139    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
140    /// let (mode, slope, level, hysteresis) = client.osci1t_trig_get_typed()?;
141    /// println!("Mode: {:?}, Slope: {:?}, Level: {}", mode, slope, level);
142    /// # Ok::<(), Box<dyn std::error::Error>>(())
143    /// ```
144    pub fn osci1t_trig_get_typed(
145        &mut self,
146    ) -> Result<
147        (
148            super::types::OsciTriggerMode,
149            super::types::TriggerSlope,
150            f64,
151            f64,
152        ),
153        NanonisError,
154    > {
155        let (mode_raw, slope_raw, level, hysteresis) = self.osci1t_trig_get()?;
156        let mode = super::types::OsciTriggerMode::try_from(mode_raw)?;
157        let slope = super::types::TriggerSlope::try_from(slope_raw)?;
158        Ok((mode, slope, level, hysteresis))
159    }
160
161    /// Start the Oscilloscope 1-Channel
162    pub fn osci1t_run(&mut self) -> Result<(), NanonisError> {
163        self.quick_send("Osci1T.Run", vec![], vec![], vec![])?;
164        Ok(())
165    }
166
167    /// Get the graph data from the Oscilloscope 1-Channel
168    /// data_to_get: 0 = Current, 1 = Next trigger, 2 = Wait 2 triggers
169    /// Returns: (t0, dt, size, data_values)
170    pub fn osci1t_data_get(
171        &mut self,
172        data_to_get: u16,
173    ) -> Result<(f64, f64, i32, Vec<f64>), NanonisError> {
174        let result = self.quick_send(
175            "Osci1T.DataGet",
176            vec![NanonisValue::U16(data_to_get)],
177            vec!["H"],
178            vec!["d", "d", "i", "*d"],
179        )?;
180
181        if result.len() >= 4 {
182            let t0 = result[0].as_f64()?;
183            let dt = result[1].as_f64()?;
184            let size = result[2].as_i32()?;
185            let data = result[3].as_f64_array()?.to_vec();
186            Ok((t0, dt, size, data))
187        } else {
188            Err(NanonisError::Protocol(
189                "Invalid oscilloscope 1T data response".to_string(),
190            ))
191        }
192    }
193}