pub struct LookupTable<'a, D> {
min: i16,
step: i16,
data: &'a [D],
}
fn interpolate(ohm_100: i32, first: (i32, i32), second: (i32, i32)) -> i32 {
let numerator = (second.0 - first.0) * (ohm_100 - first.1);
let denominator = second.1 - first.1;
numerator / denominator + first.0
}
pub trait LookupToI32 {
fn lookup(&self, ind: usize) -> i32;
fn binary_search(&self, val: i32) -> Result<usize, usize>;
}
impl<'a> LookupToI32 for LookupTable<'a, u16> {
fn lookup(&self, ind: usize) -> i32 {
self.data[ind] as i32
}
fn binary_search(&self, val: i32) -> Result<usize, usize> {
let val = val as u16;
self.data.binary_search(&val)
}
}
impl<'a> LookupToI32 for LookupTable<'a, u32> {
fn lookup(&self, ind: usize) -> i32 {
self.data[ind] as i32
}
fn binary_search(&self, val: i32) -> Result<usize, usize> {
let val = val as u32;
self.data.binary_search(&val)
}
}
impl<'a, D> LookupTable<'a, D>
where
LookupTable<'a, D>: LookupToI32,
{
fn reverse_index(&self, index: usize) -> i32 {
(self.min as i32 + (index * self.step as usize) as i32) * 100
}
fn ohm_lower_bound(&self) -> i32 {
self.lookup(1)
}
fn ohm_upper_bound(&self) -> i32 {
self.lookup(self.data.len() - 2)
}
fn interpolate_index(&self, ohm_100: i32, index: usize) -> i32 {
let first = (self.reverse_index(index), self.lookup(index));
let second = (self.reverse_index(index + 1), self.lookup(index + 1));
interpolate(ohm_100, first, second)
}
pub fn lookup_temperature(&self, ohm_100: i32) -> i32 {
if ohm_100 < self.ohm_lower_bound() {
self.interpolate_index(ohm_100, 0)
} else if ohm_100 > self.ohm_upper_bound() {
self.interpolate_index(ohm_100, self.data.len() - 2)
} else {
let index = match self.binary_search(ohm_100) {
Ok(val) => val,
Err(val) => val - 1,
};
self.interpolate_index(ohm_100, index)
}
}
}
pub const LOOKUP_TABLE_PT100_SHORT: LookupTable<'static, u16> = LookupTable {
min: 0,
step: 10,
data: &[
10000, 10390, 10779, 11167, 11554, 11940, 12324, 12708, 13090, 13471, 13851, 14229, 14607,
14983,
],
};
pub const LOOKUP_VEC_PT100: LookupTable<'static, u32> = LookupTable {
min: -200,
step: 20,
data: &[
1852, 2710, 3554, 4388, 5211, 6026, 6833, 7633, 8427, 9216, 10000, 10779, 11554, 12324,
13090, 13851, 14607, 15358, 16105, 16848, 17586, 18319, 19047, 19771, 20490, 21205, 21915,
22621, 23321, 24018, 24709, 25396, 26078, 26756, 27429, 28098, 28762, 29421, 30075, 30725,
31371, 32012, 32648, 33279, 33906, 34528, 35146, 35759, 36367, 36971,
],
};
pub const LOOKUP_VEC_PT1000: LookupTable<'static, u32> = LookupTable {
min: -200,
step: 20,
data: &[
18520, 27096, 35543, 43876, 52110, 60256, 68325, 76328, 84271, 92160, 100000, 107794,
115541, 123242, 130897, 138505, 146068, 153584, 161054, 168478, 175856, 183188, 190473,
197712, 204905, 212052, 219152, 226206, 233214, 240176, 247092, 253961, 260785, 267562,
274293, 280978, 287616, 294208, 300754, 307254, 313708, 320116, 326477, 332792, 339061,
345284, 351460, 357590, 363674, 369712,
],
};