1use enum_iterator::IntoEnumIterator;
2use num_derive::*;
3use std::fmt;
4
5#[allow(non_camel_case_types)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[derive(
9 Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq, PartialOrd, Ord, IntoEnumIterator,
10)]
11pub enum PicoRange {
12 X1_PROBE_5MV = -1,
13 X1_PROBE_10MV = 0,
14 X1_PROBE_20MV = 1,
15 X1_PROBE_50MV = 2,
16 X1_PROBE_100MV = 3,
17 X1_PROBE_200MV = 4,
18 X1_PROBE_500MV = 5,
19 X1_PROBE_1V = 6,
20 X1_PROBE_2V = 7,
21 X1_PROBE_5V = 8,
22 X1_PROBE_10V = 9,
23 X1_PROBE_20V = 10,
24 X1_PROBE_50V = 11,
25 X1_PROBE_100V = 12,
26 X1_PROBE_200V = 13,
27
28 X10_PROBE_50MV = 31,
29 X10_PROBE_100MV = 32,
30 X10_PROBE_200MV = 33,
31 X10_PROBE_500MV = 34,
32 X10_PROBE_1V = 35,
33 X10_PROBE_2V = 36,
34 X10_PROBE_5V = 37,
35 X10_PROBE_10V = 38,
36 X10_PROBE_20V = 39,
37 X10_PROBE_50V = 40,
38 X10_PROBE_100V = 41,
39 X10_PROBE_200V = 42,
40 X10_PROBE_500V = 43,
41
42 PS4000A_RESISTANCE_315K = 512,
43 PS4000A_RESISTANCE_1100K = 513,
44 PS4000A_RESISTANCE_10M = 514,
45 PS4000A_RESISTANCE_ADCV_FLAG = 268_435_456,
46
47 CONNECT_PROBE_OFF = 1024,
48 CURRENT_CLAMP_200A_2kA_1A = 4000,
49 CURRENT_CLAMP_200A_2kA_2A = 4001,
50 CURRENT_CLAMP_200A_2kA_5A = 4002,
51 CURRENT_CLAMP_200A_2kA_10A = 4003,
52 CURRENT_CLAMP_200A_2kA_20A = 4004,
53 CURRENT_CLAMP_200A_2kA_50A = 4005,
54 CURRENT_CLAMP_200A_2kA_100A = 4006,
55 CURRENT_CLAMP_200A_2kA_200A = 4007,
56 CURRENT_CLAMP_200A_2kA_500A = 4008,
57 CURRENT_CLAMP_200A_2kA_1000A = 4009,
58 CURRENT_CLAMP_200A_2kA_2000A = 4010,
59 CURRENT_CLAMP_40A_100mA = 5000,
60 CURRENT_CLAMP_40A_200mA = 5001,
61 CURRENT_CLAMP_40A_500mA = 5002,
62 CURRENT_CLAMP_40A_1A = 5003,
63 CURRENT_CLAMP_40A_2A = 5004,
64 CURRENT_CLAMP_40A_5A = 5005,
65 CURRENT_CLAMP_40A_10A = 5006,
66 CURRENT_CLAMP_40A_20A = 5007,
67 CURRENT_CLAMP_40A_40A = 5008,
68
69 _1KV_2_5V = 6003,
70 _1KV_5V = 6004,
71 _1KV_12_5V = 6005,
72 _1KV_25V = 6006,
73 _1KV_50V = 6007,
74 _1KV_125V = 6008,
75 _1KV_250V = 6009,
76 _1KV_500V = 6010,
77 _1KV_1000V = 6011,
78
79 CURRENT_CLAMP_2000ARMS_10A = 6500,
80 CURRENT_CLAMP_2000ARMS_20A = 6501,
81 CURRENT_CLAMP_2000ARMS_50A = 6502,
82 CURRENT_CLAMP_2000ARMS_100A = 6503,
83 CURRENT_CLAMP_2000ARMS_200A = 6504,
84 CURRENT_CLAMP_2000ARMS_500A = 6505,
85 CURRENT_CLAMP_2000ARMS_1000A = 6506,
86 CURRENT_CLAMP_2000ARMS_2000A = 6507,
87 CURRENT_CLAMP_2000ARMS_5000A = 6508,
88
89 RESISTANCE_LEAD_NEG5_TO_20OHM = 7000,
90 RESISTANCE_LEAD_NEG50_TO_200OHM = 7001,
91 RESISTANCE_LEAD_NEG500_TO_2KOHM = 7002,
92 RESISTANCE_LEAD_NEG5K_TO_20KOHM = 7003,
93 RESISTANCE_LEAD_NEG50K_TO_LEAD_200KOHM = 7004,
94 RESISTANCE_LEAD_NEG500K_TO_LEAD_2MOHM = 7005,
95 RESISTANCE_LEAD_DIODE_TEST = 7006,
96
97 HT_NEG3_TO_5KV = 8950,
98 HT_NEG3_TO_10KV = 8951,
99 HT_NEG5_TO_20KV = 8952,
100 HT_NEG5_TO_50KV = 8953,
101 HT_NEG5_TO_100KV = 8954,
102 HT_NEG3_TO_5KV_INVERTED = 8955,
103 HT_NEG3_TO_10KV_INVERTED = 8956,
104 HT_NEG5_TO_20KV_INVERTED = 8957,
105 HT_NEG5_TO_50KV_INVERTED = 8958,
106 HT_NEG5_TO_100KV_INVERTED = 8959,
107
108 TEMPERATURE_NEG50_TO_150DEGC = 9000,
109
110 PRESSURE_SENSOR_NEG100000_TO_150000_PASCALS = 9100,
111 PRESSURE_SENSOR_NEG100000_TO_400000_PASCALS = 9101,
112 PRESSURE_SENSOR_NEG200000_TO_800000_PASCALS = 9102,
113 PRESSURE_SENSOR_NEG400000_TO_1600000_PASCALS = 9103,
114 PRESSURE_SENSOR_NEG400000_TO_3400000_PASCALS = 9104,
115 PRESSURE_SENSOR_NEG150000_TO_1350000_PASCALS = 9105,
116
117 CURRENT_CLAMP_100A_2_5A = 10000,
118 CURRENT_CLAMP_100A_5A = 10001,
119 CURRENT_CLAMP_100A_10A = 10002,
120 CURRENT_CLAMP_100A_25A = 10003,
121 CURRENT_CLAMP_100A_50A = 10004,
122 CURRENT_CLAMP_100A_100A = 10005,
123
124 CURRENT_CLAMP_60A_2A = 10500,
125 CURRENT_CLAMP_60A_5A = 10501,
126 CURRENT_CLAMP_60A_10A = 10502,
127 CURRENT_CLAMP_60A_20A = 10503,
128 CURRENT_CLAMP_60A_50A = 10504,
129 CURRENT_CLAMP_60A_60A = 10505,
130
131 OPTICAL_SENSOR_10V = 10550,
132
133 CURRENT_CLAMP_60A_V2_0_5A = 10600,
134 CURRENT_CLAMP_60A_V2_1A = 10601,
135 CURRENT_CLAMP_60A_V2_2A = 10602,
136 CURRENT_CLAMP_60A_V2_5A = 10603,
137 CURRENT_CLAMP_60A_V2_10A = 10604,
138 CURRENT_CLAMP_60A_V2_20A = 10605,
139 CURRENT_CLAMP_60A_V2_50A = 10606,
140 CURRENT_CLAMP_60A_V2_60A = 10607,
141}
142
143fn normalize(input: &str) -> String {
145 input.replace([' ', '±'], "").to_uppercase()
146}
147
148fn strip_probe_suffix(input: &str) -> &str {
150 ["(X1)", "(X10)", "(X100)"]
151 .iter()
152 .find_map(|suffix| input.strip_suffix(suffix))
153 .unwrap_or(input)
154}
155
156impl PicoRange {
157 pub fn parse(input: &str, valid_ranges: Option<&[Self]>) -> Option<Self> {
158 let input = normalize(input);
159 let all_ranges = PicoRange::into_enum_iter().collect::<Vec<Self>>();
160 let valid_ranges = valid_ranges.unwrap_or(&all_ranges);
161
162 if let Some(range) = valid_ranges
164 .iter()
165 .find(|range| normalize(&range.to_string()) == input)
166 {
167 return Some(*range);
168 }
169
170 valid_ranges
172 .iter()
173 .find(|range| strip_probe_suffix(&normalize(&range.to_string())) == input)
174 .copied()
175 }
176
177 pub fn from_probe_and_nano_volts(probe: u32, nano_volts: i64) -> Option<Self> {
178 match (probe, nano_volts) {
179 (1, 5_000_000) => Some(PicoRange::X1_PROBE_5MV),
180 (1, 10_000_000) => Some(PicoRange::X1_PROBE_10MV),
181 (1, 20_000_000) => Some(PicoRange::X1_PROBE_20MV),
182 (1, 50_000_000) => Some(PicoRange::X1_PROBE_50MV),
183 (1, 100_000_000) => Some(PicoRange::X1_PROBE_100MV),
184 (1, 200_000_000) => Some(PicoRange::X1_PROBE_200MV),
185 (1, 500_000_000) => Some(PicoRange::X1_PROBE_500MV),
186 (1, 1_000_000_000) => Some(PicoRange::X1_PROBE_1V),
187 (1, 2_000_000_000) => Some(PicoRange::X1_PROBE_2V),
188 (1, 5_000_000_000) => Some(PicoRange::X1_PROBE_5V),
189 (1, 10_000_000_000) => Some(PicoRange::X1_PROBE_10V),
190 (1, 20_000_000_000) => Some(PicoRange::X1_PROBE_20V),
191 (1, 50_000_000_000) => Some(PicoRange::X1_PROBE_50V),
192 (1, 100_000_000_000) => Some(PicoRange::X1_PROBE_100V),
193 (1, 200_000_000_000) => Some(PicoRange::X1_PROBE_200V),
194 (10, 50_000_000) => Some(PicoRange::X10_PROBE_50MV),
195 (10, 100_000_000) => Some(PicoRange::X10_PROBE_100MV),
196 (10, 200_000_000) => Some(PicoRange::X10_PROBE_200MV),
197 (10, 500_000_000) => Some(PicoRange::X10_PROBE_500MV),
198 (10, 1_000_000_000) => Some(PicoRange::X10_PROBE_1V),
199 (10, 2_000_000_000) => Some(PicoRange::X10_PROBE_2V),
200 (10, 5_000_000_000) => Some(PicoRange::X10_PROBE_5V),
201 (10, 10_000_000_000) => Some(PicoRange::X10_PROBE_10V),
202 (10, 20_000_000_000) => Some(PicoRange::X10_PROBE_20V),
203 (10, 50_000_000_000) => Some(PicoRange::X10_PROBE_50V),
204 (10, 100_000_000_000) => Some(PicoRange::X10_PROBE_100V),
205 (10, 200_000_000_000) => Some(PicoRange::X10_PROBE_200V),
206 (10, 500_000_000_000) => Some(PicoRange::X10_PROBE_500V),
207 _ => None,
208 }
209 }
210
211 pub fn to_nano_volts(&self) -> i64 {
212 match self {
213 PicoRange::X1_PROBE_5MV => 5_000_000,
214 PicoRange::X1_PROBE_10MV => 10_000_000,
215 PicoRange::X1_PROBE_20MV => 20_000_000,
216 PicoRange::X1_PROBE_50MV => 50_000_000,
217 PicoRange::X1_PROBE_100MV => 100_000_000,
218 PicoRange::X1_PROBE_200MV => 200_000_000,
219 PicoRange::X1_PROBE_500MV => 500_000_000,
220 PicoRange::X1_PROBE_1V => 1_000_000_000,
221 PicoRange::X1_PROBE_2V => 2_000_000_000,
222 PicoRange::X1_PROBE_5V => 5_000_000_000,
223 PicoRange::X1_PROBE_10V => 10_000_000_000,
224 PicoRange::X1_PROBE_20V => 20_000_000_000,
225 PicoRange::X1_PROBE_50V => 50_000_000_000,
226 PicoRange::X1_PROBE_100V => 100_000_000_000,
227 PicoRange::X1_PROBE_200V => 200_000_000_000,
228 PicoRange::X10_PROBE_50MV => 50_000_000,
229 PicoRange::X10_PROBE_100MV => 100_000_000,
230 PicoRange::X10_PROBE_200MV => 200_000_000,
231 PicoRange::X10_PROBE_500MV => 500_000_000,
232 PicoRange::X10_PROBE_1V => 1_000_000_000,
233 PicoRange::X10_PROBE_2V => 2_000_000_000,
234 PicoRange::X10_PROBE_5V => 5_000_000_000,
235 PicoRange::X10_PROBE_10V => 10_000_000_000,
236 PicoRange::X10_PROBE_20V => 20_000_000_000,
237 PicoRange::X10_PROBE_50V => 50_000_000_000,
238 PicoRange::X10_PROBE_100V => 100_000_000_000,
239 PicoRange::X10_PROBE_200V => 200_000_000_000,
240 PicoRange::X10_PROBE_500V => 500_000_000_000,
241 _ => panic!("Does not support conversion from {} to nano volts", self),
242 }
243 }
244
245 pub fn to_probe_range(&self) -> u32 {
246 match self {
247 PicoRange::X1_PROBE_5MV
248 | PicoRange::X1_PROBE_10MV
249 | PicoRange::X1_PROBE_20MV
250 | PicoRange::X1_PROBE_50MV
251 | PicoRange::X1_PROBE_100MV
252 | PicoRange::X1_PROBE_200MV
253 | PicoRange::X1_PROBE_500MV
254 | PicoRange::X1_PROBE_1V
255 | PicoRange::X1_PROBE_2V
256 | PicoRange::X1_PROBE_5V
257 | PicoRange::X1_PROBE_10V
258 | PicoRange::X1_PROBE_20V
259 | PicoRange::X1_PROBE_50V
260 | PicoRange::X1_PROBE_100V
261 | PicoRange::X1_PROBE_200V => 1,
262
263 PicoRange::X10_PROBE_50MV
264 | PicoRange::X10_PROBE_100MV
265 | PicoRange::X10_PROBE_200MV
266 | PicoRange::X10_PROBE_500MV
267 | PicoRange::X10_PROBE_1V
268 | PicoRange::X10_PROBE_2V
269 | PicoRange::X10_PROBE_5V
270 | PicoRange::X10_PROBE_10V
271 | PicoRange::X10_PROBE_20V
272 | PicoRange::X10_PROBE_50V
273 | PicoRange::X10_PROBE_100V
274 | PicoRange::X10_PROBE_200V
275 | PicoRange::X10_PROBE_500V => 10,
276 _ => panic!("Does not support conversion from {} to nano volts", self),
277 }
278 }
279}
280
281impl fmt::Display for PicoRange {
282 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283 match self {
284 PicoRange::X1_PROBE_5MV => write!(f, "±5 mV"),
285 PicoRange::X1_PROBE_10MV => write!(f, "±10 mV"),
286 PicoRange::X1_PROBE_20MV => write!(f, "±20 mV"),
287 PicoRange::X1_PROBE_50MV => write!(f, "±50 mV"),
288 PicoRange::X1_PROBE_100MV => write!(f, "±100 mV"),
289 PicoRange::X1_PROBE_200MV => write!(f, "±200 mV"),
290 PicoRange::X1_PROBE_500MV => write!(f, "±500 mV"),
291 PicoRange::X1_PROBE_1V => write!(f, "±1 V"),
292 PicoRange::X1_PROBE_2V => write!(f, "±2 V"),
293 PicoRange::X1_PROBE_5V => write!(f, "±5 V"),
294 PicoRange::X1_PROBE_10V => write!(f, "±10 V"),
295 PicoRange::X1_PROBE_20V => write!(f, "±20 V"),
296 PicoRange::X1_PROBE_50V => write!(f, "±50 V"),
297 PicoRange::X1_PROBE_100V => write!(f, "±100 V"),
298 PicoRange::X1_PROBE_200V => write!(f, "±200 V"),
299 PicoRange::X10_PROBE_50MV => write!(f, "±50 mV (x10)"),
300 PicoRange::X10_PROBE_100MV => write!(f, "±100 mV (x10)"),
301 PicoRange::X10_PROBE_200MV => write!(f, "±200 mV (x10)"),
302 PicoRange::X10_PROBE_500MV => write!(f, "±500 mV (x10)"),
303 PicoRange::X10_PROBE_1V => write!(f, "±1 V (x10)"),
304 PicoRange::X10_PROBE_2V => write!(f, "±2 V (x10)"),
305 PicoRange::X10_PROBE_5V => write!(f, "±5 V (x10)"),
306 PicoRange::X10_PROBE_10V => write!(f, "±10 V (x10)"),
307 PicoRange::X10_PROBE_20V => write!(f, "±20 V (x10)"),
308 PicoRange::X10_PROBE_50V => write!(f, "±50 V (x10)"),
309 PicoRange::X10_PROBE_100V => write!(f, "±100 V (x10)"),
310 PicoRange::X10_PROBE_200V => write!(f, "±200 V (x10)"),
311 PicoRange::X10_PROBE_500V => write!(f, "±500 V (x10)"),
312 PicoRange::CURRENT_CLAMP_200A_2kA_1A => write!(f, "±1 A"),
313 PicoRange::CURRENT_CLAMP_200A_2kA_2A => write!(f, "±2 A"),
314 PicoRange::CURRENT_CLAMP_200A_2kA_5A => write!(f, "±5 A"),
315 PicoRange::CURRENT_CLAMP_200A_2kA_10A => write!(f, "±10 A"),
316 PicoRange::CURRENT_CLAMP_200A_2kA_20A => write!(f, "±20 A"),
317 PicoRange::CURRENT_CLAMP_200A_2kA_50A => write!(f, "±50 A"),
318 PicoRange::CURRENT_CLAMP_200A_2kA_100A => write!(f, "±100 A"),
319 PicoRange::CURRENT_CLAMP_200A_2kA_200A => write!(f, "±200 A"),
320 PicoRange::CURRENT_CLAMP_200A_2kA_500A => write!(f, "±500 A"),
321 PicoRange::CURRENT_CLAMP_200A_2kA_1000A => write!(f, "±1000 A"),
322 PicoRange::CURRENT_CLAMP_200A_2kA_2000A => write!(f, "±2000 A"),
323 PicoRange::CURRENT_CLAMP_40A_100mA => write!(f, "±100 mA"),
324 PicoRange::CURRENT_CLAMP_40A_200mA => write!(f, "±200 mA"),
325 PicoRange::CURRENT_CLAMP_40A_500mA => write!(f, "±500 mA"),
326 PicoRange::CURRENT_CLAMP_40A_1A => write!(f, "±1 A"),
327 PicoRange::CURRENT_CLAMP_40A_2A => write!(f, "±2 A"),
328 PicoRange::CURRENT_CLAMP_40A_5A => write!(f, "±5 A"),
329 PicoRange::CURRENT_CLAMP_40A_10A => write!(f, "±10 A"),
330 PicoRange::CURRENT_CLAMP_40A_20A => write!(f, "±20 A"),
331 PicoRange::CURRENT_CLAMP_40A_40A => write!(f, "±40 A"),
332 PicoRange::_1KV_2_5V => write!(f, "±2.5 V"),
333 PicoRange::_1KV_5V => write!(f, "±5 V"),
334 PicoRange::_1KV_12_5V => write!(f, "±12.5 V"),
335 PicoRange::_1KV_25V => write!(f, "±25 V"),
336 PicoRange::_1KV_50V => write!(f, "±50 V"),
337 PicoRange::_1KV_125V => write!(f, "±125 V"),
338 PicoRange::_1KV_250V => write!(f, "±250 V"),
339 PicoRange::_1KV_500V => write!(f, "±500 V"),
340 PicoRange::_1KV_1000V => write!(f, "±1 kV"),
341 PicoRange::CURRENT_CLAMP_2000ARMS_10A => write!(f, "±10 A"),
342 PicoRange::CURRENT_CLAMP_2000ARMS_20A => write!(f, "±20 A"),
343 PicoRange::CURRENT_CLAMP_2000ARMS_50A => write!(f, "±50 A"),
344 PicoRange::CURRENT_CLAMP_2000ARMS_100A => write!(f, "±100 A"),
345 PicoRange::CURRENT_CLAMP_2000ARMS_200A => write!(f, "±200 A"),
346 PicoRange::CURRENT_CLAMP_2000ARMS_500A => write!(f, "±500 A"),
347 PicoRange::CURRENT_CLAMP_2000ARMS_1000A => write!(f, "±1000 A"),
348 PicoRange::CURRENT_CLAMP_2000ARMS_2000A => write!(f, "±2000 A"),
349 PicoRange::CURRENT_CLAMP_2000ARMS_5000A => write!(f, "±5000 A"),
350 PicoRange::CURRENT_CLAMP_60A_2A => write!(f, "±2 A"),
351 PicoRange::CURRENT_CLAMP_60A_5A => write!(f, "±5 A"),
352 PicoRange::CURRENT_CLAMP_60A_10A => write!(f, "±10 A"),
353 PicoRange::CURRENT_CLAMP_60A_20A => write!(f, "±20 A"),
354 PicoRange::CURRENT_CLAMP_60A_50A => write!(f, "±50 A"),
355 PicoRange::CURRENT_CLAMP_60A_60A => write!(f, "±60 A"),
356 rest => write!(f, "{:?}", rest),
357 }
358 }
359}
360
361impl From<PicoRange> for u32 {
362 fn from(value: PicoRange) -> Self {
363 num_traits::ToPrimitive::to_u32(&value).expect("Non-valid range")
364 }
365}
366
367impl From<PicoRange> for i32 {
368 fn from(value: PicoRange) -> Self {
369 num_traits::ToPrimitive::to_i32(&value).expect("Non-valid range")
370 }
371}
372
373impl From<PicoRange> for i16 {
374 fn from(value: PicoRange) -> Self {
375 num_traits::ToPrimitive::to_i16(&value).expect("Non-valid range")
376 }
377}
378
379impl From<i32> for PicoRange {
380 fn from(value: i32) -> Self {
381 num_traits::FromPrimitive::from_i32(value)
382 .unwrap_or_else(|| panic!("Invalid PicoRange range '{}'", value))
383 }
384}
385
386impl From<u32> for PicoRange {
387 fn from(value: u32) -> Self {
388 num_traits::FromPrimitive::from_u32(value)
389 .unwrap_or_else(|| panic!("Invalid PicoRange range '{}'", value))
390 }
391}
392
393pub struct UnitStrings {
395 pub long: String,
396 pub short: String,
397}
398
399impl UnitStrings {
400 pub fn new(long: &str, short: &str) -> Self {
401 UnitStrings {
402 long: long.to_string(),
403 short: short.to_string(),
404 }
405 }
406}
407
408impl PicoRange {
409 pub fn get_units(self) -> UnitStrings {
411 match self {
412 PicoRange::PS4000A_RESISTANCE_315K
413 | PicoRange::PS4000A_RESISTANCE_1100K
414 | PicoRange::PS4000A_RESISTANCE_10M
415 | PicoRange::RESISTANCE_LEAD_NEG5_TO_20OHM
416 | PicoRange::RESISTANCE_LEAD_NEG50_TO_200OHM
417 | PicoRange::RESISTANCE_LEAD_NEG500_TO_2KOHM
418 | PicoRange::RESISTANCE_LEAD_NEG5K_TO_20KOHM
419 | PicoRange::RESISTANCE_LEAD_NEG50K_TO_LEAD_200KOHM
420 | PicoRange::RESISTANCE_LEAD_NEG500K_TO_LEAD_2MOHM => UnitStrings::new("Ohms", "Ω"),
421 PicoRange::CURRENT_CLAMP_200A_2kA_1A
422 | PicoRange::CURRENT_CLAMP_200A_2kA_2A
423 | PicoRange::CURRENT_CLAMP_200A_2kA_5A
424 | PicoRange::CURRENT_CLAMP_200A_2kA_10A
425 | PicoRange::CURRENT_CLAMP_200A_2kA_20A
426 | PicoRange::CURRENT_CLAMP_200A_2kA_50A
427 | PicoRange::CURRENT_CLAMP_200A_2kA_100A
428 | PicoRange::CURRENT_CLAMP_200A_2kA_200A
429 | PicoRange::CURRENT_CLAMP_200A_2kA_500A
430 | PicoRange::CURRENT_CLAMP_200A_2kA_1000A
431 | PicoRange::CURRENT_CLAMP_200A_2kA_2000A
432 | PicoRange::CURRENT_CLAMP_40A_100mA
433 | PicoRange::CURRENT_CLAMP_40A_200mA
434 | PicoRange::CURRENT_CLAMP_40A_500mA
435 | PicoRange::CURRENT_CLAMP_40A_1A
436 | PicoRange::CURRENT_CLAMP_40A_2A
437 | PicoRange::CURRENT_CLAMP_40A_5A
438 | PicoRange::CURRENT_CLAMP_40A_10A
439 | PicoRange::CURRENT_CLAMP_40A_20A
440 | PicoRange::CURRENT_CLAMP_40A_40A
441 | PicoRange::CURRENT_CLAMP_2000ARMS_20A
442 | PicoRange::CURRENT_CLAMP_2000ARMS_10A
443 | PicoRange::CURRENT_CLAMP_2000ARMS_50A
444 | PicoRange::CURRENT_CLAMP_2000ARMS_100A
445 | PicoRange::CURRENT_CLAMP_2000ARMS_200A
446 | PicoRange::CURRENT_CLAMP_2000ARMS_500A
447 | PicoRange::CURRENT_CLAMP_2000ARMS_1000A
448 | PicoRange::CURRENT_CLAMP_2000ARMS_2000A
449 | PicoRange::CURRENT_CLAMP_2000ARMS_5000A
450 | PicoRange::CURRENT_CLAMP_100A_2_5A
451 | PicoRange::CURRENT_CLAMP_100A_5A
452 | PicoRange::CURRENT_CLAMP_100A_10A
453 | PicoRange::CURRENT_CLAMP_100A_25A
454 | PicoRange::CURRENT_CLAMP_100A_50A
455 | PicoRange::CURRENT_CLAMP_100A_100A
456 | PicoRange::CURRENT_CLAMP_60A_2A
457 | PicoRange::CURRENT_CLAMP_60A_5A
458 | PicoRange::CURRENT_CLAMP_60A_10A
459 | PicoRange::CURRENT_CLAMP_60A_20A
460 | PicoRange::CURRENT_CLAMP_60A_50A
461 | PicoRange::CURRENT_CLAMP_60A_60A => UnitStrings::new("Amps", "A"),
462 _ => UnitStrings::new("Volts", "V"),
463 }
464 }
465
466 pub fn get_max_scaled_value(self) -> f64 {
468 match self {
469 PicoRange::X1_PROBE_10MV => 0.01,
470 PicoRange::X1_PROBE_20MV => 0.02,
471 PicoRange::X1_PROBE_50MV => 0.05,
472 PicoRange::X1_PROBE_100MV => 0.1,
473 PicoRange::X1_PROBE_200MV => 0.2,
474 PicoRange::X1_PROBE_500MV => 0.5,
475 PicoRange::X1_PROBE_1V => 1.0,
476 PicoRange::X1_PROBE_2V => 2.0,
477 PicoRange::X1_PROBE_5V => 5.0,
478 PicoRange::X1_PROBE_10V => 10.0,
479 PicoRange::X1_PROBE_20V => 20.0,
480 PicoRange::X1_PROBE_50V => 50.0,
481 PicoRange::X1_PROBE_100V => 100.0,
482 PicoRange::X1_PROBE_200V => 200.0,
483 PicoRange::X10_PROBE_100MV => 0.1,
484 PicoRange::X10_PROBE_200MV => 0.2,
485 PicoRange::X10_PROBE_500MV => 0.5,
486 PicoRange::X10_PROBE_1V => 1.0,
487 PicoRange::X10_PROBE_2V => 2.0,
488 PicoRange::X10_PROBE_5V => 5.0,
489 PicoRange::X10_PROBE_10V => 10.0,
490 PicoRange::X10_PROBE_20V => 20.0,
491 PicoRange::X10_PROBE_50V => 50.0,
492 PicoRange::X10_PROBE_100V => 100.0,
493 PicoRange::X10_PROBE_200V => 200.0,
494 PicoRange::X10_PROBE_500V => 500.0,
495 PicoRange::PS4000A_RESISTANCE_315K => 315_000.0,
496 PicoRange::PS4000A_RESISTANCE_1100K => 1_100_000.0,
497 PicoRange::PS4000A_RESISTANCE_10M => 10_000_000.0,
498 PicoRange::CURRENT_CLAMP_200A_2kA_1A => 1.0,
499 PicoRange::CURRENT_CLAMP_200A_2kA_2A => 2.0,
500 PicoRange::CURRENT_CLAMP_200A_2kA_5A => 5.0,
501 PicoRange::CURRENT_CLAMP_200A_2kA_10A => 10.0,
502 PicoRange::CURRENT_CLAMP_200A_2kA_20A => 20.0,
503 PicoRange::CURRENT_CLAMP_200A_2kA_50A => 50.0,
504 PicoRange::CURRENT_CLAMP_200A_2kA_100A => 100.0,
505 PicoRange::CURRENT_CLAMP_200A_2kA_200A => 200.0,
506 PicoRange::CURRENT_CLAMP_200A_2kA_500A => 500.0,
507 PicoRange::CURRENT_CLAMP_200A_2kA_1000A => 1_000.0,
508 PicoRange::CURRENT_CLAMP_200A_2kA_2000A => 2_000.0,
509 PicoRange::CURRENT_CLAMP_40A_100mA => 0.1,
510 PicoRange::CURRENT_CLAMP_40A_200mA => 0.2,
511 PicoRange::CURRENT_CLAMP_40A_500mA => 0.5,
512 PicoRange::CURRENT_CLAMP_40A_1A => 1.0,
513 PicoRange::CURRENT_CLAMP_40A_2A => 2.0,
514 PicoRange::CURRENT_CLAMP_40A_5A => 5.0,
515 PicoRange::CURRENT_CLAMP_40A_10A => 10.0,
516 PicoRange::CURRENT_CLAMP_40A_20A => 20.0,
517 PicoRange::CURRENT_CLAMP_40A_40A => 40.0,
518 PicoRange::_1KV_2_5V => 2.5,
519 PicoRange::_1KV_5V => 5.0,
520 PicoRange::_1KV_12_5V => 12.5,
521 PicoRange::_1KV_25V => 25.0,
522 PicoRange::_1KV_50V => 50.0,
523 PicoRange::_1KV_125V => 125.0,
524 PicoRange::_1KV_250V => 250.0,
525 PicoRange::_1KV_500V => 500.0,
526 PicoRange::_1KV_1000V => 1_000.0,
527 PicoRange::CURRENT_CLAMP_2000ARMS_10A => 10.0,
528 PicoRange::CURRENT_CLAMP_2000ARMS_20A => 20.0,
529 PicoRange::CURRENT_CLAMP_2000ARMS_50A => 50.0,
530 PicoRange::CURRENT_CLAMP_2000ARMS_100A => 100.0,
531 PicoRange::CURRENT_CLAMP_2000ARMS_200A => 200.0,
532 PicoRange::CURRENT_CLAMP_2000ARMS_500A => 500.0,
533 PicoRange::CURRENT_CLAMP_2000ARMS_1000A => 1_000.0,
534 PicoRange::CURRENT_CLAMP_2000ARMS_2000A => 2_000.0,
535 PicoRange::CURRENT_CLAMP_2000ARMS_5000A => 5_000.0,
536 PicoRange::RESISTANCE_LEAD_NEG5_TO_20OHM => 20.0,
537 PicoRange::RESISTANCE_LEAD_NEG50_TO_200OHM => 200.0,
538 PicoRange::RESISTANCE_LEAD_NEG500_TO_2KOHM => 2_000.0,
539 PicoRange::RESISTANCE_LEAD_NEG5K_TO_20KOHM => 20_000.0,
540 PicoRange::RESISTANCE_LEAD_NEG50K_TO_LEAD_200KOHM => 200_000.0,
541 PicoRange::RESISTANCE_LEAD_NEG500K_TO_LEAD_2MOHM => 2_000_000.0,
542 PicoRange::HT_NEG3_TO_5KV => 5_000.0,
544 PicoRange::HT_NEG3_TO_10KV => 10_000.0,
545 PicoRange::HT_NEG5_TO_20KV => 20_000.0,
546 PicoRange::HT_NEG5_TO_50KV => 50_000.0,
547 PicoRange::HT_NEG5_TO_100KV => 100_000.0,
548 PicoRange::HT_NEG3_TO_5KV_INVERTED => -5_000.0,
549 PicoRange::HT_NEG3_TO_10KV_INVERTED => -10_000.0,
550 PicoRange::HT_NEG5_TO_20KV_INVERTED => -20_000.0,
551 PicoRange::HT_NEG5_TO_50KV_INVERTED => -50_000.0,
552 PicoRange::HT_NEG5_TO_100KV_INVERTED => -100_000.0,
553 PicoRange::TEMPERATURE_NEG50_TO_150DEGC => 150.0,
554 PicoRange::CURRENT_CLAMP_100A_2_5A => 2.5,
561 PicoRange::CURRENT_CLAMP_100A_5A => 5.0,
562 PicoRange::CURRENT_CLAMP_100A_10A => 10.0,
563 PicoRange::CURRENT_CLAMP_100A_25A => 25.0,
564 PicoRange::CURRENT_CLAMP_100A_50A => 50.0,
565 PicoRange::CURRENT_CLAMP_100A_100A => 100.0,
566 PicoRange::CURRENT_CLAMP_60A_2A => 2.0,
567 PicoRange::CURRENT_CLAMP_60A_5A => 5.0,
568 PicoRange::CURRENT_CLAMP_60A_10A => 10.0,
569 PicoRange::CURRENT_CLAMP_60A_20A => 20.0,
570 PicoRange::CURRENT_CLAMP_60A_50A => 50.0,
571 PicoRange::CURRENT_CLAMP_60A_60A => 60.0,
572 oops => panic!("Scaling for range '{:?}' not defined", oops),
573 }
574 }
575}
576
577#[cfg(test)]
578mod range_tests {
579 use super::*;
580
581 const X10_RANGES: &[PicoRange] = &[
582 PicoRange::X10_PROBE_100MV,
583 PicoRange::X10_PROBE_200MV,
584 PicoRange::X10_PROBE_500MV,
585 PicoRange::X10_PROBE_1V,
586 PicoRange::X10_PROBE_2V,
587 PicoRange::X10_PROBE_5V,
588 ];
589
590 #[test]
591 fn channel_parse() {
592 assert_eq!(
593 PicoRange::parse("200mv", None),
594 Some(PicoRange::X1_PROBE_200MV)
595 );
596 assert_eq!(
597 PicoRange::parse(" 20 v ", None),
598 Some(PicoRange::X1_PROBE_20V)
599 );
600 assert_eq!(
601 PicoRange::parse("±20V", None),
602 Some(PicoRange::X1_PROBE_20V)
603 );
604 assert_eq!(PicoRange::parse("20 Gigavolts", None), None);
605 }
606
607 #[test]
608 fn channel_parse_with_probe_suffix() {
609 assert_eq!(
611 PicoRange::parse("200 mv (x10)", None),
612 Some(PicoRange::X10_PROBE_200MV)
613 );
614 assert_eq!(
615 PicoRange::parse("±200mV(x10)", Some(X10_RANGES)),
616 Some(PicoRange::X10_PROBE_200MV)
617 );
618 }
619
620 #[test]
621 fn channel_parse_falls_back_to_ignoring_probe_suffix() {
622 assert_eq!(
624 PicoRange::parse("200 mv", None),
625 Some(PicoRange::X1_PROBE_200MV)
626 );
627
628 assert_eq!(
630 PicoRange::parse("200 mv", Some(X10_RANGES)),
631 Some(PicoRange::X10_PROBE_200MV)
632 );
633
634 assert_eq!(PicoRange::parse("50 mv", Some(X10_RANGES)), None);
636 }
637}