2017-05-11 23:15:01 +08:00
|
|
|
use board;
|
|
|
|
|
|
|
|
pub struct Electrometer {
|
|
|
|
range: board::ElectrometerRange,
|
2017-05-13 15:40:41 +08:00
|
|
|
out_of_range_count: u8,
|
|
|
|
ignore_count: u8,
|
2017-06-12 19:22:23 +08:00
|
|
|
ic_buffer: [f32; 512],
|
2017-05-11 23:15:01 +08:00
|
|
|
ic_buffer_count: usize,
|
|
|
|
last_ic: Option<f32>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
pub struct ElectrometerStatus {
|
|
|
|
pub ic: Option<f32>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Electrometer {
|
|
|
|
pub const fn new() -> Electrometer {
|
|
|
|
Electrometer {
|
|
|
|
range: board::ElectrometerRange::Med,
|
2017-05-13 15:40:41 +08:00
|
|
|
out_of_range_count: 0,
|
|
|
|
ignore_count: 0,
|
2017-06-12 19:22:23 +08:00
|
|
|
ic_buffer: [0.0; 512],
|
2017-05-11 23:15:01 +08:00
|
|
|
ic_buffer_count: 0,
|
|
|
|
last_ic: None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn adc_input(&mut self, ic_sample: u16) {
|
2017-05-13 15:40:41 +08:00
|
|
|
if self.ignore_count > 0 {
|
|
|
|
self.ignore_count -= 1;
|
|
|
|
} else {
|
2017-05-18 17:07:07 +08:00
|
|
|
let mut new_range = if ic_sample > 3100 {
|
2017-05-13 15:40:41 +08:00
|
|
|
match self.range {
|
|
|
|
board::ElectrometerRange::Low => Some(board::ElectrometerRange::Med),
|
|
|
|
board::ElectrometerRange::Med => Some(board::ElectrometerRange::High),
|
|
|
|
board::ElectrometerRange::High => None
|
|
|
|
}
|
2017-06-08 21:51:11 +08:00
|
|
|
} else if ic_sample < 105 {
|
2017-05-13 15:40:41 +08:00
|
|
|
match self.range {
|
|
|
|
board::ElectrometerRange::Low => None,
|
|
|
|
board::ElectrometerRange::Med => Some(board::ElectrometerRange::Low),
|
|
|
|
board::ElectrometerRange::High => Some(board::ElectrometerRange::Med)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
if new_range.is_some() {
|
|
|
|
self.out_of_range_count += 1;
|
2017-06-12 19:22:23 +08:00
|
|
|
if self.out_of_range_count < 75 {
|
2017-05-13 15:40:41 +08:00
|
|
|
new_range = None;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.out_of_range_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if new_range.is_some() {
|
2017-06-12 19:22:23 +08:00
|
|
|
self.ignore_count = 150;
|
2017-05-13 15:40:41 +08:00
|
|
|
self.ic_buffer_count = 0;
|
|
|
|
self.last_ic = None;
|
|
|
|
self.range = new_range.unwrap();
|
|
|
|
board::set_electrometer_range(self.range);
|
|
|
|
} else {
|
|
|
|
let gain = match self.range {
|
|
|
|
board::ElectrometerRange::Low => board::IC_ADC_GAIN_LOW,
|
|
|
|
board::ElectrometerRange::Med => board::IC_ADC_GAIN_MED,
|
|
|
|
board::ElectrometerRange::High => board::IC_ADC_GAIN_HIGH
|
|
|
|
};
|
|
|
|
self.ic_buffer[self.ic_buffer_count] = ((ic_sample as f32) - board::IC_ADC_OFFSET)/gain;
|
|
|
|
self.ic_buffer_count += 1;
|
|
|
|
if self.ic_buffer_count == self.ic_buffer.len() {
|
|
|
|
let mut ic_avg: f32 = 0.0;
|
|
|
|
for ic in self.ic_buffer.iter() {
|
|
|
|
ic_avg += *ic;
|
|
|
|
}
|
|
|
|
self.last_ic = Some(ic_avg/(self.ic_buffer.len() as f32));
|
|
|
|
self.ic_buffer_count = 0;
|
|
|
|
}
|
2017-05-11 23:15:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_status(&self) -> ElectrometerStatus {
|
|
|
|
ElectrometerStatus {
|
|
|
|
ic: self.last_ic
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ElectrometerStatus {
|
|
|
|
pub fn debug_print(&self) {
|
|
|
|
if self.ic.is_some() {
|
2017-05-12 11:07:35 +08:00
|
|
|
println!("ion: {}nA", 1e9*self.ic.unwrap());
|
2017-05-11 23:15:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|