1mod types;
2pub use types::*;
3
4use super::NanonisClient;
5use crate::error::NanonisError;
6use crate::types::NanonisValue;
7use std::time::Duration;
8
9impl NanonisClient {
10 pub fn motor_start_move(
12 &mut self,
13 direction: impl Into<MotorDirection>,
14 number_of_steps: impl Into<u16>,
15 group: impl Into<MotorGroup>,
16 wait_until_finished: bool,
17 ) -> Result<(), NanonisError> {
18 let wait_flag = if wait_until_finished { 1u32 } else { 0u32 };
19 self.quick_send(
20 "Motor.StartMove",
21 vec![
22 NanonisValue::U32(direction.into().into()),
23 NanonisValue::U16(number_of_steps.into()),
24 NanonisValue::U32(group.into().into()),
25 NanonisValue::U32(wait_flag),
26 ],
27 vec!["I", "H", "I", "I"],
28 vec![],
29 )?;
30 Ok(())
31 }
32
33 pub fn motor_start_closed_loop(
35 &mut self,
36 movement_mode: MovementMode,
37 target_position: Position3D,
38 wait_until_finished: bool,
39 group: MotorGroup,
40 ) -> Result<(), NanonisError> {
41 let wait_flag = if wait_until_finished { 1u32 } else { 0u32 };
42 self.quick_send(
43 "Motor.StartClosedLoop",
44 vec![
45 NanonisValue::U32(movement_mode.into()),
46 NanonisValue::F64(target_position.x),
47 NanonisValue::F64(target_position.y),
48 NanonisValue::F64(target_position.z),
49 NanonisValue::U32(wait_flag),
50 NanonisValue::U32(group.into()),
51 ],
52 vec!["I", "d", "d", "d", "I", "I"],
53 vec![],
54 )?;
55 Ok(())
56 }
57
58 pub fn motor_stop_move(&mut self) -> Result<(), NanonisError> {
60 self.quick_send("Motor.StopMove", vec![], vec![], vec![])?;
61 Ok(())
62 }
63
64 pub fn motor_pos_get(
66 &mut self,
67 group: MotorGroup,
68 timeout: Duration,
69 ) -> Result<Position3D, NanonisError> {
70 let result = self.quick_send(
71 "Motor.PosGet",
72 vec![
73 NanonisValue::U32(group.into()),
74 NanonisValue::U32(timeout.as_millis() as u32),
75 ],
76 vec!["I", "I"],
77 vec!["d", "d", "d"],
78 )?;
79
80 if result.len() >= 3 {
81 let x = result[0].as_f64()?;
82 let y = result[1].as_f64()?;
83 let z = result[2].as_f64()?;
84 Ok(Position3D::new(x, y, z))
85 } else {
86 Err(NanonisError::Protocol(
87 "Invalid motor position response".to_string(),
88 ))
89 }
90 }
91
92 pub fn motor_step_counter_get(
95 &mut self,
96 reset_x: bool,
97 reset_y: bool,
98 reset_z: bool,
99 ) -> Result<(i32, i32, i32), NanonisError> {
100 let reset_x_flag = if reset_x { 1u32 } else { 0u32 };
101 let reset_y_flag = if reset_y { 1u32 } else { 0u32 };
102 let reset_z_flag = if reset_z { 1u32 } else { 0u32 };
103
104 let result = self.quick_send(
105 "Motor.StepCounterGet",
106 vec![
107 NanonisValue::U32(reset_x_flag),
108 NanonisValue::U32(reset_y_flag),
109 NanonisValue::U32(reset_z_flag),
110 ],
111 vec!["I", "I", "I"],
112 vec!["i", "i", "i"],
113 )?;
114
115 if result.len() >= 3 {
116 let step_x = result[0].as_i32()?;
117 let step_y = result[1].as_i32()?;
118 let step_z = result[2].as_i32()?;
119 Ok((step_x, step_y, step_z))
120 } else {
121 Err(NanonisError::Protocol(
122 "Invalid step counter response".to_string(),
123 ))
124 }
125 }
126
127 pub fn motor_freq_amp_get(
130 &mut self,
131 axis: MotorAxis,
132 ) -> Result<(Frequency, Amplitude), NanonisError> {
133 let result = self.quick_send(
134 "Motor.FreqAmpGet",
135 vec![NanonisValue::U16(axis.into())],
136 vec!["H"],
137 vec!["f", "f"],
138 )?;
139
140 if result.len() >= 2 {
141 let frequency = Frequency::hz(result[0].as_f32()?);
142 let amplitude = Amplitude::volts(result[1].as_f32()?);
143 Ok((frequency, amplitude))
144 } else {
145 Err(NanonisError::Protocol(
146 "Invalid frequency/amplitude response".to_string(),
147 ))
148 }
149 }
150
151 pub fn motor_freq_amp_set(
154 &mut self,
155 frequency: impl Into<Frequency>,
156 amplitude: impl Into<Amplitude>,
157 axis: impl Into<MotorAxis>,
158 ) -> Result<(), NanonisError> {
159 self.quick_send(
160 "Motor.FreqAmpSet",
161 vec![
162 NanonisValue::F32(frequency.into().into()),
163 NanonisValue::F32(amplitude.into().into()),
164 NanonisValue::U16(axis.into().into()),
165 ],
166 vec!["f", "f", "H"],
167 vec![],
168 )?;
169 Ok(())
170 }
171}