Skip to main content

nanonis_rs/client/
oc_sync.rs

1use super::NanonisClient;
2use crate::error::NanonisError;
3use crate::types::NanonisValue;
4
5/// Link angles mode for OC Sync module.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum LinkAnglesMode {
8    #[default]
9    NoChange = 0,
10    Link = 1,
11    Unlink = 2,
12}
13
14impl From<LinkAnglesMode> for u32 {
15    fn from(mode: LinkAnglesMode) -> Self {
16        mode as u32
17    }
18}
19
20/// OC Sync angle configuration.
21#[derive(Debug, Clone, Copy, Default)]
22pub struct OCSyncAngles {
23    /// Channel 1 on angle (degrees)
24    pub ch1_on_deg: f32,
25    /// Channel 1 off angle (degrees)
26    pub ch1_off_deg: f32,
27    /// Channel 2 on angle (degrees)
28    pub ch2_on_deg: f32,
29    /// Channel 2 off angle (degrees)
30    pub ch2_off_deg: f32,
31}
32
33/// OC Sync link status.
34#[derive(Debug, Clone, Copy, Default)]
35pub struct OCSyncLinkStatus {
36    /// Channel 1 link status (true = linked)
37    pub ch1_linked: bool,
38    /// Channel 2 link status (true = linked)
39    pub ch2_linked: bool,
40}
41
42impl NanonisClient {
43    // ==================== OC Sync ====================
44
45    /// Set the angle values for digital channels 1 and 2.
46    ///
47    /// The On angle is the excitation angle at which the digital channel goes high.
48    /// The Off angle is the excitation angle at which the digital channel goes low.
49    ///
50    /// # Arguments
51    /// * `angles` - Angle configuration
52    ///
53    /// # Errors
54    /// Returns `NanonisError` if communication fails.
55    pub fn oc_sync_angles_set(&mut self, angles: &OCSyncAngles) -> Result<(), NanonisError> {
56        self.quick_send(
57            "OCSync.AnglesSet",
58            vec![
59                NanonisValue::F32(angles.ch1_on_deg),
60                NanonisValue::F32(angles.ch1_off_deg),
61                NanonisValue::F32(angles.ch2_on_deg),
62                NanonisValue::F32(angles.ch2_off_deg),
63            ],
64            vec!["f", "f", "f", "f"],
65            vec![],
66        )?;
67        Ok(())
68    }
69
70    /// Get the angle values for digital channels 1 and 2.
71    ///
72    /// # Returns
73    /// Angle configuration.
74    ///
75    /// # Errors
76    /// Returns `NanonisError` if communication fails.
77    pub fn oc_sync_angles_get(&mut self) -> Result<OCSyncAngles, NanonisError> {
78        let result =
79            self.quick_send("OCSync.AnglesGet", vec![], vec![], vec!["f", "f", "f", "f"])?;
80
81        Ok(OCSyncAngles {
82            ch1_on_deg: result[0].as_f32()?,
83            ch1_off_deg: result[1].as_f32()?,
84            ch2_on_deg: result[2].as_f32()?,
85            ch2_off_deg: result[3].as_f32()?,
86        })
87    }
88
89    /// Set the link angles status for channels 1 and 2.
90    ///
91    /// When linked, the difference between Off and On angles is kept constant.
92    ///
93    /// # Arguments
94    /// * `ch1_mode` - Channel 1 link mode
95    /// * `ch2_mode` - Channel 2 link mode
96    ///
97    /// # Errors
98    /// Returns `NanonisError` if communication fails.
99    pub fn oc_sync_link_angles_set(
100        &mut self,
101        ch1_mode: LinkAnglesMode,
102        ch2_mode: LinkAnglesMode,
103    ) -> Result<(), NanonisError> {
104        self.quick_send(
105            "OCSync.LinkAnglesSet",
106            vec![
107                NanonisValue::U32(ch1_mode.into()),
108                NanonisValue::U32(ch2_mode.into()),
109            ],
110            vec!["I", "I"],
111            vec![],
112        )?;
113        Ok(())
114    }
115
116    /// Get the link angles status for channels 1 and 2.
117    ///
118    /// # Returns
119    /// Link status for both channels.
120    ///
121    /// # Errors
122    /// Returns `NanonisError` if communication fails.
123    pub fn oc_sync_link_angles_get(&mut self) -> Result<OCSyncLinkStatus, NanonisError> {
124        let result = self.quick_send("OCSync.LinkAnglesGet", vec![], vec![], vec!["I", "I"])?;
125
126        Ok(OCSyncLinkStatus {
127            ch1_linked: result[0].as_u32()? != 0,
128            ch2_linked: result[1].as_u32()? != 0,
129        })
130    }
131}