bh1750_ehal/
lib.rs

1#![no_std]
2extern crate embedded_hal;
3
4use embedded_hal::blocking::delay;
5use embedded_hal::blocking::i2c;
6
7#[derive(Debug, Copy, Clone)]
8#[allow(non_camel_case_types)]
9pub enum Address {
10    ADDR_H = 0b101_1100, // 0x5c
11    ADDR_L = 0b010_0011, // 0x23
12}
13
14#[derive(Debug, Copy, Clone)]
15#[allow(non_camel_case_types)]
16enum Instruction {
17    POWER_DOWN = 0b0000_0000,
18    POWER_ON = 0b0000_0001,
19    RESET = 0b0000_0111,
20}
21
22#[allow(non_camel_case_types)]
23pub enum OneTimeMeasurement {
24    HIHGT_RES = 0b0010_0000,  // 1    lx resolution
25    HIHGT_RES2 = 0b0010_0001, // 0.5  lx resolution
26    LOW_RES = 0b0010_0011,    // 4    lx resolution
27}
28
29#[allow(non_camel_case_types)]
30pub enum ContinuesMeasurement {
31    HIHGT_RES = 0b0001_0000,  // 1    lx resolution
32    HIHGT_RES2 = 0b0001_0001, // 0.5  lx resolution
33    LOW_RES = 0b0001_0011,    // 4    lx resolution
34}
35pub struct BH1750<I2C, DELAY> {
36    com: I2C,
37    delay: DELAY,
38    address: Address,
39}
40
41impl<I2C, DELAY, E> BH1750<I2C, DELAY>
42where
43    I2C: i2c::WriteRead<Error = E>,
44    DELAY: delay::DelayMs<u32>,
45{
46    /// Create new BH1750 driver
47    pub fn new(i2c: I2C, delay: DELAY, address: Address) -> Result<Self, E> {
48        let chip = BH1750 {
49            com: i2c,
50            delay,
51            address,
52        };
53        Ok(chip)
54    }
55
56    pub fn light_one_shot(&mut self, mode: OneTimeMeasurement) -> u32 {
57        let delay = match mode {
58            OneTimeMeasurement::HIHGT_RES => 140,
59            OneTimeMeasurement::HIHGT_RES2 => 160,
60            OneTimeMeasurement::LOW_RES => 18,
61        };
62        let command = mode as u8;
63        self.send_instruction(command);
64        self.delay.delay_ms(delay);
65        raw_to_lx(self.resive_answer(command))
66    }
67
68    pub fn start_measurement(&mut self, mode: ContinuesMeasurement) {
69        let command = mode as u8;
70        self.send_instruction(command);
71    }
72
73    pub fn reset(&mut self) {
74        self.send_instruction(Instruction::RESET as u8);
75    }
76
77    pub fn power_down(&mut self) {
78        self.send_instruction(Instruction::POWER_DOWN as u8);
79    }
80
81    pub fn power_on(&mut self) {
82        self.send_instruction(Instruction::POWER_ON as u8);
83    }
84
85    pub fn get_measurement(&mut self, mode: ContinuesMeasurement) -> u32 {
86        let delay = match mode {
87            ContinuesMeasurement::HIHGT_RES => 120,
88            ContinuesMeasurement::HIHGT_RES2 => 120,
89            ContinuesMeasurement::LOW_RES => 16,
90        };
91        let command = mode as u8;
92        self.delay.delay_ms(delay);
93        raw_to_lx(self.resive_answer(command))
94    }
95
96    fn send_instruction(&mut self, instr: u8) {
97        let mut buffer = [0];
98        let _ = self
99            .com
100            .write_read(self.address as u8, &[instr], &mut buffer);
101    }
102
103    fn resive_answer(&mut self, instr: u8) -> u16 {
104        let mut data: [u8; 2] = [0; 2];
105        let _ = self.com.write_read(self.address as u8, &[instr], &mut data);
106        let raw_answer: u16 = ((data[0] as u16) << 8) | data[1] as u16;
107        raw_answer
108    }
109}
110
111fn raw_to_lx(raw: u16) -> u32 {
112    (raw as u32) * 12 / 10
113}