const CRC8_INITIAL: u8 = 0xFF;
const CRC8_POLYNOMIAL: u8 = 0x31;
pub fn compute_crc8(data: &[u8]) -> u8 {
let mut crc = CRC8_INITIAL;
for &byte in data {
crc ^= byte;
for _ in 0..8 {
if crc & 0x80 != 0 {
crc = (crc << 1) ^ CRC8_POLYNOMIAL;
} else {
crc <<= 1;
}
}
}
crc
}
pub fn extract_readings(data: &[u8]) -> (u32, u32) {
let raw_humidity: u32 =
((data[1] as u32) << 12) | ((data[2] as u32) << 4) | ((data[3] as u32) >> 4);
let raw_temperature: u32 =
((data[3] as u32 & 0x0f) << 16) | ((data[4] as u32) << 8) | (data[5] as u32);
(raw_humidity, raw_temperature)
}
pub fn convert_humidity(humidity: u32) -> f32 {
let humidity = humidity as f32 / 0x100000 as f32;
humidity * 100.0
}
pub fn convert_temperature(temperature: u32) -> f32 {
let temperature = temperature as f32 / 0x100000 as f32;
temperature * 200.0 - 50.0
}
#[cfg(test)]
mod tests_crc8 {
use super::*;
#[test]
fn test_crc8_beef42() {
let data = [0xBE, 0xEF, 0x42]; let expected_crc = 0x04; assert_eq!(compute_crc8(&data), expected_crc);
}
#[test]
fn test_crc8_empty() {
let data: [u8; 0] = [];
assert_eq!(compute_crc8(&data), CRC8_INITIAL); }
#[test]
fn test_crc8_single_byte() {
let data = [0x42]; let expected_crc = 0xF3; assert_eq!(compute_crc8(&data), expected_crc);
}
#[test]
fn test_crc8_bit_flipping() {
let data1 = [0x12, 0x34, 0x56];
let data2 = [0x12, 0x32, 0x57]; assert_ne!(compute_crc8(&data1), compute_crc8(&data2));
}
}
#[cfg(test)]
mod tests_convert_humidity {
use super::*;
#[test]
fn test_convert_50_percent_rh() {
let raw_humidity = 0x80000;
let expected_humidity = 50.0; let converted_humidity = convert_humidity(raw_humidity);
assert_eq!(converted_humidity, expected_humidity);
assert!(converted_humidity >= 0.0 && converted_humidity <= 100.0); }
}
#[cfg(test)]
mod tests_convert_temperature {
use super::*;
#[test]
fn test_convert_25_degrees_c() {
let raw_temperature = 0x00060000;
let expected_temperature = 25.0; let actual_temperature = convert_temperature(raw_temperature);
assert_eq!(actual_temperature, expected_temperature);
assert!(actual_temperature >= -40.0 && actual_temperature <= 80.0); }
}
#[cfg(test)]
mod tests_extract_readings {
use super::*;
#[test]
fn test_extract_known_humidity() {
let data: [u8; 8] = [0x18, 0x80, 0x00, 0x00, 0x06, 0x66, 0x66, 0x00];
let (humidity, _) = extract_readings(&data);
assert_eq!(humidity, 0x80000); }
#[test]
fn test_extract_known_temperature() {
let data: [u8; 7] = [0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00];
let (_, temperature) = extract_readings(&data);
assert_eq!(temperature, 0x60000); }
}